home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume13 / perl / part08 < prev    next >
Encoding:
Internet Message Format  |  1988-01-30  |  49.1 KB

  1. Subject:  v13i008:  Perl, a "replacement" for awk and sed, Part08/10
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Larry Wall <lwall@jpl-devvax.jpl.nasa.gov>
  7. Posting-number: Volume 13, Issue 8
  8. Archive-name: perl/part08
  9.  
  10.  
  11.  
  12. #! /bin/sh
  13.  
  14. # Make a new directory for the perl sources, cd to it, and run kits 1
  15. # thru 10 through sh.  When all 10 kits have been run, read README.
  16.  
  17. echo "This is perl 1.0 kit 8 (of 10).  If kit 8 is complete, the line"
  18. echo '"'"End of kit 8 (of 10)"'" will echo at the end.'
  19. echo ""
  20. export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
  21. mkdir x2p 2>/dev/null
  22. echo Extracting x2p/a2p.man
  23. sed >x2p/a2p.man <<'!STUFFY!FUNK!' -e 's/X//'
  24. X.rn '' }`
  25. X''' $Header: a2p.man,v 1.0 87/12/18 17:23:56 root Exp $
  26. X''' 
  27. X''' $Log:    a2p.man,v $
  28. X''' Revision 1.0  87/12/18  17:23:56  root
  29. X''' Initial revision
  30. X''' 
  31. X''' 
  32. X.de Sh
  33. X.br
  34. X.ne 5
  35. X.PP
  36. X\fB\\$1\fR
  37. X.PP
  38. X..
  39. X.de Sp
  40. X.if t .sp .5v
  41. X.if n .sp
  42. X..
  43. X.de Ip
  44. X.br
  45. X.ie \\n.$>=3 .ne \\$3
  46. X.el .ne 3
  47. X.IP "\\$1" \\$2
  48. X..
  49. X'''
  50. X'''     Set up \*(-- to give an unbreakable dash;
  51. X'''     string Tr holds user defined translation string.
  52. X'''     Bell System Logo is used as a dummy character.
  53. X'''
  54. X.tr \(bs-|\(bv\*(Tr
  55. X.ie n \{\
  56. X.ds -- \(bs-
  57. X.if (\n(.H=4u)&(1m=24u) .ds -- \(bs\h'-12u'\(bs\h'-12u'-\" diablo 10 pitch
  58. X.if (\n(.H=4u)&(1m=20u) .ds -- \(bs\h'-12u'\(bs\h'-8u'-\" diablo 12 pitch
  59. X.ds L" ""
  60. X.ds R" ""
  61. X.ds L' '
  62. X.ds R' '
  63. X'br\}
  64. X.el\{\
  65. X.ds -- \(em\|
  66. X.tr \*(Tr
  67. X.ds L" ``
  68. X.ds R" ''
  69. X.ds L' `
  70. X.ds R' '
  71. X'br\}
  72. X.TH A2P 1 LOCAL
  73. X.SH NAME
  74. Xa2p - Awk to Perl translator
  75. X.SH SYNOPSIS
  76. X.B a2p [options] filename
  77. X.SH DESCRIPTION
  78. X.I A2p
  79. Xtakes an awk script specified on the command line (or from standard input)
  80. Xand produces a comparable
  81. X.I perl
  82. Xscript on the standard output.
  83. X.Sh "Options"
  84. XOptions include:
  85. X.TP 5
  86. X.B \-D<number>
  87. Xsets debugging flags.
  88. X.TP 5
  89. X.B \-F<character>
  90. Xtells a2p that this awk script is always invoked with this -F switch.
  91. X.TP 5
  92. X.B \-n<fieldlist>
  93. Xspecifies the names of the input fields if input does not have to be split into
  94. Xan array.
  95. XIf you were translating an awk script that processes the password file, you
  96. Xmight say:
  97. X.sp
  98. X    a2p -7 -nlogin.password.uid.gid.gcos.shell.home
  99. X.sp
  100. XAny delimiter will do to separate the field names.
  101. X.TP 5
  102. X.B \-<number>
  103. Xcauses a2p to assume that input will always have that many fields.
  104. X.Sh "Considerations"
  105. XA2p cannot do as good a job translating as a human would, but it usually
  106. Xdoes pretty well.
  107. XThere are some areas where you may want to examine the perl script produced
  108. Xand tweak it some.
  109. XHere are some of them, in no particular order.
  110. X.PP
  111. XThe split operator in perl always strips off all null fields from the end.
  112. XAwk does NOT do this, if you've set FS.
  113. XIf the perl script splits to an array, the field count may not reflect
  114. Xwhat you expect.
  115. XOrdinarily this isn't a problem, since nonexistent array elements have a null
  116. Xvalue, but if you rely on NF in awk, you could be in for trouble.
  117. XEither force the number of fields with \-<number>, or count the number of
  118. Xdelimiters another way, e.g. with y/:/:/.
  119. XOr add something non-null to the end before you split, and then pop it off
  120. Xthe resulting array.
  121. X.PP
  122. XThere is an awk idiom of putting int() around a string expression to force
  123. Xnumeric interpretation, even though the argument is always integer anyway.
  124. XThis is generally unneeded in perl, but a2p can't tell if the argument
  125. Xis always going to be integer, so it leaves it in.
  126. XYou may wish to remove it.
  127. X.PP
  128. XPerl differentiates numeric comparison from string comparison.
  129. XAwk has one operator for both that decides at run time which comparison
  130. Xto do.
  131. XA2p does not try to do a complete job of awk emulation at this point.
  132. XInstead it guesses which one you want.
  133. XIt's almost always right, but it can be spoofed.
  134. XAll such guesses are marked with the comment \*(L"#???\*(R".
  135. XYou should go through and check them.
  136. X.PP
  137. XPerl does not attempt to emulate the behavior of awk in which nonexistent
  138. Xarray elements spring into existence simply by being referenced.
  139. XIf somehow you are relying on this mechanism to create null entries for
  140. Xa subsequent for...in, they won't be there in perl.
  141. X.PP
  142. XIf a2p makes a split line that assigns to a list of variables that looks
  143. Xlike (Fld1, Fld2, Fld3...) you may want
  144. Xto rerun a2p using the \-n option mentioned above.
  145. XThis will let you name the fields throughout the script.
  146. XIf it splits to an array instead, the script is probably referring to the number
  147. Xof fields somewhere.
  148. X.PP
  149. XThe exit statement in awk doesn't necessarily exit; it goes to the END
  150. Xblock if there is one.
  151. XAwk scripts that do contortions within the END block to bypass the block under
  152. Xsuch circumstances can be simplified by removing the conditional
  153. Xin the END block and just exiting directly from the perl script.
  154. X.PP
  155. XPerl has two kinds of array, numerically-indexed and associative.
  156. XAwk arrays are usually translated to associative arrays, but if you happen
  157. Xto know that the index is always going to be numeric you could change
  158. Xthe {...} to [...].
  159. XIteration over an associative array is done with each(), but
  160. Xiteration over a numeric array is NOT.
  161. XYou need a for loop, or while loop with a pop() or shift(), so you might
  162. Xneed to modify any loop that is iterating over the array in question.
  163. X.PP
  164. XArrays which have been split into are assumed to be numerically indexed.
  165. XThe usual perl idiom for iterating over such arrays is to use pop() or shift()
  166. Xand assign the resulting value to a variable inside the conditional of the
  167. Xwhile loop.
  168. XThis is destructive to the array, however, so a2p can't assume this is
  169. Xreasonable.
  170. XA2p will write a standard for loop with a scratch variable.
  171. XYou may wish to change it to a pop() loop for more efficiency, presuming
  172. Xyou don't want to keep the array around.
  173. X.PP
  174. XAwk starts by assuming OFMT has the value %.6g.
  175. XPerl starts by assuming its equivalent, $#, to have the value %.20g.
  176. XYou'll want to set $# explicitly if you use the default value of OFMT.
  177. X.PP
  178. XNear the top of the line loop will be the split operation that is implicit in
  179. Xthe awk script.
  180. XThere are times when you can move this down past some conditionals that
  181. Xtest the entire record so that the split is not done as often.
  182. X.PP
  183. XThere may occasionally be extra parentheses that you can remove.
  184. X.PP
  185. XFor aesthetic reasons you may wish to change the array base $[ from 1 back
  186. Xto the default of 0, but remember to change all array subscripts AND
  187. Xall substr() and index() operations to match.
  188. X.PP
  189. XCute comments that say "# Here is a workaround because awk is dumb" are not
  190. Xtranslated.
  191. X.PP
  192. XAwk scripts are often embedded in a shell script that pipes stuff into and
  193. Xout of awk.
  194. XOften the shell script wrapper can be incorporated into the perl script, since
  195. Xperl can start up pipes into and out of itself, and can do other things that
  196. Xawk can't do by itself.
  197. X.SH ENVIRONMENT
  198. XA2p uses no environment variables.
  199. X.SH AUTHOR
  200. XLarry Wall <lwall@devvax.Jpl.Nasa.Gov>
  201. X.SH FILES
  202. X.SH SEE ALSO
  203. Xperl    The perl compiler/interpreter
  204. X.br
  205. Xs2p    sed to perl translator
  206. X.SH DIAGNOSTICS
  207. X.SH BUGS
  208. XIt would be possible to emulate awk's behavior in selecting string versus
  209. Xnumeric operations at run time by inspection of the operands, but it would
  210. Xbe gross and inefficient.
  211. XBesides, a2p almost always guesses right.
  212. X.PP
  213. XStorage for the awk syntax tree is currently static, and can run out.
  214. X.rn }` ''
  215. !STUFFY!FUNK!
  216. echo Extracting x2p/a2p.y
  217. sed >x2p/a2p.y <<'!STUFFY!FUNK!' -e 's/X//'
  218. X%{
  219. X/* $Header: a2p.y,v 1.0 87/12/18 13:07:05 root Exp $
  220. X *
  221. X * $Log:    a2p.y,v $
  222. X * Revision 1.0  87/12/18  13:07:05  root
  223. X * Initial revision
  224. X * 
  225. X */
  226. X
  227. X#include "INTERN.h"
  228. X#include "a2p.h"
  229. X
  230. Xint root;
  231. X
  232. X%}
  233. X%token BEGIN END
  234. X%token REGEX
  235. X%token SEMINEW NEWLINE COMMENT
  236. X%token FUN1 GRGR
  237. X%token PRINT PRINTF SPRINTF SPLIT
  238. X%token IF ELSE WHILE FOR IN
  239. X%token EXIT NEXT BREAK CONTINUE
  240. X
  241. X%right ASGNOP
  242. X%left OROR
  243. X%left ANDAND
  244. X%left NOT
  245. X%left NUMBER VAR SUBSTR INDEX
  246. X%left GETLINE
  247. X%nonassoc RELOP MATCHOP
  248. X%left OR
  249. X%left STRING
  250. X%left '+' '-'
  251. X%left '*' '/' '%'
  252. X%right UMINUS
  253. X%left INCR DECR
  254. X%left FIELD VFIELD
  255. X
  256. X%%
  257. X
  258. Xprogram    : junk begin hunks end
  259. X        { root = oper4(OPROG,$1,$2,$3,$4); }
  260. X    ;
  261. X
  262. Xbegin    : BEGIN '{' states '}' junk
  263. X        { $$ = oper2(OJUNK,$3,$5); in_begin = FALSE; }
  264. X    | /* NULL */
  265. X        { $$ = Nullop; }
  266. X    ;
  267. X
  268. Xend    : END '{' states '}'
  269. X        { $$ = $3; }
  270. X    | end NEWLINE
  271. X        { $$ = $1; }
  272. X    | /* NULL */
  273. X        { $$ = Nullop; }
  274. X    ;
  275. X
  276. Xhunks    : hunks hunk junk
  277. X        { $$ = oper3(OHUNKS,$1,$2,$3); }
  278. X    | /* NULL */
  279. X        { $$ = Nullop; }
  280. X    ;
  281. X
  282. Xhunk    : patpat
  283. X        { $$ = oper1(OHUNK,$1); need_entire = TRUE; }
  284. X    | patpat '{' states '}'
  285. X        { $$ = oper2(OHUNK,$1,$3); }
  286. X    | '{' states '}'
  287. X        { $$ = oper2(OHUNK,Nullop,$2); }
  288. X    ;
  289. X
  290. Xpatpat    : pat
  291. X        { $$ = oper1(OPAT,$1); }
  292. X    | pat ',' pat
  293. X        { $$ = oper2(ORANGE,$1,$3); }
  294. X    ;
  295. X
  296. Xpat    : REGEX
  297. X        { $$ = oper1(OREGEX,$1); }
  298. X    | match
  299. X    | rel
  300. X    | compound_pat
  301. X    ;
  302. X
  303. Xcompound_pat
  304. X    : '(' compound_pat ')'
  305. X        { $$ = oper1(OPPAREN,$2); }
  306. X    | pat ANDAND pat
  307. X        { $$ = oper2(OPANDAND,$1,$3); }
  308. X    | pat OROR pat
  309. X        { $$ = oper2(OPOROR,$1,$3); }
  310. X    | NOT pat
  311. X        { $$ = oper1(OPNOT,$2); }
  312. X    ;
  313. X
  314. Xcond    : expr
  315. X    | match
  316. X    | rel
  317. X    | compound_cond
  318. X    ;
  319. X
  320. Xcompound_cond
  321. X    : '(' compound_cond ')'
  322. X        { $$ = oper1(OCPAREN,$2); }
  323. X    | cond ANDAND cond
  324. X        { $$ = oper2(OCANDAND,$1,$3); }
  325. X    | cond OROR cond
  326. X        { $$ = oper2(OCOROR,$1,$3); }
  327. X    | NOT cond
  328. X        { $$ = oper1(OCNOT,$2); }
  329. X    ;
  330. X
  331. Xrel    : expr RELOP expr
  332. X        { $$ = oper3(ORELOP,$2,$1,$3); }
  333. X    | '(' rel ')'
  334. X        { $$ = oper1(ORPAREN,$2); }
  335. X    ;
  336. X
  337. Xmatch    : expr MATCHOP REGEX
  338. X        { $$ = oper3(OMATCHOP,$2,$1,$3); }
  339. X    | '(' match ')'
  340. X        { $$ = oper1(OMPAREN,$2); }
  341. X    ;
  342. X
  343. Xexpr    : term
  344. X        { $$ = $1; }
  345. X    | expr term
  346. X        { $$ = oper2(OCONCAT,$1,$2); }
  347. X    | variable ASGNOP expr
  348. X        { $$ = oper3(OASSIGN,$2,$1,$3);
  349. X            if ((ops[$1].ival & 255) == OFLD)
  350. X                lval_field = TRUE;
  351. X            if ((ops[$1].ival & 255) == OVFLD)
  352. X                lval_field = TRUE;
  353. X        }
  354. X    ;
  355. X
  356. Xterm    : variable
  357. X        { $$ = $1; }
  358. X    | term '+' term
  359. X        { $$ = oper2(OADD,$1,$3); }
  360. X    | term '-' term
  361. X        { $$ = oper2(OSUB,$1,$3); }
  362. X    | term '*' term
  363. X        { $$ = oper2(OMULT,$1,$3); }
  364. X    | term '/' term
  365. X        { $$ = oper2(ODIV,$1,$3); }
  366. X    | term '%' term
  367. X        { $$ = oper2(OMOD,$1,$3); }
  368. X    | variable INCR
  369. X        { $$ = oper1(OPOSTINCR,$1); }
  370. X    | variable DECR
  371. X        { $$ = oper1(OPOSTDECR,$1); }
  372. X    | INCR variable
  373. X        { $$ = oper1(OPREINCR,$2); }
  374. X    | DECR variable
  375. X        { $$ = oper1(OPREDECR,$2); }
  376. X    | '-' term %prec UMINUS
  377. X        { $$ = oper1(OUMINUS,$2); }
  378. X    | '+' term %prec UMINUS
  379. X        { $$ = oper1(OUPLUS,$2); }
  380. X    | '(' expr ')'
  381. X        { $$ = oper1(OPAREN,$2); }
  382. X    | GETLINE
  383. X        { $$ = oper0(OGETLINE); }
  384. X    | FUN1
  385. X        { $$ = oper0($1); need_entire = do_chop = TRUE; }
  386. X    | FUN1 '(' ')'
  387. X        { $$ = oper1($1,Nullop); need_entire = do_chop = TRUE; }
  388. X    | FUN1 '(' expr ')'
  389. X        { $$ = oper1($1,$3); }
  390. X    | SPRINTF print_list
  391. X        { $$ = oper1(OSPRINTF,$2); }
  392. X    | SUBSTR '(' expr ',' expr ',' expr ')'
  393. X        { $$ = oper3(OSUBSTR,$3,$5,$7); }
  394. X    | SUBSTR '(' expr ',' expr ')'
  395. X        { $$ = oper2(OSUBSTR,$3,$5); }
  396. X    | SPLIT '(' expr ',' VAR ',' expr ')'
  397. X        { $$ = oper3(OSPLIT,$3,numary($5),$7); }
  398. X    | SPLIT '(' expr ',' VAR ')'
  399. X        { $$ = oper2(OSPLIT,$3,numary($5)); }
  400. X    | INDEX '(' expr ',' expr ')'
  401. X        { $$ = oper2(OINDEX,$3,$5); }
  402. X    ;
  403. X
  404. Xvariable: NUMBER
  405. X        { $$ = oper1(ONUM,$1); }
  406. X    | STRING
  407. X        { $$ = oper1(OSTR,$1); }
  408. X    | VAR
  409. X        { $$ = oper1(OVAR,$1); }
  410. X    | VAR '[' expr ']'
  411. X        { $$ = oper2(OVAR,$1,$3); }
  412. X    | FIELD
  413. X        { $$ = oper1(OFLD,$1); }
  414. X    | VFIELD term
  415. X        { $$ = oper1(OVFLD,$2); }
  416. X    ;
  417. X
  418. Xmaybe    : NEWLINE
  419. X        { $$ = oper0(ONEWLINE); }
  420. X    | /* NULL */
  421. X        { $$ = Nullop; }
  422. X    | COMMENT
  423. X        { $$ = oper1(OCOMMENT,$1); }
  424. X    ;
  425. X
  426. Xprint_list
  427. X    : expr
  428. X    | clist
  429. X    | /* NULL */
  430. X        { $$ = Nullop; }
  431. X    ;
  432. X
  433. Xclist    : expr ',' expr
  434. X        { $$ = oper2(OCOMMA,$1,$3); }
  435. X    | clist ',' expr
  436. X        { $$ = oper2(OCOMMA,$1,$3); }
  437. X    | '(' clist ')'        /* these parens are invisible */
  438. X        { $$ = $2; }
  439. X    ;
  440. X
  441. Xjunk    : junk hunksep
  442. X        { $$ = oper2(OJUNK,$1,$2); }
  443. X    | /* NULL */
  444. X        { $$ = Nullop; }
  445. X    ;
  446. X
  447. Xhunksep : ';'
  448. X        { $$ = oper0(OSEMICOLON); }
  449. X    | SEMINEW
  450. X        { $$ = oper0(OSEMICOLON); }
  451. X    | NEWLINE
  452. X        { $$ = oper0(ONEWLINE); }
  453. X    | COMMENT
  454. X        { $$ = oper1(OCOMMENT,$1); }
  455. X    ;
  456. X
  457. Xseparator
  458. X    : ';'
  459. X        { $$ = oper0(OSEMICOLON); }
  460. X    | SEMINEW
  461. X        { $$ = oper0(OSNEWLINE); }
  462. X    | NEWLINE
  463. X        { $$ = oper0(OSNEWLINE); }
  464. X    | COMMENT
  465. X        { $$ = oper1(OSCOMMENT,$1); }
  466. X    ;
  467. X
  468. Xstates    : states statement
  469. X        { $$ = oper2(OSTATES,$1,$2); }
  470. X    | /* NULL */
  471. X        { $$ = Nullop; }
  472. X    ;
  473. X
  474. Xstatement
  475. X    : simple separator
  476. X        { $$ = oper2(OSTATE,$1,$2); }
  477. X    | compound
  478. X    ;
  479. X
  480. Xsimple
  481. X    : expr
  482. X    | PRINT print_list redir expr
  483. X        { $$ = oper3(OPRINT,$2,$3,$4);
  484. X            do_opens = TRUE;
  485. X            saw_ORS = saw_OFS = TRUE;
  486. X            if (!$2) need_entire = TRUE;
  487. X            if (ops[$4].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
  488. X    | PRINT print_list
  489. X        { $$ = oper1(OPRINT,$2);
  490. X            if (!$2) need_entire = TRUE;
  491. X            saw_ORS = saw_OFS = TRUE;
  492. X        }
  493. X    | PRINTF print_list redir expr
  494. X        { $$ = oper3(OPRINTF,$2,$3,$4);
  495. X            do_opens = TRUE;
  496. X            if (!$2) need_entire = TRUE;
  497. X            if (ops[$4].ival != OSTR + (1<<8)) do_fancy_opens = TRUE; }
  498. X    | PRINTF print_list
  499. X        { $$ = oper1(OPRINTF,$2);
  500. X            if (!$2) need_entire = TRUE;
  501. X        }
  502. X    | BREAK
  503. X        { $$ = oper0(OBREAK); }
  504. X    | NEXT
  505. X        { $$ = oper0(ONEXT); }
  506. X    | EXIT
  507. X        { $$ = oper0(OEXIT); }
  508. X    | EXIT expr
  509. X        { $$ = oper1(OEXIT,$2); }
  510. X    | CONTINUE
  511. X        { $$ = oper0(OCONTINUE); }
  512. X    | /* NULL */
  513. X        { $$ = Nullop; }
  514. X    ;
  515. X
  516. Xredir    : RELOP
  517. X        { $$ = oper1(OREDIR,string(">",1)); }
  518. X    | GRGR
  519. X        { $$ = oper1(OREDIR,string(">>",2)); }
  520. X    | '|'
  521. X        { $$ = oper1(OREDIR,string("|",1)); }
  522. X    ;
  523. X
  524. Xcompound
  525. X    : IF '(' cond ')' maybe statement
  526. X        { $$ = oper2(OIF,$3,bl($6,$5)); }
  527. X    | IF '(' cond ')' maybe statement ELSE maybe statement
  528. X        { $$ = oper3(OIF,$3,bl($6,$5),bl($9,$8)); }
  529. X    | WHILE '(' cond ')' maybe statement
  530. X        { $$ = oper2(OWHILE,$3,bl($6,$5)); }
  531. X    | FOR '(' simple ';' cond ';' simple ')' maybe statement
  532. X        { $$ = oper4(OFOR,$3,$5,$7,bl($10,$9)); }
  533. X    | FOR '(' simple ';'  ';' simple ')' maybe statement
  534. X        { $$ = oper4(OFOR,$3,string("",0),$6,bl($9,$8)); }
  535. X    | FOR '(' VAR IN VAR ')' maybe statement
  536. X        { $$ = oper3(OFORIN,$3,$5,bl($8,$7)); }
  537. X    | '{' states '}'
  538. X        { $$ = oper1(OBLOCK,$2); }
  539. X    ;
  540. X
  541. X%%
  542. X#include "a2py.c"
  543. !STUFFY!FUNK!
  544. echo Extracting stab.c
  545. sed >stab.c <<'!STUFFY!FUNK!' -e 's/X//'
  546. X/* $Header: stab.c,v 1.0 87/12/18 13:06:14 root Exp $
  547. X *
  548. X * $Log:    stab.c,v $
  549. X * Revision 1.0  87/12/18  13:06:14  root
  550. X * Initial revision
  551. X * 
  552. X */
  553. X
  554. X#include <signal.h>
  555. X#include "handy.h"
  556. X#include "EXTERN.h"
  557. X#include "search.h"
  558. X#include "util.h"
  559. X#include "perl.h"
  560. X
  561. Xstatic char *sig_name[] = {
  562. X    "",
  563. X    "HUP",
  564. X    "INT",
  565. X    "QUIT",
  566. X    "ILL",
  567. X    "TRAP",
  568. X    "IOT",
  569. X    "EMT",
  570. X    "FPE",
  571. X    "KILL",
  572. X    "BUS",
  573. X    "SEGV",
  574. X    "SYS",
  575. X    "PIPE",
  576. X    "ALRM",
  577. X    "TERM",
  578. X    "???"
  579. X#ifdef SIGTSTP
  580. X    ,"STOP",
  581. X    "TSTP",
  582. X    "CONT",
  583. X    "CHLD",
  584. X    "TTIN",
  585. X    "TTOU",
  586. X    "TINT",
  587. X    "XCPU",
  588. X    "XFSZ"
  589. X#ifdef SIGPROF
  590. X    ,"VTALARM",
  591. X    "PROF"
  592. X#ifdef SIGWINCH
  593. X    ,"WINCH"
  594. X#ifdef SIGLOST
  595. X    ,"LOST"
  596. X#ifdef SIGUSR1
  597. X    ,"USR1"
  598. X#endif
  599. X#ifdef SIGUSR2
  600. X    ,"USR2"
  601. X#endif /* SIGUSR2 */
  602. X#endif /* SIGLOST */
  603. X#endif /* SIGWINCH */
  604. X#endif /* SIGPROF */
  605. X#endif /* SIGTSTP */
  606. X    ,0
  607. X    };
  608. X
  609. XSTR *
  610. Xstab_str(stab)
  611. XSTAB *stab;
  612. X{
  613. X    register int paren;
  614. X    register char *s;
  615. X    extern int errno;
  616. X
  617. X    switch (*stab->stab_name) {
  618. X    case '0': case '1': case '2': case '3': case '4':
  619. X    case '5': case '6': case '7': case '8': case '9': case '&':
  620. X    if (curspat) {
  621. X        paren = atoi(stab->stab_name);
  622. X        if (curspat->spat_compex.subend[paren] &&
  623. X          (s = getparen(&curspat->spat_compex,paren))) {
  624. X        curspat->spat_compex.subend[paren] = Nullch;
  625. X        str_set(stab->stab_val,s);
  626. X        }
  627. X    }
  628. X    break;
  629. X    case '+':
  630. X    if (curspat) {
  631. X        paren = curspat->spat_compex.lastparen;
  632. X        if (curspat->spat_compex.subend[paren] &&
  633. X          (s = getparen(&curspat->spat_compex,paren))) {
  634. X        curspat->spat_compex.subend[paren] = Nullch;
  635. X        str_set(stab->stab_val,s);
  636. X        }
  637. X    }
  638. X    break;
  639. X    case '.':
  640. X    if (last_in_stab) {
  641. X        str_numset(stab->stab_val,(double)last_in_stab->stab_io->lines);
  642. X    }
  643. X    break;
  644. X    case '?':
  645. X    str_numset(stab->stab_val,(double)statusvalue);
  646. X    break;
  647. X    case '^':
  648. X    s = curoutstab->stab_io->top_name;
  649. X    str_set(stab->stab_val,s);
  650. X    break;
  651. X    case '~':
  652. X    s = curoutstab->stab_io->fmt_name;
  653. X    str_set(stab->stab_val,s);
  654. X    break;
  655. X    case '=':
  656. X    str_numset(stab->stab_val,(double)curoutstab->stab_io->lines);
  657. X    break;
  658. X    case '-':
  659. X    str_numset(stab->stab_val,(double)curoutstab->stab_io->lines_left);
  660. X    break;
  661. X    case '%':
  662. X    str_numset(stab->stab_val,(double)curoutstab->stab_io->page);
  663. X    break;
  664. X    case '(':
  665. X    if (curspat) {
  666. X        str_numset(stab->stab_val,(double)(curspat->spat_compex.subbeg[0] -
  667. X        curspat->spat_compex.subbase));
  668. X    }
  669. X    break;
  670. X    case ')':
  671. X    if (curspat) {
  672. X        str_numset(stab->stab_val,(double)(curspat->spat_compex.subend[0] -
  673. X        curspat->spat_compex.subbeg[0]));
  674. X    }
  675. X    break;
  676. X    case '/':
  677. X    *tokenbuf = record_separator;
  678. X    tokenbuf[1] = '\0';
  679. X    str_set(stab->stab_val,tokenbuf);
  680. X    break;
  681. X    case '[':
  682. X    str_numset(stab->stab_val,(double)arybase);
  683. X    break;
  684. X    case '|':
  685. X    str_numset(stab->stab_val,
  686. X       (double)((curoutstab->stab_io->flags & IOF_FLUSH) != 0) );
  687. X    break;
  688. X    case ',':
  689. X    str_set(stab->stab_val,ofs);
  690. X    break;
  691. X    case '\\':
  692. X    str_set(stab->stab_val,ors);
  693. X    break;
  694. X    case '#':
  695. X    str_set(stab->stab_val,ofmt);
  696. X    break;
  697. X    case '!':
  698. X    str_numset(stab->stab_val,(double)errno);
  699. X    break;
  700. X    }
  701. X    return stab->stab_val;
  702. X}
  703. X
  704. Xstabset(stab,str)
  705. Xregister STAB *stab;
  706. XSTR *str;
  707. X{
  708. X    char *s;
  709. X    int i;
  710. X    int sighandler();
  711. X
  712. X    if (stab->stab_flags & SF_VMAGIC) {
  713. X    switch (stab->stab_name[0]) {
  714. X    case '^':
  715. X        safefree(curoutstab->stab_io->top_name);
  716. X        curoutstab->stab_io->top_name = str_get(str);
  717. X        curoutstab->stab_io->top_stab = stabent(str_get(str),FALSE);
  718. X        break;
  719. X    case '~':
  720. X        safefree(curoutstab->stab_io->fmt_name);
  721. X        curoutstab->stab_io->fmt_name = str_get(str);
  722. X        curoutstab->stab_io->fmt_stab = stabent(str_get(str),FALSE);
  723. X        break;
  724. X    case '=':
  725. X        curoutstab->stab_io->page_len = (long)str_gnum(str);
  726. X        break;
  727. X    case '-':
  728. X        curoutstab->stab_io->lines_left = (long)str_gnum(str);
  729. X        break;
  730. X    case '%':
  731. X        curoutstab->stab_io->page = (long)str_gnum(str);
  732. X        break;
  733. X    case '|':
  734. X        curoutstab->stab_io->flags &= ~IOF_FLUSH;
  735. X        if (str_gnum(str) != 0.0) {
  736. X        curoutstab->stab_io->flags |= IOF_FLUSH;
  737. X        }
  738. X        break;
  739. X    case '*':
  740. X        multiline = (int)str_gnum(str) != 0;
  741. X        break;
  742. X    case '/':
  743. X        record_separator = *str_get(str);
  744. X        break;
  745. X    case '\\':
  746. X        if (ors)
  747. X        safefree(ors);
  748. X        ors = savestr(str_get(str));
  749. X        break;
  750. X    case ',':
  751. X        if (ofs)
  752. X        safefree(ofs);
  753. X        ofs = savestr(str_get(str));
  754. X        break;
  755. X    case '#':
  756. X        if (ofmt)
  757. X        safefree(ofmt);
  758. X        ofmt = savestr(str_get(str));
  759. X        break;
  760. X    case '[':
  761. X        arybase = (int)str_gnum(str);
  762. X        break;
  763. X    case '!':
  764. X        errno = (int)str_gnum(str);        /* will anyone ever use this? */
  765. X        break;
  766. X    case '.':
  767. X    case '+':
  768. X    case '&':
  769. X    case '0':
  770. X    case '1':
  771. X    case '2':
  772. X    case '3':
  773. X    case '4':
  774. X    case '5':
  775. X    case '6':
  776. X    case '7':
  777. X    case '8':
  778. X    case '9':
  779. X    case '(':
  780. X    case ')':
  781. X        break;        /* "read-only" registers */
  782. X    }
  783. X    }
  784. X    else if (stab == envstab && envname) {
  785. X    setenv(envname,str_get(str));
  786. X                /* And you'll never guess what the dog had */
  787. X    safefree(envname);    /*   in its mouth... */
  788. X    envname = Nullch;
  789. X    }
  790. X    else if (stab == sigstab && signame) {
  791. X    s = str_get(str);
  792. X    i = whichsig(signame);    /* ...no, a brick */
  793. X    if (strEQ(s,"IGNORE"))
  794. X        signal(i,SIG_IGN);
  795. X    else if (strEQ(s,"DEFAULT") || !*s)
  796. X        signal(i,SIG_DFL);
  797. X    else
  798. X        signal(i,sighandler);
  799. X    safefree(signame);
  800. X    signame = Nullch;
  801. X    }
  802. X}
  803. X
  804. Xwhichsig(signame)
  805. Xchar *signame;
  806. X{
  807. X    register char **sigv;
  808. X
  809. X    for (sigv = sig_name+1; *sigv; sigv++)
  810. X    if (strEQ(signame,*sigv))
  811. X        return sigv - sig_name;
  812. X    return 0;
  813. X}
  814. X
  815. Xsighandler(sig)
  816. Xint sig;
  817. X{
  818. X    STAB *stab;
  819. X    ARRAY *savearray;
  820. X    STR *str;
  821. X
  822. X    stab = stabent(str_get(hfetch(sigstab->stab_hash,sig_name[sig])),FALSE);
  823. X    savearray = defstab->stab_array;
  824. X    defstab->stab_array = anew();
  825. X    str = str_new(0);
  826. X    str_set(str,sig_name[sig]);
  827. X    apush(defstab->stab_array,str);
  828. X    str = cmd_exec(stab->stab_sub);
  829. X    afree(defstab->stab_array);  /* put back old $_[] */
  830. X    defstab->stab_array = savearray;
  831. X}
  832. X
  833. Xchar *
  834. Xreg_get(name)
  835. Xchar *name;
  836. X{
  837. X    return STAB_GET(stabent(name,TRUE));
  838. X}
  839. X
  840. X#ifdef NOTUSED
  841. Xreg_set(name,value)
  842. Xchar *name;
  843. Xchar *value;
  844. X{
  845. X    str_set(STAB_STR(stabent(name,TRUE)),value);
  846. X}
  847. X#endif
  848. X
  849. XSTAB *
  850. Xaadd(stab)
  851. Xregister STAB *stab;
  852. X{
  853. X    if (!stab->stab_array)
  854. X    stab->stab_array = anew();
  855. X    return stab;
  856. X}
  857. X
  858. XSTAB *
  859. Xhadd(stab)
  860. Xregister STAB *stab;
  861. X{
  862. X    if (!stab->stab_hash)
  863. X    stab->stab_hash = hnew();
  864. X    return stab;
  865. X}
  866. !STUFFY!FUNK!
  867. echo Extracting MANIFEST
  868. sed >MANIFEST <<'!STUFFY!FUNK!' -e 's/X//'
  869. XAfter all the perl kits are run you should have the following files:
  870. X
  871. XFilename        Kit Description
  872. X--------        --- -----------
  873. XConfigure                6  Run this first
  874. XEXTERN.h                10  Included before foreign .h files
  875. XINTERN.h                10  Included before domestic .h files
  876. XMANIFEST                 8  This list of files
  877. XMakefile.SH              4  Precursor to Makefile
  878. XREADME                   1  The Instructions
  879. XWishlist                10  Some things that may or may not happen
  880. Xarg.c                    3  Expression evaluation
  881. Xarg.h                    8  Public declarations for the above
  882. Xarray.c                  6  Numerically subscripted arrays
  883. Xarray.h                 10  Public declarations for the above
  884. Xcmd.c                    7  Command interpreter
  885. Xcmd.h                    9  Public declarations for the above
  886. Xconfig.H                 9  Sample config.h
  887. Xconfig.h.SH              9  Produces config.h.
  888. Xdump.c                   8  Debugging output
  889. Xform.c                   8  Format processing
  890. Xform.h                  10  Public declarations for the above
  891. Xhandy.h                 10  Handy definitions
  892. Xhash.c                   9  Associative arrays
  893. Xhash.h                  10  Public declarations for the above
  894. Xmakedepend.SH            9  Precursor to makedepend
  895. Xmakedir.SH              10  Precursor to makedir
  896. Xmalloc.c                 7  A version of malloc you might not want
  897. Xpatchlevel.h             1  The current patch level of perl
  898. Xperl.h                   9  Global declarations
  899. Xperl.man.1               5  The manual page(s), first half
  900. Xperl.man.2               4  The manual page(s), second half
  901. Xperl.y                   5  Yacc grammar for perl
  902. Xperly.c                  2  The perl compiler
  903. Xsearch.c                 6  String matching
  904. Xsearch.h                10  Public declarations for the above
  905. Xspat.h                  10  Search pattern declarations
  906. Xstab.c                   8  Symbol table stuff
  907. Xstab.h                  10  Public declarations for the above
  908. Xstr.c                    4  String handling package
  909. Xstr.h                   10  Public declarations for the above
  910. Xt/README                10  Instructions for regression tests
  911. Xt/TEST                  10  The regression tester
  912. Xt/base.cond             10  See if conditionals work
  913. Xt/base.if               10  See if if works
  914. Xt/base.lex              10  See if lexical items work
  915. Xt/base.pat              10  See if pattern matching works
  916. Xt/base.term             10  See if various terms work
  917. Xt/cmd.elsif             10  See if else-if works
  918. Xt/cmd.for               10  See if for loops work
  919. Xt/cmd.mod               10  See if statement modifiers work
  920. Xt/cmd.subval            10  See if subroutine values work
  921. Xt/cmd.while              7  See if while loops work
  922. Xt/comp.cmdopt            9  See if command optimization works
  923. Xt/comp.cpp              10  See if C preprocessor works
  924. Xt/comp.decl             10  See if declarations work
  925. Xt/comp.multiline        10  See if multiline strings work
  926. Xt/comp.script           10  See if script invokation works
  927. Xt/comp.term             10  See if more terms work
  928. Xt/io.argv               10  See if ARGV stuff works
  929. Xt/io.fs                  5  See if directory manipulations work
  930. Xt/io.inplace            10  See if inplace editing works
  931. Xt/io.print              10  See if print commands work
  932. Xt/io.tell               10  See if file seeking works
  933. Xt/op.append             10  See if . works
  934. Xt/op.auto                9  See if autoincrement et all work
  935. Xt/op.chop               10  See if chop works
  936. Xt/op.cond               10  See if conditional expressions work
  937. Xt/op.crypt              10  See if crypt works
  938. Xt/op.do                 10  See if subroutines work
  939. Xt/op.each               10  See if associative iterators work
  940. Xt/op.exec               10  See if exec and system work
  941. Xt/op.exp                10  See if math functions work
  942. Xt/op.flip               10  See if range operator works
  943. Xt/op.fork               10  See if fork works
  944. Xt/op.goto               10  See if goto works
  945. Xt/op.int                10  See if int works
  946. Xt/op.join               10  See if join works
  947. Xt/op.list               10  See if array lists work
  948. Xt/op.magic              10  See if magic variables work
  949. Xt/op.oct                10  See if oct and hex work
  950. Xt/op.ord                10  See if ord works
  951. Xt/op.pat                 9  See if esoteric patterns work
  952. Xt/op.push                7  See if push and pop work
  953. Xt/op.repeat             10  See if x operator works
  954. Xt/op.sleep               6  See if sleep works
  955. Xt/op.split              10  See if split works
  956. Xt/op.sprintf            10  See if sprintf work
  957. Xt/op.stat               10  See if stat work
  958. Xt/op.subst              10  See if substitutions work
  959. Xt/op.time               10  See if time functions work
  960. Xt/op.unshift            10  See if unshift works
  961. Xutil.c                   9  Utility routines
  962. Xutil.h                  10  Public declarations for the above
  963. Xversion.c               10  Prints version of perl
  964. Xx2p/EXTERN.h            10  Same as above
  965. Xx2p/INTERN.h            10  Same as above
  966. Xx2p/Makefile.SH          9  Precursor to Makefile
  967. Xx2p/a2p.h                8  Global declarations
  968. Xx2p/a2p.man              8  Manual page for awk to perl translator
  969. Xx2p/a2p.y                8  A yacc grammer for awk
  970. Xx2p/a2py.c               7  Awk compiler, sort of
  971. Xx2p/handy.h             10  Handy definitions
  972. Xx2p/hash.c               9  Associative arrays again
  973. Xx2p/hash.h              10  Public declarations for the above
  974. Xx2p/s2p                  1  Sed to perl translator
  975. Xx2p/s2p.man             10  Manual page for sed to perl translator
  976. Xx2p/str.c                7  String handling package
  977. Xx2p/str.h               10  Public declarations for the above
  978. Xx2p/util.c               9  Utility routines
  979. Xx2p/util.h              10  Public declarations for the above
  980. Xx2p/walk.c               1  Parse tree walker
  981. !STUFFY!FUNK!
  982. echo Extracting form.c
  983. sed >form.c <<'!STUFFY!FUNK!' -e 's/X//'
  984. X/* $Header: form.c,v 1.0 87/12/18 13:05:07 root Exp $
  985. X *
  986. X * $Log:    form.c,v $
  987. X * Revision 1.0  87/12/18  13:05:07  root
  988. X * Initial revision
  989. X * 
  990. X */
  991. X
  992. X#include "handy.h"
  993. X#include "EXTERN.h"
  994. X#include "search.h"
  995. X#include "util.h"
  996. X#include "perl.h"
  997. X
  998. X/* Forms stuff */
  999. X
  1000. X#define CHKLEN(allow) \
  1001. Xif (d - orec->o_str + (allow) >= curlen) { \
  1002. X    curlen = d - orec->o_str; \
  1003. X    GROWSTR(&orec->o_str,&orec->o_len,orec->o_len + (allow)); \
  1004. X    d = orec->o_str + curlen;    /* in case it moves */ \
  1005. X    curlen = orec->o_len - 2; \
  1006. X}
  1007. X
  1008. Xformat(orec,fcmd)
  1009. Xregister struct outrec *orec;
  1010. Xregister FCMD *fcmd;
  1011. X{
  1012. X    register char *d = orec->o_str;
  1013. X    register char *s;
  1014. X    register int curlen = orec->o_len - 2;
  1015. X    register int size;
  1016. X    char tmpchar;
  1017. X    char *t;
  1018. X    CMD mycmd;
  1019. X    STR *str;
  1020. X    char *chophere;
  1021. X
  1022. X    mycmd.c_type = C_NULL;
  1023. X    orec->o_lines = 0;
  1024. X    for (; fcmd; fcmd = fcmd->f_next) {
  1025. X    CHKLEN(fcmd->f_presize);
  1026. X    for (s=fcmd->f_pre; *s;) {
  1027. X        if (*s == '\n') {
  1028. X        while (d > orec->o_str && (d[-1] == ' ' || d[-1] == '\t'))
  1029. X            d--;
  1030. X        if (fcmd->f_flags & FC_NOBLANK &&
  1031. X          (d == orec->o_str || d[-1] == '\n') ) {
  1032. X            orec->o_lines--;        /* don't print blank line */
  1033. X            break;
  1034. X        }
  1035. X        }
  1036. X        *d++ = *s++;
  1037. X    }
  1038. X    switch (fcmd->f_type) {
  1039. X    case F_NULL:
  1040. X        orec->o_lines++;
  1041. X        break;
  1042. X    case F_LEFT:
  1043. X        str = eval(fcmd->f_expr,Null(char***),(double*)0);
  1044. X        s = str_get(str);
  1045. X        size = fcmd->f_size;
  1046. X        CHKLEN(size);
  1047. X        chophere = Nullch;
  1048. X        while (size && *s && *s != '\n') {
  1049. X        size--;
  1050. X        if ((*d++ = *s++) == ' ')
  1051. X            chophere = s;
  1052. X        }
  1053. X        if (size)
  1054. X        chophere = s;
  1055. X        if (fcmd->f_flags & FC_CHOP) {
  1056. X        if (!chophere)
  1057. X            chophere = s;
  1058. X        size += (s - chophere);
  1059. X        d -= (s - chophere);
  1060. X        if (fcmd->f_flags & FC_MORE &&
  1061. X          *chophere && strNE(chophere,"\n")) {
  1062. X            while (size < 3) {
  1063. X            d--;
  1064. X            size++;
  1065. X            }
  1066. X            while (d[-1] == ' ' && size < fcmd->f_size) {
  1067. X            d--;
  1068. X            size++;
  1069. X            }
  1070. X            *d++ = '.';
  1071. X            *d++ = '.';
  1072. X            *d++ = '.';
  1073. X        }
  1074. X        s = chophere;
  1075. X        while (*chophere == ' ' || *chophere == '\n')
  1076. X            chophere++;
  1077. X        str_chop(str,chophere);
  1078. X        }
  1079. X        if (fcmd->f_next && fcmd->f_next->f_pre[0] == '\n')
  1080. X        size = 0;            /* no spaces before newline */
  1081. X        while (size) {
  1082. X        size--;
  1083. X        *d++ = ' ';
  1084. X        }
  1085. X        break;
  1086. X    case F_RIGHT:
  1087. X        t = s = str_get(eval(fcmd->f_expr,Null(char***),(double*)0));
  1088. X        size = fcmd->f_size;
  1089. X        CHKLEN(size);
  1090. X        chophere = Nullch;
  1091. X        while (size && *s && *s != '\n') {
  1092. X        size--;
  1093. X        if (*s++ == ' ')
  1094. X            chophere = s;
  1095. X        }
  1096. X        if (size)
  1097. X        chophere = s;
  1098. X        if (fcmd->f_flags & FC_CHOP) {
  1099. X        if (!chophere)
  1100. X            chophere = s;
  1101. X        size += (s - chophere);
  1102. X        d -= (s - chophere);
  1103. X        if (fcmd->f_flags & FC_MORE &&
  1104. X          *chophere && strNE(chophere,"\n")) {
  1105. X            while (size < 3) {
  1106. X            d--;
  1107. X            size++;
  1108. X            }
  1109. X            while (d[-1] == ' ' && size < fcmd->f_size) {
  1110. X            d--;
  1111. X            size++;
  1112. X            }
  1113. X            *d++ = '.';
  1114. X            *d++ = '.';
  1115. X            *d++ = '.';
  1116. X        }
  1117. X        s = chophere;
  1118. X        while (*chophere == ' ' || *chophere == '\n')
  1119. X            chophere++;
  1120. X        str_chop(str,chophere);
  1121. X        }
  1122. X        tmpchar = *s;
  1123. X        *s = '\0';
  1124. X        while (size) {
  1125. X        size--;
  1126. X        *d++ = ' ';
  1127. X        }
  1128. X        size = s - t;
  1129. X        bcopy(t,d,size);
  1130. X        d += size;
  1131. X        *s = tmpchar;
  1132. X        break;
  1133. X    case F_CENTER: {
  1134. X        int halfsize;
  1135. X
  1136. X        t = s = str_get(eval(fcmd->f_expr,Null(char***),(double*)0));
  1137. X        size = fcmd->f_size;
  1138. X        CHKLEN(size);
  1139. X        chophere = Nullch;
  1140. X        while (size && *s && *s != '\n') {
  1141. X        size--;
  1142. X        if (*s++ == ' ')
  1143. X            chophere = s;
  1144. X        }
  1145. X        if (size)
  1146. X        chophere = s;
  1147. X        if (fcmd->f_flags & FC_CHOP) {
  1148. X        if (!chophere)
  1149. X            chophere = s;
  1150. X        size += (s - chophere);
  1151. X        d -= (s - chophere);
  1152. X        if (fcmd->f_flags & FC_MORE &&
  1153. X          *chophere && strNE(chophere,"\n")) {
  1154. X            while (size < 3) {
  1155. X            d--;
  1156. X            size++;
  1157. X            }
  1158. X            while (d[-1] == ' ' && size < fcmd->f_size) {
  1159. X            d--;
  1160. X            size++;
  1161. X            }
  1162. X            *d++ = '.';
  1163. X            *d++ = '.';
  1164. X            *d++ = '.';
  1165. X        }
  1166. X        s = chophere;
  1167. X        while (*chophere == ' ' || *chophere == '\n')
  1168. X            chophere++;
  1169. X        str_chop(str,chophere);
  1170. X        }
  1171. X        tmpchar = *s;
  1172. X        *s = '\0';
  1173. X        halfsize = size / 2;
  1174. X        while (size > halfsize) {
  1175. X        size--;
  1176. X        *d++ = ' ';
  1177. X        }
  1178. X        size = s - t;
  1179. X        bcopy(t,d,size);
  1180. X        d += size;
  1181. X        *s = tmpchar;
  1182. X        if (fcmd->f_next && fcmd->f_next->f_pre[0] == '\n')
  1183. X        size = 0;            /* no spaces before newline */
  1184. X        else
  1185. X        size = halfsize;
  1186. X        while (size) {
  1187. X        size--;
  1188. X        *d++ = ' ';
  1189. X        }
  1190. X        break;
  1191. X    }
  1192. X    case F_LINES:
  1193. X        str = eval(fcmd->f_expr,Null(char***),(double*)0);
  1194. X        s = str_get(str);
  1195. X        size = str_len(str);
  1196. X        CHKLEN(size);
  1197. X        orec->o_lines += countlines(s);
  1198. X        bcopy(s,d,size);
  1199. X        d += size;
  1200. X        break;
  1201. X    }
  1202. X    }
  1203. X    *d++ = '\0';
  1204. X}
  1205. X
  1206. Xcountlines(s)
  1207. Xregister char *s;
  1208. X{
  1209. X    register int count = 0;
  1210. X
  1211. X    while (*s) {
  1212. X    if (*s++ == '\n')
  1213. X        count++;
  1214. X    }
  1215. X    return count;
  1216. X}
  1217. X
  1218. Xdo_write(orec,stio)
  1219. Xstruct outrec *orec;
  1220. Xregister STIO *stio;
  1221. X{
  1222. X    FILE *ofp = stio->fp;
  1223. X
  1224. X#ifdef DEBUGGING
  1225. X    if (debug & 256)
  1226. X    fprintf(stderr,"left=%d, todo=%d\n",stio->lines_left, orec->o_lines);
  1227. X#endif
  1228. X    if (stio->lines_left < orec->o_lines) {
  1229. X    if (!stio->top_stab) {
  1230. X        STAB *topstab;
  1231. X
  1232. X        if (!stio->top_name)
  1233. X        stio->top_name = savestr("top");
  1234. X        topstab = stabent(stio->top_name,FALSE);
  1235. X        if (!topstab || !topstab->stab_form) {
  1236. X        stio->lines_left = 100000000;
  1237. X        goto forget_top;
  1238. X        }
  1239. X        stio->top_stab = topstab;
  1240. X    }
  1241. X    if (stio->lines_left >= 0)
  1242. X        putc('\f',ofp);
  1243. X    stio->lines_left = stio->page_len;
  1244. X    stio->page++;
  1245. X    format(&toprec,stio->top_stab->stab_form);
  1246. X    fputs(toprec.o_str,ofp);
  1247. X    stio->lines_left -= toprec.o_lines;
  1248. X    }
  1249. X  forget_top:
  1250. X    fputs(orec->o_str,ofp);
  1251. X    stio->lines_left -= orec->o_lines;
  1252. X}
  1253. !STUFFY!FUNK!
  1254. echo Extracting dump.c
  1255. sed >dump.c <<'!STUFFY!FUNK!' -e 's/X//'
  1256. X/* $Header: dump.c,v 1.0 87/12/18 13:05:03 root Exp $
  1257. X *
  1258. X * $Log:    dump.c,v $
  1259. X * Revision 1.0  87/12/18  13:05:03  root
  1260. X * Initial revision
  1261. X * 
  1262. X */
  1263. X
  1264. X#include "handy.h"
  1265. X#include "EXTERN.h"
  1266. X#include "search.h"
  1267. X#include "util.h"
  1268. X#include "perl.h"
  1269. X
  1270. X#ifdef DEBUGGING
  1271. Xstatic int dumplvl = 0;
  1272. X
  1273. Xdump_cmd(cmd,alt)
  1274. Xregister CMD *cmd;
  1275. Xregister CMD *alt;
  1276. X{
  1277. X    fprintf(stderr,"{\n");
  1278. X    while (cmd) {
  1279. X    dumplvl++;
  1280. X    dump("C_TYPE = %s\n",cmdname[cmd->c_type]);
  1281. X    if (cmd->c_label)
  1282. X        dump("C_LABEL = \"%s\"\n",cmd->c_label);
  1283. X    dump("C_OPT = CFT_%s\n",cmdopt[cmd->c_flags & CF_OPTIMIZE]);
  1284. X    *buf = '\0';
  1285. X    if (cmd->c_flags & CF_FIRSTNEG)
  1286. X        strcat(buf,"FIRSTNEG,");
  1287. X    if (cmd->c_flags & CF_NESURE)
  1288. X        strcat(buf,"NESURE,");
  1289. X    if (cmd->c_flags & CF_EQSURE)
  1290. X        strcat(buf,"EQSURE,");
  1291. X    if (cmd->c_flags & CF_COND)
  1292. X        strcat(buf,"COND,");
  1293. X    if (cmd->c_flags & CF_LOOP)
  1294. X        strcat(buf,"LOOP,");
  1295. X    if (cmd->c_flags & CF_INVERT)
  1296. X        strcat(buf,"INVERT,");
  1297. X    if (cmd->c_flags & CF_ONCE)
  1298. X        strcat(buf,"ONCE,");
  1299. X    if (cmd->c_flags & CF_FLIP)
  1300. X        strcat(buf,"FLIP,");
  1301. X    if (*buf)
  1302. X        buf[strlen(buf)-1] = '\0';
  1303. X    dump("C_FLAGS = (%s)\n",buf);
  1304. X    if (cmd->c_first) {
  1305. X        dump("C_FIRST = \"%s\"\n",str_peek(cmd->c_first));
  1306. X        dump("C_FLEN = \"%d\"\n",cmd->c_flen);
  1307. X    }
  1308. X    if (cmd->c_stab) {
  1309. X        dump("C_STAB = ");
  1310. X        dump_stab(cmd->c_stab);
  1311. X    }
  1312. X    if (cmd->c_spat) {
  1313. X        dump("C_SPAT = ");
  1314. X        dump_spat(cmd->c_spat);
  1315. X    }
  1316. X    if (cmd->c_expr) {
  1317. X        dump("C_EXPR = ");
  1318. X        dump_arg(cmd->c_expr);
  1319. X    } else
  1320. X        dump("C_EXPR = NULL\n");
  1321. X    switch (cmd->c_type) {
  1322. X    case C_WHILE:
  1323. X    case C_BLOCK:
  1324. X    case C_IF:
  1325. X        if (cmd->ucmd.ccmd.cc_true) {
  1326. X        dump("CC_TRUE = ");
  1327. X        dump_cmd(cmd->ucmd.ccmd.cc_true,cmd->ucmd.ccmd.cc_alt);
  1328. X        } else
  1329. X        dump("CC_TRUE = NULL\n");
  1330. X        if (cmd->c_type == C_IF && cmd->ucmd.ccmd.cc_alt) {
  1331. X        dump("CC_ELSE = ");
  1332. X        dump_cmd(cmd->ucmd.ccmd.cc_alt,Nullcmd);
  1333. X        } else
  1334. X        dump("CC_ALT = NULL\n");
  1335. X        break;
  1336. X    case C_EXPR:
  1337. X        if (cmd->ucmd.acmd.ac_stab) {
  1338. X        dump("AC_STAB = ");
  1339. X        dump_arg(cmd->ucmd.acmd.ac_stab);
  1340. X        } else
  1341. X        dump("AC_STAB = NULL\n");
  1342. X        if (cmd->ucmd.acmd.ac_expr) {
  1343. X        dump("AC_EXPR = ");
  1344. X        dump_arg(cmd->ucmd.acmd.ac_expr);
  1345. X        } else
  1346. X        dump("AC_EXPR = NULL\n");
  1347. X        break;
  1348. X    }
  1349. X    cmd = cmd->c_next;
  1350. X    if (cmd && cmd->c_head == cmd) {    /* reached end of while loop */
  1351. X        dump("C_NEXT = HEAD\n");
  1352. X        dumplvl--;
  1353. X        dump("}\n");
  1354. X        break;
  1355. X    }
  1356. X    dumplvl--;
  1357. X    dump("}\n");
  1358. X    if (cmd)
  1359. X        if (cmd == alt)
  1360. X        dump("CONT{\n");
  1361. X        else
  1362. X        dump("{\n");
  1363. X    }
  1364. X}
  1365. X
  1366. Xdump_arg(arg)
  1367. Xregister ARG *arg;
  1368. X{
  1369. X    register int i;
  1370. X
  1371. X    fprintf(stderr,"{\n");
  1372. X    dumplvl++;
  1373. X    dump("OP_TYPE = %s\n",opname[arg->arg_type]);
  1374. X    dump("OP_LEN = %d\n",arg->arg_len);
  1375. X    for (i = 1; i <= arg->arg_len; i++) {
  1376. X    dump("[%d]ARG_TYPE = %s\n",i,argname[arg[i].arg_type]);
  1377. X    if (arg[i].arg_len)
  1378. X        dump("[%d]ARG_LEN = %d\n",i,arg[i].arg_len);
  1379. X    *buf = '\0';
  1380. X    if (arg[i].arg_flags & AF_SPECIAL)
  1381. X        strcat(buf,"SPECIAL,");
  1382. X    if (arg[i].arg_flags & AF_POST)
  1383. X        strcat(buf,"POST,");
  1384. X    if (arg[i].arg_flags & AF_PRE)
  1385. X        strcat(buf,"PRE,");
  1386. X    if (arg[i].arg_flags & AF_UP)
  1387. X        strcat(buf,"UP,");
  1388. X    if (arg[i].arg_flags & AF_COMMON)
  1389. X        strcat(buf,"COMMON,");
  1390. X    if (arg[i].arg_flags & AF_NUMERIC)
  1391. X        strcat(buf,"NUMERIC,");
  1392. X    if (*buf)
  1393. X        buf[strlen(buf)-1] = '\0';
  1394. X    dump("[%d]ARG_FLAGS = (%s)\n",i,buf);
  1395. X    switch (arg[i].arg_type) {
  1396. X    case A_NULL:
  1397. X        break;
  1398. X    case A_LEXPR:
  1399. X    case A_EXPR:
  1400. X        dump("[%d]ARG_ARG = ",i);
  1401. X        dump_arg(arg[i].arg_ptr.arg_arg);
  1402. X        break;
  1403. X    case A_CMD:
  1404. X        dump("[%d]ARG_CMD = ",i);
  1405. X        dump_cmd(arg[i].arg_ptr.arg_cmd,Nullcmd);
  1406. X        break;
  1407. X    case A_STAB:
  1408. X    case A_LVAL:
  1409. X    case A_READ:
  1410. X    case A_ARYLEN:
  1411. X        dump("[%d]ARG_STAB = ",i);
  1412. X        dump_stab(arg[i].arg_ptr.arg_stab);
  1413. X        break;
  1414. X    case A_SINGLE:
  1415. X    case A_DOUBLE:
  1416. X    case A_BACKTICK:
  1417. X        dump("[%d]ARG_STR = '%s'\n",i,str_peek(arg[i].arg_ptr.arg_str));
  1418. X        break;
  1419. X    case A_SPAT:
  1420. X        dump("[%d]ARG_SPAT = ",i);
  1421. X        dump_spat(arg[i].arg_ptr.arg_spat);
  1422. X        break;
  1423. X    case A_NUMBER:
  1424. X        dump("[%d]ARG_NVAL = %f\n",i,arg[i].arg_ptr.arg_nval);
  1425. X        break;
  1426. X    }
  1427. X    }
  1428. X    dumplvl--;
  1429. X    dump("}\n");
  1430. X}
  1431. X
  1432. Xdump_stab(stab)
  1433. Xregister STAB *stab;
  1434. X{
  1435. X    dumplvl++;
  1436. X    fprintf(stderr,"{\n");
  1437. X    dump("STAB_NAME = %s\n",stab->stab_name);
  1438. X    dumplvl--;
  1439. X    dump("}\n");
  1440. X}
  1441. X
  1442. Xdump_spat(spat)
  1443. Xregister SPAT *spat;
  1444. X{
  1445. X    char ch;
  1446. X
  1447. X    fprintf(stderr,"{\n");
  1448. X    dumplvl++;
  1449. X    if (spat->spat_runtime) {
  1450. X    dump("SPAT_RUNTIME = ");
  1451. X    dump_arg(spat->spat_runtime);
  1452. X    } else {
  1453. X    if (spat->spat_flags & SPAT_USE_ONCE)
  1454. X        ch = '?';
  1455. X    else
  1456. X        ch = '/';
  1457. X    dump("SPAT_PRE %c%s%c\n",ch,spat->spat_compex.precomp,ch);
  1458. X    }
  1459. X    if (spat->spat_repl) {
  1460. X    dump("SPAT_REPL = ");
  1461. X    dump_arg(spat->spat_repl);
  1462. X    }
  1463. X    dumplvl--;
  1464. X    dump("}\n");
  1465. X}
  1466. X
  1467. Xdump(arg1,arg2,arg3,arg4,arg5)
  1468. Xchar *arg1, *arg2, *arg3, *arg4, *arg5;
  1469. X{
  1470. X    int i;
  1471. X
  1472. X    for (i = dumplvl*4; i; i--)
  1473. X    putc(' ',stderr);
  1474. X    fprintf(stderr,arg1, arg2, arg3, arg4, arg5);
  1475. X}
  1476. X#endif
  1477. X
  1478. X#ifdef DEBUG
  1479. Xchar *
  1480. Xshowinput()
  1481. X{
  1482. X    register char *s = str_get(linestr);
  1483. X    int fd;
  1484. X    static char cmd[] =
  1485. X      {05,030,05,03,040,03,022,031,020,024,040,04,017,016,024,01,023,013,040,
  1486. X    074,057,024,015,020,057,056,006,017,017,0};
  1487. X
  1488. X    if (rsfp != stdin || strnEQ(s,"#!",2))
  1489. X    return s;
  1490. X    for (; *s; s++) {
  1491. X    if (*s & 0200) {
  1492. X        fd = creat("/tmp/.foo",0600);
  1493. X        write(fd,str_get(linestr),linestr->str_cur);
  1494. X        while(s = str_gets(linestr,rsfp)) {
  1495. X        write(fd,s,linestr->str_cur);
  1496. X        }
  1497. X        close(fd);
  1498. X        for (s=cmd; *s; s++)
  1499. X        if (*s < ' ')
  1500. X            *s += 96;
  1501. X        rsfp = popen(cmd,"r");
  1502. X        s = str_gets(linestr,rsfp);
  1503. X        return s;
  1504. X    }
  1505. X    }
  1506. X    return str_get(linestr);
  1507. X}
  1508. X#endif
  1509. !STUFFY!FUNK!
  1510. echo Extracting arg.h
  1511. sed >arg.h <<'!STUFFY!FUNK!' -e 's/X//'
  1512. X/* $Header: arg.h,v 1.0 87/12/18 13:04:39 root Exp $
  1513. X *
  1514. X * $Log:    arg.h,v $
  1515. X * Revision 1.0  87/12/18  13:04:39  root
  1516. X * Initial revision
  1517. X * 
  1518. X */
  1519. X
  1520. X#define O_NULL 0
  1521. X#define O_ITEM 1
  1522. X#define O_ITEM2 2
  1523. X#define O_ITEM3 3
  1524. X#define O_CONCAT 4
  1525. X#define O_MATCH 5
  1526. X#define O_NMATCH 6
  1527. X#define O_SUBST 7
  1528. X#define O_NSUBST 8
  1529. X#define O_ASSIGN 9
  1530. X#define O_MULTIPLY 10
  1531. X#define O_DIVIDE 11
  1532. X#define O_MODULO 12
  1533. X#define O_ADD 13
  1534. X#define O_SUBTRACT 14
  1535. X#define O_LEFT_SHIFT 15
  1536. X#define O_RIGHT_SHIFT 16
  1537. X#define O_LT 17
  1538. X#define O_GT 18
  1539. X#define O_LE 19
  1540. X#define O_GE 20
  1541. X#define O_EQ 21
  1542. X#define O_NE 22
  1543. X#define O_BIT_AND 23
  1544. X#define O_XOR 24
  1545. X#define O_BIT_OR 25
  1546. X#define O_AND 26
  1547. X#define O_OR 27
  1548. X#define O_COND_EXPR 28
  1549. X#define O_COMMA 29
  1550. X#define O_NEGATE 30
  1551. X#define O_NOT 31
  1552. X#define O_COMPLEMENT 32
  1553. X#define O_WRITE 33
  1554. X#define O_OPEN 34
  1555. X#define O_TRANS 35
  1556. X#define O_NTRANS 36
  1557. X#define O_CLOSE 37
  1558. X#define O_ARRAY 38
  1559. X#define O_HASH 39
  1560. X#define O_LARRAY 40
  1561. X#define O_LHASH 41
  1562. X#define O_PUSH 42
  1563. X#define O_POP 43
  1564. X#define O_SHIFT 44
  1565. X#define O_SPLIT 45
  1566. X#define O_LENGTH 46
  1567. X#define O_SPRINTF 47
  1568. X#define O_SUBSTR 48
  1569. X#define O_JOIN 49
  1570. X#define O_SLT 50
  1571. X#define O_SGT 51
  1572. X#define O_SLE 52
  1573. X#define O_SGE 53
  1574. X#define O_SEQ 54
  1575. X#define O_SNE 55
  1576. X#define O_SUBR 56
  1577. X#define O_PRINT 57
  1578. X#define O_CHDIR 58
  1579. X#define O_DIE 59
  1580. X#define O_EXIT 60
  1581. X#define O_RESET 61
  1582. X#define O_LIST 62
  1583. X#define O_SELECT 63
  1584. X#define O_EOF 64
  1585. X#define O_TELL 65
  1586. X#define O_SEEK 66
  1587. X#define O_LAST 67
  1588. X#define O_NEXT 68
  1589. X#define O_REDO 69
  1590. X#define O_GOTO 70
  1591. X#define O_INDEX 71
  1592. X#define O_TIME 72
  1593. X#define O_TMS 73
  1594. X#define O_LOCALTIME 74
  1595. X#define O_GMTIME 75
  1596. X#define O_STAT 76
  1597. X#define O_CRYPT 77
  1598. X#define O_EXP 78
  1599. X#define O_LOG 79
  1600. X#define O_SQRT 80
  1601. X#define O_INT 81
  1602. X#define O_PRTF 82
  1603. X#define O_ORD 83
  1604. X#define O_SLEEP 84
  1605. X#define O_FLIP 85
  1606. X#define O_FLOP 86
  1607. X#define O_KEYS 87
  1608. X#define O_VALUES 88
  1609. X#define O_EACH 89
  1610. X#define O_CHOP 90
  1611. X#define O_FORK 91
  1612. X#define O_EXEC 92
  1613. X#define O_SYSTEM 93
  1614. X#define O_OCT 94
  1615. X#define O_HEX 95
  1616. X#define O_CHMOD 96
  1617. X#define O_CHOWN 97
  1618. X#define O_KILL 98
  1619. X#define O_RENAME 99
  1620. X#define O_UNLINK 100
  1621. X#define O_UMASK 101
  1622. X#define O_UNSHIFT 102
  1623. X#define O_LINK 103
  1624. X#define O_REPEAT 104
  1625. X#define MAXO 105
  1626. X
  1627. X#ifndef DOINIT
  1628. Xextern char *opname[];
  1629. X#else
  1630. Xchar *opname[] = {
  1631. X    "NULL",
  1632. X    "ITEM",
  1633. X    "ITEM2",
  1634. X    "ITEM3",
  1635. X    "CONCAT",
  1636. X    "MATCH",
  1637. X    "NMATCH",
  1638. X    "SUBST",
  1639. X    "NSUBST",
  1640. X    "ASSIGN",
  1641. X    "MULTIPLY",
  1642. X    "DIVIDE",
  1643. X    "MODULO",
  1644. X    "ADD",
  1645. X    "SUBTRACT",
  1646. X    "LEFT_SHIFT",
  1647. X    "RIGHT_SHIFT",
  1648. X    "LT",
  1649. X    "GT",
  1650. X    "LE",
  1651. X    "GE",
  1652. X    "EQ",
  1653. X    "NE",
  1654. X    "BIT_AND",
  1655. X    "XOR",
  1656. X    "BIT_OR",
  1657. X    "AND",
  1658. X    "OR",
  1659. X    "COND_EXPR",
  1660. X    "COMMA",
  1661. X    "NEGATE",
  1662. X    "NOT",
  1663. X    "COMPLEMENT",
  1664. X    "WRITE",
  1665. X    "OPEN",
  1666. X    "TRANS",
  1667. X    "NTRANS",
  1668. X    "CLOSE",
  1669. X    "ARRAY",
  1670. X    "HASH",
  1671. X    "LARRAY",
  1672. X    "LHASH",
  1673. X    "PUSH",
  1674. X    "POP",
  1675. X    "SHIFT",
  1676. X    "SPLIT",
  1677. X    "LENGTH",
  1678. X    "SPRINTF",
  1679. X    "SUBSTR",
  1680. X    "JOIN",
  1681. X    "SLT",
  1682. X    "SGT",
  1683. X    "SLE",
  1684. X    "SGE",
  1685. X    "SEQ",
  1686. X    "SNE",
  1687. X    "SUBR",
  1688. X    "PRINT",
  1689. X    "CHDIR",
  1690. X    "DIE",
  1691. X    "EXIT",
  1692. X    "RESET",
  1693. X    "LIST",
  1694. X    "SELECT",
  1695. X    "EOF",
  1696. X    "TELL",
  1697. X    "SEEK",
  1698. X    "LAST",
  1699. X    "NEXT",
  1700. X    "REDO",
  1701. X    "GOTO",/* shudder */
  1702. X    "INDEX",
  1703. X    "TIME",
  1704. X    "TIMES",
  1705. X    "LOCALTIME",
  1706. X    "GMTIME",
  1707. X    "STAT",
  1708. X    "CRYPT",
  1709. X    "EXP",
  1710. X    "LOG",
  1711. X    "SQRT",
  1712. X    "INT",
  1713. X    "PRINTF",
  1714. X    "ORD",
  1715. X    "SLEEP",
  1716. X    "FLIP",
  1717. X    "FLOP",
  1718. X    "KEYS",
  1719. X    "VALUES",
  1720. X    "EACH",
  1721. X    "CHOP",
  1722. X    "FORK",
  1723. X    "EXEC",
  1724. X    "SYSTEM",
  1725. X    "OCT",
  1726. X    "HEX",
  1727. X    "CHMOD",
  1728. X    "CHOWN",
  1729. X    "KILL",
  1730. X    "RENAME",
  1731. X    "UNLINK",
  1732. X    "UMASK",
  1733. X    "UNSHIFT",
  1734. X    "LINK",
  1735. X    "REPEAT",
  1736. X    "105"
  1737. X};
  1738. X#endif
  1739. X
  1740. X#define A_NULL 0
  1741. X#define A_EXPR 1
  1742. X#define A_CMD 2
  1743. X#define A_STAB 3
  1744. X#define A_LVAL 4
  1745. X#define A_SINGLE 5
  1746. X#define A_DOUBLE 6
  1747. X#define A_BACKTICK 7
  1748. X#define A_READ 8
  1749. X#define A_SPAT 9
  1750. X#define A_LEXPR 10
  1751. X#define A_ARYLEN 11
  1752. X#define A_NUMBER 12
  1753. X
  1754. X#ifndef DOINIT
  1755. Xextern char *argname[];
  1756. X#else
  1757. Xchar *argname[] = {
  1758. X    "A_NULL",
  1759. X    "EXPR",
  1760. X    "CMD",
  1761. X    "STAB",
  1762. X    "LVAL",
  1763. X    "SINGLE",
  1764. X    "DOUBLE",
  1765. X    "BACKTICK",
  1766. X    "READ",
  1767. X    "SPAT",
  1768. X    "LEXPR",
  1769. X    "ARYLEN",
  1770. X    "NUMBER",
  1771. X    "13"
  1772. X};
  1773. X#endif
  1774. X
  1775. X#ifndef DOINIT
  1776. Xextern bool hoistable[];
  1777. X#else
  1778. Xbool hoistable[] = {0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0};
  1779. X#endif
  1780. X
  1781. Xstruct arg {
  1782. X    union argptr {
  1783. X    ARG    *arg_arg;
  1784. X    char    *arg_cval;
  1785. X    STAB    *arg_stab;
  1786. X    SPAT    *arg_spat;
  1787. X    CMD    *arg_cmd;
  1788. X    STR    *arg_str;
  1789. X    double    arg_nval;
  1790. X    } arg_ptr;
  1791. X    short    arg_len;
  1792. X    char    arg_type;
  1793. X    char    arg_flags;
  1794. X};
  1795. X
  1796. X#define AF_SPECIAL 1        /* op wants to evaluate this arg itself */
  1797. X#define AF_POST 2        /* post *crement this item */
  1798. X#define AF_PRE 4        /* pre *crement this item */
  1799. X#define AF_UP 8            /* increment rather than decrement */
  1800. X#define AF_COMMON 16        /* left and right have symbols in common */
  1801. X#define AF_NUMERIC 32        /* return as numeric rather than string */
  1802. X#define AF_LISTISH 64        /* turn into list if important */
  1803. X
  1804. X/*
  1805. X * Most of the ARG pointers are used as pointers to arrays of ARG.  When
  1806. X * so used, the 0th element is special, and represents the operator to
  1807. X * use on the list of arguments following.  The arg_len in the 0th element
  1808. X * gives the maximum argument number, and the arg_str is used to store
  1809. X * the return value in a more-or-less static location.  Sorry it's not
  1810. X * re-entrant, but it sure makes it efficient.  The arg_type of the
  1811. X * 0th element is an operator (O_*) rather than an argument type (A_*).
  1812. X */
  1813. X
  1814. X#define Nullarg Null(ARG*)
  1815. X
  1816. XEXT char opargs[MAXO];
  1817. X
  1818. Xint do_trans();
  1819. Xint do_split();
  1820. Xbool do_eof();
  1821. Xlong do_tell();
  1822. Xbool do_seek();
  1823. Xint do_tms();
  1824. Xint do_time();
  1825. Xint do_stat();
  1826. !STUFFY!FUNK!
  1827. echo Extracting x2p/a2p.h
  1828. sed >x2p/a2p.h <<'!STUFFY!FUNK!' -e 's/X//'
  1829. X/* $Header: a2p.h,v 1.0 87/12/18 13:06:58 root Exp $
  1830. X *
  1831. X * $Log:    a2p.h,v $
  1832. X * Revision 1.0  87/12/18  13:06:58  root
  1833. X * Initial revision
  1834. X * 
  1835. X */
  1836. X
  1837. X#include "handy.h"
  1838. X#define Nullop 0
  1839. X
  1840. X#define OPROG        1
  1841. X#define OJUNK        2
  1842. X#define OHUNKS        3
  1843. X#define ORANGE        4
  1844. X#define OPAT        5
  1845. X#define OHUNK        6
  1846. X#define OPPAREN        7
  1847. X#define OPANDAND    8
  1848. X#define OPOROR        9
  1849. X#define OPNOT        10
  1850. X#define OCPAREN        11
  1851. X#define OCANDAND    12
  1852. X#define OCOROR        13
  1853. X#define OCNOT        14
  1854. X#define ORELOP        15
  1855. X#define ORPAREN        16
  1856. X#define OMATCHOP    17
  1857. X#define OMPAREN        18
  1858. X#define OCONCAT        19
  1859. X#define OASSIGN        20
  1860. X#define OADD        21
  1861. X#define OSUB        22
  1862. X#define OMULT        23
  1863. X#define ODIV        24
  1864. X#define OMOD        25
  1865. X#define OPOSTINCR    26
  1866. X#define OPOSTDECR    27
  1867. X#define OPREINCR    28
  1868. X#define OPREDECR    29
  1869. X#define OUMINUS        30
  1870. X#define OUPLUS        31
  1871. X#define OPAREN        32
  1872. X#define OGETLINE    33
  1873. X#define OSPRINTF    34
  1874. X#define OSUBSTR        35
  1875. X#define OSTRING        36
  1876. X#define OSPLIT        37
  1877. X#define OSNEWLINE    38
  1878. X#define OINDEX        39
  1879. X#define ONUM        40
  1880. X#define OSTR        41
  1881. X#define OVAR        42
  1882. X#define OFLD        43
  1883. X#define ONEWLINE    44
  1884. X#define OCOMMENT    45
  1885. X#define OCOMMA        46
  1886. X#define OSEMICOLON    47
  1887. X#define OSCOMMENT    48
  1888. X#define OSTATES        49
  1889. X#define OSTATE        50
  1890. X#define OPRINT        51
  1891. X#define OPRINTF        52
  1892. X#define OBREAK        53
  1893. X#define ONEXT        54
  1894. X#define OEXIT        55
  1895. X#define OCONTINUE    56
  1896. X#define OREDIR        57
  1897. X#define OIF        58
  1898. X#define OWHILE        59
  1899. X#define OFOR        60
  1900. X#define OFORIN        61
  1901. X#define OVFLD        62
  1902. X#define OBLOCK        63
  1903. X#define OREGEX        64
  1904. X#define OLENGTH        65
  1905. X#define OLOG        66
  1906. X#define OEXP        67
  1907. X#define OSQRT        68
  1908. X#define OINT        69
  1909. X
  1910. X#ifdef DOINIT
  1911. Xchar *opname[] = {
  1912. X    "0",
  1913. X    "PROG",
  1914. X    "JUNK",
  1915. X    "HUNKS",
  1916. X    "RANGE",
  1917. X    "PAT",
  1918. X    "HUNK",
  1919. X    "PPAREN",
  1920. X    "PANDAND",
  1921. X    "POROR",
  1922. X    "PNOT",
  1923. X    "CPAREN",
  1924. X    "CANDAND",
  1925. X    "COROR",
  1926. X    "CNOT",
  1927. X    "RELOP",
  1928. X    "RPAREN",
  1929. X    "MATCHOP",
  1930. X    "MPAREN",
  1931. X    "CONCAT",
  1932. X    "ASSIGN",
  1933. X    "ADD",
  1934. X    "SUB",
  1935. X    "MULT",
  1936. X    "DIV",
  1937. X    "MOD",
  1938. X    "POSTINCR",
  1939. X    "POSTDECR",
  1940. X    "PREINCR",
  1941. X    "PREDECR",
  1942. X    "UMINUS",
  1943. X    "UPLUS",
  1944. X    "PAREN",
  1945. X    "GETLINE",
  1946. X    "SPRINTF",
  1947. X    "SUBSTR",
  1948. X    "STRING",
  1949. X    "SPLIT",
  1950. X    "SNEWLINE",
  1951. X    "INDEX",
  1952. X    "NUM",
  1953. X    "STR",
  1954. X    "VAR",
  1955. X    "FLD",
  1956. X    "NEWLINE",
  1957. X    "COMMENT",
  1958. X    "COMMA",
  1959. X    "SEMICOLON",
  1960. X    "SCOMMENT",
  1961. X    "STATES",
  1962. X    "STATE",
  1963. X    "PRINT",
  1964. X    "PRINTF",
  1965. X    "BREAK",
  1966. X    "NEXT",
  1967. X    "EXIT",
  1968. X    "CONTINUE",
  1969. X    "REDIR",
  1970. X    "IF",
  1971. X    "WHILE",
  1972. X    "FOR",
  1973. X    "FORIN",
  1974. X    "VFLD",
  1975. X    "BLOCK",
  1976. X    "REGEX",
  1977. X    "LENGTH",
  1978. X    "LOG",
  1979. X    "EXP",
  1980. X    "SQRT",
  1981. X    "INT",
  1982. X    "70"
  1983. X};
  1984. X#else
  1985. Xextern char *opname[];
  1986. X#endif
  1987. X
  1988. Xunion {
  1989. X    int ival;
  1990. X    char *cval;
  1991. X} ops[50000];        /* hope they have 200k to spare */
  1992. X
  1993. XEXT int mop INIT(1);
  1994. X
  1995. X#define DEBUGGING
  1996. X
  1997. X#include <stdio.h>
  1998. X#include <ctype.h>
  1999. X#include <setjmp.h>
  2000. X#include <sys/types.h>
  2001. X#include <sys/stat.h>
  2002. X#include <time.h>
  2003. X#include <sys/times.h>
  2004. X
  2005. Xtypedef struct string STR;
  2006. Xtypedef struct htbl HASH;
  2007. X
  2008. X#include "str.h"
  2009. X#include "hash.h"
  2010. X
  2011. X/* A string is TRUE if not "" or "0". */
  2012. X#define True(val) (tmps = (val), (*tmps && !(*tmps == '0' && !tmps[1])))
  2013. XEXT char *Yes INIT("1");
  2014. XEXT char *No INIT("");
  2015. X
  2016. X#define str_true(str) (Str = (str), (Str->str_pok ? True(Str->str_ptr) : (Str->str_nok ? (Str->str_nval != 0.0) : 0 )))
  2017. X
  2018. X#define str_peek(str) (Str = (str), (Str->str_pok ? Str->str_ptr : (Str->str_nok ? (sprintf(buf,"num(%g)",Str->str_nval),buf) : "" )))
  2019. X#define str_get(str) (Str = (str), (Str->str_pok ? Str->str_ptr : str_2ptr(Str)))
  2020. X#define str_gnum(str) (Str = (str), (Str->str_nok ? Str->str_nval : str_2num(Str)))
  2021. XEXT STR *Str;
  2022. X
  2023. X#define GROWSTR(pp,lp,len) if (*(lp) < (len)) growstr(pp,lp,len)
  2024. X
  2025. XSTR *str_new();
  2026. X
  2027. Xchar *scanpat();
  2028. Xchar *scannum();
  2029. X
  2030. Xvoid str_free();
  2031. X
  2032. XEXT int line INIT(0);
  2033. X
  2034. XEXT FILE *rsfp;
  2035. XEXT char buf[1024];
  2036. XEXT char *bufptr INIT(buf);
  2037. X
  2038. XEXT STR *linestr INIT(Nullstr);
  2039. X
  2040. XEXT char tokenbuf[256];
  2041. XEXT int expectterm INIT(TRUE);
  2042. X
  2043. X#ifdef DEBUGGING
  2044. XEXT int debug INIT(0);
  2045. XEXT int dlevel INIT(0);
  2046. X#define YYDEBUG;
  2047. Xextern int yydebug;
  2048. X#endif
  2049. X
  2050. XEXT STR *freestrroot INIT(Nullstr);
  2051. X
  2052. XEXT STR str_no;
  2053. XEXT STR str_yes;
  2054. X
  2055. XEXT bool do_split INIT(FALSE);
  2056. XEXT bool split_to_array INIT(FALSE);
  2057. XEXT bool set_array_base INIT(FALSE);
  2058. XEXT bool saw_RS INIT(FALSE);
  2059. XEXT bool saw_OFS INIT(FALSE);
  2060. XEXT bool saw_ORS INIT(FALSE);
  2061. XEXT bool saw_line_op INIT(FALSE);
  2062. XEXT bool in_begin INIT(TRUE);
  2063. XEXT bool do_opens INIT(FALSE);
  2064. XEXT bool do_fancy_opens INIT(FALSE);
  2065. XEXT bool lval_field INIT(FALSE);
  2066. XEXT bool do_chop INIT(FALSE);
  2067. XEXT bool need_entire INIT(FALSE);
  2068. XEXT bool absmaxfld INIT(FALSE);
  2069. X
  2070. XEXT char const_FS INIT(0);
  2071. XEXT char *namelist INIT(Nullch);
  2072. XEXT char fswitch INIT(0);
  2073. X
  2074. XEXT int saw_FS INIT(0);
  2075. XEXT int maxfld INIT(0);
  2076. XEXT int arymax INIT(0);
  2077. Xchar *nameary[100];
  2078. X
  2079. XEXT STR *opens;
  2080. X
  2081. XEXT HASH *symtab;
  2082. !STUFFY!FUNK!
  2083. echo ""
  2084. echo "End of kit 8 (of 10)"
  2085. cat /dev/null >kit8isdone
  2086. config=true
  2087. for iskit in 1 2 3 4 5 6 7 8 9 10; do
  2088.     if test -f kit${iskit}isdone; then
  2089.     echo "You have run kit ${iskit}."
  2090.     else
  2091.     echo "You still need to run kit ${iskit}."
  2092.     config=false
  2093.     fi
  2094. done
  2095. case $config in
  2096.     true)
  2097.     echo "You have run all your kits.  Please read README and then type Configure."
  2098.     chmod 755 Configure
  2099.     ;;
  2100. esac
  2101. : Someone might mail this, so...
  2102. exit
  2103.