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 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342
|
.TH GPP 1 \" -*- nroff -*-
.SH NAME
GPP \- Generic Preprocessor
.SH SYNOPSIS
gpp [\-{o|O} \fIoutfile\fP] [\-I\fI/include/path\fP] [\-D\fIname=val\fP ...]
[\-z|+z] [\-x] [\-m] [\-C|\-T|\-H|\-X|\-P|\-U ... [\-M ...]]
[\-n|+n] [+c\fI<n>\fP \fIstr1\fP \fIstr2\fP] [+s\fI<n>\fP \fIstr1\fP \fIstr2\fP \fIc\fP]
[\-c \fIstr1\fP] [\-\-nostdinc] [\-\-nocurinc]
[\-\-curdirinclast] [\-\-warninglevel \fIn\fP]
[\-\-includemarker \fIstr\fP] [\-\-include \fIfile\fP]
[\fIinfile\fP]
gpp \-\-help
gpp \-\-version
.SH DESCRIPTION
.P
GPP is a general-purpose preprocessor with customizable syntax,
suitable for a wide range of preprocessing tasks. Its independence from
any programming language makes it much more versatile than cpp,
while its syntax is lighter and more flexible than that of m4.
.P
GPP is targeted at all common preprocessing tasks where cpp is not
suitable and where no very sophisticated features are needed. In order to be
able to process equally efficiently text files or source code in a variety
of languages, the syntax used by GPP is fully customizable. The
handling of comments and strings is especially advanced.
.P
Initially, GPP only understands a minimal set of built-in macros,
called \fImeta-macros\fP. These meta-macros allow the definition of
\fIuser macros\fP as well as some basic operations forming the core of
the preprocessing system, including conditional tests, arithmetic
evaluation, wildcard matching (globbing), and syntax
specification. All user macro definitions are global -- \fIi.e.\fP,
they remain valid until explicitly removed; meta-macros cannot be
redefined. With each user macro definition GPP keeps track of the
corresponding syntax specification so that a macro can be safely
invoked regardless of any subsequent change in operating mode.
.P
In addition to macros, GPP understands comments and strings, whose syntax
and behavior can be widely customized to fit any particular purpose.
Internally comments and strings are the same construction, so everything
that applies to comments applies to strings as well.
.SH OPTIONS
.P
GPP recognizes the following command-line switches and options. Note that
the \-nostdinc, \-nocurinc, \-curdirinclast, \-warninglevel, and \-includemarker
options from version 2.1 and earlier are deprecated and should not be used. Use
the "long option" variants instead (\-\-nostdinc, \fIetc.\fP).
.TP
.BI "\-h \-\-help" ""
Print a short help message.
.TP
.BI "\-\-version" ""
Print version information.
.TP
.BI "\-o " "outfile"
Specify a file to which all output should be sent (by default, everything
is sent to standard output).
.TP
.BI "\-O " "outfile"
Specify a file to which all output should be sent; output is simultanously
sent to stdout.
.TP
.BI "\-I" "/include/path"
Specify a path where the \fI#include\fP meta-macro will look for include
files if they are not present in the current directory. The default is
/usr/include if no \-I option is specified. Multiple \-I options may be
specified to look in several directories.
.TP
.BI "\-D" "name=val"
Define the user macro \fIname\fP as equal to \fIval\fP. This is strictly
equivalent to using the \fI#define\fP meta-macro, but makes it possible
to define macros from the command-line. If \fIval\fP makes references to
arguments or other macros, it should conform to the syntax of the mode
specified on the command-line. Starting with version 2.1, macro argument
naming is allowed on the command-line. The syntax is as follows:
\-D\fImacro\fP(\fIarg1\fP,...)=\fIdefinition\fP. The arguments are specified
in C-style syntax, without any whitespace, but the definition should still
conform to the syntax of the mode specified on the command-line.
.TP
.BI "+z" ""
Set text mode to Unix mode (LF terminator). Any CR character in the
input is systematically discarded. This is the default under Unix systems.
.TP
.BI "\-z" ""
Set text mode to DOS mode (CR-LF terminator). In this mode all CR characters
are removed from the input, and all output LF characters are converted to
CR-LF. This is the default if GPP is compiled with the WIN_NT option.
.TP
.BI "\-x" ""
Enable the use of the \fI#exec\fP meta-macro. Since \fI#exec\fP includes
the output of an arbitrary shell command line, it may cause a potential
security threat, and is thus disabled unless this option is specified.
.TP
.BI "\-m" ""
Enable automatic mode switching to the cpp compatibility mode if the name
of an included file ends in `.h' or `.c'. This makes it possible to
include C header files with only minor modifications.
.TP
.BI "\-n" ""
Prevent newline or whitespace characters from being removed from the input
when they occur as the end of a macro call or of a comment. By default,
when a newline or whitespace character forms the end of a macro or a comment
it is parsed as part of the macro call or comment and therefore removed from
output. Use the \-n option to keep the last character in the input stream
if it was whitespace or a newline. This is activated in cpp and Prolog
modes.
.TP
.BI "+n" ""
The opposite of \-n. This is the default in all modes except cpp and Prolog.
Note that +n must be placed \fIafter\fP \-C or \-P in order to have any effect.
.TP
.BI "\-U " "arg1 ... arg9"
User-defined mode. The nine following command-line arguments are taken to
be respectively the macro start sequence, the macro end sequence for a call
without arguments, the argument start sequence, the argument separator,
the argument end sequence, the list of characters to stack for argument
balancing, the list of characters to unstack, the string to be used for
referring to an argument by number, and finally the quote character (if
there is none an empty string should be provided).
These settings apply both to user macros and to meta-macros, unless the \-M
option is used to define other settings for meta-macros. See the section
on syntax specification for more details.
.TP
.BI "\-M " "arg1 ... arg7"
User-defined mode specifications for meta-macros. This option can only be
used together with \-M. The seven following command-line arguments are
taken to be respectively the macro start sequence, the macro end sequence
for a call without arguments, the argument start sequence, the argument
separator, the argument end sequence, the list of characters to stack for
argument balancing, and the list of characters to unstack. See below for
more details.
.TP
.BI "(default mode)" ""
The default mode is a vaguely cpp-like mode, but it does not handle
comments, and presents various incompatibilities with cpp.
Typical meta-macros and user macros look like this:
#define x y
macro(arg,...)
This mode is equivalent to
-U "" "" "(" "," ")" "(" ")" "#" "\\\\"
-M "#" "\\n" " " " " "\\n" "(" ")"
.TP
.BI "\-C" ""
cpp compatibility mode. This is the mode where GPP's behavior is the
closest to that of cpp. Unlike in the default mode, meta-macro expansion
occurs only at the beginning of lines, and C comments and strings are
understood. This mode is equivalent to
-n -U "" "" "(" "," ")" "(" ")" "#" ""
-M "\\n#\\w" "\\n" " " " " "\\n" "" ""
+c "/*" "*/" +c "//" "\\n" +c "\\\\\\n" ""
+s "\\"" "\\"" "\\\\" +s "'" "'" "\\\\"
.TP
.BI "\-T" ""
TeX-like mode. In this mode, typical meta-macros and user macros look like
this:
\\define{x}{y}
\\macro{arg}{...}
No comments are understood. This mode is equivalent to
-U "\\\\" "" "{" "}{" "}" "{" "}" "#" "@"
.TP
.BI "\-H" ""
HTML-like mode. In this mode, typical meta-macros and user macros look like
this:
<#define x|y>
<#macro arg|...>
No comments are understood. This mode is equivalent to
-U "<#" ">" "\\B" "|" ">" "<" ">" "#" "\\\\"
.TP
.BI "\-X" ""
XHTML-like mode. In this mode, typical meta-macros and user macros look like
this:
<#define x|y/>
<#macro arg|.../>
No comments are understood. This mode is equivalent to
-U "<#" "/>" "\\B" "|" "/>" "<" ">" "#" "\\\\"
.TP
.BI "\-P" ""
Prolog-compatible cpp-like mode. This mode differs from the cpp
compatibility mode by its handling of comments, and is equivalent to
-n -U "" "" "(" "," ")" "(" ")" "#" ""
-M "\\n#\\w" "\\n" " " " " "\\n" "" ""
+ccss "\\!o/*" "*/" +ccss "%" "\\n" +ccii "\\\\\\n" ""
+s "\\"" "\\"" "" +s "\\!#'" "'" ""
.TP
.BI "+c" "<n> str1 str2"
Specify comments. Any unquoted occurrence of \fIstr1\fP will be
interpreted as the beginning of a comment. All input up to the first
following occurrence of \fIstr2\fP will be discarded. This
option may be used multiple times to specify different types of comment
delimiters. The optional parameter \fI<n>\fP can be specified to
alter the behavior of the comment and, \fIe.g.\fP, turn it into a string or make it
ignored under certain circumstances, see below.
.TP
.BI "\-c " "str1"
Un-specify comments or strings. The comment/string specification whose
start sequence is \fIstr1\fP is removed. This is useful to alter the
built-in comment specifications of a standard mode -- \fIe.g.\fP, the cpp
compatibility mode.
.TP
.BI "+s" "<n> str1 str2 c"
Specify strings. Any unquoted occurrence of \fIstr1\fP will be
interpreted as the beginning of a string. All input up to the first
following occurrence of \fIstr2\fP will be output as is without any
evaluation. The delimiters themselves are output. If \fIc\fP is non-empty,
its first character is used as a \fIstring-quote character\fP -- \fIi.e.\fP, a
character whose presence immediately before an occurrence of \fIstr2\fP
prevents it from terminating the string.
The optional parameter \fI<n>\fP can be specified to
alter the behavior of the string and, \fIe.g.\fP, turn it into a comment, enable
macro evaluation inside the string, or make the string specification
ignored under certain circumstances. See below.
.TP
.BI "\-s " "str1"
Un-specify comments or strings. Identical to \-c.
.TP
.BI "\-\-include " "file"
Process \fIfile\fP before \fIinfile\fP
.TP
.BI "\-\-nostdinc" ""
Do not look for include files in the standard directory /usr/include.
.TP
.BI "\-\-nocurinc" ""
Do not look for include files in the current directory.
.TP
.BI "\-\-curdirinclast" ""
Look for include files in the current directory \fIafter\fP the directories
specified by \fI\-I\fP rather than before them.
.TP
.BI "\-\-warninglevel " "n"
Set warning level to \fIn\fP (0, 1 or 2). Default is 2 (most verbose).
.TP
.BI "\-\-includemarker " "str"
keep track of \fI#include\fP directives by inserting a marker in the
output stream. The format of the marker is determined by \fIstr\fP, which
must contain three occurrences of the character \fI%\fP (or equivalently
\fI?\fP). The first occurrence is replaced with the line number, the second
with the file name, and the third with 1, 2 or blank. When this option
is specified in default, cpp or Prolog mode, GPP does its best to
ensure that line numbers are the same in the output as in the input by
inserting blank lines in the place of definitions or comments.
.TP
.BI "infile" ""
Specify an input file from which GPP reads its input. If no input
file is specified, input is read from standard input.
.SH SYNTAX SPECIFICATION
.P
The syntax of a macro call is as follows: it must start with a
sequence of characters matching the \fImacro start sequence\fP as specified
in the current mode, followed immediately by the name of the macro, which
must be a valid \fIidentifier\fP -- \fIi.e.\fP, a sequence of letters, digits, or
underscores ("_"). The macro name must be followed by a \fIshort macro end
sequence\fP if the macro has no arguments, or by a sequence of arguments
initiated by an \fIargument start sequence\fP. The various arguments are
then separated by an \fIargument separator\fP, and the macro ends with
a \fIlong macro end sequence\fP.
.P
In all cases, the parameters of the current context -- \fIi.e.\fP, the arguments
passed to the body being evaluated -- can be referred to by using an
\fIargument reference sequence\fP followed by a digit between 1 and 9.
Alternatively, macro parameters may be named (see below). Furthermore, to
avoid interference between the GPP syntax and the contents of the input file,
a \fIquote character\fP is provided. The quote character can be used to
prevent the interpretation of a macro call, comment, or string as anything
but plain text. The quote character "protects" the following character, and
always gets removed during evaluation. Two consecutive quote characters
evaluate as a single quote character.
.P
Finally, to facilitate proper argument delimitation, certain characters can
be "stacked" when they occur in a macro argument, so that the argument
separator or macro end sequence are not parsed if the argument body is not
balanced. This allows nesting macro calls without using quotes. If an
improperly balanced argument is needed, quote characters should be added in
front of some stacked characters to make it balanced.
.P
The macro construction sequences described above can be different for
meta-macros and for user macros: this is the case in cpp mode, for example.
Note that, since meta-macros can only have up to two arguments, the
delimitation rules for the second argument are somewhat sloppier, and
unquoted argument separator sequences are allowed in the second argument
of a meta-macro.
.P
Unless one of the standard operating modes is selected, the above syntax
sequences can be specified either on the command-line, using the \-M and
\-U options respectively for meta-macros and user macros, or inside an
input file via the \fI#mode meta\fP and \fI#mode user\fP meta-macro calls.
In both cases the mode description consists of nine parameters for user macro
specifications, namely the macro start sequence, the short macro end
sequence, the argument start sequence, the argument separator, the long
macro end sequence, the string listing characters to stack, the string
listing characters to unstack, the argument reference sequence, and finally
the quote character. As explained below, these sequences should be supplied
using the syntax of C strings; they must start with a non-alphanumeric
character, and in the first five strings special matching sequences can
be used (see below). If the argument corresponding to the quote character
is the empty string, that argument's functionality is disabled. For meta-macro
specifications there are only seven parameters, as the argument reference
sequence and quote character are shared with the user macro syntax.
.P
The structure of a comment/string is as follows: it must start with a
sequence of characters matching the given \fIcomment/string start sequence\fP,
and always ends at the first occurrence of the \fIcomment/string end
sequence\fP, unless it is preceded by an odd number of occurrences of the
\fIstring-quote character\fP (if such a character has been specified).
In certain cases comment/strings can be specified to enable macro evaluation
inside the comment/string; in that case, if a quote character has been
defined for macros it can be used as well to prevent the comment/string from
ending, with the difference that the macro quote character is always removed
from output whereas the string-quote character is always output. Also note
that under certain circumstances a comment/string specification can be
\fIdisabled\fP, in which case the comment/string start sequence is simply
ignored. Finally, it is possible to specify a \fIstring warning character\fP
whose presence inside a comment/string will cause GPP to output a warning
(this is useful to locate unterminated strings in cpp mode).
Note that input files are not allowed to contain unterminated comments/strings.
.P
A comment/string specification can be declared from within the input
file using the \fI#mode comment\fP meta-macro call (or equivalently
\fI#mode string\fP), in which case the number of C strings to be given as
arguments to describe the comment/string can be anywhere between two and four:
the first two arguments (mandatory) are the start sequence and the end
sequence, and can make use of the special matching sequences (see below).
They may not start with alphanumeric characters. The first
character of the third argument, if there is one, is used as the string-quote
character (use an empty string to disable the functionality), and the
first character of the fourth argument, if there is one, is used as the
string-warning character. A specification may also be given from the
command-line, in which case there must be two arguments if using the
+c option and three if using the +s option.
.P
The behavior of a comment/string is specified by a three-character
modifier string, which may be passed as an optional argument either
to the +c/+s command-line options or to the \fI#mode comment\fP/\fI#mode
string\fP meta-macros. If no modifier string is specified, the default
value is "ccc" for comments and "sss" for strings. The first character
corresponds to the behavior inside meta-macro calls (including user-macro
definitions since these come inside a \fI#define\fP meta-macro call),
the second character corresponds to the behavior inside user-macro
parameters, and the third character corresponds to the behavior outside
of any macro call. Each of these characters can take the following
values:
.TP
.BI "i" ""
disable the comment/string specification.
.TP
.BI "c" ""
comment (neither evaluated nor output).
.TP
.BI "s" ""
string (the string and its delimiter sequences are output as-is).
.TP
.BI "q" ""
quoted string (the string is output as-is, without the delimiter sequences).
.TP
.BI "C" ""
evaluated comment (macros are evaluated, but output is discarded).
.TP
.BI "S" ""
evaluated string (macros are evaluated, delimiters are output).
.TP
.BI "Q" ""
evaluated quoted string (macros are evaluated, delimiters are not output).
.P
Important note: any occurrence of a comment/string start sequence inside
another comment/string is always ignored, even if macro evaluation is
enabled. In other words, comments/strings cannot be nested. In particular,
the `Q' modifier can be a convenient way of defining a syntax for
temporarily disabling all comment and string specifications.
.P
Syntax specification strings should always be provided as C strings,
whether they are given as arguments to a \fI#mode\fP meta-macro call or
on the command-line of a Unix shell. If command-line arguments are given
via another method than a standard Unix shell, then the shell behavior
must be emulated -- \fIi.e.\fP, the surrounding "" quotes should be removed,
all occurrences of `\\\\' should be replaced by a single backslash,
and similarly `\\"' should be replaced by `"'.
Sequences like `\\n' are recognized by GPP and should be left as is.
.P
Special sequences matching certain subsets of the character set can be
used. They are of the form `\\\fIx\fP', where \fIx\fP is one of:
.TP
.BI "b" ""
matches any sequence of one or more spaces or tab characters (`\\b' is
identical to `\ ').
.TP
.BI "w" ""
matches any sequence of zero or more spaces or tab characters.
.TP
.BI "B" ""
matches any sequence of one or more spaces, tabs or newline characters.
.TP
.BI "W" ""
matches any sequence of zero or more spaces, tabs or newline characters.
.TP
.BI "a" ""
an alphabetic character (`a' to `z' and `A' to `Z').
.TP
.BI "A" ""
an alphabetic character, or a space, tab or newline.
.TP
.BI "#" ""
a digit (`0' to `9').
.TP
.BI "i" ""
an identifier character. The set of matched characters is customizable
using the \fI#mode charset id\fP command. The default setting matches
alphanumeric characters and underscores (`a' to `z', `A' to `Z', `0' to `9'
and `_').
.TP
.BI "t" ""
a tab character.
.TP
.BI "n" ""
a newline character.
.TP
.BI "o" ""
an operator character. The set of matched characters is customizable
using the \fI#mode charset op\fP command. The default setting matches
all characters in "+-*/\\^<>=`~:.?@#&!%|", except in Prolog mode
where `!', `%' and `|' are not matched.
.TP
.BI "O" ""
an operator character or a parenthesis character. The set of additional
matched characters in comparison with `\\o' is customizable using the
\fI#mode charset par\fP command. The default setting is to have the
characters in "()[]{}" as parentheses.
.P
Moreover, all of these matching subsets except `\\w' and `\\W' can be
negated by inserting a `!' -- \fIi.e.\fP, by writing `\\!\fIx\fP' instead of `\\\fIx\fP'.
.P
Note an important distinctive feature of \fIstart sequences\fP: when the
first character of a macro or comment/string start sequence is '\ ' or one
of the above special sequences, it is not taken to be part of the sequence
itself but is used instead as a context check: for example a start sequence
beginning with '\\n' matches only at the beginning of a line, but the
matching newline character is not taken to be part of the sequence.
Similarly a start sequence beginning with '\ ' matches only if some
whitespace is present, but the matching whitespace is not considered to
be part of the start sequence and is therefore sent to output. If a context
check is performed at the very beginning of a file (or more generally of
any body to be evaluated), the result is the same as matching with a newline
character (this makes it possible for a cpp-mode file to start with a
meta-macro call).
.P
Two special syntax rules were added in version 2.1. First,
argument references (#\fIn\fP) are no longer evaluated when they are
outside of macro calls and definitions. However, they are no longer allowed
to appear (unless protected by quote characters) inside a call to a defined
user macro; the current behavior (backwards compatible) is to remove them
silently from the input if that happens.
.P
Second, if the end sequence (either for macros or comments) consists of a
single newline character, and if delimitation rules lead
to evaluation in a context where the final newline character is absent,
GPP silently ignores the missing newline instead of producing an
error. The main consequence is that meta-macro calls can now be nested
in a simple way in standard, cpp and Prolog modes.
.SH EVALUATION RULES
.P
Input is read sequentially and interpreted according to the rules of the
current mode. All input text is first matched against the specified
comment/string start sequences of the current mode (except those which
are disabled by the 'i' modifier), unless the body being evaluated is
the contents of a comment/string whose modifier enables macro evaluation.
The most recently defined comment/string specifications are checked for
first. Important note: comments may not appear between the name of a macro
and its arguments (doing so results in undefined behavior).
.P
Anything that is not a comment/string is then matched against a possible
meta-macro call, and if that fails too, against a possible user-macro
call. All remaining text undergoes substitution of argument reference
sequences by the relevant argument text (empty unless the body being
evaluated is the definition of a user macro) and removal of the quote
character if there is one.
.P
Note that meta-macro arguments are passed to the meta-macro prior to
any evaluation (although the meta-macro may choose to evaluate them,
see meta-macro descriptions below). In the case of the \fI#mode\fP
meta-macro, GPP temporarily adds a comment/string specification to
enable recognition of C strings ("...") and prevent any evaluation
inside them, so no interference of the characters being put in the C
string arguments to \fI#mode\fP with the current syntax is to be feared.
.P
On the other hand, the arguments to a user macro are systematically
evaluated, and then passed as context parameters to the macro definition
body, which gets evaluated with that environment. The only exception is
when the macro definition is empty, in which case its arguments are not
evaluated. Note that GPP temporarily switches back to the mode in which
the macro was defined in order to evaluate it, so it is perfectly safe
to change the operating mode between the time a macro is defined
and the time when it is called. Conversely, if a user macro wishes to
work with the current mode instead of the one that was used to define it
it needs to start with a \fI#mode restore\fP call and end with a
\fI#mode save\fP call.
.P
A user macro may be defined with named arguments (see \fI#define\fP
description below). In that case, when the macro definition is being
evaluated, each named parameter causes a temporary virtual user-macro
definition to be created; such a macro may be called only without arguments
and simply returns the text of the corresponding argument.
.P
Note that, since macros are evaluated when they are called rather than
when they are defined, any attempt to call a recursive macro causes
undefined behavior except in the very specific case when the macro
uses \fI#undef\fP to erase itself after finitely many loop iterations.
.P
Finally, a special case occurs when a user macro whose definition does not
involve any arguments (neither named arguments nor the argument reference
sequence) is called in a mode where the short user-macro end sequence is
empty (\fIe.g.\fP, cpp or TeX\ mode). In that case it is assumed to be an
\fIalias macro\fP: its arguments are first evaluated in the current mode
as usual, but instead of being passed to the macro definition as parameters
(which would cause them to be discarded) they are actually appended to the
macro definition, using the syntax rules of the mode in which the macro was
defined, and the resulting text is evaluated again. It is therefore
important to note that, in the case of a macro alias, the arguments
actually get evaluated twice in two potentially different modes.
.SH META-MACROS
.P
These macros are always predefined. Their actual calling sequence depends
on the current mode; here we use cpp-like notation.
.TP
.BI "#define " "x y"
This defines the user macro \fIx\fP as \fIy\fP. \fIy\fP can be any valid
GPP input, and may for example refer to other macros. \fIx\fP must
be an identifier (\fIi.e.\fP, a sequence of alphanumeric characters and '_'),
unless named arguments are specified. If \fIx\fP is already defined,
the previous definition is overwritten. If no second argument is given,
\fIx\fP will be defined as a macro that outputs nothing. Neither \fIx\fP
nor \fIy\fP are evaluated; the macro definition is only evaluated when
it is called, not when it is declared.
It is also possible to name the arguments in a macro definition: in
that case, the argument \fIx\fP should be a user-macro call whose arguments
are all identifiers. These identifiers become available as user-macros
inside the macro definition; these virtual macros must be called without
arguments, and evaluate to the corresponding macro parameter.
.TP
.BI "#defeval " "x y"
This acts in a similar way to \fI#define\fP, but the second argument \fIy\fP
is evaluated immediately. Since user macro definitions are also evaluated
each time they are called, this means that the macro \fIy\fP will undergo
\fItwo\fP successive evaluations. The usefulness of \fI#defeval\fP is
considerable as it is the only way to evaluate something more than once,
which may be needed to force evaluation of the arguments of a
meta-macro that normally doesn't perform any evaluation. However since all
argument references evaluated at define-time are understood as the arguments
of the body in which the macro is being defined and not as the arguments of
the macro itself, usually one has to use the quote character to prevent
immediate evaluation of argument references.
.TP
.BI "#undef " "x"
This removes any existing definition of the user macro \fIx\fP.
.TP
.BI "#ifdef " "x"
This begins a conditional block. Everything that follows is evaluated only
if the identifier \fIx\fP is defined, and until either a \fI#else\fP or a
\fI#endif\fP statement is reached. Note, however, that the commented text is
still scanned thoroughly, so its syntax must be valid. It is in particular
legal to have the \fI#else\fP or \fI#endif\fP statement ending the conditional
block appear only as the result of a user-macro expansion and not explicitly
in the input.
.TP
.BI "#ifndef " "x"
This begins a conditional block. Everything that follows is evaluated only
if the identifier \fIx\fP is not defined.
.TP
.BI "#ifeq " "x y"
This begins a conditional block. Everything that follows is evaluated
only if the results of the evaluations of \fIx\fP and \fIy\fP are identical
as character strings. Any leading or trailing whitespace is ignored for
the comparison. Note that in cpp-mode any unquoted whitespace character
is understood as the end of the first argument, so it is necessary to be
careful.
.TP
.BI "#ifneq " "x y"
This begins a conditional block. Everything that follows is evaluated only
if the results of the evaluations of \fIx\fP and \fIy\fP are not identical
(even up to leading or trailing whitespace).
.TP
.BI "#else" ""
This toggles the logical value of the current conditional block. What
follows is evaluated if and only if the preceding input was commented out.
.TP
.BI "#endif" ""
This ends a conditional block started by a \fI#if...\fP meta-macro.
.TP
.BI "#include " "file"
This causes GPP to open the specified file and evaluate its contents,
inserting the resulting text in the current output. All defined user macros
are still available in the included file, and reciprocally all macros
defined in the included file will be available in everything that
follows. The include file is looked for first in the current directory,
and then, if not found, in one of the directories specified by the \fI\-I\fP
command-line option (or \fI/usr/include\fP if no directory was specified).
Note that, for compatibility reasons, it is possible to put the file name
between "" or <>.
The order in which the various directories are searched for include files
is affected by the \fI\-nostdinc\fP, \fI\-nocurinc\fP and \fI\-curdirinclast\fP
command-line options.
Upon including a file, GPP immediately saves a copy of the current operating
mode onto the mode stack, and restores the operating mode at the end of the
included file. The included file may override this behavior by starting with
a \fI#mode restore\fP call and ending with a \fI#mode push\fP call.
Additionally, when the \fI\-m\fP command line option is specified, GPP will
automatically switch to the cpp compatibility mode upon including a file
whose name ends with either '.c' or '.h'.
.TP
.BI "#exec " "command"
This causes GPP to execute the specified command line and include
its standard output in the current output. Note that, for security reasons,
this meta-macro is disabled unless the \fI\-x\fP command line flag was specified.
If use of \fI#exec\fP is not allowed, a warning message is printed
and the output is left blank. Note that the specified command line is
evaluated before being executed, thus allowing the use of macros in the
command-line. However, the output of the command is included verbatim and
not evaluated. If you need the output to be evaluated, you must use
\fI#defeval\fP (see above) to cause a double evaluation.
.TP
.BI "#eval " "expr"
The \fI#eval\fP meta-macro attempts to evaluate \fIexpr\fP first by
expanding macros (normal GPP evaluation) and then by performing
arithmetic evaluation and/or wildcard matching. The syntax and
operator precedence for arithmetic expressions are the same as in C;
the only missing operators are <<, >>, ?:, and the assignment
operators.
POSIX-style wildcard matching ('globbing') is available only on POSIX
implementations and can be invoked with the =~ operator. In
brief, a '?' matches any single character, a '*' matches any string
(including the empty string), and '[...]' matches any one of the
characters enclosed in brackets. A '[...]' class is complemented
when the first character in the brackets is '!'. The characters in a '[...]'
class can also be specified as a range using the '\-'
character -- \fIe.g.\fP, '[F\-N]' is equivalent to '[FGHIJKLMN]'.
If unable to assign a numerical value to the result, the
returned text is simply the result of macro expansion without any
arithmetic evaluation. The only exceptions to this rule are the
comparison operators ==, !=, <, >, <=, and >= which, if one of
the sides does not evaluate to a number, perform string comparison
instead (ignoring trailing and leading spaces). Additionally, the
\fIlength(...)\fP arithmetic operator returns the length in
characters of its evaluated argument.
Inside arithmetic expressions, the \fIdefined(...)\fP special user macro
is also available: it takes only one argument, which is not evaluated, and
returns 1 if it is the name of a user macro and 0 otherwise.
.TP
.BI "#if " "expr"
This meta-macro invokes the arithmetic/globbing evaluator in the same
manner as \fI#eval\fP and compares the result of evaluation with the
string "0" in order to begin a conditional block. In particular note
that the logical value of \fIexpr\fP is always true when it cannot be
evaluated to a number.
.TP
.BI "#elif " "expr"
This meta-macro can be used to avoid nested \fI#if\fP conditions.
\fI#if\fP ... \fI#elif\fP ... \fI#endif\fP is equivalent
to \fI#if\fP ... \fI#else\fP \fI#if\fP ...
\fI#endif\fP \fI#endif\fP.
.TP
.BI "#mode " "keyword ..."
This meta-macro controls GPP's operating mode. See below for a list of
\fI#mode\fP commands.
.TP
.BI "#line" ""
This meta-macro evaluates to the line number of the current input file.
.TP
.BI "#file" ""
This meta-macro evaluates to the filename of the current input file as
it appears on the command line or in the argument to \fI#include\fP.
If GPP is reading its input from stdin, then \fI#file\fP evaluates
to `stdin'.
.TP
.BI "#date " "fmt"
This meta-macro evaluates to the current date and time as formatted by
the specified format string \fIfmt\fP. See the section \fIDATE AND
TIME CONVERSION SPECIFIERS\fP below.
.TP
.BI "#error " "msg"
This meta-macro causes an error message with the current filename and
line number, and with the text \fImsg\fP, to be printed to the standard
error device. Subsequent processing is then aborted.
.TP
.BI "#warning " "msg"
This meta-macro causes a warning message with the current filename and
line number, and with the text \fImsg\fP, to be printed to the standard
error device. Subsequent processing is then resumed.
.P
The key to GPP's flexibility is the \fI#mode\fP meta-macro. Its first
argument is always one of a list of available keywords (see below);
its second argument is always a sequence of words separated by whitespace.
Apart from possibly the first of them, each of these words is always a
delimiter or syntax specifier, and should be provided as a C string
delimited by double quotes ("\ "). The various special matching sequences
listed in the section on syntax specification are available. Any \fI#mode\fP
command is parsed in a mode where "..." is understood to be a C-style
string, so it is safe to put any character inside these strings.
Also note that the first argument of \fI#mode\fP (the keyword) is never
evaluated, while the second argument is evaluated (except of course for
the contents of C strings), so that the syntax specification may be obtained
as the result of a macro evaluation.
.P
The available \fI#mode\fP commands are:
.TP
.BI "#mode save / #mode push" ""
Push the current mode specification onto the mode stack.
.TP
.BI "#mode restore / #mode pop" ""
Pop mode specification from the mode stack.
.TP
.BI "#mode standard " "name"
Select one of the standard modes. The only argument must be one of:
default (default mode); cpp, C (cpp mode); tex, TeX\ (tex mode); html,
HTML (html mode); xhtml, XHTML (xhtml mode); prolog, Prolog (prolog
mode). The mode name must be given directly, not as a C string.
.TP
.BI "#mode user " """s1"" ... ""s9"""
Specify user macro syntax.
The 9 arguments, all of them C strings, are the mode specification for
user macros (see the \-U command-line option and the section on syntax
specification). The meta-macro specification is not affected.
.TP
.BI "#mode meta " "{user | ""s1"" ... ""s7""}"
Specify meta-macro syntax.
Either the only argument is \fIuser\fP (not as a string), and the user-macro
mode specifications are copied into the meta-macro mode specifications,
or there must be seven string arguments, whose significance is the same as
for the \-M command-line option (see section on syntax specification).
.TP
.BI "#mode quote " "[""c""]"
With no argument or "" as argument, removes the quote character
specification and disables the quoting functionality. With one string
argument, the first character of the string is taken to be the new
quote character. The quote character can be neither alphanumeric nor '_',
nor can it be one of the special matching sequences.
.TP
.BI "#mode comment " "[xxx] ""start"" ""end"" [""c"" [""c""]]"
Add a comment specification. Optionally a first argument consisting of
three characters not enclosed in "\ " can be used to specify a comment/string
modifier (see the section on syntax specification). The default modifier
is \fIccc\fP. The first two string
arguments are used as comment start and end sequences respectively.
The third string argument is optional and can be used to specify a
string-quote character. (If it is "", the functionality is disabled.)
The fourth string argument is optional and can be used to specify a
string delimitation warning character. (If it is "", the functionality is
disabled.)
.TP
.BI "#mode string " "[xxx] ""start"" ""end"" [""c"" [""c""]]"
Add a string specification. Identical to \fI#mode comment\fP except that
the default modifier is \fIsss\fP.
.TP
.BI "#mode nocomment / #mode nostring " "[""start""]"
With no argument, remove all comment/string specifications. With one
string argument, delete the comment/string specification whose start
sequence is the argument.
.TP
.BI "#mode preservelf " "{ on | off | 1 | 0 }"
Equivalent to the \fI-n\fP command-line switch. If the argument is \fIon\fP
or \fI1\fP, any newline or whitespace character terminating a macro call or
a comment/string is left in the input stream for further processing. If the
argument is \fIoff\fP or \fI0\fP this feature is disabled.
.TP
.BI "#mode charset " "{ id | op | par } ""string"""
Specify the character sets to be used for matching the \\o, \\O and
\\i special sequences. The first argument must be one of \fIid\fP
(the set matched by \\i), \fIop\fP (the set matched by \\o) or \fIpar\fP
(the set matched by \\O in addition to the one matched by \\o).
\fI"string"\fP is a C string which lists all characters to put in the set.
It may contain only the special matching sequences \\a, \\A, \\b, \\B,
and \\# (the other sequences and the negated sequences are not allowed).
When a '-' is found inbetween two non-special characters this adds all
characters inbetween (e.g. "A-Z" corresponds to all uppercase characters).
To have '-' in the matched set, either put it in first or last position
or place it next to a \\x sequence.
.SH DATE AND TIME CONVERSION SPECIFIERS
Ordinary characters placed in the format string are copied to without
conversion. Conversion specifiers are introduced by a `%'
character, and are replaced as follows:
.TP
.BI "%a" ""
The abbreviated weekday name according to the current locale.
.TP
.BI "%A" ""
The full weekday name according to the current
locale.
.TP
.BI "%b" ""
The abbreviated month name according to the current
locale.
.TP
.BI "%B" ""
The full month name according to the current
locale.
.TP
.BI "%c" ""
The preferred date and time representation for the
current locale.
.TP
.BI "%d" ""
The day of the month as a decimal number (range 01
to 31).
.TP
.BI "%F" ""
Equivalent to %Y-%m-%d (the ISO 8601 date format).
.TP
.BI "%H" ""
The hour as a decimal number using a 24-hour clock
(range 00 to 23).
.TP
.BI "%I" ""
The hour as a decimal number using a 12-hour clock
(range 01 to 12).
.TP
.BI "%j" ""
The day of the year as a decimal number (range 001
to 366).
.TP
.BI "%m" ""
The month as a decimal number (range 01 to 12).
.TP
.BI "%M" ""
The minute as a decimal number (range 00 to 59).
.TP
.BI "%p" ""
Either `AM' or `PM' according to the given time
value, or the corresponding strings for the current
locale. Noon is treated as `pm' and midnight as
`am'.
.TP
.BI "%R" ""
The time in 24-hour notation (%H:%M).
.TP
.BI "%S" ""
The second as a decimal number (range 00 to 61).
.TP
.BI "%U" ""
The week number of the current year as a decimal
number, range 00 to 53, starting with the first
Sunday as the first day of week 01.
.TP
.BI "%w" ""
The day of the week as a decimal, range 0 to 6,
Sunday being 0.
.TP
.BI "%W" ""
The week number of the current year as a decimal
number, range 00 to 53, starting with the first
Monday as the first day of week 01.
.TP
.BI "%x" ""
The preferred date representation for the current
locale without the time.
.TP
.BI "%X" ""
The preferred time representation for the current
locale without the date.
.TP
.BI "%y" ""
The year as a decimal number without a century
(range 00 to 99).
.TP
.BI "%Y" ""
The year as a decimal number including the century.
.TP
.BI "%Z" ""
The time zone or name or abbreviation.
.TP
.BI "%%" ""
A literal `%' character.
.P
Depending on the C compiler and library used to compile GPP, there
may be more conversion specifiers available. Consult your compiler's
documentation for the \fIstrftime()\fP function. Note, however, that
any conversion specifiers not listed above may not be portable
across installations of GPP.
.SH EXAMPLES
Here is a basic self-explanatory example in standard or cpp mode:
#define FOO This is
#define BAR a message.
#define concat #1 #2
concat(FOO,BAR)
#ifeq (concat(foo,bar)) (foo bar)
This is output.
#else
This is not output.
#endif
Using argument naming, the \fIconcat\fP macro could alternatively be defined
as
#define concat(x,y) x y
In TeX\ mode and using argument naming, the same example becomes:
\\define{FOO}{This is}
\\define{BAR}{a message.}
\\define{\\concat{x}{y}}{\\x \\y}
\\concat{\\FOO}{\\BAR}
\\ifeq{\\concat{foo}{bar}}{foo bar}
This is output.
\\else
This is not output.
\\endif
In HTML mode and without argument naming, one gets similarly:
<#define FOO|This is>
<#define BAR|a message.>
<#define concat|#1 #2>
<#concat <#FOO>|<#BAR>>
<#ifeq <#concat foo|bar>|foo bar>
This is output.
<#else>
This is not output.
<#endif>
The following example (in standard mode) illustrates the use of
the quote character:
#define FOO This is \\
a multiline definition.
#define BLAH(x) My argument is x
BLAH(urf)
\\BLAH(urf)
Note that the multiline definition is also valid in cpp and Prolog
modes despite the absence of quote character, because '\\' followed
by a newline is then interpreted as a comment and discarded.
.P
In cpp mode, C strings and comments are understood as such, as illustrated
by the following example:
#define BLAH foo
BLAH "BLAH" /* BLAH */
'It\\'s a /*string*/ !'
The main difference between Prolog mode and cpp mode is the handling of
strings and comments: in Prolog, a '...' string may not begin
immediately after a digit, and a /*...*/ comment may not begin immediately
after an operator character. Furthermore, comments are not removed from
the output unless they occur in a #command.
.P
The differences between cpp mode and default mode are deeper: in default
mode #commands may start anywhere, while in cpp mode they must be at the
beginning of a line; the default mode has no knowledge of comments and
strings, but has a quote character ('\\'), while cpp mode has extensive
comment/string specifications but no quote character. Moreover, the
arguments to meta-macros need to be correctly parenthesized in default
mode, while no such checking is performed in cpp mode.
.P
This makes it easier to nest meta-macro calls in default mode than in
cpp mode. For example, consider the following HTML mode input, which
tests for the availability of the \fI#exec\fP command:
<#ifeq <#exec echo blah>|blah
> #exec allowed <#else> #exec not allowed <#endif>
There is no cpp mode equivalent, while in default mode it can be easily
translated as
#ifeq (#exec echo blah
) (blah
)
\\#exec allowed
#else
\\#exec not allowed
#endif
In order to nest meta-macro calls in cpp mode it is necessary to modify
the mode description, either by changing the meta-macro call syntax, or
more elegantly by defining a silent string and using the fact that the
context at the beginning of an evaluated string is a newline character:
#mode string QQQ "$" "$"
#ifeq $#exec echo blah
$ $blah
$
\\#exec allowed
#else
\\#exec not allowed
#endif
Note, however, that comments/strings cannot be nested ("..." inside
$...$ would go undetected), so one needs to be careful about what to
include inside such a silent evaluated string. In this example, the loose
meta-macro nesting introduced in version 2.1 makes it possible to use the
following simpler version:
#ifeq blah #exec echo -n blah
\\#exec allowed
#else
\\#exec not allowed
#endif
Remember that macros without arguments are actually understood to be
aliases when they are called with arguments, as illustrated by the
following example (default or cpp mode):
#define DUP(x) x x
#define FOO and I said: DUP
FOO(blah)
The usefulness of the \fI#defeval\fP meta-macro is shown by the following
example in HTML mode:
<#define APPLY|<#defeval TEMP|<\\##1 \\#1>><#TEMP #2>>
<#define <#foo x>|<#x> and <#x>>
<#APPLY foo|BLAH>
The reason why \fI#defeval\fP is needed is that, since everything is
evaluated in a single pass, the input that will result in the desired macro
call needs to be generated by a first evaluation of the arguments passed to
APPLY before being evaluated a second time.
.P
To translate this example in default mode, one needs to resort to
parenthesizing in order to nest the #defeval call inside the definition
of APPLY, but need to do so without outputting the parentheses. The
easiest solution is
#define BALANCE(x) x
#define APPLY(f,v) BALANCE(#defeval TEMP f
TEMP(v))
#define foo(x) x and x
APPLY(\\foo,BLAH)
As explained above the simplest version in cpp mode relies on defining
a silent evaluated string to play the role of the BALANCE macro.
.P
The following example (default or cpp mode) demonstrates arithmetic
evaluation:
#define x 4
The answer is:
#eval x*x + 2*(16-x) + 1998%x
#if defined(x)&&!(3*x+5>17)
This should be output.
#endif
To finish, here are some examples involving mode switching.
The following example is self-explanatory (starting in default mode):
#mode push
#define f(x) x x
#mode standard tex
\\f{blah}
\\mode{string}{"$" "$"}
\\mode{comment}{"/*" "*/"}
$\\f{urf}$ /* blah */
\\define{FOO}{bar/* and some more */}
\\mode{pop}
f($FOO$)
A good example where a user-defined mode becomes useful is the GPP
source of this document (available with GPP's source code distribution).
.P
Another interesting application is selectively forcing evaluation of macros
in C strings when in cpp mode. For example, consider the following input:
#define blah(x) "and he said: x"
blah(foo)
Obviously one would want the parameter \fIx\fP to be expanded inside the
string. There are several ways around this problem:
#mode push
#mode nostring "\\""
#define blah(x) "and he said: x"
#mode pop
#mode quote "`"
#define blah(x) `"and he said: x`"
#mode string QQQ "$$" "$$"
#define blah(x) $$"and he said: x"$$
The first method is very natural, but has the inconvenience of being lengthy
and neutralizing string semantics, so that having an unevaluated instance
of 'x' in the string, or an occurrence of '/*', would be impossible without
resorting to further contortions.
.P
The second method is slightly more efficient because the local presence of a
quote character makes it easier to control what is evaluated and what isn't,
but has the drawback that it is sometimes impossible to find a reasonable
quote character without having to either significantly alter the source file
or enclose it inside a \fI#mode push/pop\fP construct. For example, any
occurrence of '/*' in the string would have to be quoted.
.P
The last method demonstrates the efficiency of evaluated strings in the
context of selective evaluation: since comments/strings cannot be nested,
any occurrence of '"' or '/*' inside the '$$' gets output as plain text,
as expected inside a string, and only macro evaluation is enabled. Also note
that there is much more freedom in the choice of a string delimiter than
in the choice of a quote character.
.P
Starting with version 2.1, meta-macro calls can be nested more efficiently
in default, cpp and Prolog modes. This makes it easy to make a user
version of a meta-macro, or to increment a counter:
#define myeval #eval #1
#define x 1
#defeval x #eval x+1
.SH ADVANCED EXAMPLES
.P
Here are some examples of advanced constructions using GPP. They tend to
be pretty awkward and should be considered as evidence of GPP's limitations.
.P
The first example is a recursive macro. The main problem is that (since GPP
evaluates everything) a recursive macro must be very careful about the way
in which recursion is terminated in order to avoid undefined behavior (most
of the time GPP will simply crash). In particular, relying on a
\fI#if/#else/#endif\fP construct to end recursion is not possible and results
in an infinite loop, because GPP scans user macro calls even in the
unevaluated branch of the conditional block. A safe way to proceed is for
example as follows (we give the example in TeX\ mode):
\\define{countdown}{
\\if{#1}
#1...
\\define{loop}{\\countdown}
\\else
Done.
\\define{loop}{}
\\endif
\\loop{\\eval{#1-1}}
}
\\countdown{10}
.P
Another example, in cpp mode:
#mode string QQQ "$" "$"
#define triangle(x,y) y \\
$#if length(y)<x$ $#define iter triangle$ $#else$ \\
$#define iter$ $#endif
$ iter(x,*y)
triangle(20)
.P
The following is an (unfortunately very weak) attempt at implementing
functional abstraction in GPP (in standard mode). Understanding this
example and why it can't be made much simpler is an exercise left to the
curious reader.
#mode string "`" "`" "\\\\"
#define ASIS(x) x
#define SILENT(x) ASIS()
#define EVAL(x,f,v) SILENT(
#mode string QQQ "`" "`" "\\\\"
#defeval TEMP0 x
#defeval TEMP1 (
\\#define \\TEMP2(TEMP0) f
)
TEMP1
)TEMP2(v)
#define LAMBDA(x,f,v) SILENT(
#ifneq (v) ()
#define TEMP3(a,b,c) EVAL(a,b,c)
#else
#define TEMP3(a,b,c) \\LAMBDA(a,b)
#endif
)TEMP3(x,f,v)
#define EVALAMBDA(x,y) SILENT(
#defeval TEMP4 x
#defeval TEMP5 y
)
#define APPLY(f,v) SILENT(
#defeval TEMP6 ASIS(\\EVA)f
TEMP6
)EVAL(TEMP4,TEMP5,v)
This yields the following results:
LAMBDA(z,z+z)
=> LAMBDA(z,z+z)
LAMBDA(z,z+z,2)
=> 2+2
#define f LAMBDA(y,y*y)
f
=> LAMBDA(y,y*y)
APPLY(f,blah)
=> blah*blah
APPLY(LAMBDA(t,t t),(t t))
=> (t t) (t t)
LAMBDA(x,APPLY(f,(x+x)),urf)
=> (urf+urf)*(urf+urf)
APPLY(APPLY(LAMBDA(x,LAMBDA(y,x*y)),foo),bar)
=> foo*bar
#define test LAMBDA(y,`#ifeq y urf
y is urf#else
y is not urf#endif
`)
APPLY(test,urf)
=> urf is urf
APPLY(test,foo)
=> foo is not urf
.SH SEE ALSO
strftime(3), glob(7), m4(1V), cpp(1)
.P
GPP home page: http://www.nothingisreal.com/gpp/
.SH AUTHOR
GPP was written by Denis Auroux <auroux@math.mit.edu>.
Since version 2.12 it has been maintained by Tristan Miller <psychonaut@nothingisreal.com>.
.SH COPYRIGHT
Copyright (C)\ 1996-2001 Denis Auroux.
.P
Copyright (C)\ 2003, 2004 Tristan Miller.
.P
Permission is granted to anyone to make or distribute verbatim copies
of this document as received, in any medium, provided that the
copyright notice and this permission notice are preserved, thus giving
the recipient permission to redistribute in turn.
.P
Permission is granted to distribute modified versions of this
document, or of portions of it, under the above conditions, provided
also that they carry prominent notices stating who last changed them.
|