13379Seric # include "useful.h" 23379Seric 3*4454Seric static char SccsId[] = "@(#)macro.c 3.5 10/02/81"; 43379Seric 53379Seric char *Macro[128]; 64073Seric extern int Debug; 73379Seric 83379Seric /* 93379Seric ** EXPAND -- macro expand a string using $x escapes. 103379Seric ** 113379Seric ** Parameters: 123379Seric ** s -- the string to expand. 133379Seric ** buf -- the place to put the expansion. 143379Seric ** buflim -- the buffer limit, i.e., the address 153379Seric ** of the last usable position in buf. 163379Seric ** 173379Seric ** Returns: 184319Seric ** End of interpolated output. 193379Seric ** 203379Seric ** Side Effects: 213379Seric ** none. 223379Seric */ 233379Seric 243379Seric char * 253379Seric expand(s, buf, buflim) 263379Seric register char *s; 273379Seric register char *buf; 283379Seric char *buflim; 293379Seric { 303379Seric register char *bp; 314319Seric bool skipping; /* set if conditionally skipping output */ 323379Seric 333379Seric # ifdef DEBUG 344073Seric if (Debug > 3) 353379Seric printf("expand(%s)\n", s); 363379Seric # endif DEBUG 373379Seric 383387Seric skipping = FALSE; 393379Seric for (bp = buf; *s != '\0'; s++) 403379Seric { 414319Seric register char *q; 424319Seric 434319Seric /* 444319Seric ** Check for non-ordinary (special?) character -- 454319Seric ** always escaped with dollar sign. 464319Seric ** 'q' will be the interpolated quantity. 474319Seric */ 484319Seric 493379Seric q = NULL; 503379Seric if (*s == '$') 513387Seric { 523387Seric char c; 533379Seric 543387Seric c = *++s; 553387Seric switch (c) 563387Seric { 573387Seric case '?': /* see if var set */ 583387Seric c = *++s; 593387Seric skipping = Macro[c] == NULL; 603387Seric break; 613387Seric 623387Seric case ':': /* else */ 633387Seric skipping = !skipping; 643387Seric break; 653387Seric 663387Seric case '.': /* end if */ 673387Seric skipping = FALSE; 683387Seric break; 693387Seric 703387Seric default: 713387Seric q = Macro[c & 0177]; 723387Seric break; 733387Seric } 744172Seric if (q == NULL && c != '$') 753387Seric continue; 763387Seric } 773387Seric 783379Seric /* 793379Seric ** Interpolate q or output one character 803379Seric */ 813379Seric 823387Seric if (skipping) 833387Seric continue; 843379Seric if (q != NULL) 853379Seric bp = expand(q, bp, buflim); 863379Seric else if (bp < buflim - 1) 873379Seric *bp++ = *s; 883379Seric } 893379Seric *bp = '\0'; 903379Seric 913379Seric # ifdef DEBUG 924073Seric if (Debug > 3) 933379Seric printf("expand ==> '%s'\n", buf); 943379Seric # endif DEBUG 953379Seric 963379Seric return (bp); 973379Seric } 983379Seric /* 993379Seric ** DEFINE -- define a macro. 1003379Seric ** 1013379Seric ** this would be better done using a #define macro. 1023379Seric ** 1033379Seric ** Parameters: 1043379Seric ** n -- the macro name. 1053379Seric ** v -- the macro value. 1063379Seric ** 1073379Seric ** Returns: 1083379Seric ** none. 1093379Seric ** 1103379Seric ** Side Effects: 1113379Seric ** Macro[n] is defined. 1124092Seric ** 1134092Seric ** Notes: 1144092Seric ** There is one macro for each ASCII character, 1154092Seric ** although they are not all used. The currently 1164092Seric ** defined macros are: 1174092Seric ** 1184202Seric ** $a date in ARPANET format (preferring the Date: line 1194202Seric ** of the message) 1204202Seric ** $b the current date (as opposed to the date as found 1214202Seric ** the message) in ARPANET format 1224092Seric ** $c hop count 1234202Seric ** $d (current) date in UNIX (ctime) format 1244092Seric ** $f raw from address 1254092Seric ** $g translated from address 1264092Seric ** $h to host 1274092Seric ** $l UNIX-style from line+ 1284092Seric ** $n name of sendmail ("MAILER-DAEMON" on local 1294092Seric ** net typically)+ 1304092Seric ** $o delimiters ("operators") for address tokens+ 1314092Seric ** $p my process id in decimal 1324092Seric ** $t the current time in seconds since 1/1/1970 1334092Seric ** $u to user 1344092Seric ** $v version number of sendmail 1354092Seric ** $x signature (full name) of from person 1364202Seric ** $y the tty id of our terminal 1374092Seric ** $z home directory of to person 1384092Seric ** 1394092Seric ** Macros marked with + must be defined in the 1404092Seric ** configuration file and are used internally, but 1414092Seric ** are not set. 1424092Seric ** 1434092Seric ** There are also some macros that can be used 1444092Seric ** arbitrarily to make the configuration file 1454092Seric ** cleaner. In general all upper-case letters 1464092Seric ** are available. 1473379Seric */ 1483379Seric 1493379Seric define(n, v) 1503379Seric char n; 1513379Seric char *v; 1523379Seric { 1533379Seric # ifdef DEBUG 1544073Seric if (Debug > 3) 1553379Seric printf("define(%c as %s)\n", n, v); 1563379Seric # endif DEBUG 1573379Seric Macro[n & 0177] = v; 1583379Seric } 159*4454Seric /* 160*4454Seric ** MACVALUE -- return uninterpreted value of a macro. 161*4454Seric ** 162*4454Seric ** Parameters: 163*4454Seric ** n -- the name of the macro. 164*4454Seric ** 165*4454Seric ** Returns: 166*4454Seric ** The value of n. 167*4454Seric ** 168*4454Seric ** Side Effects: 169*4454Seric ** none. 170*4454Seric */ 171*4454Seric 172*4454Seric char * 173*4454Seric macvalue(n) 174*4454Seric char n; 175*4454Seric { 176*4454Seric return (Macro[n & 0177]); 177*4454Seric } 178