1 char rcsid[] = "$Header: perly.c,v 1.0.1.1 88/01/21 21:25:57 root Exp $";
4 * Revision 1.0.1.1 88/01/21 21:25:57 root
5 * Now uses CPP and CPPMINUS symbols from config.h.
7 * Revision 1.0 87/12/18 15:53:31 root
12 bool preprocess = FALSE;
13 bool assume_n = FALSE;
14 bool assume_p = FALSE;
15 bool doswitches = FALSE;
17 char *e_tmpname = "/tmp/perl-eXXXXXX";
30 linestr = str_new(80);
31 str = str_make("-I/usr/lib/perl "); /* first used for -I flags */
32 for (argc--,argv++; argc; argc--,argv++) {
33 if (argv[0][0] != '-' || !argv[0][1])
39 debug = atoi(argv[0]+2);
41 yydebug = (debug & 1);
48 e_fp = fopen(e_tmpname,"w");
56 inplace = savestr(argv[0]+2);
57 argvoutstab = stabent("ARGVOUT",TRUE);
70 strcpy(argv[0], argv[0]+1);
74 strcpy(argv[0], argv[0]+1);
78 strcpy(argv[0], argv[0]+1);
82 strcpy(argv[0], argv[0]+1);
93 fatal("Unrecognized switch: %s\n",argv[0]);
104 str_set(&str_yes,Yes);
109 if (argv[0] == Nullch)
111 filename = savestr(argv[0]);
112 if (strEQ(filename,"-"))
116 /bin/sed -e '/^[^#]/b' \
117 -e '/^#[ ]*include[ ]/b' \
118 -e '/^#[ ]*define[ ]/b' \
119 -e '/^#[ ]*if[ ]/b' \
120 -e '/^#[ ]*ifdef[ ]/b' \
122 -e '/^#[ ]*endif/b' \
125 argv[0], CPP, str_get(str), CPPMINUS);
126 rsfp = popen(buf,"r");
131 rsfp = fopen(argv[0],"r");
133 fatal("Perl script \"%s\" doesn't seem to exist.\n",filename);
134 str_free(str); /* free -I directories */
136 defstab = stabent("_",TRUE);
140 bufptr = str_get(linestr);
142 /* now parse the report spec */
145 fatal("Execution aborted due to compilation errors.\n");
151 argc--,argv++; /* skip name of script */
153 for (; argc > 0 && **argv == '-'; argc--,argv++) {
154 if (argv[0][1] == '-') {
158 str_numset(stabent(argv[0]+1,TRUE)->stab_val,(double)1.0);
161 if (argvstab = stabent("ARGV",FALSE)) {
162 for (; argc > 0; argc--,argv++) {
163 apush(argvstab->stab_array,str_make(argv[0]));
166 if (envstab = stabent("ENV",FALSE)) {
167 for (; *env; env++) {
168 if (!(s = index(*env,'=')))
172 str->str_link.str_magic = envstab;
173 hstore(envstab->stab_hash,*env,str);
177 sigstab = stabent("SIG",FALSE);
179 magicalize("!#?^~=-%0123456789.+&*(),\\/[|");
181 (tmpstab = stabent("0",FALSE)) && str_set(STAB_STR(tmpstab),filename);
182 (tmpstab = stabent("$",FALSE)) &&
183 str_numset(STAB_STR(tmpstab),(double)getpid());
185 tmpstab = stabent("stdin",TRUE);
186 tmpstab->stab_io = stio_new();
187 tmpstab->stab_io->fp = stdin;
189 tmpstab = stabent("stdout",TRUE);
190 tmpstab->stab_io = stio_new();
191 tmpstab->stab_io->fp = stdout;
192 defoutstab = tmpstab;
193 curoutstab = tmpstab;
195 tmpstab = stabent("stderr",TRUE);
196 tmpstab->stab_io = stio_new();
197 tmpstab->stab_io->fp = stderr;
199 setjmp(top_env); /* sets goto_targ on longjump */
203 dump_cmd(main_root,Nullcmd);
205 fprintf(stderr,"\nEXECUTING...\n\n");
210 (void) cmd_exec(main_root);
213 fatal("Can't find label \"%s\"--aborting.\n",goto_targ);
224 while (*sym = *list++) {
225 if (stab = stabent(sym,FALSE)) {
226 stab->stab_flags = SF_VMAGIC;
227 stab->stab_val->str_link.str_magic = stab;
232 #define RETURN(retval) return (bufptr = s,retval)
233 #define OPERATOR(retval) return (expectterm = TRUE,bufptr = s,retval)
234 #define TERM(retval) return (expectterm = FALSE,bufptr = s,retval)
235 #define LOOPX(f) return (yylval.ival = f,expectterm = FALSE,bufptr = s,LOOPEX)
236 #define UNI(f) return (yylval.ival = f,expectterm = TRUE,bufptr = s,UNIOP)
237 #define FUN0(f) return (yylval.ival = f,expectterm = FALSE,bufptr = s,FUNC0)
238 #define FUN1(f) return (yylval.ival = f,expectterm = FALSE,bufptr = s,FUNC1)
239 #define FUN2(f) return (yylval.ival = f,expectterm = FALSE,bufptr = s,FUNC2)
240 #define FUN3(f) return (yylval.ival = f,expectterm = FALSE,bufptr = s,FUNC3)
241 #define SFUN(f) return (yylval.ival = f,expectterm = FALSE,bufptr = s,STABFUN)
245 register char *s = bufptr;
248 static bool in_format = FALSE;
249 static bool firstline = TRUE;
255 fprintf(stderr,"Tokener at %s",s);
257 fprintf(stderr,"Tokener at %s\n",s);
262 "Unrecognized character %c in file %s line %d--ignoring.\n",
266 s = str_get(linestr);
268 if (firstline && (assume_n || assume_p)) {
270 str_set(linestr,"while (<>) {");
271 s = str_get(linestr);
277 yylval.formval = load_format(); /* leaves . in buffer */
279 s = str_get(linestr);
283 if ((s = str_gets(linestr, rsfp)) == Nullch) {
286 else if (rsfp != stdin)
289 if (assume_n || assume_p) {
290 str_set(linestr,assume_p ? "}continue{print;" : "");
291 str_cat(linestr,"}");
292 s = str_get(linestr);
295 s = str_get(linestr);
299 else if (firstline) {
311 if (preprocess && s == str_get(linestr) &&
312 s[1] == ' ' && isdigit(s[2])) {
314 for (s += 2; isdigit(*s); s++) ;
315 while (*s && isspace(*s)) s++;
318 s[strlen(s)-1] = '\0'; /* wipe out newline */
319 filename = savestr(s);
320 s = str_get(linestr);
410 while (isalpha(*s) || isdigit(*s) || *s == '_') \
416 if (s[1] == '#' && (isalpha(s[2]) || s[2] == '_')) {
418 s = scanreg(s,tokenbuf);
419 yylval.stabval = aadd(stabent(tokenbuf,TRUE));
422 s = scanreg(s,tokenbuf);
423 yylval.stabval = stabent(tokenbuf,TRUE);
427 s = scanreg(s,tokenbuf);
428 yylval.stabval = aadd(stabent(tokenbuf,TRUE));
431 case '/': /* may either be division or pattern */
432 case '?': /* may either be conditional or pattern */
441 if (!expectterm || !isdigit(s[1])) {
450 case '0': case '1': case '2': case '3': case '4':
451 case '5': case '6': case '7': case '8': case '9':
452 case '\'': case '"': case '`':
458 yylval.cval = savestr(d);
462 yylval.cval = savestr(d);
466 yylval.cval = savestr(d);
470 if (strEQ(d,"continue"))
472 if (strEQ(d,"chdir"))
474 if (strEQ(d,"close"))
476 if (strEQ(d,"crypt"))
480 if (strEQ(d,"chmod")) {
481 yylval.ival = O_CHMOD;
484 if (strEQ(d,"chown")) {
485 yylval.ival = O_CHOWN;
488 yylval.cval = savestr(d);
496 yylval.cval = savestr(d);
502 if (strEQ(d,"elsif"))
504 if (strEQ(d,"eq") || strEQ(d,"EQ"))
514 if (strEQ(d,"exec")) {
515 yylval.ival = O_EXEC;
518 yylval.cval = savestr(d);
524 if (strEQ(d,"format")) {
530 yylval.cval = savestr(d);
534 if (strEQ(d,"gt") || strEQ(d,"GT"))
536 if (strEQ(d,"ge") || strEQ(d,"GE"))
540 if (strEQ(d,"gmtime"))
542 yylval.cval = savestr(d);
548 yylval.cval = savestr(d);
554 if (strEQ(d,"index"))
558 yylval.cval = savestr(d);
564 yylval.cval = savestr(d);
570 if (strEQ(d,"kill")) {
571 yylval.ival = O_KILL;
574 yylval.cval = savestr(d);
580 if (strEQ(d,"length"))
582 if (strEQ(d,"lt") || strEQ(d,"LT"))
584 if (strEQ(d,"le") || strEQ(d,"LE"))
586 if (strEQ(d,"localtime"))
592 yylval.cval = savestr(d);
600 yylval.cval = savestr(d);
606 if (strEQ(d,"ne") || strEQ(d,"NE"))
608 yylval.cval = savestr(d);
618 yylval.cval = savestr(d);
622 if (strEQ(d,"print")) {
623 yylval.ival = O_PRINT;
626 if (strEQ(d,"printf")) {
627 yylval.ival = O_PRTF;
630 if (strEQ(d,"push")) {
631 yylval.ival = O_PUSH;
636 yylval.cval = savestr(d);
640 yylval.cval = savestr(d);
644 if (strEQ(d,"reset"))
648 if (strEQ(d,"rename"))
650 yylval.cval = savestr(d);
658 if (strEQ(d,"shift"))
660 if (strEQ(d,"split"))
662 if (strEQ(d,"substr"))
664 if (strEQ(d,"sprintf"))
668 if (strEQ(d,"select"))
676 if (strEQ(d,"sleep"))
678 if (strEQ(d,"system")) {
679 yylval.ival = O_SYSTEM;
682 yylval.cval = savestr(d);
694 if (strEQ(d,"times"))
696 yylval.cval = savestr(d);
700 if (strEQ(d,"using"))
702 if (strEQ(d,"until"))
704 if (strEQ(d,"unless"))
706 if (strEQ(d,"umask"))
708 if (strEQ(d,"unshift")) {
709 yylval.ival = O_UNSHIFT;
712 if (strEQ(d,"unlink")) {
713 yylval.ival = O_UNLINK;
716 yylval.cval = savestr(d);
720 if (strEQ(d,"values"))
722 yylval.cval = savestr(d);
726 if (strEQ(d,"write"))
728 if (strEQ(d,"while"))
730 yylval.cval = savestr(d);
734 if (!expectterm && strEQ(d,"x"))
736 yylval.cval = savestr(d);
744 yylval.cval = savestr(d);
748 yylval.cval = savestr(d);
760 for (stab = stab_index[*name]; stab; stab = stab->stab_next) {
761 if (strEQ(name,stab->stab_name))
765 /* no entry--should we add one? */
768 stab = (STAB *) safemalloc(sizeof(STAB));
769 bzero((char*)stab, sizeof(STAB));
770 stab->stab_name = savestr(name);
771 stab->stab_val = str_new(0);
772 stab->stab_next = stab_index[*name];
773 stab_index[*name] = stab;
782 STIO *stio = (STIO *) safemalloc(sizeof(STIO));
784 bzero((char*)stio, sizeof(STIO));
798 while (isalpha(*s) || isdigit(*s) || *s == '_')
806 while (*s && *s != '}')
816 if (*d == '^' && !isspace(*s))
825 register STR *retstr;
829 if (index(string,'|')) {
832 retstr = str_make(string);
836 case '.': case '[': case '$': case '(': case ')': case '|':
840 if (index("wWbB0123456789",d[1])) {
861 if (d[1] == '*' || d[1] == '+' || d[1] == '?') {
872 retstr->str_cur = strlen(retstr->str_ptr); /* XXX cheating here */
880 register SPAT *spat = (SPAT *) safemalloc(sizeof (SPAT));
883 bzero((char *)spat, sizeof(SPAT));
884 spat->spat_next = spat_root; /* link into spat list */
886 init_compex(&spat->spat_compex);
895 spat->spat_flags |= SPAT_USE_ONCE;
898 fatal("Search pattern not found:\n%s",str_get(linestr));
900 s = cpytill(tokenbuf,s,s[-1]);
902 fatal("Search pattern not terminated:\n%s",str_get(linestr));
904 if (*tokenbuf == '^') {
905 spat->spat_first = scanconst(tokenbuf+1);
906 if (spat->spat_first) {
907 spat->spat_flen = strlen(spat->spat_first->str_ptr);
908 if (spat->spat_flen == strlen(tokenbuf+1))
909 spat->spat_flags |= SPAT_SCANALL;
913 spat->spat_flags |= SPAT_SCANFIRST;
914 spat->spat_first = scanconst(tokenbuf);
915 if (spat->spat_first) {
916 spat->spat_flen = strlen(spat->spat_first->str_ptr);
917 if (spat->spat_flen == strlen(tokenbuf))
918 spat->spat_flags |= SPAT_SCANALL;
921 if (d = compile(&spat->spat_compex,tokenbuf,TRUE,FALSE))
923 yylval.arg = make_match(O_MATCH,stab_to_arg(A_STAB,defstab),spat);
931 register SPAT *spat = (SPAT *) safemalloc(sizeof (SPAT));
934 bzero((char *)spat, sizeof(SPAT));
935 spat->spat_next = spat_root; /* link into spat list */
937 init_compex(&spat->spat_compex);
939 s = cpytill(tokenbuf,s+1,*s);
941 fatal("Substitution pattern not terminated:\n%s",str_get(linestr));
942 for (d=tokenbuf; *d; d++) {
943 if (*d == '$' && d[1] && d[-1] != '\\' && d[1] != '|') {
946 spat->spat_runtime = arg = op_new(1);
947 arg->arg_type = O_ITEM;
948 arg[1].arg_type = A_DOUBLE;
949 arg[1].arg_ptr.arg_str = str_make(tokenbuf);
950 goto get_repl; /* skip compiling for now */
953 if (*tokenbuf == '^') {
954 spat->spat_first = scanconst(tokenbuf+1);
955 if (spat->spat_first)
956 spat->spat_flen = strlen(spat->spat_first->str_ptr);
959 spat->spat_flags |= SPAT_SCANFIRST;
960 spat->spat_first = scanconst(tokenbuf);
961 if (spat->spat_first)
962 spat->spat_flen = strlen(spat->spat_first->str_ptr);
964 if (d = compile(&spat->spat_compex,tokenbuf,TRUE,FALSE))
969 fatal("Substitution replacement not terminated:\n%s",str_get(linestr));
970 spat->spat_repl = yylval.arg;
973 spat->spat_flags &= ~SPAT_USE_ONCE;
976 spat->spat_flags |= SPAT_USE_ONCE;
977 yylval.arg = make_match(O_SUBST,stab_to_arg(A_STAB,defstab),spat);
986 if (arg->arg_type != O_MATCH) {
987 register SPAT *spat = (SPAT *) safemalloc(sizeof (SPAT));
990 bzero((char *)spat, sizeof(SPAT));
991 spat->spat_next = spat_root; /* link into spat list */
993 init_compex(&spat->spat_compex);
995 spat->spat_runtime = arg;
996 arg = make_match(O_MATCH,stab_to_arg(A_STAB,defstab),spat);
998 arg->arg_type = O_SPLIT;
999 arg[2].arg_ptr.arg_spat->spat_repl = stab_to_arg(A_STAB,aadd(stab));
1008 register char *d = t;
1012 if (s[1] == '-' && s[2]) {
1013 for (i = s[0]; i <= s[2]; i++)
1029 l(make_op(O_TRANS,2,stab_to_arg(A_STAB,defstab),Nullarg,Nullarg,0));
1032 register char *tbl = safemalloc(256);
1035 arg[2].arg_type = A_NULL;
1036 arg[2].arg_ptr.arg_cval = tbl;
1037 for (i=0; i<256; i++)
1041 fatal("Translation pattern not terminated:\n%s",str_get(linestr));
1042 t = expand_charset(str_get(yylval.arg[1].arg_ptr.arg_str));
1043 free_arg(yylval.arg);
1046 fatal("Translation replacement not terminated:\n%s",str_get(linestr));
1047 r = expand_charset(str_get(yylval.arg[1].arg_ptr.arg_str));
1048 free_arg(yylval.arg);
1054 for (i = 0; t[i]; i++) {
1057 tbl[t[i] & 0377] = r[i];
1069 if (tail == Nullcmd) {
1072 return tail->c_head;
1076 append_line(head,tail)
1080 if (tail == Nullcmd)
1082 if (!tail->c_head) /* make sure tail is well formed */
1083 tail->c_head = tail;
1084 if (head != Nullcmd) {
1085 tail = tail->c_head; /* get to start of tail list */
1087 head->c_head = head; /* start a new head list */
1088 while (head->c_next) {
1089 head->c_next->c_head = head->c_head;
1090 head = head->c_next; /* get to end of head list */
1092 head->c_next = tail; /* link to end of old list */
1093 tail->c_head = head->c_head; /* propagate head pointer */
1095 while (tail->c_next) {
1096 tail->c_next->c_head = tail->c_head;
1097 tail = tail->c_next;
1103 make_acmd(type,stab,cond,arg)
1109 register CMD *cmd = (CMD *) safemalloc(sizeof (CMD));
1111 bzero((char *)cmd, sizeof(CMD));
1113 cmd->ucmd.acmd.ac_stab = stab;
1114 cmd->ucmd.acmd.ac_expr = arg;
1118 cmd->c_flags |= CF_COND;
1124 make_ccmd(type,arg,cblock)
1127 struct compcmd cblock;
1129 register CMD *cmd = (CMD *) safemalloc(sizeof (CMD));
1131 bzero((char *)cmd, sizeof(CMD));
1134 cmd->ucmd.ccmd.cc_true = cblock.comp_true;
1135 cmd->ucmd.ccmd.cc_alt = cblock.comp_alt;
1138 cmd->c_flags |= CF_COND;
1144 opt_arg(cmd,fliporflop)
1152 char *tmps; /* for True macro */
1153 int context = 0; /* 0 = normal, 1 = before &&, 2 = before || */
1154 int flp = fliporflop;
1160 /* Turn "if (!expr)" into "unless (expr)" */
1162 while (arg->arg_type == O_NOT && arg[1].arg_type == A_EXPR) {
1163 cmd->c_flags ^= CF_INVERT; /* flip sense of cmd */
1164 cmd->c_expr = arg[1].arg_ptr.arg_arg; /* hoist the rest of expr */
1166 arg = cmd->c_expr; /* here we go again */
1169 if (!arg->arg_len) { /* sanity check */
1170 cmd->c_flags |= opt;
1174 /* for "cond .. cond" we set up for the initial check */
1176 if (arg->arg_type == O_FLIP)
1179 /* for "cond && expr" and "cond || expr" we can ignore expr, sort of */
1181 if (arg->arg_type == O_AND)
1183 else if (arg->arg_type == O_OR)
1185 if (context && arg[flp].arg_type == A_EXPR) {
1186 arg = arg[flp].arg_ptr.arg_arg;
1190 if (arg[flp].arg_flags & (AF_PRE|AF_POST)) {
1191 cmd->c_flags |= opt;
1192 return; /* side effect, can't optimize */
1195 if (arg->arg_type == O_ITEM || arg->arg_type == O_FLIP ||
1196 arg->arg_type == O_AND || arg->arg_type == O_OR) {
1197 if (arg[flp].arg_type == A_SINGLE) {
1198 opt = (str_true(arg[flp].arg_ptr.arg_str) ? CFT_TRUE : CFT_FALSE);
1199 cmd->c_first = arg[flp].arg_ptr.arg_str;
1202 else if (arg[flp].arg_type == A_STAB || arg[flp].arg_type == A_LVAL) {
1203 cmd->c_stab = arg[flp].arg_ptr.arg_stab;
1206 if (!context) { /* no && or ||? */
1208 cmd->c_expr = Nullarg;
1211 cmd->c_flags |= CF_EQSURE;
1213 cmd->c_flags |= CF_NESURE;
1216 else if (arg->arg_type == O_MATCH || arg->arg_type == O_SUBST ||
1217 arg->arg_type == O_NMATCH || arg->arg_type == O_NSUBST) {
1218 if ((arg[1].arg_type == A_STAB || arg[1].arg_type == A_LVAL) &&
1219 arg[2].arg_type == A_SPAT &&
1220 arg[2].arg_ptr.arg_spat->spat_first ) {
1221 cmd->c_stab = arg[1].arg_ptr.arg_stab;
1222 cmd->c_first = arg[2].arg_ptr.arg_spat->spat_first;
1223 cmd->c_flen = arg[2].arg_ptr.arg_spat->spat_flen;
1224 if (arg[2].arg_ptr.arg_spat->spat_flags & SPAT_SCANALL &&
1225 (arg->arg_type == O_MATCH || arg->arg_type == O_NMATCH) )
1226 sure |= CF_EQSURE; /* (SUBST must be forced even */
1227 /* if we know it will work.) */
1228 arg[2].arg_ptr.arg_spat->spat_first = Nullstr;
1229 arg[2].arg_ptr.arg_spat->spat_flen = 0; /* only one chk */
1230 sure |= CF_NESURE; /* normally only sure if it fails */
1231 if (arg->arg_type == O_NMATCH || arg->arg_type == O_NSUBST)
1232 cmd->c_flags |= CF_FIRSTNEG;
1233 if (context & 1) { /* only sure if thing is false */
1234 if (cmd->c_flags & CF_FIRSTNEG)
1239 else if (context & 2) { /* only sure if thing is true */
1240 if (cmd->c_flags & CF_FIRSTNEG)
1245 if (sure & (CF_EQSURE|CF_NESURE)) { /* if we know anything*/
1246 if (arg[2].arg_ptr.arg_spat->spat_flags & SPAT_SCANFIRST)
1250 if (sure == (CF_EQSURE|CF_NESURE) /* really sure? */
1251 && arg->arg_type == O_MATCH
1253 && fliporflop == 1) {
1254 arg[2].arg_type = A_SINGLE; /* don't do twice */
1255 arg[2].arg_ptr.arg_str = &str_yes;
1257 cmd->c_flags |= sure;
1261 else if (arg->arg_type == O_SEQ || arg->arg_type == O_SNE ||
1262 arg->arg_type == O_SLT || arg->arg_type == O_SGT) {
1263 if (arg[1].arg_type == A_STAB || arg[1].arg_type == A_LVAL) {
1264 if (arg[2].arg_type == A_SINGLE) {
1265 cmd->c_stab = arg[1].arg_ptr.arg_stab;
1266 cmd->c_first = arg[2].arg_ptr.arg_str;
1267 cmd->c_flen = 30000;
1268 switch (arg->arg_type) {
1269 case O_SLT: case O_SGT:
1271 cmd->c_flags |= CF_FIRSTNEG;
1274 cmd->c_flags |= CF_FIRSTNEG;
1277 sure |= CF_NESURE|CF_EQSURE;
1280 if (context & 1) { /* only sure if thing is false */
1281 if (cmd->c_flags & CF_FIRSTNEG)
1286 else if (context & 2) { /* only sure if thing is true */
1287 if (cmd->c_flags & CF_FIRSTNEG)
1292 if (sure & (CF_EQSURE|CF_NESURE)) {
1294 cmd->c_flags |= sure;
1299 else if (arg->arg_type == O_ASSIGN &&
1300 (arg[1].arg_type == A_STAB || arg[1].arg_type == A_LVAL) &&
1301 arg[1].arg_ptr.arg_stab == defstab &&
1302 arg[2].arg_type == A_EXPR ) {
1303 arg2 = arg[2].arg_ptr.arg_arg;
1304 if (arg2->arg_type == O_ITEM && arg2[1].arg_type == A_READ) {
1306 cmd->c_stab = arg2[1].arg_ptr.arg_stab;
1307 if (!(arg2[1].arg_ptr.arg_stab->stab_io->flags & IOF_ARGV)) {
1310 cmd->c_expr = Nullarg;
1314 else if (arg->arg_type == O_CHOP &&
1315 (arg[1].arg_type == A_STAB || arg[1].arg_type == A_LVAL) ) {
1317 cmd->c_stab = arg[1].arg_ptr.arg_stab;
1319 cmd->c_expr = Nullarg;
1323 cmd->c_flags |= opt;
1325 if (cmd->c_flags & CF_FLIP) {
1326 if (fliporflop == 1) {
1327 arg = cmd->c_expr; /* get back to O_FLIP arg */
1328 arg[3].arg_ptr.arg_cmd = (CMD*)safemalloc(sizeof(CMD));
1329 bcopy((char *)cmd, (char *)arg[3].arg_ptr.arg_cmd, sizeof(CMD));
1330 arg[4].arg_ptr.arg_cmd = (CMD*)safemalloc(sizeof(CMD));
1331 bcopy((char *)cmd, (char *)arg[4].arg_ptr.arg_cmd, sizeof(CMD));
1332 opt_arg(arg[4].arg_ptr.arg_cmd,2);
1333 arg->arg_len = 2; /* this is a lie */
1336 if ((opt & CF_OPTIMIZE) == CFT_EVAL)
1337 cmd->c_flags = (cmd->c_flags & ~CF_OPTIMIZE) | CFT_UNFLIP;
1343 mod_match(type,left,pat)
1348 register SPAT *spat;
1349 register ARG *newarg;
1351 if ((pat->arg_type == O_MATCH ||
1352 pat->arg_type == O_SUBST ||
1353 pat->arg_type == O_TRANS ||
1354 pat->arg_type == O_SPLIT
1356 pat[1].arg_ptr.arg_stab == defstab ) {
1357 switch (pat->arg_type) {
1359 newarg = make_op(type == O_MATCH ? O_MATCH : O_NMATCH,
1361 left,Nullarg,Nullarg,0);
1364 newarg = l(make_op(type == O_MATCH ? O_SUBST : O_NSUBST,
1366 left,Nullarg,Nullarg,0));
1369 newarg = l(make_op(type == O_MATCH ? O_TRANS : O_NTRANS,
1371 left,Nullarg,Nullarg,0));
1374 newarg = make_op(type == O_MATCH ? O_SPLIT : O_SPLIT,
1376 left,Nullarg,Nullarg,0);
1379 if (pat->arg_len >= 2) {
1380 newarg[2].arg_type = pat[2].arg_type;
1381 newarg[2].arg_ptr = pat[2].arg_ptr;
1382 newarg[2].arg_flags = pat[2].arg_flags;
1383 if (pat->arg_len >= 3) {
1384 newarg[3].arg_type = pat[3].arg_type;
1385 newarg[3].arg_ptr = pat[3].arg_ptr;
1386 newarg[3].arg_flags = pat[3].arg_flags;
1389 safefree((char*)pat);
1392 spat = (SPAT *) safemalloc(sizeof (SPAT));
1393 bzero((char *)spat, sizeof(SPAT));
1394 spat->spat_next = spat_root; /* link into spat list */
1396 init_compex(&spat->spat_compex);
1398 spat->spat_runtime = pat;
1399 newarg = make_op(type,2,left,Nullarg,Nullarg,0);
1400 newarg[2].arg_type = A_SPAT;
1401 newarg[2].arg_ptr.arg_spat = spat;
1402 newarg[2].arg_flags = AF_SPECIAL;
1425 cmd->c_flags |= CF_COND;
1436 cmd->c_flags |= CF_COND|CF_LOOP;
1437 if (cmd->c_type == C_BLOCK)
1438 cmd->c_flags &= ~CF_COND;
1440 arg = cmd->ucmd.acmd.ac_expr;
1441 if (arg && arg->arg_type == O_ITEM && arg[1].arg_type == A_CMD)
1442 cmd->c_flags &= ~CF_COND; /* "do {} while" happens at least once */
1443 if (arg && arg->arg_type == O_SUBR)
1444 cmd->c_flags &= ~CF_COND; /* likewise for "do subr() while" */
1453 cmd->c_flags ^= CF_INVERT;
1461 char *tname = tmpbuf;
1464 tname = tokename[yychar-256];
1465 if (strEQ(tname,"word"))
1466 strcpy(tname,tokenbuf);
1467 else if (strEQ(tname,"register"))
1468 sprintf(tname,"$%s",tokenbuf);
1469 else if (strEQ(tname,"array_length"))
1470 sprintf(tname,"$#%s",tokenbuf);
1473 strcpy(tname,"EOF");
1474 else if (yychar < 32)
1475 sprintf(tname,"^%c",yychar+64);
1476 else if (yychar == 127)
1479 sprintf(tname,"%c",yychar);
1480 printf("%s in file %s at line %d, next token \"%s\"\n",
1481 s,filename,line,tname);
1491 register bool makesingle = FALSE;
1492 char *leave = "\\$nrtfb0123456789"; /* which backslash sequences to keep */
1496 arg->arg_type = O_ITEM;
1499 default: /* a substitution replacement */
1500 arg[1].arg_type = A_DOUBLE;
1501 makesingle = TRUE; /* maybe disable runtime scanning */
1511 arg[1].arg_type = A_SINGLE;
1516 else if (s[1] == '.')
1527 fatal("Illegal octal digit at line %d",line);
1529 case '0': case '1': case '2': case '3': case '4':
1530 case '5': case '6': case '7':
1534 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1535 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1539 i += (*s++ & 7) + 9;
1544 sprintf(tokenbuf,"%d",i);
1545 arg[1].arg_ptr.arg_str = str_make(tokenbuf);
1548 case '1': case '2': case '3': case '4': case '5':
1549 case '6': case '7': case '8': case '9': case '.':
1551 arg[1].arg_type = A_SINGLE;
1553 while (isdigit(*s) || *s == '_')
1555 if (*s == '.' && index("0123456789eE",s[1]))
1557 while (isdigit(*s) || *s == '_')
1559 if (index("eE",*s) && index("+-0123456789",s[1]))
1561 if (*s == '+' || *s == '-')
1566 arg[1].arg_ptr.arg_str = str_make(tokenbuf);
1569 arg[1].arg_type = A_SINGLE;
1575 arg[1].arg_type = A_READ;
1576 s = cpytill(tokenbuf,s+1,'>');
1578 strcpy(tokenbuf,"ARGV");
1581 if (rsfp == stdin && strEQ(tokenbuf,"stdin"))
1582 fatal("Can't get both program and data from <stdin>\n");
1583 arg[1].arg_ptr.arg_stab = stabent(tokenbuf,TRUE);
1584 arg[1].arg_ptr.arg_stab->stab_io = stio_new();
1585 if (strEQ(tokenbuf,"ARGV")) {
1586 aadd(arg[1].arg_ptr.arg_stab);
1587 arg[1].arg_ptr.arg_stab->stab_io->flags |= IOF_ARGV|IOF_START;
1591 arg[1].arg_type = A_DOUBLE;
1592 makesingle = TRUE; /* maybe disable runtime scanning */
1596 arg[1].arg_type = A_BACKTICK;
1604 tmpstr = str_new(strlen(s));
1605 s = str_append_till(tmpstr,s+1,term,leave);
1606 while (!*s) { /* multiple line string? */
1607 s = str_gets(linestr, rsfp);
1609 fatal("EOF in string at line %d\n",sqstart);
1611 s = str_append_till(tmpstr,s,term,leave);
1615 arg[1].arg_ptr.arg_str = tmpstr;
1619 s = d = tmpstr->str_ptr; /* assuming shrinkage only */
1621 if (*s == '$' && s[1]) {
1622 makesingle = FALSE; /* force interpretation */
1623 if (!isalpha(s[1])) { /* an internal register? */
1626 len = scanreg(s,tokenbuf) - s;
1627 stabent(tokenbuf,TRUE); /* make sure it's created */
1633 else if (*s == '\\' && s[1]) {
1638 if (!leave || index(leave,*s))
1642 case '0': case '1': case '2': case '3':
1643 case '4': case '5': case '6': case '7':
1645 if (index("01234567",*s)) {
1649 else if (!index('`"',term)) { /* oops, a subpattern */
1653 if (index("01234567",*s)) {
1681 if (arg[1].arg_type == A_DOUBLE) {
1683 arg[1].arg_type = A_SINGLE; /* now we can optimize on it */
1686 for (d = s = tmpstr->str_ptr; *s; *d++ = *s++) {
1687 if (*s == '\\' && (!leave || index(leave,s[1])))
1692 tmpstr->str_cur = d - tmpstr->str_ptr; /* XXX cheat */
1693 arg[1].arg_ptr.arg_str = tmpstr;
1702 make_op(type,newlen,arg1,arg2,arg3,dolist)
1714 arg = op_new(newlen);
1715 arg->arg_type = type;
1716 doarg = opargs[type];
1719 arg[1].arg_flags |= AF_SPECIAL;
1721 arg[1].arg_flags |= AF_NUMERIC;
1722 if (chld->arg_type == O_ITEM &&
1723 (hoistable[chld[1].arg_type] || chld[1].arg_type == A_LVAL) ) {
1724 arg[1].arg_type = chld[1].arg_type;
1725 arg[1].arg_ptr = chld[1].arg_ptr;
1726 arg[1].arg_flags |= chld[1].arg_flags;
1730 arg[1].arg_type = A_EXPR;
1731 arg[1].arg_ptr.arg_arg = chld;
1733 if (chld->arg_type == O_LIST) {
1734 if (newlen == 1) { /* we can hoist entire list */
1735 chld->arg_type = type;
1740 arg[1].arg_flags |= AF_SPECIAL;
1743 else if (chld->arg_type == O_ARRAY && chld->arg_len == 1)
1744 arg[1].arg_flags |= AF_SPECIAL;
1750 arg[2].arg_flags |= AF_SPECIAL;
1752 arg[2].arg_flags |= AF_NUMERIC;
1753 if (chld->arg_type == O_ITEM &&
1754 (hoistable[chld[1].arg_type] ||
1755 (type == O_ASSIGN &&
1756 (chld[1].arg_type == A_READ ||
1757 chld[1].arg_type == A_DOUBLE ||
1758 chld[1].arg_type == A_BACKTICK ) ) ) ) {
1759 arg[2].arg_type = chld[1].arg_type;
1760 arg[2].arg_ptr = chld[1].arg_ptr;
1764 arg[2].arg_type = A_EXPR;
1765 arg[2].arg_ptr.arg_arg = chld;
1767 (chld->arg_type == O_LIST ||
1768 (chld->arg_type == O_ARRAY && chld->arg_len == 1) ))
1769 arg[2].arg_flags |= AF_SPECIAL;
1774 arg[3].arg_flags |= AF_SPECIAL;
1776 arg[3].arg_flags |= AF_NUMERIC;
1777 if (chld->arg_type == O_ITEM && hoistable[chld[1].arg_type]) {
1778 arg[3].arg_type = chld[1].arg_type;
1779 arg[3].arg_ptr = chld[1].arg_ptr;
1783 arg[3].arg_type = A_EXPR;
1784 arg[3].arg_ptr.arg_arg = chld;
1786 (chld->arg_type == O_LIST ||
1787 (chld->arg_type == O_ARRAY && chld->arg_len == 1) ))
1788 arg[3].arg_flags |= AF_SPECIAL;
1793 fprintf(stderr,"%lx <= make_op(%s",arg,opname[arg->arg_type]);
1795 fprintf(stderr,",%s=%lx",
1796 argname[arg[1].arg_type],arg[1].arg_ptr.arg_arg);
1798 fprintf(stderr,",%s=%lx",
1799 argname[arg[2].arg_type],arg[2].arg_ptr.arg_arg);
1801 fprintf(stderr,",%s=%lx",
1802 argname[arg[3].arg_type],arg[3].arg_ptr.arg_arg);
1803 fprintf(stderr,")\n");
1806 evalstatic(arg); /* see if we can consolidate anything */
1810 /* turn 123 into 123 == $. */
1816 if (arg && arg->arg_type == O_ITEM && arg[1].arg_type == A_SINGLE) {
1817 arg = (ARG*)saferealloc((char*)arg,3*sizeof(ARG));
1818 arg->arg_type = O_EQ;
1820 arg[2].arg_type = A_STAB;
1821 arg[2].arg_flags = 0;
1822 arg[2].arg_ptr.arg_stab = stabent(".",TRUE);
1834 double value; /* must not be register */
1835 register char *tmps;
1837 double exp(), log(), sqrt(), modf();
1840 if (!arg || !arg->arg_len)
1843 if (arg[1].arg_type == A_SINGLE &&
1844 (arg->arg_len == 1 || arg[2].arg_type == A_SINGLE) ) {
1846 s1 = arg[1].arg_ptr.arg_str;
1847 if (arg->arg_len > 1)
1848 s2 = arg[2].arg_ptr.arg_str;
1851 switch (arg->arg_type) {
1854 str = Nullstr; /* can't be evaluated yet */
1861 i = (int)str_gnum(s2);
1866 value = str_gnum(s1);
1867 str_numset(str,value * str_gnum(s2));
1870 value = str_gnum(s1);
1871 str_numset(str,value / str_gnum(s2));
1874 value = str_gnum(s1);
1875 str_numset(str,(double)(((long)value) % ((long)str_gnum(s2))));
1878 value = str_gnum(s1);
1879 str_numset(str,value + str_gnum(s2));
1882 value = str_gnum(s1);
1883 str_numset(str,value - str_gnum(s2));
1886 value = str_gnum(s1);
1887 str_numset(str,(double)(((long)value) << ((long)str_gnum(s2))));
1890 value = str_gnum(s1);
1891 str_numset(str,(double)(((long)value) >> ((long)str_gnum(s2))));
1894 value = str_gnum(s1);
1895 str_numset(str,(double)(value < str_gnum(s2)));
1898 value = str_gnum(s1);
1899 str_numset(str,(double)(value > str_gnum(s2)));
1902 value = str_gnum(s1);
1903 str_numset(str,(double)(value <= str_gnum(s2)));
1906 value = str_gnum(s1);
1907 str_numset(str,(double)(value >= str_gnum(s2)));
1910 value = str_gnum(s1);
1911 str_numset(str,(double)(value == str_gnum(s2)));
1914 value = str_gnum(s1);
1915 str_numset(str,(double)(value != str_gnum(s2)));
1918 value = str_gnum(s1);
1919 str_numset(str,(double)(((long)value) & ((long)str_gnum(s2))));
1922 value = str_gnum(s1);
1923 str_numset(str,(double)(((long)value) ^ ((long)str_gnum(s2))));
1926 value = str_gnum(s1);
1927 str_numset(str,(double)(((long)value) | ((long)str_gnum(s2))));
1931 str = str_make(str_get(s2));
1933 str = str_make(str_get(s1));
1937 str = str_make(str_get(s1));
1939 str = str_make(str_get(s2));
1942 if (arg[3].arg_type != A_SINGLE) {
1947 str = str_make(str_get(str_true(s1) ? s2 : arg[3].arg_ptr.arg_str));
1948 str_free(arg[3].arg_ptr.arg_str);
1952 str_numset(str,(double)(-str_gnum(s1)));
1955 str_numset(str,(double)(!str_true(s1)));
1958 str_numset(str,(double)(~(long)str_gnum(s1)));
1961 str_numset(str, (double)str_len(s1));
1964 if (arg[3].arg_type != A_SINGLE || stabent("[",FALSE)) {
1965 str_free(str); /* making the fallacious assumption */
1966 str = Nullstr; /* that any $[ occurs before substr()*/
1970 int len = (int)str_gnum(s2);
1973 for (beg = str_get(s1); *beg && len > 0; beg++,len--) ;
1974 len = (int)str_gnum(arg[3].arg_ptr.arg_str);
1975 str_free(arg[3].arg_ptr.arg_str);
1976 if (len > (tmp = strlen(beg)))
1978 str_nset(str,beg,len);
1983 str_numset(str,(double)(strLT(tmps,str_get(s2))));
1987 str_numset(str,(double)(strGT(tmps,str_get(s2))));
1991 str_numset(str,(double)(strLE(tmps,str_get(s2))));
1995 str_numset(str,(double)(strGE(tmps,str_get(s2))));
1999 str_numset(str,(double)(strEQ(tmps,str_get(s2))));
2003 str_numset(str,(double)(strNE(tmps,str_get(s2))));
2007 str_set(str,crypt(tmps,str_get(s2)));
2010 str_numset(str,exp(str_gnum(s1)));
2013 str_numset(str,log(str_gnum(s1)));
2016 str_numset(str,sqrt(str_gnum(s1)));
2019 modf(str_gnum(s1),&value);
2020 str_numset(str,value);
2023 str_numset(str,(double)(*str_get(s1)));
2027 arg->arg_type = O_ITEM; /* note arg1 type is already SINGLE */
2030 arg[1].arg_ptr.arg_str = str;
2042 arg->arg_flags |= AF_COMMON; /* XXX should cross-match */
2044 /* see if it's an array reference */
2046 if (arg[1].arg_type == A_EXPR) {
2047 arg1 = arg[1].arg_ptr.arg_arg;
2049 if (arg1->arg_type == O_LIST && arg->arg_type != O_ITEM) {
2050 /* assign to list */
2051 arg[1].arg_flags |= AF_SPECIAL;
2052 arg[2].arg_flags |= AF_SPECIAL;
2053 for (i = arg1->arg_len; i >= 1; i--) {
2054 switch (arg1[i].arg_type) {
2055 case A_STAB: case A_LVAL:
2056 arg1[i].arg_type = A_LVAL;
2058 case A_EXPR: case A_LEXPR:
2059 arg1[i].arg_type = A_LEXPR;
2060 if (arg1[i].arg_ptr.arg_arg->arg_type == O_ARRAY)
2061 arg1[i].arg_ptr.arg_arg->arg_type = O_LARRAY;
2062 else if (arg1[i].arg_ptr.arg_arg->arg_type == O_HASH)
2063 arg1[i].arg_ptr.arg_arg->arg_type = O_LHASH;
2064 if (arg1[i].arg_ptr.arg_arg->arg_type == O_LARRAY)
2066 if (arg1[i].arg_ptr.arg_arg->arg_type == O_LHASH)
2071 "Illegal item (%s) as lvalue",argname[arg1[i].arg_type]);
2076 else if (arg1->arg_type == O_ARRAY) {
2077 if (arg1->arg_len == 1 && arg->arg_type != O_ITEM) {
2078 /* assign to array */
2079 arg[1].arg_flags |= AF_SPECIAL;
2080 arg[2].arg_flags |= AF_SPECIAL;
2083 arg1->arg_type = O_LARRAY; /* assign to array elem */
2085 else if (arg1->arg_type == O_HASH)
2086 arg1->arg_type = O_LHASH;
2089 "Illegal expression (%s) as lvalue",opname[arg1->arg_type]);
2092 arg[1].arg_type = A_LEXPR;
2095 fprintf(stderr,"lval LEXPR\n");
2100 /* not an array reference, should be a register name */
2102 if (arg[1].arg_type != A_STAB && arg[1].arg_type != A_LVAL) {
2104 "Illegal item (%s) as lvalue",argname[arg[1].arg_type]);
2107 arg[1].arg_type = A_LVAL;
2110 fprintf(stderr,"lval LVAL\n");
2116 addflags(i,flags,arg)
2119 arg[i].arg_flags |= flags;
2127 if (arg->arg_type == O_ARRAY)
2128 return make_op(O_ITEM,1,arg,Nullarg,Nullarg,0);
2138 register ARG *nxtnode;
2144 arg->arg_type = O_LIST;
2146 if (arg->arg_type != O_COMMA) {
2147 arg->arg_flags |= AF_LISTISH; /* see listish() below */
2150 for (i = 2, node = arg; ; i++) {
2151 if (node->arg_len < 2)
2153 if (node[2].arg_type != A_EXPR)
2155 node = node[2].arg_ptr.arg_arg;
2156 if (node->arg_type != O_COMMA)
2162 tmpstr = arg->arg_ptr.arg_str;
2163 *arg = *node; /* copy everything except the STR */
2164 arg->arg_ptr.arg_str = tmpstr;
2172 nxtnode = node[2].arg_ptr.arg_arg;
2177 arg->arg_type = O_LIST;
2182 /* turn a single item into a list */
2188 if (arg->arg_flags & AF_LISTISH)
2189 arg = make_op(O_LIST,1,arg,Nullarg,Nullarg,0);
2194 stab_to_arg(atype,stab)
2196 register STAB *stab;
2201 arg->arg_type = O_ITEM;
2202 arg[1].arg_type = atype;
2203 arg[1].arg_ptr.arg_stab = stab;
2209 register char *cval;
2214 arg->arg_type = O_ITEM;
2215 arg[1].arg_type = A_SINGLE;
2216 arg[1].arg_ptr.arg_str = str_make(cval);
2227 arg = (ARG*)safemalloc((numargs + 1) * sizeof (ARG));
2228 bzero((char *)arg, (numargs + 1) * sizeof (ARG));
2229 arg->arg_ptr.arg_str = str_new(0);
2230 arg->arg_len = numargs;
2238 str_free(arg->arg_ptr.arg_str);
2239 safefree((char*)arg);
2243 make_match(type,expr,spat)
2250 arg = make_op(type,2,expr,Nullarg,Nullarg,0);
2252 arg[2].arg_type = A_SPAT;
2253 arg[2].arg_ptr.arg_spat = spat;
2256 fprintf(stderr,"make_match SPAT=%lx\n",spat);
2259 if (type == O_SUBST || type == O_NSUBST) {
2260 if (arg[1].arg_type != A_STAB)
2261 yyerror("Illegal lvalue");
2262 arg[1].arg_type = A_LVAL;
2274 arg->arg_type = O_ITEM;
2275 arg[1].arg_type = A_CMD;
2276 arg[1].arg_ptr.arg_cmd = cmd;
2285 register ARG *arg = cmd->c_expr;
2286 char *tmps; /* used by True macro */
2288 /* hoist "while (<channel>)" up into command block */
2290 if (arg && arg->arg_type == O_ITEM && arg[1].arg_type == A_READ) {
2291 cmd->c_flags &= ~CF_OPTIMIZE; /* clear optimization type */
2292 cmd->c_flags |= CFT_GETS; /* and set it to do the input */
2293 cmd->c_stab = arg[1].arg_ptr.arg_stab;
2294 if (arg[1].arg_ptr.arg_stab->stab_io->flags & IOF_ARGV) {
2295 cmd->c_expr = l(make_op(O_ASSIGN, 2, /* fake up "$_ =" */
2296 stab_to_arg(A_LVAL,defstab), arg, Nullarg,1 ));
2300 cmd->c_expr = Nullarg;
2304 /* First find the end of the true list */
2306 if (cmd->ucmd.ccmd.cc_true == Nullcmd)
2308 for (tail = cmd->ucmd.ccmd.cc_true; tail->c_next; tail = tail->c_next) ;
2310 /* if there's a continue block, link it to true block and find end */
2312 if (cmd->ucmd.ccmd.cc_alt != Nullcmd) {
2313 tail->c_next = cmd->ucmd.ccmd.cc_alt;
2314 for ( ; tail->c_next; tail = tail->c_next) ;
2317 /* Here's the real trick: link the end of the list back to the beginning,
2318 * inserting a "last" block to break out of the loop. This saves one or
2319 * two procedure calls every time through the loop, because of how cmd_exec
2320 * does tail recursion.
2323 tail->c_next = (CMD *) safemalloc(sizeof (CMD));
2324 tail = tail->c_next;
2325 if (!cmd->ucmd.ccmd.cc_alt)
2326 cmd->ucmd.ccmd.cc_alt = tail; /* every loop has a continue now */
2328 bcopy((char *)cmd, (char *)tail, sizeof(CMD));
2329 tail->c_type = C_EXPR;
2330 tail->c_flags ^= CF_INVERT; /* turn into "last unless" */
2331 tail->c_next = tail->ucmd.ccmd.cc_true; /* loop directly back to top */
2332 tail->ucmd.acmd.ac_expr = make_op(O_LAST,0,Nullarg,Nullarg,Nullarg,0);
2333 tail->ucmd.acmd.ac_stab = Nullstab;
2342 register FCMD *fprev = &froot;
2343 register FCMD *fcmd;
2346 register char tmpchar;
2349 while ((s = str_gets(linestr,rsfp)) != Nullch) {
2351 if (strEQ(s,".\n")) {
2353 return froot.f_next;
2357 flinebeg = Nullfcmd;
2360 fcmd = (FCMD *)safemalloc(sizeof (FCMD));
2361 bzero((char*)fcmd, sizeof (FCMD));
2362 fprev->f_next = fcmd;
2364 for (t=s; *t && *t != '@' && *t != '^'; t++) {
2372 fcmd->f_pre = savestr(s);
2373 fcmd->f_presize = strlen(s);
2378 fcmd->f_flags |= FC_NOBLANK;
2382 flinebeg = fcmd; /* start values here */
2384 fcmd->f_flags |= FC_CHOP; /* for doing text filling */
2387 fcmd->f_type = F_LINES;
2391 fcmd->f_type = F_LEFT;
2396 fcmd->f_type = F_RIGHT;
2401 fcmd->f_type = F_CENTER;
2406 fcmd->f_type = F_LEFT;
2409 if (fcmd->f_flags & FC_CHOP && *s == '.') {
2410 fcmd->f_flags |= FC_MORE;
2418 if ((bufptr = str_gets(linestr ,rsfp)) == Nullch)
2421 if (strEQ(bufptr,".\n")) {
2422 yyerror("Missing values line");
2423 return froot.f_next;
2427 lex_newlines = TRUE;
2428 while (flinebeg || *bufptr) {
2431 yyerror("Bad value in format");
2436 yyerror("Missing value in format");
2440 yylval.arg = stab_to_arg(A_LVAL,yylval.stabval);
2444 yyerror("Extra value in format");
2446 flinebeg->f_expr = yylval.arg;
2448 flinebeg = flinebeg->f_next;
2449 } while (flinebeg && flinebeg->f_size == 0);
2456 lex_newlines = FALSE;
2460 bufptr = str_get(linestr);
2461 yyerror("Format not terminated");
2462 return froot.f_next;