sed0.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  1. #include <stdlib.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include "sed.h"
  5. struct label *labtab = ltab;
  6. char CGMES[] = "sed: Command garbled: %s\n";
  7. char TMMES[] = "sed: Too much text: %s\n";
  8. char LTL[] = "sed: Label too long: %s\n";
  9. char AD0MES[] = "sed: No addresses allowed: %s\n";
  10. char AD1MES[] = "sed: Only one address allowed: %s\n";
  11. uchar bittab[] = {
  12. 1,
  13. 2,
  14. 4,
  15. 8,
  16. 16,
  17. 32,
  18. 64,
  19. 128
  20. };
  21. main(int argc, char **argv)
  22. {
  23. eargc = argc;
  24. eargv = (uchar**)argv;
  25. badp = &bad;
  26. aptr = abuf;
  27. hspend = holdsp;
  28. lab = labtab + 1; /* 0 reserved for end-pointer */
  29. rep = ptrspace;
  30. rep->r1.ad1 = respace;
  31. lbend = &linebuf[LBSIZE];
  32. hend = &holdsp[LBSIZE];
  33. lcomend = &genbuf[64];
  34. ptrend = &ptrspace[PTRSIZE];
  35. reend = &respace[RESIZE];
  36. labend = &labtab[LABSIZE];
  37. lnum = 0;
  38. pending = 0;
  39. depth = 0;
  40. spend = linebuf;
  41. hspend = holdsp;
  42. fcode[0] = stdout;
  43. nfiles = 1;
  44. lastre = NULL;
  45. if(eargc == 1)
  46. exit(0);
  47. while (--eargc > 0 && (++eargv)[0][0] == '-')
  48. switch (eargv[0][1]) {
  49. case 'n':
  50. nflag++;
  51. continue;
  52. case 'f':
  53. if(eargc-- <= 0) exit(2);
  54. if((fin = fopen((char*)(*++eargv), "r")) == NULL) {
  55. fprintf(stderr, "sed: Cannot open pattern-file: %s\n", *eargv);
  56. exit(2);
  57. }
  58. fcomp();
  59. fclose(fin);
  60. continue;
  61. case 'e':
  62. eflag++;
  63. fcomp();
  64. eflag = 0;
  65. continue;
  66. case 'g':
  67. gflag++;
  68. continue;
  69. default:
  70. fprintf(stderr, "sed: Unknown flag: %c\n", eargv[0][1]);
  71. continue;
  72. }
  73. if(compfl == 0) {
  74. eargv--;
  75. eargc++;
  76. eflag++;
  77. fcomp();
  78. eargv++;
  79. eargc--;
  80. eflag = 0;
  81. }
  82. if(depth) {
  83. fprintf(stderr, "sed: Too many {'s\n");
  84. exit(2);
  85. }
  86. labtab->address = rep;
  87. dechain();
  88. /* abort(); /*DEBUG*/
  89. if(eargc <= 0)
  90. execute((uchar *)NULL);
  91. else while(--eargc >= 0) {
  92. execute(*eargv++);
  93. }
  94. fclose(stdout);
  95. exit(0);
  96. }
  97. void
  98. fcomp(void)
  99. {
  100. uchar *p, *op, *tp;
  101. uchar *address(uchar*);
  102. union reptr *pt, *pt1;
  103. int i;
  104. struct label *lpt;
  105. compfl = 1;
  106. op = lastre;
  107. if(rline(linebuf) < 0) {
  108. lastre = op;
  109. return;
  110. }
  111. if(*linebuf == '#') {
  112. if(linebuf[1] == 'n')
  113. nflag = 1;
  114. }
  115. else {
  116. cp = linebuf;
  117. goto comploop;
  118. }
  119. for(;;) {
  120. if(rline(linebuf) < 0) break;
  121. cp = linebuf;
  122. comploop:
  123. /* fprintf(stdout, "cp: %s\n", cp); /*DEBUG*/
  124. while(*cp == ' ' || *cp == '\t') cp++;
  125. if(*cp == '\0' || *cp == '#') continue;
  126. if(*cp == ';') {
  127. cp++;
  128. goto comploop;
  129. }
  130. p = address(rep->r1.ad1);
  131. if(p == badp) {
  132. fprintf(stderr, CGMES, linebuf);
  133. exit(2);
  134. }
  135. if(p == 0) {
  136. p = rep->r1.ad1;
  137. rep->r1.ad1 = 0;
  138. } else {
  139. if(p == rep->r1.ad1) {
  140. if(op)
  141. rep->r1.ad1 = op;
  142. else {
  143. fprintf(stderr, "sed: First RE may not be null\n");
  144. exit(2);
  145. }
  146. }
  147. if(*rep->r1.ad1 != CLNUM && *rep->r1.ad1 != CEND)
  148. op = rep->r1.ad1;
  149. if(*cp == ',' || *cp == ';') {
  150. cp++;
  151. if((rep->r1.ad2 = p) > reend) {
  152. fprintf(stderr, TMMES, linebuf);
  153. exit(2);
  154. }
  155. p = address(rep->r1.ad2);
  156. if(p == badp || p == 0) {
  157. fprintf(stderr, CGMES, linebuf);
  158. exit(2);
  159. }
  160. if(p == rep->r1.ad2)
  161. rep->r1.ad2 = op;
  162. else{
  163. if(*rep->r1.ad2 != CLNUM && *rep->r1.ad2 != CEND)
  164. op = rep->r1.ad2;
  165. }
  166. } else
  167. rep->r1.ad2 = 0;
  168. }
  169. if(p > reend) {
  170. fprintf(stderr, "sed: Too much text: %s\n", linebuf);
  171. exit(2);
  172. }
  173. while(*cp == ' ' || *cp == '\t') cp++;
  174. swit:
  175. switch(*cp++) {
  176. default:
  177. /*fprintf(stderr, "cp = %d; *cp = %o\n", cp - linebuf, *cp);*/
  178. fprintf(stderr, "sed: Unrecognized command: %s\n", linebuf);
  179. exit(2);
  180. case '!':
  181. rep->r1.negfl = 1;
  182. goto swit;
  183. case '{':
  184. rep->r1.command = BCOM;
  185. rep->r1.negfl = !(rep->r1.negfl);
  186. cmpend[depth++] = &rep->r2.lb1;
  187. if(++rep >= ptrend) {
  188. fprintf(stderr, "sed: Too many commands: %s\n", linebuf);
  189. exit(2);
  190. }
  191. rep->r1.ad1 = p;
  192. if(*cp == '\0') continue;
  193. goto comploop;
  194. case '}':
  195. if(rep->r1.ad1) {
  196. fprintf(stderr, AD0MES, linebuf);
  197. exit(2);
  198. }
  199. if(--depth < 0) {
  200. fprintf(stderr, "sed: Too many }'s\n");
  201. exit(2);
  202. }
  203. *cmpend[depth] = rep;
  204. rep->r1.ad1 = p;
  205. if(*cp == 0) continue;
  206. goto comploop;
  207. case '=':
  208. rep->r1.command = EQCOM;
  209. if(rep->r1.ad2) {
  210. fprintf(stderr, AD1MES, linebuf);
  211. exit(2);
  212. }
  213. break;
  214. case ':':
  215. if(rep->r1.ad1) {
  216. fprintf(stderr, AD0MES, linebuf);
  217. exit(2);
  218. }
  219. while(*cp++ == ' ');
  220. cp--;
  221. tp = lab->asc;
  222. while((*tp = *cp++) && *tp != ';')
  223. if(++tp >= &(lab->asc[8])) {
  224. fprintf(stderr, LTL, linebuf);
  225. exit(2);
  226. }
  227. *tp = '\0';
  228. if(*lab->asc == 0) {
  229. fprintf(stderr, CGMES, linebuf);
  230. exit(2);
  231. }
  232. if(lpt = search(lab)) {
  233. if(lpt->address) {
  234. fprintf(stderr, "sed: Duplicate labels: %s\n", linebuf);
  235. exit(2);
  236. }
  237. } else {
  238. lab->chain = 0;
  239. lpt = lab;
  240. if(++lab >= labend) {
  241. fprintf(stderr, "sed: Too many labels: %s\n", linebuf);
  242. exit(2);
  243. }
  244. }
  245. lpt->address = rep;
  246. rep->r1.ad1 = p;
  247. continue;
  248. case 'a':
  249. rep->r1.command = ACOM;
  250. if(rep->r1.ad2) {
  251. fprintf(stderr, AD1MES, linebuf);
  252. exit(2);
  253. }
  254. if(*cp == '\\') cp++;
  255. if(*cp++ != '\n') {
  256. fprintf(stderr, CGMES, linebuf);
  257. exit(2);
  258. }
  259. rep->r1.re1 = p;
  260. p = text(rep->r1.re1);
  261. break;
  262. case 'c':
  263. rep->r1.command = CCOM;
  264. if(*cp == '\\') cp++;
  265. if(*cp++ != ('\n')) {
  266. fprintf(stderr, CGMES, linebuf);
  267. exit(2);
  268. }
  269. rep->r1.re1 = p;
  270. p = text(rep->r1.re1);
  271. break;
  272. case 'i':
  273. rep->r1.command = ICOM;
  274. if(rep->r1.ad2) {
  275. fprintf(stderr, AD1MES, linebuf);
  276. exit(2);
  277. }
  278. if(*cp == '\\') cp++;
  279. if(*cp++ != ('\n')) {
  280. fprintf(stderr, CGMES, linebuf);
  281. exit(2);
  282. }
  283. rep->r1.re1 = p;
  284. p = text(rep->r1.re1);
  285. break;
  286. case 'g':
  287. rep->r1.command = GCOM;
  288. break;
  289. case 'G':
  290. rep->r1.command = CGCOM;
  291. break;
  292. case 'h':
  293. rep->r1.command = HCOM;
  294. break;
  295. case 'H':
  296. rep->r1.command = CHCOM;
  297. break;
  298. case 't':
  299. rep->r1.command = TCOM;
  300. goto jtcommon;
  301. case 'b':
  302. rep->r1.command = BCOM;
  303. jtcommon:
  304. while(*cp++ == ' ');
  305. cp--;
  306. if(*cp == '\0') {
  307. if(pt = labtab->chain) {
  308. while(pt1 = pt->r2.lb1)
  309. pt = pt1;
  310. pt->r2.lb1 = rep;
  311. } else
  312. labtab->chain = rep;
  313. break;
  314. }
  315. tp = lab->asc;
  316. while((*tp = *cp++) && *tp != ';')
  317. if(++tp >= &(lab->asc[8])) {
  318. fprintf(stderr, LTL, linebuf);
  319. exit(2);
  320. }
  321. cp--;
  322. *tp = '\0';
  323. if(*lab->asc == 0) {
  324. fprintf(stderr, CGMES, linebuf);
  325. exit(2);
  326. }
  327. if(lpt = search(lab)) {
  328. if(lpt->address) {
  329. rep->r2.lb1 = lpt->address;
  330. } else {
  331. pt = lpt->chain;
  332. while(pt1 = pt->r2.lb1)
  333. pt = pt1;
  334. pt->r2.lb1 = rep;
  335. }
  336. } else {
  337. lab->chain = rep;
  338. lab->address = 0;
  339. if(++lab >= labend) {
  340. fprintf(stderr, "sed: Too many labels: %s\n", linebuf);
  341. exit(2);
  342. }
  343. }
  344. break;
  345. case 'n':
  346. rep->r1.command = NCOM;
  347. break;
  348. case 'N':
  349. rep->r1.command = CNCOM;
  350. break;
  351. case 'p':
  352. rep->r1.command = PCOM;
  353. break;
  354. case 'P':
  355. rep->r1.command = CPCOM;
  356. break;
  357. case 'r':
  358. rep->r1.command = RCOM;
  359. if(rep->r1.ad2) {
  360. fprintf(stderr, AD1MES, linebuf);
  361. exit(2);
  362. }
  363. if(*cp++ != ' ') {
  364. fprintf(stderr, CGMES, linebuf);
  365. exit(2);
  366. }
  367. rep->r1.re1 = p;
  368. p = text(rep->r1.re1);
  369. break;
  370. case 'd':
  371. rep->r1.command = DCOM;
  372. break;
  373. case 'D':
  374. rep->r1.command = CDCOM;
  375. rep->r2.lb1 = ptrspace;
  376. break;
  377. case 'q':
  378. rep->r1.command = QCOM;
  379. if(rep->r1.ad2) {
  380. fprintf(stderr, AD1MES, linebuf);
  381. exit(2);
  382. }
  383. break;
  384. case 'l':
  385. rep->r1.command = LCOM;
  386. break;
  387. case 's':
  388. rep->r1.command = SCOM;
  389. seof = *cp++;
  390. rep->r1.re1 = p;
  391. p = compile(rep->r1.re1);
  392. if(p == badp) {
  393. fprintf(stderr, CGMES, linebuf);
  394. exit(2);
  395. }
  396. if(p == rep->r1.re1) {
  397. if(op == NULL) {
  398. fprintf(stderr, "sed: First RE may not be null.\n");
  399. exit(2);
  400. }
  401. rep->r1.re1 = op;
  402. } else {
  403. op = rep->r1.re1;
  404. }
  405. if((rep->r1.rhs = p) > reend) {
  406. fprintf(stderr, TMMES, linebuf);
  407. exit(2);
  408. }
  409. if((p = compsub(rep->r1.rhs)) == badp) {
  410. fprintf(stderr, CGMES, linebuf);
  411. exit(2);
  412. }
  413. if(*cp == 'g') {
  414. cp++;
  415. rep->r1.gfl++;
  416. } else if(gflag)
  417. rep->r1.gfl++;
  418. if(*cp == 'p') {
  419. cp++;
  420. rep->r1.pfl = 1;
  421. }
  422. if(*cp == 'P') {
  423. cp++;
  424. rep->r1.pfl = 2;
  425. }
  426. if(*cp == 'w') {
  427. cp++;
  428. if(*cp++ != ' ') {
  429. fprintf(stderr, CGMES, linebuf);
  430. exit(2);
  431. }
  432. if(nfiles >= MAXFILES) {
  433. fprintf(stderr, "sed: Too many files in w commands 1 \n");
  434. exit(2);
  435. }
  436. text((uchar*)fname[nfiles]);
  437. for(i = nfiles - 1; i >= 0; i--)
  438. if(cmp((uchar*)fname[nfiles],(uchar*)fname[i]) == 0) {
  439. rep->r1.fcode = fcode[i];
  440. goto done;
  441. }
  442. if((rep->r1.fcode = fopen(fname[nfiles], "w")) == NULL) {
  443. fprintf(stderr, "sed: Cannot open %s\n", fname[nfiles]);
  444. exit(2);
  445. }
  446. fcode[nfiles++] = rep->r1.fcode;
  447. }
  448. break;
  449. case 'w':
  450. rep->r1.command = WCOM;
  451. if(*cp++ != ' ') {
  452. fprintf(stderr, CGMES, linebuf);
  453. exit(2);
  454. }
  455. if(nfiles >= MAXFILES){
  456. fprintf(stderr, "sed: Too many files in w commands 2 \n");
  457. fprintf(stderr, "nfiles = %d; MAXF = %d\n", nfiles, MAXFILES);
  458. exit(2);
  459. }
  460. text((uchar*)fname[nfiles]);
  461. for(i = nfiles - 1; i >= 0; i--)
  462. if(cmp((uchar*)fname[nfiles], (uchar*)fname[i]) == 0) {
  463. rep->r1.fcode = fcode[i];
  464. goto done;
  465. }
  466. if((rep->r1.fcode = fopen(fname[nfiles], "w")) == NULL) {
  467. fprintf(stderr, "sed: Cannot create %s\n", fname[nfiles]);
  468. exit(2);
  469. }
  470. fcode[nfiles++] = rep->r1.fcode;
  471. break;
  472. case 'x':
  473. rep->r1.command = XCOM;
  474. break;
  475. case 'y':
  476. rep->r1.command = YCOM;
  477. seof = *cp++;
  478. rep->r1.re1 = p;
  479. p = ycomp(rep->r1.re1);
  480. if(p == badp) {
  481. fprintf(stderr, CGMES, linebuf);
  482. exit(2);
  483. }
  484. if(p > reend) {
  485. fprintf(stderr, TMMES, linebuf);
  486. exit(2);
  487. }
  488. break;
  489. }
  490. done:
  491. if(++rep >= ptrend) {
  492. fprintf(stderr, "sed: Too many commands, last: %s\n", linebuf);
  493. exit(2);
  494. }
  495. rep->r1.ad1 = p;
  496. if(*cp++ != '\0') {
  497. if(cp[-1] == ';')
  498. goto comploop;
  499. fprintf(stderr, CGMES, linebuf);
  500. exit(2);
  501. }
  502. }
  503. }
  504. uchar *
  505. compsub(uchar *rhsbuf)
  506. {
  507. uchar *p, *q, *r;
  508. p = rhsbuf;
  509. q = cp;
  510. for(;;) {
  511. if((*p = *q++) == '\\') {
  512. *++p = *q++;
  513. if(*p >= '1' && *p <= '9' && *p > numbra + '0')
  514. return(badp);
  515. if(*p == 'n')
  516. *--p = '\n';
  517. } else if(*p == seof) {
  518. *p++ = '\0';
  519. cp = q;
  520. return(p);
  521. }
  522. if(*p++ == '\0') {
  523. return(badp);
  524. }
  525. }
  526. }
  527. uchar *
  528. compile(uchar *expbuf)
  529. {
  530. int c;
  531. uchar *ep, *sp;
  532. uchar neg;
  533. uchar *lastep, *cstart;
  534. int cclcnt;
  535. int closed;
  536. uchar bracket[NBRA], *bracketp;
  537. if(*cp == seof) {
  538. cp++;
  539. return(expbuf);
  540. }
  541. ep = expbuf;
  542. lastep = 0;
  543. bracketp = bracket;
  544. closed = numbra = 0;
  545. sp = cp;
  546. if (*sp == '^') {
  547. *ep++ = 1;
  548. sp++;
  549. } else {
  550. *ep++ = 0;
  551. }
  552. for (;;) {
  553. if (ep >= reend) {
  554. cp = sp;
  555. return(badp);
  556. }
  557. if((c = *sp++) == seof) {
  558. if(bracketp != bracket) {
  559. cp = sp;
  560. return(badp);
  561. }
  562. cp = sp;
  563. *ep++ = CEOF;
  564. return(ep);
  565. }
  566. if(c != '*')
  567. lastep = ep;
  568. switch (c) {
  569. case '\\':
  570. if((c = *sp++) == '(') {
  571. if(numbra >= NBRA) {
  572. cp = sp;
  573. return(badp);
  574. }
  575. *bracketp++ = numbra;
  576. *ep++ = CBRA;
  577. *ep++ = numbra++;
  578. continue;
  579. }
  580. if(c == ')') {
  581. if(bracketp <= bracket) {
  582. cp = sp;
  583. return(badp);
  584. }
  585. *ep++ = CKET;
  586. *ep++ = *--bracketp;
  587. closed++;
  588. continue;
  589. }
  590. if(c >= '1' && c <= '9') {
  591. if((c -= '1') >= closed)
  592. return(badp);
  593. *ep++ = CBACK;
  594. *ep++ = c;
  595. continue;
  596. }
  597. if(c == '\n') {
  598. cp = sp;
  599. return(badp);
  600. }
  601. if(c == 'n') {
  602. c = '\n';
  603. }
  604. goto defchar;
  605. case '\0':
  606. case '\n':
  607. cp = sp;
  608. return(badp);
  609. case '.':
  610. *ep++ = CDOT;
  611. continue;
  612. case '*':
  613. if (lastep == 0)
  614. goto defchar;
  615. if(*lastep == CKET) {
  616. cp = sp;
  617. return(badp);
  618. }
  619. *lastep |= STAR;
  620. continue;
  621. case '$':
  622. if (*sp != seof)
  623. goto defchar;
  624. *ep++ = CDOL;
  625. continue;
  626. case '[':
  627. if(&ep[33] >= reend) {
  628. fprintf(stderr, "sed: RE too long: %s\n", linebuf);
  629. exit(2);
  630. }
  631. *ep++ = CCL;
  632. neg = 0;
  633. if((c = *sp++) == '^') {
  634. neg = 1;
  635. c = *sp++;
  636. }
  637. cstart = sp;
  638. do {
  639. if(c == '\0') {
  640. fprintf(stderr, CGMES, linebuf);
  641. exit(2);
  642. }
  643. if (c=='-' && sp>cstart && *sp!=']') {
  644. for (c = sp[-2]; c<*sp; c++)
  645. ep[c>>3] |= bittab[c&07];
  646. }
  647. if(c == '\\') {
  648. switch(c = *sp++) {
  649. case 'n':
  650. c = '\n';
  651. break;
  652. }
  653. }
  654. ep[c >> 3] |= bittab[c & 07];
  655. } while((c = *sp++) != ']');
  656. if(neg)
  657. for(cclcnt = 0; cclcnt < 32; cclcnt++)
  658. ep[cclcnt] ^= -1;
  659. ep[0] &= 0376;
  660. ep += 32;
  661. continue;
  662. defchar:
  663. default:
  664. *ep++ = CCHR;
  665. *ep++ = c;
  666. }
  667. }
  668. }
  669. int
  670. rline(uchar *lbuf)
  671. {
  672. uchar *p, *q;
  673. int t;
  674. static uchar *saveq;
  675. p = lbuf - 1;
  676. if(eflag) {
  677. if(eflag > 0) {
  678. eflag = -1;
  679. if(eargc-- <= 0)
  680. exit(2);
  681. q = *++eargv;
  682. while(*++p = *q++) {
  683. if(*p == '\\') {
  684. if((*++p = *q++) == '\0') {
  685. saveq = 0;
  686. return(-1);
  687. } else
  688. continue;
  689. }
  690. if(*p == '\n') {
  691. *p = '\0';
  692. saveq = q;
  693. return(1);
  694. }
  695. }
  696. saveq = 0;
  697. return(1);
  698. }
  699. if((q = saveq) == 0) return(-1);
  700. while(*++p = *q++) {
  701. if(*p == '\\') {
  702. if((*++p = *q++) == '0') {
  703. saveq = 0;
  704. return(-1);
  705. } else
  706. continue;
  707. }
  708. if(*p == '\n') {
  709. *p = '\0';
  710. saveq = q;
  711. return(1);
  712. }
  713. }
  714. saveq = 0;
  715. return(1);
  716. }
  717. while((t = getc(fin)) != EOF) {
  718. *++p = t;
  719. if(*p == '\\') {
  720. t = getc(fin);
  721. *++p = t;
  722. }
  723. else if(*p == '\n') {
  724. *p = '\0';
  725. return(1);
  726. }
  727. }
  728. *++p = '\0';
  729. return(-1);
  730. }
  731. uchar *
  732. address(uchar *expbuf)
  733. {
  734. uchar *rcp;
  735. long lno;
  736. if(*cp == '$') {
  737. cp++;
  738. *expbuf++ = CEND;
  739. *expbuf++ = CEOF;
  740. return(expbuf);
  741. }
  742. if(*cp == '/') {
  743. seof = '/';
  744. cp++;
  745. return(compile(expbuf));
  746. }
  747. rcp = cp;
  748. lno = 0;
  749. while(*rcp >= '0' && *rcp <= '9')
  750. lno = lno*10 + *rcp++ - '0';
  751. if(rcp > cp) {
  752. if(!lno){
  753. fprintf(stderr, "sed: line number 0 is illegal\n");
  754. exit(2);
  755. }
  756. *expbuf++ = CLNUM;
  757. *expbuf++ = lno;
  758. *expbuf++ = lno >> 8;
  759. *expbuf++ = lno >> 16;
  760. *expbuf++ = lno >> 24;
  761. *expbuf++ = CEOF;
  762. cp = rcp;
  763. return(expbuf);
  764. }
  765. return(0);
  766. }
  767. int
  768. cmp(uchar *a, uchar *b)
  769. {
  770. uchar *ra, *rb;
  771. ra = a - 1;
  772. rb = b - 1;
  773. while(*++ra == *++rb)
  774. if(*ra == '\0') return(0);
  775. return(1);
  776. }
  777. uchar *
  778. text(uchar *textbuf)
  779. {
  780. uchar *p, *q;
  781. p = textbuf;
  782. q = cp;
  783. while(*q == '\t' || *q == ' ') q++;
  784. for(;;) {
  785. if((*p = *q++) == '\\')
  786. *p = *q++;
  787. if(*p == '\0') {
  788. cp = --q;
  789. return(++p);
  790. }
  791. if(*p == '\n') {
  792. while(*q == '\t' || *q == ' ') q++;
  793. }
  794. p++;
  795. }
  796. }
  797. struct label *
  798. search(struct label *ptr)
  799. {
  800. struct label *rp;
  801. rp = labtab;
  802. while(rp < ptr) {
  803. if(cmp(rp->asc, ptr->asc) == 0)
  804. return(rp);
  805. rp++;
  806. }
  807. return(0);
  808. }
  809. void
  810. dechain(void)
  811. {
  812. struct label *lptr;
  813. union reptr *rptr, *trptr;
  814. for(lptr = labtab; lptr < lab; lptr++) {
  815. if(lptr->address == 0) {
  816. fprintf(stderr, "sed: Undefined label: %s\n", lptr->asc);
  817. exit(2);
  818. }
  819. if(lptr->chain) {
  820. rptr = lptr->chain;
  821. while(trptr = rptr->r2.lb1) {
  822. rptr->r2.lb1 = lptr->address;
  823. rptr = trptr;
  824. }
  825. rptr->r2.lb1 = lptr->address;
  826. }
  827. }
  828. }
  829. uchar *
  830. ycomp(uchar *expbuf)
  831. {
  832. uchar *ep, *tsp;
  833. int c;
  834. uchar *sp;
  835. ep = expbuf;
  836. sp = cp;
  837. for(tsp = cp; *tsp != seof; tsp++) {
  838. if(*tsp == '\\')
  839. tsp++;
  840. if(*tsp == '\n' || *tsp == '\0')
  841. return(badp);
  842. }
  843. tsp++;
  844. while((c = *sp++) != seof) {
  845. if(c == '\\' && *sp == 'n') {
  846. sp++;
  847. c = '\n';
  848. }
  849. if((ep[c] = *tsp++) == '\\' && *tsp == 'n') {
  850. ep[c] = '\n';
  851. tsp++;
  852. }
  853. if(ep[c] == seof || ep[c] == '\0')
  854. return(badp);
  855. }
  856. if(*tsp != seof)
  857. return(badp);
  858. cp = ++tsp;
  859. for(c = 0; c<0400; c++)
  860. if(ep[c] == 0)
  861. ep[c] = c;
  862. return(ep + 0400);
  863. }