#if 0 /* SAJ */ #include "compiler.h" #ifdef LATTICE #define void int #endif #endif /* SAJ */ #include "debug.h" /* sedexec.c -- execute compiled form of stream editor commands The single entry point of this module is the function execute(). It may take a string argument (the name of a file to be used as text) or the argument NULL which tells it to filter standard input. It executes the compiled commands in cmds[] on each line in turn. The function command() does most of the work. Match() and advance() are used for matchia~•لذپ…‌…¥¹حذپءة•چ½µء¥±•گپة•‌ص±…بپ•لءة•حح¥½¹جپ…¹گ)‘½حصˆ ¤پ‘½•جپة¥‌،ذµ،…¹گµح¥‘”پحص‰حر¥رصر¥½¸¸€پ•ر±¥¹” ¤پ‘½•جپر•لذپ¥¹ءصذى)ة•…‘½صذ ¤پ…¹گپµ•µچµہ ¤پ…ة”پ½صرءصذپ…¹گپحرة¥¹œµچ½µء…ة¥ح½¸پصر¥±¥ر¥•ج¸€€((ôôôôپ]ة¥رر•¸پ™½بپر،”پ9Tپ½ء•ة…ر¥¹œپحهحر•´پ‰نپة¥ŒپL¸پI…هµ½¹گ€ôôôô€(¨¼((چ¥¹چ±ص‘”€ٌحر‘¥¼¹ ّ€€€€€€¼¨پي™ُءصرج°پي™ُءة¥¹رک°پ‌•رŒ½ءصرŒ°پ™ية•ُ½ء•¸°پ™چ±½ح”€¨¼(چ¥¹چ±ص‘”€ٌچرهء”¹ ّ€€€€€€¼¨پ™½بپ¥حءة¥¹ذ ¤°پ¥ح‘¥‌¥ذ ¤°پر½…حچ¥¤ ¤پµ…چة½ج€¨¼(چ¥¹چ±ص‘”€‰ح•گ¹¯3????????>08'>!>0 ?#>0 8 r char *p = cp; /* this is for speed */ SKIPWS(p); /* discard whitespace */ do { if ((*txp = *p++) == '\\') /* handle escapes */ *txp = *p++; if (*txp == '\0') /* we're at end of input */ return(cp = --p, ++txp); else if (*txp == '\n') /* also SKIPWS after newline */ SKIPWS(p); } while (txp++); /* keep going till we find that nul */ } static label *search(ptr) /* uses global lablst */ /* find the label matching *ptr, return NULL if none */ register label *ptr; { register label *rp; for(rp = lablst; rp < ptr; rp++) if (strcmp(rp->name, ptr->name) == 0) return(rp); return(NULL); } static void resolve() /* uses global lablst */ /* write label links into the compiled-command space */ { register label *lptr; register sedcmd *rptr, *trptr; /* loop through the label table */ for(lptr = lablst; lptr < lab; lptr++) if (lptr->address == NULL) /* barf if not defined */ { fprintf(stderr, ULABL, lptr->name); exit(2); } else if (lptr->last) /* if last is non-null */ { rptr = lptr->last; /* chase it */ while(trptr = rptr->u.link) /* resolve refs */ { rptr->u.link = lptr->address; rptr = trptr; } rptr->u.link = lptr->address; } } static char *ycomp(ep, delim) /* compile a y (transliterate) command */ register char *ep; /* where to compile to */ char delim; /* end delimiter to look for */ { register char c, *tp, *sp; /* scan the 'from' section for invalid chars */ for(sp = tp = cp; *tp != delim; tp++) { if (*tp == '\\') tp++; if ((*tp == '\n') || (*tp == '\0')) return(BAD); } tp++; /* tp now points at first char of 'to' section */ /* now rescan the 'from' section */ while((c = *sp++ & 0x7F) != delim) { if (c == '\\' && *sp == 'n') { sp++; c = '\n'; } if ((ep[c] = *tp++) == '\\' && *tp == 'n') { ep[c] = '\n'; tp++; } if ((ep[c] == delim) || (ep[c] == '\0')) return(BAD); } if (*tp != delim) /* 'to', 'from' parts have unequal lengths */ return(BAD); cp = ++tp; /* point compile ptr past translit */ for(c = 0; c < 128; c++) /* fill in self-map entries in table */ if (ep[c] == 0) ep[c] = c; return(ep + 0x80); /* return first free location past table end */ } /* sedcomp.c ends here */ } else { if (ipc->flags.allbut) return(TRUE); ipc++; return(FALSE); } return(TRUE); /* SAJ for Atari ST, Mark Williams C */ } static int match(expbuf, gf) /* uses genbuf */ /* match RE at expbuf against linebuf; if gf set, copy linebuf from genbuf */ char *expbuf; { register char *p1, *p2, c; if (gf) { if (*expbuf) return(FALSE); p1 = linebuf; p2 = genbuf; while (*p1++ = *p2++); locs = p1 = loc2; } else { p1 = linebuf; locs = FALSE; } p2 = expbuf; if (*p2++) { loc1 = p1; if(*p2 == CCHR && p2[1] != *p1) /* 1st char is wrong */ return(FALSE); /* so fail */ return(advance(p1, p2)); /* else try to match rest */ } /* quick check for 1st character if it's literal */ if (*p2 == CCHR) { c = p2[1]; /* pull out character to search for */ do { if (*p1 != c) continue; /* scan the source string */ if (advance(p1, p2)) /* found it, match the rest */ return(loc1 = p1, 1); } while (*p1++); return(FALSE); /* didn't find that first char */ } /* else try for unanchored match of the pattern */ do { if (advance(p1, p2)) return(loc1 = p1, 1); } while (*p1++); /* if got here, didn't match either way */ return(FALSE); } static int advance(lp, ep) /* attempt to advance match pointer by one pattern element ہp„ˆˆدŒژدددہپ‡ہOدددددددددددہ@د„ŒOأپ‚ˆ €آO‡پ„دہہp„egister char *ep; /* regular expression element ptr */ { register char *curlp; /* save ptr for closures */ char c; /* scratch character holder */ char *bbeg; hپدددددددددددددŒہpًددددددددˆ€دأہ@Bpدددددددددددددددد„Œدأہˆہ@Bpدددددددددددددددد€pددددددددددددددددŒOœ„ہددددددددددددددہ@دپ‚ˆژدŒژژ ˆدہہpدددددددددددددددددددددددد‚دأہˆہ@Oہ@Oہپ‡ہ@BOددددہ@د‚دŒژ„OژˆOˆدہہpددددددددددددددددددددددددددددددددŒپ‚€e; /* matched */ return(FALSE); /* else return false */ case CDOT: /* anything but newline */ if (*lp++) / دˆ‚„دگ€د‚OژدکدہہpددددددددددددددددددددددددددددددددŒپ‚€@Oددددددہ@د€دˆˆO‚د‰‚ €بدˆ‚‰دہہpدددددددددددددددددددددددد„ˆ€€أک‍„B@Oدددددددددہ@دˆ„O„ˆ€€دˆژ„OہہpًددددددددددددددددŒOœ‘ہدددددددددددددددہ@د„ژپہہ‚ˆOہہpددددددددددددددددŒOœگہددددددددددددددہ@دˆ‰ہہ‚ˆOہہpدددد /* end delimiter to look for */ { register char c, *tp, *sp; /* scan the 'from' section for invalid chars */ for(sp = tp = cp; *tp != delim; tp++) { if (*tp == '\\') tp++; if ((*tp == '\n') || (*tp == '\0')) return(BAD); } tp++; /* tp now points at first char of 'to' section */ /* now rescan the 'from' section */ while((c = *sp++ & 0x7F) != delim) { if (c == '\\' && *sp == 'n') { sp++; c = '\n'; } if ((ep[c] = *tp++) == '\\' && *tp == 'n') { ep[c] = '\n'; tp++; } if ((ep[c] == delim) || (ep[c] == '\0')) return(BAD); } if (*tp != delim) /* 'to', 'from' parts have unequal lengths */ return(BAD); cp = ++tp; /* point compile ptr past translit */ for(c = 0; c < 128; c++) /* fill in self-map entries in table */ if (ep[c] == 0) ep[c] = c; return(ep + 0x80); /* return first free location past table end */ } /* sedcomp.c ends here */ sedcmd *ipc; /* ptr to s command struct */ { void dosub(); /* for if we find a match */ if (match(ipc->u.lhs, 0)) /* if no match */ dosub(ipc->rhs); /* perform it once */ else return(FALSE); /* command fails */ if (ipc->flags.global) /* if global flag enabled */ while(*loc2) /* cycle through possibles */ if (match(ipc->u.lhs, 1)) /* found another */ dosub(ipc->rhs); /* so substitute */ else /* otherwise, */ break; /* we're done */ return(TRUE); /* we succeeded */ } static void dosub(rhsbuf) /* uses linebuf, genbuf, spend */ /* generate substituted right-hand side (of s command) */ char *rhsbuf; /* where to put the result */ { register char *lp, *sp, *rp; int c; char *place(); /* copy linebuf to genbuf up to location 1 */ lp = linebuf; sp = genbuf; while (lp < loc1) *sp++ = *lp++; for (rp = rhsbuf; c = *rp++; ) { if (c == '&') { sp = place(sp, loc1, loc2); continue; } else if (c & 0200 && (c &= 0177) >= '1' && c < MAXTAGS+'1') { sp = place(sp, brastart[c-'1'], bracend[c-'1']); continue; } *sp++ = c & 0177; if (sp >= genbuf + MAXBUF) fprintf(stderr, LTLMSG); } lp = loc2; /* MRY loc2 = sp - genbuf + linebuf; */ loc2 = sp - (genbuf - linebuf); while (*sp++ = *lp++) if (sp >= genbuf + MAXBUF) fprintf(stderr, LTLMSG); lp = linebuf; sp = genbuf; while (*lp++ = *sp++); spend = lp-1; } static char *place(asp, al1, al2) /* uses genbuf */ /* place chars at *al1...*(al1 - 1) at asp... in genbuf[] */ register char *asp, *al1, *al2; { while (al1 < al2) { *asp++ = *al1++; if (asp >= genbuf + MAXBUF) fprintf(stderr, LTLMSG); } return(asp); } static void listto(p1, fp) /* write a hex dump expansion of *p1... to fp */ register char *p1; /* the source */ FILEدددددددددددہˆ‡ہOدددددددددددہ ں  to writeپ€Oہہp€pدددددددد‡ئP@@ while(*p1++) if (isprint(*p1)) putc(*p1, fp); /* pass it throug` */ else { putc('\134', fp); /* emit a backslash */ swjŒأہ‡ئBpدددددددددددددددددددددددد€pددددددددددددددددددددددددŒO /* end delimiter to look for */ { register char c, *tp, *sp; /* scan the 'from' section for invalid chars */ for(sp = tp = cp; *tp != delim; tp++) { if (*tp == '\\') tp++; if ((*tp == '\n') || (*tp == '\0')) return(BAD); } tp++; /* tp now points at first char of 'to' section */ /* now rescan the 'from' section */ while((c = *sp++ & 0x7F) != delim) { if (c == '\\' && *sp == 'n') { sp++; c = '\n'; } if ((ep[c] = *tp++) == '\\' && *tp == 'n') { ep[c] = '\n'; tp++; } if ((ep[c] == delim) || (ep[c] == '\0')) return(BAD); } if (*tp != delim) /* 'to', 'from' parts have unequal lengths */ return(BAD); cp = ++tp; /* point compile ptr past translit */ for(c = 0; c < 128; c++) /* fill in self-map entries in table */ if (ep[c] == 0) ep[c] = c; return(ep + 0x80); /* return first free location past table end */ } /* sedcomp.c ends here */