1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031
|
<!DOCTYPE html><html><head>
<title>critcl-cproc-types - C Runtime In Tcl (CriTcl)</title>
<style type="text/css"><!--
HTML {
background: #FFFFFF;
color: black;
}
BODY {
background: #FFFFFF;
color: black;
}
DIV.doctools {
margin-left: 10%;
margin-right: 10%;
}
DIV.doctools H1,DIV.doctools H2 {
margin-left: -5%;
}
H1, H2, H3, H4 {
margin-top: 1em;
font-family: sans-serif;
font-size: large;
color: #005A9C;
background: transparent;
text-align: left;
}
H1.doctools_title {
text-align: center;
}
UL,OL {
margin-right: 0em;
margin-top: 3pt;
margin-bottom: 3pt;
}
UL LI {
list-style: disc;
}
OL LI {
list-style: decimal;
}
DT {
padding-top: 1ex;
}
UL.doctools_toc,UL.doctools_toc UL, UL.doctools_toc UL UL {
font: normal 12pt/14pt sans-serif;
list-style: none;
}
LI.doctools_section, LI.doctools_subsection {
list-style: none;
margin-left: 0em;
text-indent: 0em;
padding: 0em;
}
PRE {
display: block;
font-family: monospace;
white-space: pre;
margin: 0%;
padding-top: 0.5ex;
padding-bottom: 0.5ex;
padding-left: 1ex;
padding-right: 1ex;
width: 100%;
}
PRE.doctools_example {
color: black;
background: #f5dcb3;
border: 1px solid black;
}
UL.doctools_requirements LI, UL.doctools_syntax LI {
list-style: none;
margin-left: 0em;
text-indent: 0em;
padding: 0em;
}
DIV.doctools_synopsis {
color: black;
background: #80ffff;
border: 1px solid black;
font-family: serif;
margin-top: 1em;
margin-bottom: 1em;
}
UL.doctools_syntax {
margin-top: 1em;
border-top: 1px solid black;
}
UL.doctools_requirements {
margin-bottom: 1em;
border-bottom: 1px solid black;
}
--></style>
</head>
<!-- Generated from file 'critcl_cproc.man' by tcllib/doctools with format 'html'
-->
<!-- Copyright &copy; Jean-Claude Wippler -- Copyright &copy; Steve Landers -- Copyright &copy; 2011-2018 Andreas Kupries
-->
<!-- critcl-cproc-types.n
-->
<body><hr> [
<a href="../toc.html">Table Of Contents</a>
| <a href="../index.html">Keyword Index</a>
] <hr>
<div class="doctools">
<h1 class="doctools_title">critcl-cproc-types(n) 3.1.18 doc "C Runtime In Tcl (CriTcl)"</h1>
<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
<p>critcl-cproc-types - Critcl - cproc Type Reference</p>
</div>
<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
<ul class="doctools_toc">
<li class="doctools_section"><a href="#toc">Table Of Contents</a></li>
<li class="doctools_section"><a href="#synopsis">Synopsis</a></li>
<li class="doctools_section"><a href="#section1">Description</a></li>
<li class="doctools_section"><a href="#section2">Standard argument types</a></li>
<li class="doctools_section"><a href="#section3">Standard result types</a></li>
<li class="doctools_section"><a href="#section4">Advanced: Adding types</a></li>
<li class="doctools_section"><a href="#section5">Examples</a>
<ul>
<li class="doctools_subsection"><a href="#subsection1">A Simple Procedure</a></li>
<li class="doctools_subsection"><a href="#subsection2">Custom Types, Introduction</a></li>
<li class="doctools_subsection"><a href="#subsection3">Custom Types, Semi-trivial</a></li>
<li class="doctools_subsection"><a href="#subsection4">Custom Types, Support structures</a></li>
<li class="doctools_subsection"><a href="#subsection5">Custom Types, Results</a></li>
</ul>
</li>
<li class="doctools_section"><a href="#section6">Authors</a></li>
<li class="doctools_section"><a href="#section7">Bugs, Ideas, Feedback</a></li>
<li class="doctools_section"><a href="#keywords">Keywords</a></li>
<li class="doctools_section"><a href="#category">Category</a></li>
<li class="doctools_section"><a href="#copyright">Copyright</a></li>
</ul>
</div>
<div id="synopsis" class="doctools_section"><h2><a name="synopsis">Synopsis</a></h2>
<div class="doctools_synopsis">
<ul class="doctools_requirements">
<li>package require <b class="pkgname">Tcl 8.4</b></li>
<li>package require <b class="pkgname">critcl <span class="opt">?3.1.18?</span></b></li>
</ul>
<ul class="doctools_syntax">
<li><a href="#1"><b class="cmd">::critcl::has-resulttype</b> <i class="arg">name</i></a></li>
<li><a href="#2"><b class="cmd">::critcl::resulttype</b> <i class="arg">name</i> <i class="arg">body</i> <span class="opt">?<i class="arg">ctype</i>?</span></a></li>
<li><a href="#3"><b class="cmd">::critcl::resulttype</b> <i class="arg">name</i> <b class="method">=</b> <i class="arg">origname</i></a></li>
<li><a href="#4"><b class="cmd">::critcl::has-argtype</b> <i class="arg">name</i></a></li>
<li><a href="#5"><b class="cmd">::critcl::argtype</b> <i class="arg">name</i> <i class="arg">body</i> <span class="opt">?<i class="arg">ctype</i>?</span> <span class="opt">?<i class="arg">ctypefun</i>?</span></a></li>
<li><a href="#6"><b class="cmd">::critcl::argtype</b> <i class="arg">name</i> <b class="method">=</b> <i class="arg">origname</i></a></li>
<li><a href="#7"><b class="cmd">::critcl::argtypesupport</b> <i class="arg">name</i> <i class="arg">code</i> <span class="opt">?<i class="arg">guard</i>?</span></a></li>
<li><a href="#8"><b class="cmd">::critcl::argtyperelease</b> <i class="arg">name</i> <i class="arg">code</i></a></li>
</ul>
</div>
</div>
<div id="section1" class="doctools_section"><h2><a name="section1">Description</a></h2>
<p><i class="term">C Runtime In Tcl</i>, or <i class="term"><a href="critcl_pkg.html">CriTcl</a></i> , is a system for compiling C code
embedded in Tcl on the fly and either loading the resulting objects into Tcl for
immediate use or packaging them for distribution. Use <i class="term"><a href="critcl_pkg.html">CriTcl</a></i> to improve
performance by rewriting in C those routines that are performance bottlenecks.</p>
<p>This document is a breakout of the descriptions for the predefined
argument- and result-types usable with the <b class="cmd">critcl::cproc</b>
command, as detailed in the reference manpage for the <b class="package"><a href="critcl_pkg.html">critcl</a></b>
package, plus the information on how to extend the predefined set with
custom types. The breakout was made to make this information easier to
find (toplevel document vs. having to search the large main reference).</p>
<p>Its intended audience are developers wishing to write Tcl
packages with embedded C code.</p>
</div>
<div id="section2" class="doctools_section"><h2><a name="section2">Standard argument types</a></h2>
<p>Before going into the details first a quick overview:</p>
<pre class="doctools_example">
Critcl type | C type | Tcl type | Notes
----------- | -------------- | --------- | ------------------------------
Tcl_Interp* | Tcl_Interp* | n/a | <em>Special</em>, only first
----------- | -------------- | --------- | ------------------------------
Tcl_Obj* | Tcl_Obj* | Any | <em>Read-only</em>
object | | | Alias of <b class="type">Tcl_Obj*</b> above
list | critcl_list | List | <em>Read-only</em>
----------- | -------------- | --------- | ------------------------------
char* | const char* | Any | <em>Read-only</em>, <em>string rep</em>
pstring | critcl_pstring | Any | <em>Read-only</em>
bytes | critcl_bytes | ByteArray | <em>Read-only</em>
----------- | -------------- | --------- | ------------------------------
int | int | Int |
long | long | Long |
wideint | Tcl_WideInt | WideInt |
double | double | Double |
float | float | Double |
----------- | -------------- | --------- | ------------------------------
X > 0 | | | For X in <b class="type">int</b> ... <b class="type">float</b> above.
X >= 0 | | | C types as per the base type X.
X < 0 | | | Allowed argument values are
X <= 0 | | | restricted as per the shown
X > 1 | | | relation
X >= 1 | | |
X < 1 | | | This is not a general mechanism
X <= 1 | | | open to other values. Only 0/1.
----------- | -------------- | --------- | ------------------------------
boolean | int | Boolean |
bool | | | Alias of <b class="type">boolean</b> above
----------- | -------------- | --------- | ------------------------------
bytearray | | | <em>DEPRECATED</em>
rawchar | | | <em>DEPRECATED</em>
rawchar* | | | <em>DEPRECATED</em>
double* | | | <em>DEPRECATED</em>
float* | | | <em>DEPRECATED</em>
int* | | | <em>DEPRECATED</em>
void* | | | <em>DEPRECATED</em>
</pre>
<p>And now the details:</p>
<dl class="doctools_definitions">
<dt>Tcl_Interp*</dt>
<dd><p><em>Attention</em>: This is a <em>special</em> argument type. It can
<em>only</em> be used by the <em>first</em> argument of a function.
Any other argument using it will cause critcl to throw an error.</p>
<p>When used, the argument will contain a reference to the current
interpreter that the function body may use. Furthermore the argument
will <em>not</em> be an argument of the Tcl command for the function.</p>
<p>This is useful when the function has to do more than simply
returning a value. Examples would be setting up error messages on
failure, or querying the interpreter for variables and other data.</p></dd>
<dt>Tcl_Obj*</dt>
<dd></dd>
<dt>object</dt>
<dd><p>The function takes an argument of type <b class="type">Tcl_Obj*</b>.
No argument checking is done.
The Tcl level word is passed to the argument as-is.
Note that this value must be treated as <em>read-only</em> (except for
hidden changes to its intrep, i.e. <i class="term">shimmering</i>).</p></dd>
<dt>pstring</dt>
<dd><p>The function takes an argument of type <b class="type">critcl_pstring</b>
containing the original <b class="type">Tcl_Obj*</b> reference of the Tcl argument,
plus the length of the string and a pointer to the character array.</p>
<pre class="doctools_example">
typedef struct critcl_pstring {
Tcl_Obj* o;
const char* s;
int len;
} critcl_pstring;
</pre>
<p>Note the <em>const</em>. The string is <em>read-only</em>. Any
modification can have arbitrary effects, from pulling out the rug
under the script because of string value and internal representation
not matching anymore, up to crashes anytime later.</p></dd>
<dt>list</dt>
<dd><p>The function takes an argument of type <b class="type">critcl_list</b> containing
the original <b class="type">Tcl_Obj*</b> reference of the Tcl argument, plus the
length of the Tcl list and a pointer to the array of the list
elements.</p>
<pre class="doctools_example">
typedef struct critcl_list {
Tcl_Obj* o;
Tcl_Obj* const* v;
int c;
} critcl_list;
</pre>
<p>The Tcl argument must be convertible to <b class="type">List</b>, an error is
thrown otherwise.</p>
<p>Note the <em>const</em>. The list is <em>read-only</em>. Any
modification can have arbitrary effects, from pulling out the rug
under the script because of string value and internal representation
not matching anymore, up to crashes anytime later.</p></dd>
<dt>bytearray</dt>
<dd></dd>
<dt>rawchar*</dt>
<dd></dd>
<dt>rawchar</dt>
<dd><p>The function takes an argument of type <b class="type">char*</b>.
The Tcl argument must be convertible to <b class="type">ByteArray</b>, an error is
thrown otherwise.
<em>Note</em> that the length of the <b class="type">ByteArray</b> is <em>not</em>
passed to the function, making this type not very usable.</p>
<p><em>Attention</em>: These types are considered <em>DEPRECATED</em>.
It is planned to remove their documentation in release 3.2, and their
implementation in release 3.3. Their deprecation can be undone if
good use cases are shown.</p></dd>
<dt>bytes</dt>
<dd><p>This is the <em>new</em> and usable <b class="type">ByteArray</b> type.</p>
<p>The function takes an argument of type <b class="type">critcl_bytes</b>
containing the original <b class="type">Tcl_Obj*</b> reference of the Tcl argument,
plus the length of the byte array and a pointer to the byte data.</p>
<pre class="doctools_example">
typedef struct critcl_bytes {
Tcl_Obj* o;
const unsigned char* s;
int len;
} critcl_list;
</pre>
<p>The Tcl argument must be convertible to <b class="type">ByteArray</b>, an error is
thrown otherwise.</p>
<p>Note the <em>const</em>. The bytes are <em>read-only</em>. Any
modification can have arbitrary effects, from pulling out the rug
under the script because of string value and internal representation
not matching anymore, up to crashes anytime later.</p></dd>
<dt>char*</dt>
<dd><p>The function takes an argument of type <b class="type">const char*</b>.
The string representation of the Tcl argument is passed in.</p>
<p>Note the <em>const</em>. The string is <em>read-only</em>. Any
modification can have arbitrary effects, from pulling out the rug
under the script because of string value and internal representation
not matching anymore, up to crashes anytime later.</p></dd>
<dt>double</dt>
<dd><p>The function takes an argument of type <b class="type">double</b>.
The Tcl argument must be convertible to <b class="type">Double</b>, an error is
thrown otherwise.</p></dd>
<dt>double > 0</dt>
<dd></dd>
<dt>double >= 0</dt>
<dd></dd>
<dt>double < 0</dt>
<dd></dd>
<dt>double <= 0</dt>
<dd></dd>
<dt>double > 1</dt>
<dd></dd>
<dt>double >= 1</dt>
<dd></dd>
<dt>double < 1</dt>
<dd></dd>
<dt>double <= 1</dt>
<dd><p>These are variants of <i class="term">double</i> above, restricting the argument
value to the shown relation. An error is thrown for Tcl arguments
outside of the specified range.
<em>Note:</em> This is not a general range specification syntax. Only
the listed types exist.</p></dd>
<dt>float</dt>
<dd><p>The function takes an argument of type <b class="type">float</b>.
The Tcl argument must be convertible to <b class="type">Double</b>, an error is
thrown otherwise.</p></dd>
<dt>float > 0</dt>
<dd></dd>
<dt>float >= 0</dt>
<dd></dd>
<dt>float < 0</dt>
<dd></dd>
<dt>float <= 0</dt>
<dd></dd>
<dt>float > 1</dt>
<dd></dd>
<dt>float >= 1</dt>
<dd></dd>
<dt>float < 1</dt>
<dd></dd>
<dt>float <= 1</dt>
<dd><p>These are variants of <i class="term">float</i> above, restricting the argument
value to the shown relation. An error is thrown for Tcl arguments
outside of the specified range.
<em>Note:</em> This is not a general range specification syntax. Only
the listed types exist.</p></dd>
<dt>boolean</dt>
<dd></dd>
<dt>bool</dt>
<dd><p>The function takes an argument of type <b class="type">int</b>.
The Tcl argument must be convertible to <b class="type">Boolean</b>, an error is
thrown otherwise.</p></dd>
<dt>channel</dt>
<dd><p>The function takes an argument of type <b class="type">Tcl_Channel</b>.
The Tcl argument must be convertible to type <b class="type">Channel</b>, an error
is thrown otherwise.
The channel is further assumed to be <em>already registered</em>
with the interpreter.</p></dd>
<dt>unshared-channel</dt>
<dd><p>This type is an extension of <b class="type">channel</b> above.
All of the information above applies.</p>
<p>Beyond that the channel must not be shared by multiple
interpreters, an error is thrown otherwise.</p></dd>
<dt>take-channel</dt>
<dd><p>This type is an extension of <b class="type">unshared-channel</b> above.
All of the information above applies.</p>
<p>Beyond that the code removes the channel from the current
interpreter without closing it, and disables all pre-existing event
handling for it.</p>
<p>With this the function takes full ownership of the channel in
question, taking it away from the interpreter invoking it. It is then
responsible for the lifecycle of the channel, up to and including
closing it.</p>
<p>Should the system the function is a part of wish to return
control of the channel back to the interpeter it then has to use the
result type <b class="type">return-channel</b>. This will undo the registration
changes made by this argument type.
<em>Note</em> however that the removal of pre-existing event handling
done here cannot be undone.</p>
<p><em>Attention</em> Removal from the interpreter without closing
the channel is effected by incrementing the channel's reference count
without providing an interpreter, before decrementing the same for the
current interpreter. This leaves the overall reference count intact
without causing Tcl to close it when it is removed from the
interpreter structures. At this point the channel is effectively a
globally-owned part of the system not associated with any interpreter.</p>
<p>The complementary result type then runs this sequence in
reverse. And if the channel is never returned to Tcl either the
function or the system it is a part of have to unregister the global
reference when they are done with it.</p></dd>
<dt>int</dt>
<dd><p>The function takes an argument of type <b class="type">int</b>.
The Tcl argument must be convertible to <b class="type">Int</b>, an error is thrown
otherwise.</p></dd>
<dt>int > 0</dt>
<dd></dd>
<dt>int >= 0</dt>
<dd></dd>
<dt>int < 0</dt>
<dd></dd>
<dt>int <= 0</dt>
<dd></dd>
<dt>int > 1</dt>
<dd></dd>
<dt>int >= 1</dt>
<dd></dd>
<dt>int < 1</dt>
<dd></dd>
<dt>int <= 1</dt>
<dd><p>These are variants of <i class="term">int</i> above, restricting the argument value
to the shown relation. An error is thrown for Tcl arguments outside of
the specified range.
<em>Note:</em> This is not a general range specification syntax. Only
the listed types exist.</p></dd>
<dt>long</dt>
<dd><p>The function takes an argument of type <b class="type">long int</b>.
The Tcl argument must be convertible to <b class="type">Long</b>, an error is
thrown otherwise.</p></dd>
<dt>long > 0</dt>
<dd></dd>
<dt>long >= 0</dt>
<dd></dd>
<dt>long < 0</dt>
<dd></dd>
<dt>long <= 0</dt>
<dd></dd>
<dt>long > 1</dt>
<dd></dd>
<dt>long >= 1</dt>
<dd></dd>
<dt>long < 1</dt>
<dd></dd>
<dt>long <= 1</dt>
<dd><p>These are variants of <i class="term">long</i> above, restricting the argument
value to the shown relation. An error is thrown for Tcl arguments
outside of the specified range.
<em>Note:</em> This is not a general range specification syntax. Only
the listed types exist.</p></dd>
<dt>wideint</dt>
<dd><p>The function takes an argument of type <b class="type">Tcl_WideInt</b>.
The Tcl argument must be convertible to <b class="type">WideInt</b>, an error is
thrown otherwise.</p></dd>
<dt>wideint > 0</dt>
<dd></dd>
<dt>wideint >= 0</dt>
<dd></dd>
<dt>wideint < 0</dt>
<dd></dd>
<dt>wideint <= 0</dt>
<dd></dd>
<dt>wideint > 1</dt>
<dd></dd>
<dt>wideint >= 1</dt>
<dd></dd>
<dt>wideint < 1</dt>
<dd></dd>
<dt>wideint <= 1</dt>
<dd><p>These are variants of <i class="term">wideint</i> above, restricting the argument
value to the shown relation. An error is thrown for Tcl arguments
outside of the specified range.
<em>Note:</em> This is not a general range specification syntax. Only
the listed types exist.</p></dd>
<dt>void*</dt>
<dd></dd>
<dt>double*</dt>
<dd></dd>
<dt>float*</dt>
<dd></dd>
<dt>int*</dt>
<dd><p>The function takes an argument of the same-named C type.
The Tcl argument must be convertible to ByteArray, an error is thrown
otherwise.
The bytes in the ByteArray are then re-interpreted as the raw
representation of a single C pointer of the given type which is then
passed as argument to the function.
In other words, this is for Tcl values somehow holding raw C pointers,
i.e. memory addresses.</p>
<p><em>Attention</em>: These types are considered <em>DEPRECATED</em>.
It is planned to remove their documentation in release 3.2, and their
implementation in release 3.3. Their deprecation can be undone if
good use cases are shown.</p></dd>
</dl>
</div>
<div id="section3" class="doctools_section"><h2><a name="section3">Standard result types</a></h2>
<p>Before going into the details first a quick overview:</p>
<pre class="doctools_example">
Critcl type | C type | Tcl type | Notes
------------- | -------------- | --------- | ------------------------------
void | n/a | n/a | Always OK. Body sets result
ok | int | n/a | Result code. Body sets result
------------- | -------------- | --------- | ------------------------------
int | int | Int |
boolean | | | Alias of <b class="type">int</b> above
bool | | | Alias of <b class="type">int</b> above
long | long | Long |
wideint | Tcl_WideInt | WideInt |
double | double | Double |
float | float | Double |
------------- | -------------- | --------- | ------------------------------
char* | char* | String | <em>Makes a copy</em>
vstring | | | Alias of <b class="type">char*</b> above
const char* | const char* | | Behavior of <b class="type">char*</b> above
------------- | -------------- | --------- | ------------------------------
string | | String | Freeable string set directly
| | | <em>No copy is made</em>
dstring | | | Alias of <b class="type">string</b> above
------------- | -------------- | --------- | ------------------------------
| | | For all below: Null is ERROR
| | | Body has to set any message
Tcl_Obj* | Tcl_Obj* | Any | <em>refcount --</em>
object | | | Alias of <b class="type">Tcl_Obj*</b> above
Tcl_Obj*0 | | Any | <em>refcount unchanged</em>
object0 | | | Alias of <b class="type">Tcl_Obj*0</b> above
------------- | -------------- | --------- | ------------------------------
known-channel | Tcl_Channel | String | Assumes to already be registered
new-channel | Tcl_Channel | String | New channel, will be registered
</pre>
<p>And now the details:</p>
<dl class="doctools_definitions">
<dt>Tcl_Obj*</dt>
<dd></dd>
<dt>object</dt>
<dd><p>If the returned <b class="type">Tcl_Obj*</b> is <b class="const">NULL</b>, the Tcl return code
is <b class="const">TCL_ERROR</b> and the function should <a href="https://www.tcl-lang.org/man/tcl/TclLib/SetResult.htm">set an error mesage</a>
as the interpreter result. Otherwise, the returned <b class="type">Tcl_Obj*</b> is
set as the interpreter result.</p>
<p>Note that setting an error message requires the function body
to have access to the interpreter the function is running in. See the
argument type <b class="type">Tcl_Interp*</b> for the details on how to make that
happen.</p>
<p>Note further that the returned <b class="type">Tcl_Obj*</b> should have a
reference count greater than <b class="const">0</b>. This is because the converter
decrements the reference count to release possession after setting the
interpreter result. It assumes that the function incremented the
reference count of the returned <b class="type">Tcl_Obj*</b>.
If a <b class="type">Tcl_Obj*</b> with a reference count of <b class="const">0</b> were
returned, the reference count would become <b class="const">1</b> when set as the
interpreter result, and immediately thereafter be decremented to
<b class="const">0</b> again, causing the memory to be freed. The system is then
likely to crash at some point after the return due to reuse of the
freed memory.</p></dd>
<dt>Tcl_Obj*0</dt>
<dd></dd>
<dt>object0</dt>
<dd><p>Like <b class="const">Tcl_Obj*</b> except that this conversion assumes that the
returned value has a reference count of <b class="const">0</b> and
<em>does not</em> decrement it. Returning a value whose reference
count is greater than <b class="const">0</b> is therefore likely to cause a memory
leak.</p>
<p>Note that setting an error message requires the function body
to have access to the interpreter the function is running in. See the
argument type <b class="type">Tcl_Interp*</b> for the details on how to make that
happen.</p></dd>
<dt>new-channel</dt>
<dd><p>A <b class="type">String</b> Tcl_Obj holding the name of the returned
<b class="type">Tcl_Channel</b> is set as the interpreter result.
The channel is further assumed to be <em>new</em>, and therefore
registered with the interpreter to make it known.</p></dd>
<dt>known-channel</dt>
<dd><p>A <b class="type">String</b> Tcl_Obj holding the name of the returned
<b class="type">Tcl_Channel</b> is set as the interpreter result.
The channel is further assumed to be <em>already registered</em>
with the interpreter.</p></dd>
<dt>return-channel</dt>
<dd><p>This type is a variant of <b class="type">new-channel</b> above.
It varies slightly from it in the registration sequence to be properly
complementary to the argument type <b class="type">take-channel</b>.
A <b class="type">String</b> Tcl_Obj holding the name of the returned
<b class="type">Tcl_Channel</b> is set as the interpreter result.
The channel is further assumed to be <em>new</em>, and therefore
registered with the interpreter to make it known.</p></dd>
<dt>char*</dt>
<dd></dd>
<dt>vstring</dt>
<dd><p>A <b class="type">String</b> Tcl_Obj holding a <em>copy</em> of the returned
<b class="type">char*</b> is set as the interpreter result. If the value is
allocated then the function itself and the extension it is a part of
are responsible for releasing the memory when the data is not in use
any longer.</p></dd>
<dt>const char*</dt>
<dd><p>Like <b class="const">char*</b> above, except that the returned string is
<b class="const">const</b>-qualified.</p></dd>
<dt>string</dt>
<dd></dd>
<dt>dstring</dt>
<dd><p>The returned <b class="type">char*</b> is directly set as the interpreter result
<em>without making a copy</em>. Therefore it must be dynamically
allocated via <b class="function">Tcl_Alloc</b>. Release happens automatically when the
Interpreter finds that the value is not required any longer.</p></dd>
<dt>double</dt>
<dd></dd>
<dt>float</dt>
<dd><p>The returned <b class="type">double</b> or <b class="type">float</b> is converted to a <b class="type">Double</b>
Tcl_Obj and set as the interpreter result.</p></dd>
<dt>boolean</dt>
<dd></dd>
<dt>bool</dt>
<dd><p>The returned <b class="type">int</b> value is converted to an <b class="type">Int</b> Tcl_Obj and set as
the interpreter result.</p></dd>
<dt>int</dt>
<dd><p>The returned <b class="type">int</b> value is converted to an <b class="type">Int</b> Tcl_Obj and set as
the interpreter result.</p></dd>
<dt>long</dt>
<dd><p>The returned <b class="type">long int</b> value is converted to a <b class="type">Long</b> Tcl_Obj and
set as the interpreter result.</p></dd>
<dt>wideint</dt>
<dd><p>The returned <b class="type">Tcl_WideInt</b> value is converted to a <b class="type">WideInt</b> Tcl_Obj
and set as the interpreter result.</p></dd>
<dt>ok</dt>
<dd><p>The returned <b class="type">int</b> value becomes the Tcl return code.
The interpreter result is left untouched and can be set by the
function if desired. Note that doing this requires the function body
to have access to the interpreter the function is running in. See the
argument type <b class="type">Tcl_Interp*</b> for the details on how to make that
happen.</p></dd>
<dt>void</dt>
<dd><p>The function does not return a value.
The interpreter result is left untouched and can be set by the function if
desired.</p></dd>
</dl>
</div>
<div id="section4" class="doctools_section"><h2><a name="section4">Advanced: Adding types</a></h2>
<p>While the <b class="cmd">critcl::cproc</b> command understands the most common C
types (as per the previous 2 sections), sometimes this is not enough.</p>
<p>To get around this limitation the commands in this section
enable users of <b class="package"><a href="critcl_pkg.html">critcl</a></b> to extend the set of argument and
result types understood by <b class="cmd">critcl::cproc</b>. In other words, they
allow them to define their own, custom, types.</p>
<dl class="doctools_definitions">
<dt><a name="1"><b class="cmd">::critcl::has-resulttype</b> <i class="arg">name</i></a></dt>
<dd><p>This command tests if the named result-type is known or not.
It returns a boolean value, <b class="const">true</b> if the type is known and
<b class="const">false</b> otherwise.</p></dd>
<dt><a name="2"><b class="cmd">::critcl::resulttype</b> <i class="arg">name</i> <i class="arg">body</i> <span class="opt">?<i class="arg">ctype</i>?</span></a></dt>
<dd><p>This command defines the result type <i class="arg">name</i>, and associates it
with the C code doing the conversion (<i class="arg">body</i>) from C to Tcl.
The C return type of the associated function, also the C type of the
result variable, is <i class="arg">ctype</i>. This type defaults to <i class="arg">name</i> if
it is not specified.</p>
<p>If <i class="arg">name</i> is already declared an error is thrown.
<em>Attention!</em> The standard result type <b class="const">void</b> is special as
it has no accompanying result variable. This cannot be expressed
by this extension command.</p>
<p>The <i class="arg">body</i>'s responsibility is the conversion of the
functions result into a Tcl result and a Tcl status. The first has to
be set into the interpreter we are in, and the second has to be
returned.</p>
<p>The C code of <i class="arg">body</i> is guaranteed to be called last in the
wrapper around the actual implementation of the <b class="cmd">cproc</b> in
question and has access to the following environment:</p>
<dl class="doctools_definitions">
<dt><b class="variable">interp</b></dt>
<dd><p>A Tcl_Interp* typed C variable referencing the
interpreter the result has to be stored into.</p></dd>
<dt><b class="variable">rv</b></dt>
<dd><p>The C variable holding the result to convert, of type
<i class="arg">ctype</i>.</p></dd>
</dl>
<p>As examples here are the definitions of two standard result types:</p>
<pre class="doctools_example">
resulttype int {
Tcl_SetObjResult(interp, Tcl_NewIntObj(rv));
return TCL_OK;
}
resulttype ok {
/* interp result must be set by cproc body */
return rv;
} int
</pre>
</dd>
<dt><a name="3"><b class="cmd">::critcl::resulttype</b> <i class="arg">name</i> <b class="method">=</b> <i class="arg">origname</i></a></dt>
<dd><p>This form of the <b class="cmd">resulttype</b> command declares <i class="arg">name</i> as an
alias of result type <i class="arg">origname</i>, which has to be defined
already. If this is not the case an error is thrown.</p></dd>
<dt><a name="4"><b class="cmd">::critcl::has-argtype</b> <i class="arg">name</i></a></dt>
<dd><p>This command tests if the named argument-type is known or not.
It returns a boolean value, <b class="const">true</b> if the type is known and
<b class="const">false</b> otherwise.</p></dd>
<dt><a name="5"><b class="cmd">::critcl::argtype</b> <i class="arg">name</i> <i class="arg">body</i> <span class="opt">?<i class="arg">ctype</i>?</span> <span class="opt">?<i class="arg">ctypefun</i>?</span></a></dt>
<dd><p>This command defines the argument type <i class="arg">name</i>, and associates it
with the C code doing the conversion (<i class="arg">body</i>) from Tcl to C.
<i class="arg">ctype</i> is the C type of the variable to hold the conversion result
and <i class="arg">ctypefun</i> is the type of the function argument itself.
Both types default to <i class="arg">name</i> if they are the empty string or are not
provided.</p>
<p>If <i class="arg">name</i> is already declared an error is thrown.</p>
<p><i class="arg">body</i> is a C code fragment that converts a Tcl_Obj* into a
C value which is stored in a helper variable in the underlying function.</p>
<p><i class="arg">body</i> is called inside its own code block to isolate local
variables, and the following items are in scope:</p>
<dl class="doctools_definitions">
<dt><b class="variable">interp</b></dt>
<dd><p>A variable of type <b class="const">Tcl_Interp*</b> which is the
interpreter the code is running in.</p></dd>
<dt><b class="const">@@</b></dt>
<dd><p>A placeholder for an expression that evaluates to the
<b class="const">Tcl_Obj*</b> to convert.</p></dd>
<dt><b class="const">@A</b></dt>
<dd><p>A placeholder for the name of the variable to store the
converted argument into.</p></dd>
</dl>
<p>As examples, here are the definitions of two standard argument types:</p>
<pre class="doctools_example">
argtype int {
if (Tcl_GetIntFromObj(interp, @@, &@A) != TCL_OK) return TCL_ERROR;
}
argtype float {
double t;
if (Tcl_GetDoubleFromObj(interp, @@, &t) != TCL_OK) return TCL_ERROR;
@A = (float) t;
}
</pre>
</dd>
<dt><a name="6"><b class="cmd">::critcl::argtype</b> <i class="arg">name</i> <b class="method">=</b> <i class="arg">origname</i></a></dt>
<dd><p>This form of the <b class="cmd">argtype</b> command declares <i class="arg">name</i> as an alias
of argument type <i class="arg">origname</i>, which has to be defined already. If
this is not the case an error is thrown.</p></dd>
<dt><a name="7"><b class="cmd">::critcl::argtypesupport</b> <i class="arg">name</i> <i class="arg">code</i> <span class="opt">?<i class="arg">guard</i>?</span></a></dt>
<dd><p>This command defines a C code fragment for the already defined
argument type <i class="arg">name</i> which is inserted before all functions
using that type. Its purpose is the definition of any supporting C
types needed by the argument type.
If the type is used by many functions the system ensures that only the
first of the multiple insertions of the code fragment is active, and
the others disabled.
The guard identifier is normally derived from <i class="arg">name</i>, but can also
be set explicitly, via <i class="arg">guard</i>. This latter allows different
custom types to share a common support structure without having to
perform their own guarding.</p></dd>
<dt><a name="8"><b class="cmd">::critcl::argtyperelease</b> <i class="arg">name</i> <i class="arg">code</i></a></dt>
<dd><p>This command defines a C code fragment for the already defined
argument type <i class="arg">name</i> which is inserted whenever the worker
function of a <b class="cmd">critcl::cproc</b> returns to the shim. It is the
responsibility of this fragment to unconditionally release any
resources the <b class="cmd">critcl::argtype</b> conversion code allocated.
An example of this are the <em>variadic</em> types for the support of
the special, variadic <i class="arg">args</i> argument to <b class="cmd">critcl::cproc</b>'s.
They allocate a C array for the collected arguments which has to be
released when the worker returns. This command defines the C code
for doing that.</p></dd>
</dl>
</div>
<div id="section5" class="doctools_section"><h2><a name="section5">Examples</a></h2>
<p>The examples shown here have been drawn from section "Embedding C" in
the document about <i class="term">Using CriTcl</i>. Please see that document
for many more examples.</p>
<div id="subsection1" class="doctools_subsection"><h3><a name="subsection1">A Simple Procedure</a></h3>
<p>Starting simple, let us assume that the Tcl code in question is
something like</p>
<pre class="doctools_example">
proc math {x y z} {
return [expr {(sin($x)*rand())/$y**log($z)}]
}
</pre>
<p>with the expression pretending to be something very complex and
slow. Converting this to C we get:</p>
<pre class="doctools_example">
critcl::cproc math {double x double y double z} double {
double up = rand () * sin (x);
double down = pow(y, log (z));
return up/down;
}
</pre>
<p>Notable about this translation:</p>
<ol class="doctools_enumerated">
<li><p>All the arguments got type information added to them, here
"double". Like in C the type precedes the argument name. Other
than that it is pretty much a Tcl dictionary, with keys and
values swapped.</p></li>
<li><p>We now also have to declare the type of the result, here
"double", again.</p></li>
<li><p>The reference manpage lists all the legal C types supported as
arguments and results.</p></li>
</ol>
</div>
<div id="subsection2" class="doctools_subsection"><h3><a name="subsection2">Custom Types, Introduction</a></h3>
<p>When writing bindings to external libraries <b class="cmd">critcl::cproc</b> is
usually the most convenient way of writing the lower layers. This is
however hampered by the fact that critcl on its own only supports a
few standard (arguably the most import) standard types, whereas the
functions we wish to bind most certainly will use much more, specific
to the library's function.</p>
<p>The critcl commands <b class="cmd">argtype</b>, <b class="cmd">resulttype</b> and their
adjuncts are provided to help here, by allowing a developer to extend
critcl's type system with custom conversions.</p>
<p>This and the three following sections will demonstrate this,
from trivial to complex.</p>
<p>The most trivial use is to create types which are aliases of
existing types, standard or other. As an alias it simply copies and
uses the conversion code from the referenced types.</p>
<p>Our example is pulled from an incomplete project of mine, a
binding to <i class="term">Jeffrey Kegler</i>'s <i class="term">libmarpa</i> library managing
Earley parsers. Several custom types simply reflect the typedef's done
by the library, to make the <b class="cmd">critcl::cproc</b>s as self-documenting
as the underlying library functions themselves.</p>
<pre class="doctools_example">
critcl::argtype Marpa_Symbol_ID = int
critcl::argtype Marpa_Rule_ID = int
critcl::argtype Marpa_Rule_Int = int
critcl::argtype Marpa_Rank = int
critcl::argtype Marpa_Earleme = int
critcl::argtype Marpa_Earley_Set_ID = int
...
method sym-rank: proc {
Marpa_Symbol_ID sym
Marpa_Rank rank
} Marpa_Rank {
return marpa_g_symbol_rank_set (instance->grammar, sym, rank);
}
...
</pre>
</div>
<div id="subsection3" class="doctools_subsection"><h3><a name="subsection3">Custom Types, Semi-trivial</a></h3>
<p>A more involved custom argument type would be to map from Tcl strings
to some internal representation, like an integer code.</p>
<p>The first example is taken from the <b class="package">tclyaml</b> package,
a binding to the <b class="package">libyaml</b> library. In a few places we have to
map readable names for block styles, scalar styles, etc. to the
internal enumeration.</p>
<pre class="doctools_example">
critcl::argtype yaml_sequence_style_t {
if (!encode_sequence_style (interp, @@, &@A)) return TCL_ERROR;
}
...
critcl::ccode {
static const char* ty_block_style_names [] = {
"any", "block", "flow", NULL
};
static int
encode_sequence_style (Tcl_Interp* interp, Tcl_Obj* style,
yaml_sequence_style_t* estyle)
{
int value;
if (Tcl_GetIndexFromObj (interp, style, ty_block_style_names,
"sequence style", 0, &value) != TCL_OK) {
return 0;
}
*estyle = value;
return 1;
}
}
...
method sequence_start proc {
pstring anchor
pstring tag
int implicit
yaml_sequence_style_t style
} ok {
/* Syntax: <instance> seq_start <anchor> <tag> <implicit> <style> */
...
}
...
</pre>
<p>It should be noted that this code precedes the advent of the
supporting generator package <b class="package"><a href="critcl_emap.html">critcl::emap</a></b>. using the
generator the definition of the mapping becomes much simpler:</p>
<pre class="doctools_example">
critcl::emap::def yaml_sequence_style_t {
any 0
block 1
flow 2
}
</pre>
<p>Note that the generator will not only provide the conversions, but
also define the argument and result types needed for their use by
<b class="cmd">critcl::cproc</b>.
Another example of such a semi-trivial argument type can be found in
the <b class="package">CRIMP</b> package, which defines a <b class="type">Tcl_ObjType</b> for
<i class="term">image</i> values. This not only provides a basic argument type for
any image, but also derived types which check that the image has a
specific format. Here we see for the first time non-integer arguments,
and the need to define the C types used for variables holding the C
level value, and the type of function parameters (Due to C promotion
rules we may need different types).</p>
<pre class="doctools_example">
critcl::argtype image {
if (crimp_get_image_from_obj (interp, @@, &@A) != TCL_OK) {
return TCL_ERROR;
}
} crimp_image* crimp_image*
...
set map [list <<type>> $type]
critcl::argtype image_$type [string map $map {
if (crimp_get_image_from_obj (interp, @@, &@A) != TCL_OK) {
return TCL_ERROR;
}
if (@A->itype != crimp_imagetype_find ("crimp::image::<<type>>")) {
Tcl_SetObjResult (interp,
Tcl_NewStringObj ("expected image type <<type>>",
-1));
return TCL_ERROR;
}
}] crimp_image* crimp_image*
...
</pre>
</div>
<div id="subsection4" class="doctools_subsection"><h3><a name="subsection4">Custom Types, Support structures</a></h3>
<p>The adjunct command <b class="cmd">critcl::argtypesupport</b> is for when the
conversion needs additional definitions, for example a helper
structure.</p>
<p>An example of this can be found among the standard types of
critcl itself, the <b class="type">pstring</b> type. This type provides the C
function with not only the string pointer, but also the string length,
and the <b class="type">Tcl_Obj*</b> this data came from. As <b class="cmd">critcl::cproc</b>'s
calling conventions allow us only one argument for the data of the
parameter a structure is needed to convey these three pieces of
information.</p>
<p>Thus the argument type is defined as</p>
<pre class="doctools_example">
critcl::argtype pstring {
@A.s = Tcl_GetStringFromObj(@@, &(@A.len));
@A.o = @@;
} critcl_pstring critcl_pstring
critcl::argtypesupport pstring {
typedef struct critcl_pstring {
Tcl_Obj* o;
const char* s;
int len;
} critcl_pstring;
}
</pre>
<p>In the case of such a structure being large we may wish to
allocate it on the heap instead of having it taking space on the
stack. If we do that we need another adjunct command,
<b class="cmd">critcl::argtyperelease</b>. This command specifies the code required
to release dynamically allocated resources when the worker function
returns, before the shim returns to the caller in Tcl.
To keep things simple our example is synthetic, a modification of
<b class="const">pstring</b> above, to demonstrate the technique. An actual, but
more complex example is the code to support the variadic <i class="arg">args</i>
argument of <b class="cmd">critcl::cproc</b>.</p>
<pre class="doctools_example">
critcl::argtype pstring {
@A = (critcl_pstring*) ckalloc(sizeof(critcl_pstring));
@A->s = Tcl_GetStringFromObj(@@, &(@A->len));
@A->o = @@;
} critcl_pstring* critcl_pstring*
critcl::argtypesupport pstring {
typedef struct critcl_pstring {
Tcl_Obj* o;
const char* s;
int len;
} critcl_pstring;
}
critcl::argtyperelease pstring {
ckfree ((char*)) @A);
}
</pre>
<p>Note, the above example shows only the most simple case of an
allocated argument, with a conversion that cannot fail (namely, string
retrieval). If the conversion can fail then either the allocation has
to be defered to happen only on successful conversion, or the
conversion code has to release the allocated memory itself in the
failure path, because it will never reach the code defined via
<b class="cmd">critcl::argtyperelease</b> in that case.</p>
</div>
<div id="subsection5" class="doctools_subsection"><h3><a name="subsection5">Custom Types, Results</a></h3>
<p>All of the previous sections dealt with argument conversions,
i.e. going from Tcl into C.
Custom result types are for the reverse direction, from C to Tcl.
This is usually easier, as most of the time errors should not be
possible. Supporting structures, or allocating them on the heap are
not really required and therefore not supported.</p>
<p>The example of a result type shown below was pulled from
<b class="package">KineTcl</b>. It is a variant of the builtin result type
<b class="type">Tcl_Obj*</b>, aka <b class="type">object</b>. The builtin conversion assumes
that the object returned by the function has a refcount of 1 (or
higher), with the function having held the reference, and releases
that reference after placing the value into the interp result. The
conversion below on the other hand assumes that the value has a
refcount of 0 and thus that decrementing it is forbidden, lest it be
released much to early, and crashing the system.</p>
<pre class="doctools_example">
critcl::resulttype KTcl_Obj* {
if (rv == NULL) { return TCL_ERROR; }
Tcl_SetObjResult(interp, rv);
/* No refcount adjustment */
return TCL_OK;
} Tcl_Obj*
</pre>
<p>This type of definition is also found in <b class="package">Marpa</b> and recent
hacking hacking on <b class="package">CRIMP</b> introduced it there as well. Which
is why this definition became a builtin type starting with version
3.1.16, under the names <b class="type">Tcl_Obj*0</b> and <b class="type">object0</b>.</p>
<p>Going back to errors and their handling, of course, if a
function we are wrapping signals them in-band, then the conversion of
such results has to deal with that. This happens for example in
<b class="package">KineTcl</b>, where we find</p>
<pre class="doctools_example">
critcl::resulttype XnStatus {
if (rv != XN_STATUS_OK) {
Tcl_AppendResult (interp, xnGetStatusString (rv), NULL);
return TCL_ERROR;
}
return TCL_OK;
}
critcl::resulttype XnDepthPixel {
if (rv == ((XnDepthPixel) -1)) {
Tcl_AppendResult (interp,
"Inheritance error: Not a depth generator",
NULL);
return TCL_ERROR;
}
Tcl_SetObjResult (interp, Tcl_NewIntObj (rv));
return TCL_OK;
}
</pre>
</div>
</div>
<div id="section6" class="doctools_section"><h2><a name="section6">Authors</a></h2>
<p>Jean Claude Wippler, Steve Landers, Andreas Kupries</p>
</div>
<div id="section7" class="doctools_section"><h2><a name="section7">Bugs, Ideas, Feedback</a></h2>
<p>This document, and the package it describes, will undoubtedly contain
bugs and other problems.
Please report them at <a href="https://github.com/andreas-kupries/critcl/issues">https://github.com/andreas-kupries/critcl/issues</a>.
Ideas for enhancements you may have for either package, application,
and/or the documentation are also very welcome and should be reported
at <a href="https://github.com/andreas-kupries/critcl/issues">https://github.com/andreas-kupries/critcl/issues</a> as well.</p>
</div>
<div id="keywords" class="doctools_section"><h2><a name="keywords">Keywords</a></h2>
<p><a href="../index.html#key8">C code</a>, <a href="../index.html#key3">Embedded C Code</a>, <a href="../index.html#key6">code generator</a>, <a href="../index.html#key0">compile & run</a>, <a href="../index.html#key10">compiler</a>, <a href="../index.html#key1">dynamic code generation</a>, <a href="../index.html#key2">dynamic compilation</a>, <a href="../index.html#key9">generate package</a>, <a href="../index.html#key4">linker</a>, <a href="../index.html#key5">on demand compilation</a>, <a href="../index.html#key7">on-the-fly compilation</a></p>
</div>
<div id="category" class="doctools_section"><h2><a name="category">Category</a></h2>
<p>Glueing/Embedded C code</p>
</div>
<div id="copyright" class="doctools_section"><h2><a name="copyright">Copyright</a></h2>
<p>Copyright © Jean-Claude Wippler<br>
Copyright © Steve Landers<br>
Copyright © 2011-2018 Andreas Kupries</p>
</div>
</div></body></html>
|