1 char rcsid[] = "$Header: perly.c,v 1.0 87/12/18 15:53:31 root Exp $";
4 * Revision 1.0 87/12/18 15:53:31 root
9 bool preprocess = FALSE;
10 bool assume_n = FALSE;
11 bool assume_p = FALSE;
12 bool doswitches = FALSE;
14 char *e_tmpname = "/tmp/perl-eXXXXXX";
27 linestr = str_new(80);
28 str = str_make("-I/usr/lib/perl "); /* first used for -I flags */
29 for (argc--,argv++; argc; argc--,argv++) {
30 if (argv[0][0] != '-' || !argv[0][1])
36 debug = atoi(argv[0]+2);
38 yydebug = (debug & 1);
45 e_fp = fopen(e_tmpname,"w");
53 inplace = savestr(argv[0]+2);
54 argvoutstab = stabent("ARGVOUT",TRUE);
67 strcpy(argv[0], argv[0]+1);
71 strcpy(argv[0], argv[0]+1);
75 strcpy(argv[0], argv[0]+1);
79 strcpy(argv[0], argv[0]+1);
90 fatal("Unrecognized switch: %s\n",argv[0]);
101 str_set(&str_yes,Yes);
106 if (argv[0] == Nullch)
108 filename = savestr(argv[0]);
109 if (strEQ(filename,"-"))
113 /bin/sed -e '/^[^#]/b' \
114 -e '/^#[ ]*include[ ]/b' \
115 -e '/^#[ ]*define[ ]/b' \
116 -e '/^#[ ]*if[ ]/b' \
117 -e '/^#[ ]*ifdef[ ]/b' \
119 -e '/^#[ ]*endif/b' \
121 %s | /lib/cpp -C %s-",
122 argv[0], str_get(str));
123 rsfp = popen(buf,"r");
128 rsfp = fopen(argv[0],"r");
130 fatal("Perl script \"%s\" doesn't seem to exist.\n",filename);
131 str_free(str); /* free -I directories */
133 defstab = stabent("_",TRUE);
137 bufptr = str_get(linestr);
139 /* now parse the report spec */
142 fatal("Execution aborted due to compilation errors.\n");
148 argc--,argv++; /* skip name of script */
150 for (; argc > 0 && **argv == '-'; argc--,argv++) {
151 if (argv[0][1] == '-') {
155 str_numset(stabent(argv[0]+1,TRUE)->stab_val,(double)1.0);
158 if (argvstab = stabent("ARGV",FALSE)) {
159 for (; argc > 0; argc--,argv++) {
160 apush(argvstab->stab_array,str_make(argv[0]));
163 if (envstab = stabent("ENV",FALSE)) {
164 for (; *env; env++) {
165 if (!(s = index(*env,'=')))
169 str->str_link.str_magic = envstab;
170 hstore(envstab->stab_hash,*env,str);
174 sigstab = stabent("SIG",FALSE);
176 magicalize("!#?^~=-%0123456789.+&*(),\\/[|");
178 (tmpstab = stabent("0",FALSE)) && str_set(STAB_STR(tmpstab),filename);
179 (tmpstab = stabent("$",FALSE)) &&
180 str_numset(STAB_STR(tmpstab),(double)getpid());
182 tmpstab = stabent("stdin",TRUE);
183 tmpstab->stab_io = stio_new();
184 tmpstab->stab_io->fp = stdin;
186 tmpstab = stabent("stdout",TRUE);
187 tmpstab->stab_io = stio_new();
188 tmpstab->stab_io->fp = stdout;
189 defoutstab = tmpstab;
190 curoutstab = tmpstab;
192 tmpstab = stabent("stderr",TRUE);
193 tmpstab->stab_io = stio_new();
194 tmpstab->stab_io->fp = stderr;
196 setjmp(top_env); /* sets goto_targ on longjump */
200 dump_cmd(main_root,Nullcmd);
202 fprintf(stderr,"\nEXECUTING...\n\n");
207 (void) cmd_exec(main_root);
210 fatal("Can't find label \"%s\"--aborting.\n",goto_targ);
221 while (*sym = *list++) {
222 if (stab = stabent(sym,FALSE)) {
223 stab->stab_flags = SF_VMAGIC;
224 stab->stab_val->str_link.str_magic = stab;
229 #define RETURN(retval) return (bufptr = s,retval)
230 #define OPERATOR(retval) return (expectterm = TRUE,bufptr = s,retval)
231 #define TERM(retval) return (expectterm = FALSE,bufptr = s,retval)
232 #define LOOPX(f) return (yylval.ival = f,expectterm = FALSE,bufptr = s,LOOPEX)
233 #define UNI(f) return (yylval.ival = f,expectterm = TRUE,bufptr = s,UNIOP)
234 #define FUN0(f) return (yylval.ival = f,expectterm = FALSE,bufptr = s,FUNC0)
235 #define FUN1(f) return (yylval.ival = f,expectterm = FALSE,bufptr = s,FUNC1)
236 #define FUN2(f) return (yylval.ival = f,expectterm = FALSE,bufptr = s,FUNC2)
237 #define FUN3(f) return (yylval.ival = f,expectterm = FALSE,bufptr = s,FUNC3)
238 #define SFUN(f) return (yylval.ival = f,expectterm = FALSE,bufptr = s,STABFUN)
242 register char *s = bufptr;
245 static bool in_format = FALSE;
246 static bool firstline = TRUE;
252 fprintf(stderr,"Tokener at %s",s);
254 fprintf(stderr,"Tokener at %s\n",s);
259 "Unrecognized character %c in file %s line %d--ignoring.\n",
263 s = str_get(linestr);
265 if (firstline && (assume_n || assume_p)) {
267 str_set(linestr,"while (<>) {");
268 s = str_get(linestr);
274 yylval.formval = load_format(); /* leaves . in buffer */
276 s = str_get(linestr);
280 if ((s = str_gets(linestr, rsfp)) == Nullch) {
283 else if (rsfp != stdin)
286 if (assume_n || assume_p) {
287 str_set(linestr,assume_p ? "}continue{print;" : "");
288 str_cat(linestr,"}");
289 s = str_get(linestr);
292 s = str_get(linestr);
296 else if (firstline) {
308 if (preprocess && s == str_get(linestr) &&
309 s[1] == ' ' && isdigit(s[2])) {
311 for (s += 2; isdigit(*s); s++) ;
312 while (*s && isspace(*s)) s++;
315 s[strlen(s)-1] = '\0'; /* wipe out newline */
316 filename = savestr(s);
317 s = str_get(linestr);
407 while (isalpha(*s) || isdigit(*s) || *s == '_') \
413 if (s[1] == '#' && (isalpha(s[2]) || s[2] == '_')) {
415 s = scanreg(s,tokenbuf);
416 yylval.stabval = aadd(stabent(tokenbuf,TRUE));
419 s = scanreg(s,tokenbuf);
420 yylval.stabval = stabent(tokenbuf,TRUE);
424 s = scanreg(s,tokenbuf);
425 yylval.stabval = aadd(stabent(tokenbuf,TRUE));
428 case '/': /* may either be division or pattern */
429 case '?': /* may either be conditional or pattern */
438 if (!expectterm || !isdigit(s[1])) {
447 case '0': case '1': case '2': case '3': case '4':
448 case '5': case '6': case '7': case '8': case '9':
449 case '\'': case '"': case '`':
455 yylval.cval = savestr(d);
459 yylval.cval = savestr(d);
463 yylval.cval = savestr(d);
467 if (strEQ(d,"continue"))
469 if (strEQ(d,"chdir"))
471 if (strEQ(d,"close"))
473 if (strEQ(d,"crypt"))
477 if (strEQ(d,"chmod")) {
478 yylval.ival = O_CHMOD;
481 if (strEQ(d,"chown")) {
482 yylval.ival = O_CHOWN;
485 yylval.cval = savestr(d);
493 yylval.cval = savestr(d);
499 if (strEQ(d,"elsif"))
501 if (strEQ(d,"eq") || strEQ(d,"EQ"))
511 if (strEQ(d,"exec")) {
512 yylval.ival = O_EXEC;
515 yylval.cval = savestr(d);
521 if (strEQ(d,"format")) {
527 yylval.cval = savestr(d);
531 if (strEQ(d,"gt") || strEQ(d,"GT"))
533 if (strEQ(d,"ge") || strEQ(d,"GE"))
537 if (strEQ(d,"gmtime"))
539 yylval.cval = savestr(d);
545 yylval.cval = savestr(d);
551 if (strEQ(d,"index"))
555 yylval.cval = savestr(d);
561 yylval.cval = savestr(d);
567 if (strEQ(d,"kill")) {
568 yylval.ival = O_KILL;
571 yylval.cval = savestr(d);
577 if (strEQ(d,"length"))
579 if (strEQ(d,"lt") || strEQ(d,"LT"))
581 if (strEQ(d,"le") || strEQ(d,"LE"))
583 if (strEQ(d,"localtime"))
589 yylval.cval = savestr(d);
597 yylval.cval = savestr(d);
603 if (strEQ(d,"ne") || strEQ(d,"NE"))
605 yylval.cval = savestr(d);
615 yylval.cval = savestr(d);
619 if (strEQ(d,"print")) {
620 yylval.ival = O_PRINT;
623 if (strEQ(d,"printf")) {
624 yylval.ival = O_PRTF;
627 if (strEQ(d,"push")) {
628 yylval.ival = O_PUSH;
633 yylval.cval = savestr(d);
637 yylval.cval = savestr(d);
641 if (strEQ(d,"reset"))
645 if (strEQ(d,"rename"))
647 yylval.cval = savestr(d);
655 if (strEQ(d,"shift"))
657 if (strEQ(d,"split"))
659 if (strEQ(d,"substr"))
661 if (strEQ(d,"sprintf"))
665 if (strEQ(d,"select"))
673 if (strEQ(d,"sleep"))
675 if (strEQ(d,"system")) {
676 yylval.ival = O_SYSTEM;
679 yylval.cval = savestr(d);
691 if (strEQ(d,"times"))
693 yylval.cval = savestr(d);
697 if (strEQ(d,"using"))
699 if (strEQ(d,"until"))
701 if (strEQ(d,"unless"))
703 if (strEQ(d,"umask"))
705 if (strEQ(d,"unshift")) {
706 yylval.ival = O_UNSHIFT;
709 if (strEQ(d,"unlink")) {
710 yylval.ival = O_UNLINK;
713 yylval.cval = savestr(d);
717 if (strEQ(d,"values"))
719 yylval.cval = savestr(d);
723 if (strEQ(d,"write"))
725 if (strEQ(d,"while"))
727 yylval.cval = savestr(d);
731 if (!expectterm && strEQ(d,"x"))
733 yylval.cval = savestr(d);
741 yylval.cval = savestr(d);
745 yylval.cval = savestr(d);
757 for (stab = stab_index[*name]; stab; stab = stab->stab_next) {
758 if (strEQ(name,stab->stab_name))
762 /* no entry--should we add one? */
765 stab = (STAB *) safemalloc(sizeof(STAB));
766 bzero((char*)stab, sizeof(STAB));
767 stab->stab_name = savestr(name);
768 stab->stab_val = str_new(0);
769 stab->stab_next = stab_index[*name];
770 stab_index[*name] = stab;
779 STIO *stio = (STIO *) safemalloc(sizeof(STIO));
781 bzero((char*)stio, sizeof(STIO));
795 while (isalpha(*s) || isdigit(*s) || *s == '_')
803 while (*s && *s != '}')
813 if (*d == '^' && !isspace(*s))
822 register STR *retstr;
826 if (index(string,'|')) {
829 retstr = str_make(string);
833 case '.': case '[': case '$': case '(': case ')': case '|':
837 if (index("wWbB0123456789",d[1])) {
858 if (d[1] == '*' || d[1] == '+' || d[1] == '?') {
869 retstr->str_cur = strlen(retstr->str_ptr); /* XXX cheating here */
877 register SPAT *spat = (SPAT *) safemalloc(sizeof (SPAT));
880 bzero((char *)spat, sizeof(SPAT));
881 spat->spat_next = spat_root; /* link into spat list */
883 init_compex(&spat->spat_compex);
892 spat->spat_flags |= SPAT_USE_ONCE;
895 fatal("Search pattern not found:\n%s",str_get(linestr));
897 s = cpytill(tokenbuf,s,s[-1]);
899 fatal("Search pattern not terminated:\n%s",str_get(linestr));
901 if (*tokenbuf == '^') {
902 spat->spat_first = scanconst(tokenbuf+1);
903 if (spat->spat_first) {
904 spat->spat_flen = strlen(spat->spat_first->str_ptr);
905 if (spat->spat_flen == strlen(tokenbuf+1))
906 spat->spat_flags |= SPAT_SCANALL;
910 spat->spat_flags |= SPAT_SCANFIRST;
911 spat->spat_first = scanconst(tokenbuf);
912 if (spat->spat_first) {
913 spat->spat_flen = strlen(spat->spat_first->str_ptr);
914 if (spat->spat_flen == strlen(tokenbuf))
915 spat->spat_flags |= SPAT_SCANALL;
918 if (d = compile(&spat->spat_compex,tokenbuf,TRUE,FALSE))
920 yylval.arg = make_match(O_MATCH,stab_to_arg(A_STAB,defstab),spat);
928 register SPAT *spat = (SPAT *) safemalloc(sizeof (SPAT));
931 bzero((char *)spat, sizeof(SPAT));
932 spat->spat_next = spat_root; /* link into spat list */
934 init_compex(&spat->spat_compex);
936 s = cpytill(tokenbuf,s+1,*s);
938 fatal("Substitution pattern not terminated:\n%s",str_get(linestr));
939 for (d=tokenbuf; *d; d++) {
940 if (*d == '$' && d[1] && d[-1] != '\\' && d[1] != '|') {
943 spat->spat_runtime = arg = op_new(1);
944 arg->arg_type = O_ITEM;
945 arg[1].arg_type = A_DOUBLE;
946 arg[1].arg_ptr.arg_str = str_make(tokenbuf);
947 goto get_repl; /* skip compiling for now */
950 if (*tokenbuf == '^') {
951 spat->spat_first = scanconst(tokenbuf+1);
952 if (spat->spat_first)
953 spat->spat_flen = strlen(spat->spat_first->str_ptr);
956 spat->spat_flags |= SPAT_SCANFIRST;
957 spat->spat_first = scanconst(tokenbuf);
958 if (spat->spat_first)
959 spat->spat_flen = strlen(spat->spat_first->str_ptr);
961 if (d = compile(&spat->spat_compex,tokenbuf,TRUE,FALSE))
966 fatal("Substitution replacement not terminated:\n%s",str_get(linestr));
967 spat->spat_repl = yylval.arg;
970 spat->spat_flags &= ~SPAT_USE_ONCE;
973 spat->spat_flags |= SPAT_USE_ONCE;
974 yylval.arg = make_match(O_SUBST,stab_to_arg(A_STAB,defstab),spat);
983 if (arg->arg_type != O_MATCH) {
984 register SPAT *spat = (SPAT *) safemalloc(sizeof (SPAT));
987 bzero((char *)spat, sizeof(SPAT));
988 spat->spat_next = spat_root; /* link into spat list */
990 init_compex(&spat->spat_compex);
992 spat->spat_runtime = arg;
993 arg = make_match(O_MATCH,stab_to_arg(A_STAB,defstab),spat);
995 arg->arg_type = O_SPLIT;
996 arg[2].arg_ptr.arg_spat->spat_repl = stab_to_arg(A_STAB,aadd(stab));
1005 register char *d = t;
1009 if (s[1] == '-' && s[2]) {
1010 for (i = s[0]; i <= s[2]; i++)
1026 l(make_op(O_TRANS,2,stab_to_arg(A_STAB,defstab),Nullarg,Nullarg,0));
1029 register char *tbl = safemalloc(256);
1032 arg[2].arg_type = A_NULL;
1033 arg[2].arg_ptr.arg_cval = tbl;
1034 for (i=0; i<256; i++)
1038 fatal("Translation pattern not terminated:\n%s",str_get(linestr));
1039 t = expand_charset(str_get(yylval.arg[1].arg_ptr.arg_str));
1040 free_arg(yylval.arg);
1043 fatal("Translation replacement not terminated:\n%s",str_get(linestr));
1044 r = expand_charset(str_get(yylval.arg[1].arg_ptr.arg_str));
1045 free_arg(yylval.arg);
1051 for (i = 0; t[i]; i++) {
1054 tbl[t[i] & 0377] = r[i];
1066 if (tail == Nullcmd) {
1069 return tail->c_head;
1073 append_line(head,tail)
1077 if (tail == Nullcmd)
1079 if (!tail->c_head) /* make sure tail is well formed */
1080 tail->c_head = tail;
1081 if (head != Nullcmd) {
1082 tail = tail->c_head; /* get to start of tail list */
1084 head->c_head = head; /* start a new head list */
1085 while (head->c_next) {
1086 head->c_next->c_head = head->c_head;
1087 head = head->c_next; /* get to end of head list */
1089 head->c_next = tail; /* link to end of old list */
1090 tail->c_head = head->c_head; /* propagate head pointer */
1092 while (tail->c_next) {
1093 tail->c_next->c_head = tail->c_head;
1094 tail = tail->c_next;
1100 make_acmd(type,stab,cond,arg)
1106 register CMD *cmd = (CMD *) safemalloc(sizeof (CMD));
1108 bzero((char *)cmd, sizeof(CMD));
1110 cmd->ucmd.acmd.ac_stab = stab;
1111 cmd->ucmd.acmd.ac_expr = arg;
1115 cmd->c_flags |= CF_COND;
1121 make_ccmd(type,arg,cblock)
1124 struct compcmd cblock;
1126 register CMD *cmd = (CMD *) safemalloc(sizeof (CMD));
1128 bzero((char *)cmd, sizeof(CMD));
1131 cmd->ucmd.ccmd.cc_true = cblock.comp_true;
1132 cmd->ucmd.ccmd.cc_alt = cblock.comp_alt;
1135 cmd->c_flags |= CF_COND;
1141 opt_arg(cmd,fliporflop)
1149 char *tmps; /* for True macro */
1150 int context = 0; /* 0 = normal, 1 = before &&, 2 = before || */
1151 int flp = fliporflop;
1157 /* Turn "if (!expr)" into "unless (expr)" */
1159 while (arg->arg_type == O_NOT && arg[1].arg_type == A_EXPR) {
1160 cmd->c_flags ^= CF_INVERT; /* flip sense of cmd */
1161 cmd->c_expr = arg[1].arg_ptr.arg_arg; /* hoist the rest of expr */
1163 arg = cmd->c_expr; /* here we go again */
1166 if (!arg->arg_len) { /* sanity check */
1167 cmd->c_flags |= opt;
1171 /* for "cond .. cond" we set up for the initial check */
1173 if (arg->arg_type == O_FLIP)
1176 /* for "cond && expr" and "cond || expr" we can ignore expr, sort of */
1178 if (arg->arg_type == O_AND)
1180 else if (arg->arg_type == O_OR)
1182 if (context && arg[flp].arg_type == A_EXPR) {
1183 arg = arg[flp].arg_ptr.arg_arg;
1187 if (arg[flp].arg_flags & (AF_PRE|AF_POST)) {
1188 cmd->c_flags |= opt;
1189 return; /* side effect, can't optimize */
1192 if (arg->arg_type == O_ITEM || arg->arg_type == O_FLIP ||
1193 arg->arg_type == O_AND || arg->arg_type == O_OR) {
1194 if (arg[flp].arg_type == A_SINGLE) {
1195 opt = (str_true(arg[flp].arg_ptr.arg_str) ? CFT_TRUE : CFT_FALSE);
1196 cmd->c_first = arg[flp].arg_ptr.arg_str;
1199 else if (arg[flp].arg_type == A_STAB || arg[flp].arg_type == A_LVAL) {
1200 cmd->c_stab = arg[flp].arg_ptr.arg_stab;
1203 if (!context) { /* no && or ||? */
1205 cmd->c_expr = Nullarg;
1208 cmd->c_flags |= CF_EQSURE;
1210 cmd->c_flags |= CF_NESURE;
1213 else if (arg->arg_type == O_MATCH || arg->arg_type == O_SUBST ||
1214 arg->arg_type == O_NMATCH || arg->arg_type == O_NSUBST) {
1215 if ((arg[1].arg_type == A_STAB || arg[1].arg_type == A_LVAL) &&
1216 arg[2].arg_type == A_SPAT &&
1217 arg[2].arg_ptr.arg_spat->spat_first ) {
1218 cmd->c_stab = arg[1].arg_ptr.arg_stab;
1219 cmd->c_first = arg[2].arg_ptr.arg_spat->spat_first;
1220 cmd->c_flen = arg[2].arg_ptr.arg_spat->spat_flen;
1221 if (arg[2].arg_ptr.arg_spat->spat_flags & SPAT_SCANALL &&
1222 (arg->arg_type == O_MATCH || arg->arg_type == O_NMATCH) )
1223 sure |= CF_EQSURE; /* (SUBST must be forced even */
1224 /* if we know it will work.) */
1225 arg[2].arg_ptr.arg_spat->spat_first = Nullstr;
1226 arg[2].arg_ptr.arg_spat->spat_flen = 0; /* only one chk */
1227 sure |= CF_NESURE; /* normally only sure if it fails */
1228 if (arg->arg_type == O_NMATCH || arg->arg_type == O_NSUBST)
1229 cmd->c_flags |= CF_FIRSTNEG;
1230 if (context & 1) { /* only sure if thing is false */
1231 if (cmd->c_flags & CF_FIRSTNEG)
1236 else if (context & 2) { /* only sure if thing is true */
1237 if (cmd->c_flags & CF_FIRSTNEG)
1242 if (sure & (CF_EQSURE|CF_NESURE)) { /* if we know anything*/
1243 if (arg[2].arg_ptr.arg_spat->spat_flags & SPAT_SCANFIRST)
1247 if (sure == (CF_EQSURE|CF_NESURE) /* really sure? */
1248 && arg->arg_type == O_MATCH
1250 && fliporflop == 1) {
1251 arg[2].arg_type = A_SINGLE; /* don't do twice */
1252 arg[2].arg_ptr.arg_str = &str_yes;
1254 cmd->c_flags |= sure;
1258 else if (arg->arg_type == O_SEQ || arg->arg_type == O_SNE ||
1259 arg->arg_type == O_SLT || arg->arg_type == O_SGT) {
1260 if (arg[1].arg_type == A_STAB || arg[1].arg_type == A_LVAL) {
1261 if (arg[2].arg_type == A_SINGLE) {
1262 cmd->c_stab = arg[1].arg_ptr.arg_stab;
1263 cmd->c_first = arg[2].arg_ptr.arg_str;
1264 cmd->c_flen = 30000;
1265 switch (arg->arg_type) {
1266 case O_SLT: case O_SGT:
1268 cmd->c_flags |= CF_FIRSTNEG;
1271 cmd->c_flags |= CF_FIRSTNEG;
1274 sure |= CF_NESURE|CF_EQSURE;
1277 if (context & 1) { /* only sure if thing is false */
1278 if (cmd->c_flags & CF_FIRSTNEG)
1283 else if (context & 2) { /* only sure if thing is true */
1284 if (cmd->c_flags & CF_FIRSTNEG)
1289 if (sure & (CF_EQSURE|CF_NESURE)) {
1291 cmd->c_flags |= sure;
1296 else if (arg->arg_type == O_ASSIGN &&
1297 (arg[1].arg_type == A_STAB || arg[1].arg_type == A_LVAL) &&
1298 arg[1].arg_ptr.arg_stab == defstab &&
1299 arg[2].arg_type == A_EXPR ) {
1300 arg2 = arg[2].arg_ptr.arg_arg;
1301 if (arg2->arg_type == O_ITEM && arg2[1].arg_type == A_READ) {
1303 cmd->c_stab = arg2[1].arg_ptr.arg_stab;
1304 if (!(arg2[1].arg_ptr.arg_stab->stab_io->flags & IOF_ARGV)) {
1307 cmd->c_expr = Nullarg;
1311 else if (arg->arg_type == O_CHOP &&
1312 (arg[1].arg_type == A_STAB || arg[1].arg_type == A_LVAL) ) {
1314 cmd->c_stab = arg[1].arg_ptr.arg_stab;
1316 cmd->c_expr = Nullarg;
1320 cmd->c_flags |= opt;
1322 if (cmd->c_flags & CF_FLIP) {
1323 if (fliporflop == 1) {
1324 arg = cmd->c_expr; /* get back to O_FLIP arg */
1325 arg[3].arg_ptr.arg_cmd = (CMD*)safemalloc(sizeof(CMD));
1326 bcopy((char *)cmd, (char *)arg[3].arg_ptr.arg_cmd, sizeof(CMD));
1327 arg[4].arg_ptr.arg_cmd = (CMD*)safemalloc(sizeof(CMD));
1328 bcopy((char *)cmd, (char *)arg[4].arg_ptr.arg_cmd, sizeof(CMD));
1329 opt_arg(arg[4].arg_ptr.arg_cmd,2);
1330 arg->arg_len = 2; /* this is a lie */
1333 if ((opt & CF_OPTIMIZE) == CFT_EVAL)
1334 cmd->c_flags = (cmd->c_flags & ~CF_OPTIMIZE) | CFT_UNFLIP;
1340 mod_match(type,left,pat)
1345 register SPAT *spat;
1346 register ARG *newarg;
1348 if ((pat->arg_type == O_MATCH ||
1349 pat->arg_type == O_SUBST ||
1350 pat->arg_type == O_TRANS ||
1351 pat->arg_type == O_SPLIT
1353 pat[1].arg_ptr.arg_stab == defstab ) {
1354 switch (pat->arg_type) {
1356 newarg = make_op(type == O_MATCH ? O_MATCH : O_NMATCH,
1358 left,Nullarg,Nullarg,0);
1361 newarg = l(make_op(type == O_MATCH ? O_SUBST : O_NSUBST,
1363 left,Nullarg,Nullarg,0));
1366 newarg = l(make_op(type == O_MATCH ? O_TRANS : O_NTRANS,
1368 left,Nullarg,Nullarg,0));
1371 newarg = make_op(type == O_MATCH ? O_SPLIT : O_SPLIT,
1373 left,Nullarg,Nullarg,0);
1376 if (pat->arg_len >= 2) {
1377 newarg[2].arg_type = pat[2].arg_type;
1378 newarg[2].arg_ptr = pat[2].arg_ptr;
1379 newarg[2].arg_flags = pat[2].arg_flags;
1380 if (pat->arg_len >= 3) {
1381 newarg[3].arg_type = pat[3].arg_type;
1382 newarg[3].arg_ptr = pat[3].arg_ptr;
1383 newarg[3].arg_flags = pat[3].arg_flags;
1386 safefree((char*)pat);
1389 spat = (SPAT *) safemalloc(sizeof (SPAT));
1390 bzero((char *)spat, sizeof(SPAT));
1391 spat->spat_next = spat_root; /* link into spat list */
1393 init_compex(&spat->spat_compex);
1395 spat->spat_runtime = pat;
1396 newarg = make_op(type,2,left,Nullarg,Nullarg,0);
1397 newarg[2].arg_type = A_SPAT;
1398 newarg[2].arg_ptr.arg_spat = spat;
1399 newarg[2].arg_flags = AF_SPECIAL;
1422 cmd->c_flags |= CF_COND;
1433 cmd->c_flags |= CF_COND|CF_LOOP;
1434 if (cmd->c_type == C_BLOCK)
1435 cmd->c_flags &= ~CF_COND;
1437 arg = cmd->ucmd.acmd.ac_expr;
1438 if (arg && arg->arg_type == O_ITEM && arg[1].arg_type == A_CMD)
1439 cmd->c_flags &= ~CF_COND; /* "do {} while" happens at least once */
1440 if (arg && arg->arg_type == O_SUBR)
1441 cmd->c_flags &= ~CF_COND; /* likewise for "do subr() while" */
1450 cmd->c_flags ^= CF_INVERT;
1458 char *tname = tmpbuf;
1461 tname = tokename[yychar-256];
1462 if (strEQ(tname,"word"))
1463 strcpy(tname,tokenbuf);
1464 else if (strEQ(tname,"register"))
1465 sprintf(tname,"$%s",tokenbuf);
1466 else if (strEQ(tname,"array_length"))
1467 sprintf(tname,"$#%s",tokenbuf);
1470 strcpy(tname,"EOF");
1471 else if (yychar < 32)
1472 sprintf(tname,"^%c",yychar+64);
1473 else if (yychar == 127)
1476 sprintf(tname,"%c",yychar);
1477 printf("%s in file %s at line %d, next token \"%s\"\n",
1478 s,filename,line,tname);
1488 register bool makesingle = FALSE;
1489 char *leave = "\\$nrtfb0123456789"; /* which backslash sequences to keep */
1493 arg->arg_type = O_ITEM;
1496 default: /* a substitution replacement */
1497 arg[1].arg_type = A_DOUBLE;
1498 makesingle = TRUE; /* maybe disable runtime scanning */
1508 arg[1].arg_type = A_SINGLE;
1513 else if (s[1] == '.')
1524 fatal("Illegal octal digit at line %d",line);
1526 case '0': case '1': case '2': case '3': case '4':
1527 case '5': case '6': case '7':
1531 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1532 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1536 i += (*s++ & 7) + 9;
1541 sprintf(tokenbuf,"%d",i);
1542 arg[1].arg_ptr.arg_str = str_make(tokenbuf);
1545 case '1': case '2': case '3': case '4': case '5':
1546 case '6': case '7': case '8': case '9': case '.':
1548 arg[1].arg_type = A_SINGLE;
1550 while (isdigit(*s) || *s == '_')
1552 if (*s == '.' && index("0123456789eE",s[1]))
1554 while (isdigit(*s) || *s == '_')
1556 if (index("eE",*s) && index("+-0123456789",s[1]))
1558 if (*s == '+' || *s == '-')
1563 arg[1].arg_ptr.arg_str = str_make(tokenbuf);
1566 arg[1].arg_type = A_SINGLE;
1572 arg[1].arg_type = A_READ;
1573 s = cpytill(tokenbuf,s+1,'>');
1575 strcpy(tokenbuf,"ARGV");
1578 if (rsfp == stdin && strEQ(tokenbuf,"stdin"))
1579 fatal("Can't get both program and data from <stdin>\n");
1580 arg[1].arg_ptr.arg_stab = stabent(tokenbuf,TRUE);
1581 arg[1].arg_ptr.arg_stab->stab_io = stio_new();
1582 if (strEQ(tokenbuf,"ARGV")) {
1583 aadd(arg[1].arg_ptr.arg_stab);
1584 arg[1].arg_ptr.arg_stab->stab_io->flags |= IOF_ARGV|IOF_START;
1588 arg[1].arg_type = A_DOUBLE;
1589 makesingle = TRUE; /* maybe disable runtime scanning */
1593 arg[1].arg_type = A_BACKTICK;
1601 tmpstr = str_new(strlen(s));
1602 s = str_append_till(tmpstr,s+1,term,leave);
1603 while (!*s) { /* multiple line string? */
1604 s = str_gets(linestr, rsfp);
1606 fatal("EOF in string at line %d\n",sqstart);
1608 s = str_append_till(tmpstr,s,term,leave);
1612 arg[1].arg_ptr.arg_str = tmpstr;
1616 s = d = tmpstr->str_ptr; /* assuming shrinkage only */
1618 if (*s == '$' && s[1]) {
1619 makesingle = FALSE; /* force interpretation */
1620 if (!isalpha(s[1])) { /* an internal register? */
1623 len = scanreg(s,tokenbuf) - s;
1624 stabent(tokenbuf,TRUE); /* make sure it's created */
1630 else if (*s == '\\' && s[1]) {
1635 if (!leave || index(leave,*s))
1639 case '0': case '1': case '2': case '3':
1640 case '4': case '5': case '6': case '7':
1642 if (index("01234567",*s)) {
1646 else if (!index('`"',term)) { /* oops, a subpattern */
1650 if (index("01234567",*s)) {
1678 if (arg[1].arg_type == A_DOUBLE) {
1680 arg[1].arg_type = A_SINGLE; /* now we can optimize on it */
1683 for (d = s = tmpstr->str_ptr; *s; *d++ = *s++) {
1684 if (*s == '\\' && (!leave || index(leave,s[1])))
1689 tmpstr->str_cur = d - tmpstr->str_ptr; /* XXX cheat */
1690 arg[1].arg_ptr.arg_str = tmpstr;
1699 make_op(type,newlen,arg1,arg2,arg3,dolist)
1711 arg = op_new(newlen);
1712 arg->arg_type = type;
1713 doarg = opargs[type];
1716 arg[1].arg_flags |= AF_SPECIAL;
1718 arg[1].arg_flags |= AF_NUMERIC;
1719 if (chld->arg_type == O_ITEM &&
1720 (hoistable[chld[1].arg_type] || chld[1].arg_type == A_LVAL) ) {
1721 arg[1].arg_type = chld[1].arg_type;
1722 arg[1].arg_ptr = chld[1].arg_ptr;
1723 arg[1].arg_flags |= chld[1].arg_flags;
1727 arg[1].arg_type = A_EXPR;
1728 arg[1].arg_ptr.arg_arg = chld;
1730 if (chld->arg_type == O_LIST) {
1731 if (newlen == 1) { /* we can hoist entire list */
1732 chld->arg_type = type;
1737 arg[1].arg_flags |= AF_SPECIAL;
1740 else if (chld->arg_type == O_ARRAY && chld->arg_len == 1)
1741 arg[1].arg_flags |= AF_SPECIAL;
1747 arg[2].arg_flags |= AF_SPECIAL;
1749 arg[2].arg_flags |= AF_NUMERIC;
1750 if (chld->arg_type == O_ITEM &&
1751 (hoistable[chld[1].arg_type] ||
1752 (type == O_ASSIGN &&
1753 (chld[1].arg_type == A_READ ||
1754 chld[1].arg_type == A_DOUBLE ||
1755 chld[1].arg_type == A_BACKTICK ) ) ) ) {
1756 arg[2].arg_type = chld[1].arg_type;
1757 arg[2].arg_ptr = chld[1].arg_ptr;
1761 arg[2].arg_type = A_EXPR;
1762 arg[2].arg_ptr.arg_arg = chld;
1764 (chld->arg_type == O_LIST ||
1765 (chld->arg_type == O_ARRAY && chld->arg_len == 1) ))
1766 arg[2].arg_flags |= AF_SPECIAL;
1771 arg[3].arg_flags |= AF_SPECIAL;
1773 arg[3].arg_flags |= AF_NUMERIC;
1774 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type]) {
1775 arg[3].arg_type = chld[1].arg_type;
1776 arg[3].arg_ptr = chld[1].arg_ptr;
1780 arg[3].arg_type = A_EXPR;
1781 arg[3].arg_ptr.arg_arg = chld;
1783 (chld->arg_type == O_LIST ||
1784 (chld->arg_type == O_ARRAY && chld->arg_len == 1) ))
1785 arg[3].arg_flags |= AF_SPECIAL;
1790 fprintf(stderr,"%lx <= make_op(%s",arg,opname[arg->arg_type]);
1792 fprintf(stderr,",%s=%lx",
1793 argname[arg[1].arg_type],arg[1].arg_ptr.arg_arg);
1795 fprintf(stderr,",%s=%lx",
1796 argname[arg[2].arg_type],arg[2].arg_ptr.arg_arg);
1798 fprintf(stderr,",%s=%lx",
1799 argname[arg[3].arg_type],arg[3].arg_ptr.arg_arg);
1800 fprintf(stderr,")\n");
1803 evalstatic(arg); /* see if we can consolidate anything */
1807 /* turn 123 into 123 == $. */
1813 if (arg && arg->arg_type == O_ITEM && arg[1].arg_type == A_SINGLE) {
1814 arg = (ARG*)saferealloc((char*)arg,3*sizeof(ARG));
1815 arg->arg_type = O_EQ;
1817 arg[2].arg_type = A_STAB;
1818 arg[2].arg_flags = 0;
1819 arg[2].arg_ptr.arg_stab = stabent(".",TRUE);
1831 double value; /* must not be register */
1832 register char *tmps;
1834 double exp(), log(), sqrt(), modf();
1837 if (!arg || !arg->arg_len)
1840 if (arg[1].arg_type == A_SINGLE &&
1841 (arg->arg_len == 1 || arg[2].arg_type == A_SINGLE) ) {
1843 s1 = arg[1].arg_ptr.arg_str;
1844 if (arg->arg_len > 1)
1845 s2 = arg[2].arg_ptr.arg_str;
1848 switch (arg->arg_type) {
1851 str = Nullstr; /* can't be evaluated yet */
1858 i = (int)str_gnum(s2);
1863 value = str_gnum(s1);
1864 str_numset(str,value * str_gnum(s2));
1867 value = str_gnum(s1);
1868 str_numset(str,value / str_gnum(s2));
1871 value = str_gnum(s1);
1872 str_numset(str,(double)(((long)value) % ((long)str_gnum(s2))));
1875 value = str_gnum(s1);
1876 str_numset(str,value + str_gnum(s2));
1879 value = str_gnum(s1);
1880 str_numset(str,value - str_gnum(s2));
1883 value = str_gnum(s1);
1884 str_numset(str,(double)(((long)value) << ((long)str_gnum(s2))));
1887 value = str_gnum(s1);
1888 str_numset(str,(double)(((long)value) >> ((long)str_gnum(s2))));
1891 value = str_gnum(s1);
1892 str_numset(str,(double)(value < str_gnum(s2)));
1895 value = str_gnum(s1);
1896 str_numset(str,(double)(value > str_gnum(s2)));
1899 value = str_gnum(s1);
1900 str_numset(str,(double)(value <= str_gnum(s2)));
1903 value = str_gnum(s1);
1904 str_numset(str,(double)(value >= str_gnum(s2)));
1907 value = str_gnum(s1);
1908 str_numset(str,(double)(value == str_gnum(s2)));
1911 value = str_gnum(s1);
1912 str_numset(str,(double)(value != str_gnum(s2)));
1915 value = str_gnum(s1);
1916 str_numset(str,(double)(((long)value) & ((long)str_gnum(s2))));
1919 value = str_gnum(s1);
1920 str_numset(str,(double)(((long)value) ^ ((long)str_gnum(s2))));
1923 value = str_gnum(s1);
1924 str_numset(str,(double)(((long)value) | ((long)str_gnum(s2))));
1928 str = str_make(str_get(s2));
1930 str = str_make(str_get(s1));
1934 str = str_make(str_get(s1));
1936 str = str_make(str_get(s2));
1939 if (arg[3].arg_type != A_SINGLE) {
1944 str = str_make(str_get(str_true(s1) ? s2 : arg[3].arg_ptr.arg_str));
1945 str_free(arg[3].arg_ptr.arg_str);
1949 str_numset(str,(double)(-str_gnum(s1)));
1952 str_numset(str,(double)(!str_true(s1)));
1955 str_numset(str,(double)(~(long)str_gnum(s1)));
1958 str_numset(str, (double)str_len(s1));
1961 if (arg[3].arg_type != A_SINGLE || stabent("[",FALSE)) {
1962 str_free(str); /* making the fallacious assumption */
1963 str = Nullstr; /* that any $[ occurs before substr()*/
1967 int len = (int)str_gnum(s2);
1970 for (beg = str_get(s1); *beg && len > 0; beg++,len--) ;
1971 len = (int)str_gnum(arg[3].arg_ptr.arg_str);
1972 str_free(arg[3].arg_ptr.arg_str);
1973 if (len > (tmp = strlen(beg)))
1975 str_nset(str,beg,len);
1980 str_numset(str,(double)(strLT(tmps,str_get(s2))));
1984 str_numset(str,(double)(strGT(tmps,str_get(s2))));
1988 str_numset(str,(double)(strLE(tmps,str_get(s2))));
1992 str_numset(str,(double)(strGE(tmps,str_get(s2))));
1996 str_numset(str,(double)(strEQ(tmps,str_get(s2))));
2000 str_numset(str,(double)(strNE(tmps,str_get(s2))));
2004 str_set(str,crypt(tmps,str_get(s2)));
2007 str_numset(str,exp(str_gnum(s1)));
2010 str_numset(str,log(str_gnum(s1)));
2013 str_numset(str,sqrt(str_gnum(s1)));
2016 modf(str_gnum(s1),&value);
2017 str_numset(str,value);
2020 str_numset(str,(double)(*str_get(s1)));
2024 arg->arg_type = O_ITEM; /* note arg1 type is already SINGLE */
2027 arg[1].arg_ptr.arg_str = str;
2039 arg->arg_flags |= AF_COMMON; /* XXX should cross-match */
2041 /* see if it's an array reference */
2043 if (arg[1].arg_type == A_EXPR) {
2044 arg1 = arg[1].arg_ptr.arg_arg;
2046 if (arg1->arg_type == O_LIST && arg->arg_type != O_ITEM) {
2047 /* assign to list */
2048 arg[1].arg_flags |= AF_SPECIAL;
2049 arg[2].arg_flags |= AF_SPECIAL;
2050 for (i = arg1->arg_len; i >= 1; i--) {
2051 switch (arg1[i].arg_type) {
2052 case A_STAB: case A_LVAL:
2053 arg1[i].arg_type = A_LVAL;
2055 case A_EXPR: case A_LEXPR:
2056 arg1[i].arg_type = A_LEXPR;
2057 if (arg1[i].arg_ptr.arg_arg->arg_type == O_ARRAY)
2058 arg1[i].arg_ptr.arg_arg->arg_type = O_LARRAY;
2059 else if (arg1[i].arg_ptr.arg_arg->arg_type == O_HASH)
2060 arg1[i].arg_ptr.arg_arg->arg_type = O_LHASH;
2061 if (arg1[i].arg_ptr.arg_arg->arg_type == O_LARRAY)
2063 if (arg1[i].arg_ptr.arg_arg->arg_type == O_LHASH)
2068 "Illegal item (%s) as lvalue",argname[arg1[i].arg_type]);
2073 else if (arg1->arg_type == O_ARRAY) {
2074 if (arg1->arg_len == 1 && arg->arg_type != O_ITEM) {
2075 /* assign to array */
2076 arg[1].arg_flags |= AF_SPECIAL;
2077 arg[2].arg_flags |= AF_SPECIAL;
2080 arg1->arg_type = O_LARRAY; /* assign to array elem */
2082 else if (arg1->arg_type == O_HASH)
2083 arg1->arg_type = O_LHASH;
2086 "Illegal expression (%s) as lvalue",opname[arg1->arg_type]);
2089 arg[1].arg_type = A_LEXPR;
2092 fprintf(stderr,"lval LEXPR\n");
2097 /* not an array reference, should be a register name */
2099 if (arg[1].arg_type != A_STAB && arg[1].arg_type != A_LVAL) {
2101 "Illegal item (%s) as lvalue",argname[arg[1].arg_type]);
2104 arg[1].arg_type = A_LVAL;
2107 fprintf(stderr,"lval LVAL\n");
2113 addflags(i,flags,arg)
2116 arg[i].arg_flags |= flags;
2124 if (arg->arg_type == O_ARRAY)
2125 return make_op(O_ITEM,1,arg,Nullarg,Nullarg,0);
2135 register ARG *nxtnode;
2141 arg->arg_type = O_LIST;
2143 if (arg->arg_type != O_COMMA) {
2144 arg->arg_flags |= AF_LISTISH; /* see listish() below */
2147 for (i = 2, node = arg; ; i++) {
2148 if (node->arg_len < 2)
2150 if (node[2].arg_type != A_EXPR)
2152 node = node[2].arg_ptr.arg_arg;
2153 if (node->arg_type != O_COMMA)
2159 tmpstr = arg->arg_ptr.arg_str;
2160 *arg = *node; /* copy everything except the STR */
2161 arg->arg_ptr.arg_str = tmpstr;
2169 nxtnode = node[2].arg_ptr.arg_arg;
2174 arg->arg_type = O_LIST;
2179 /* turn a single item into a list */
2185 if (arg->arg_flags & AF_LISTISH)
2186 arg = make_op(O_LIST,1,arg,Nullarg,Nullarg,0);
2191 stab_to_arg(atype,stab)
2193 register STAB *stab;
2198 arg->arg_type = O_ITEM;
2199 arg[1].arg_type = atype;
2200 arg[1].arg_ptr.arg_stab = stab;
2206 register char *cval;
2211 arg->arg_type = O_ITEM;
2212 arg[1].arg_type = A_SINGLE;
2213 arg[1].arg_ptr.arg_str = str_make(cval);
2224 arg = (ARG*)safemalloc((numargs + 1) * sizeof (ARG));
2225 bzero((char *)arg, (numargs + 1) * sizeof (ARG));
2226 arg->arg_ptr.arg_str = str_new(0);
2227 arg->arg_len = numargs;
2235 str_free(arg->arg_ptr.arg_str);
2236 safefree((char*)arg);
2240 make_match(type,expr,spat)
2247 arg = make_op(type,2,expr,Nullarg,Nullarg,0);
2249 arg[2].arg_type = A_SPAT;
2250 arg[2].arg_ptr.arg_spat = spat;
2253 fprintf(stderr,"make_match SPAT=%lx\n",spat);
2256 if (type == O_SUBST || type == O_NSUBST) {
2257 if (arg[1].arg_type != A_STAB)
2258 yyerror("Illegal lvalue");
2259 arg[1].arg_type = A_LVAL;
2271 arg->arg_type = O_ITEM;
2272 arg[1].arg_type = A_CMD;
2273 arg[1].arg_ptr.arg_cmd = cmd;
2282 register ARG *arg = cmd->c_expr;
2283 char *tmps; /* used by True macro */
2285 /* hoist "while (<channel>)" up into command block */
2287 if (arg && arg->arg_type == O_ITEM && arg[1].arg_type == A_READ) {
2288 cmd->c_flags &= ~CF_OPTIMIZE; /* clear optimization type */
2289 cmd->c_flags |= CFT_GETS; /* and set it to do the input */
2290 cmd->c_stab = arg[1].arg_ptr.arg_stab;
2291 if (arg[1].arg_ptr.arg_stab->stab_io->flags & IOF_ARGV) {
2292 cmd->c_expr = l(make_op(O_ASSIGN, 2, /* fake up "$_ =" */
2293 stab_to_arg(A_LVAL,defstab), arg, Nullarg,1 ));
2297 cmd->c_expr = Nullarg;
2301 /* First find the end of the true list */
2303 if (cmd->ucmd.ccmd.cc_true == Nullcmd)
2305 for (tail = cmd->ucmd.ccmd.cc_true; tail->c_next; tail = tail->c_next) ;
2307 /* if there's a continue block, link it to true block and find end */
2309 if (cmd->ucmd.ccmd.cc_alt != Nullcmd) {
2310 tail->c_next = cmd->ucmd.ccmd.cc_alt;
2311 for ( ; tail->c_next; tail = tail->c_next) ;
2314 /* Here's the real trick: link the end of the list back to the beginning,
2315 * inserting a "last" block to break out of the loop. This saves one or
2316 * two procedure calls every time through the loop, because of how cmd_exec
2317 * does tail recursion.
2320 tail->c_next = (CMD *) safemalloc(sizeof (CMD));
2321 tail = tail->c_next;
2322 if (!cmd->ucmd.ccmd.cc_alt)
2323 cmd->ucmd.ccmd.cc_alt = tail; /* every loop has a continue now */
2325 bcopy((char *)cmd, (char *)tail, sizeof(CMD));
2326 tail->c_type = C_EXPR;
2327 tail->c_flags ^= CF_INVERT; /* turn into "last unless" */
2328 tail->c_next = tail->ucmd.ccmd.cc_true; /* loop directly back to top */
2329 tail->ucmd.acmd.ac_expr = make_op(O_LAST,0,Nullarg,Nullarg,Nullarg,0);
2330 tail->ucmd.acmd.ac_stab = Nullstab;
2339 register FCMD *fprev = &froot;
2340 register FCMD *fcmd;
2343 register char tmpchar;
2346 while ((s = str_gets(linestr,rsfp)) != Nullch) {
2348 if (strEQ(s,".\n")) {
2350 return froot.f_next;
2354 flinebeg = Nullfcmd;
2357 fcmd = (FCMD *)safemalloc(sizeof (FCMD));
2358 bzero((char*)fcmd, sizeof (FCMD));
2359 fprev->f_next = fcmd;
2361 for (t=s; *t && *t != '@' && *t != '^'; t++) {
2369 fcmd->f_pre = savestr(s);
2370 fcmd->f_presize = strlen(s);
2375 fcmd->f_flags |= FC_NOBLANK;
2379 flinebeg = fcmd; /* start values here */
2381 fcmd->f_flags |= FC_CHOP; /* for doing text filling */
2384 fcmd->f_type = F_LINES;
2388 fcmd->f_type = F_LEFT;
2393 fcmd->f_type = F_RIGHT;
2398 fcmd->f_type = F_CENTER;
2403 fcmd->f_type = F_LEFT;
2406 if (fcmd->f_flags & FC_CHOP && *s == '.') {
2407 fcmd->f_flags |= FC_MORE;
2415 if ((bufptr = str_gets(linestr ,rsfp)) == Nullch)
2418 if (strEQ(bufptr,".\n")) {
2419 yyerror("Missing values line");
2420 return froot.f_next;
2424 lex_newlines = TRUE;
2425 while (flinebeg || *bufptr) {
2428 yyerror("Bad value in format");
2433 yyerror("Missing value in format");
2437 yylval.arg = stab_to_arg(A_LVAL,yylval.stabval);
2441 yyerror("Extra value in format");
2443 flinebeg->f_expr = yylval.arg;
2445 flinebeg = flinebeg->f_next;
2446 } while (flinebeg && flinebeg->f_size == 0);
2453 lex_newlines = FALSE;
2457 bufptr = str_get(linestr);
2458 yyerror("Format not terminated");
2459 return froot.f_next;