You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

arg.c 48KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144
  1. /* $Header: arg.c,v 1.0.1.5 88/01/30 08:53:16 root Exp $
  2. *
  3. * $Log: arg.c,v $
  4. * Revision 1.0.1.5 88/01/30 08:53:16 root
  5. * patch9: fixed some missing right parens introduced (?) by patch 2
  6. *
  7. * Revision 1.0.1.4 88/01/28 10:22:06 root
  8. * patch8: added eval operator.
  9. *
  10. * Revision 1.0.1.2 88/01/24 03:52:34 root
  11. * patch 2: added STATBLKS dependencies.
  12. *
  13. * Revision 1.0.1.1 88/01/21 21:27:10 root
  14. * Now defines signal return values correctly using VOIDSIG.
  15. *
  16. * Revision 1.0 87/12/18 13:04:33 root
  17. * Initial revision
  18. *
  19. */
  20. #include <signal.h>
  21. #include "handy.h"
  22. #include "EXTERN.h"
  23. #include "search.h"
  24. #include "util.h"
  25. #include "perl.h"
  26. ARG *debarg;
  27. bool
  28. do_match(s,arg)
  29. register char *s;
  30. register ARG *arg;
  31. {
  32. register SPAT *spat = arg[2].arg_ptr.arg_spat;
  33. register char *d;
  34. register char *t;
  35. if (!spat || !s)
  36. fatal("panic: do_match\n");
  37. if (spat->spat_flags & SPAT_USED) {
  38. #ifdef DEBUGGING
  39. if (debug & 8)
  40. deb("2.SPAT USED\n");
  41. #endif
  42. return FALSE;
  43. }
  44. if (spat->spat_runtime) {
  45. t = str_get(eval(spat->spat_runtime,Null(STR***)));
  46. #ifdef DEBUGGING
  47. if (debug & 8)
  48. deb("2.SPAT /%s/\n",t);
  49. #endif
  50. if (d = compile(&spat->spat_compex,t,TRUE,FALSE)) {
  51. #ifdef DEBUGGING
  52. deb("/%s/: %s\n", t, d);
  53. #endif
  54. return FALSE;
  55. }
  56. if (spat->spat_compex.complen <= 1 && curspat)
  57. spat = curspat;
  58. if (execute(&spat->spat_compex, s, TRUE, 0)) {
  59. if (spat->spat_compex.numsubs)
  60. curspat = spat;
  61. return TRUE;
  62. }
  63. else
  64. return FALSE;
  65. }
  66. else {
  67. #ifdef DEBUGGING
  68. if (debug & 8) {
  69. char ch;
  70. if (spat->spat_flags & SPAT_USE_ONCE)
  71. ch = '?';
  72. else
  73. ch = '/';
  74. deb("2.SPAT %c%s%c\n",ch,spat->spat_compex.precomp,ch);
  75. }
  76. #endif
  77. if (spat->spat_compex.complen <= 1 && curspat)
  78. spat = curspat;
  79. if (spat->spat_first) {
  80. if (spat->spat_flags & SPAT_SCANFIRST) {
  81. str_free(spat->spat_first);
  82. spat->spat_first = Nullstr; /* disable optimization */
  83. }
  84. else if (*spat->spat_first->str_ptr != *s ||
  85. strnNE(spat->spat_first->str_ptr, s, spat->spat_flen) )
  86. return FALSE;
  87. }
  88. if (execute(&spat->spat_compex, s, TRUE, 0)) {
  89. if (spat->spat_compex.numsubs)
  90. curspat = spat;
  91. if (spat->spat_flags & SPAT_USE_ONCE)
  92. spat->spat_flags |= SPAT_USED;
  93. return TRUE;
  94. }
  95. else
  96. return FALSE;
  97. }
  98. /*NOTREACHED*/
  99. }
  100. int
  101. do_subst(str,arg)
  102. STR *str;
  103. register ARG *arg;
  104. {
  105. register SPAT *spat;
  106. register STR *dstr;
  107. register char *s;
  108. register char *m;
  109. spat = arg[2].arg_ptr.arg_spat;
  110. s = str_get(str);
  111. if (!spat || !s)
  112. fatal("panic: do_subst\n");
  113. else if (spat->spat_runtime) {
  114. char *d;
  115. m = str_get(eval(spat->spat_runtime,Null(STR***)));
  116. if (d = compile(&spat->spat_compex,m,TRUE,FALSE)) {
  117. #ifdef DEBUGGING
  118. deb("/%s/: %s\n", m, d);
  119. #endif
  120. return 0;
  121. }
  122. }
  123. #ifdef DEBUGGING
  124. if (debug & 8) {
  125. deb("2.SPAT /%s/\n",spat->spat_compex.precomp);
  126. }
  127. #endif
  128. if (spat->spat_compex.complen <= 1 && curspat)
  129. spat = curspat;
  130. if (spat->spat_first) {
  131. if (spat->spat_flags & SPAT_SCANFIRST) {
  132. str_free(spat->spat_first);
  133. spat->spat_first = Nullstr; /* disable optimization */
  134. }
  135. else if (*spat->spat_first->str_ptr != *s ||
  136. strnNE(spat->spat_first->str_ptr, s, spat->spat_flen) )
  137. return 0;
  138. }
  139. if (m = execute(&spat->spat_compex, s, TRUE, 1)) {
  140. int iters = 0;
  141. dstr = str_new(str_len(str));
  142. if (spat->spat_compex.numsubs)
  143. curspat = spat;
  144. do {
  145. if (iters++ > 10000)
  146. fatal("Substitution loop?\n");
  147. if (spat->spat_compex.numsubs)
  148. s = spat->spat_compex.subbase;
  149. str_ncat(dstr,s,m-s);
  150. s = spat->spat_compex.subend[0];
  151. str_scat(dstr,eval(spat->spat_repl,Null(STR***)));
  152. if (spat->spat_flags & SPAT_USE_ONCE)
  153. break;
  154. } while (m = execute(&spat->spat_compex, s, FALSE, 1));
  155. str_cat(dstr,s);
  156. str_replace(str,dstr);
  157. STABSET(str);
  158. return iters;
  159. }
  160. return 0;
  161. }
  162. int
  163. do_trans(str,arg)
  164. STR *str;
  165. register ARG *arg;
  166. {
  167. register char *tbl;
  168. register char *s;
  169. register int matches = 0;
  170. register int ch;
  171. tbl = arg[2].arg_ptr.arg_cval;
  172. s = str_get(str);
  173. if (!tbl || !s)
  174. fatal("panic: do_trans\n");
  175. #ifdef DEBUGGING
  176. if (debug & 8) {
  177. deb("2.TBL\n");
  178. }
  179. #endif
  180. while (*s) {
  181. if (ch = tbl[*s & 0377]) {
  182. matches++;
  183. *s = ch;
  184. }
  185. s++;
  186. }
  187. STABSET(str);
  188. return matches;
  189. }
  190. int
  191. do_split(s,spat,retary)
  192. register char *s;
  193. register SPAT *spat;
  194. STR ***retary;
  195. {
  196. register STR *dstr;
  197. register char *m;
  198. register ARRAY *ary;
  199. static ARRAY *myarray = Null(ARRAY*);
  200. int iters = 0;
  201. STR **sarg;
  202. register char *e;
  203. int i;
  204. if (!spat || !s)
  205. fatal("panic: do_split\n");
  206. else if (spat->spat_runtime) {
  207. char *d;
  208. m = str_get(eval(spat->spat_runtime,Null(STR***)));
  209. if (d = compile(&spat->spat_compex,m,TRUE,FALSE)) {
  210. #ifdef DEBUGGING
  211. deb("/%s/: %s\n", m, d);
  212. #endif
  213. return FALSE;
  214. }
  215. }
  216. #ifdef DEBUGGING
  217. if (debug & 8) {
  218. deb("2.SPAT /%s/\n",spat->spat_compex.precomp);
  219. }
  220. #endif
  221. if (retary)
  222. ary = myarray;
  223. else
  224. ary = spat->spat_repl[1].arg_ptr.arg_stab->stab_array;
  225. if (!ary)
  226. myarray = ary = anew();
  227. ary->ary_fill = -1;
  228. while (*s && (m = execute(&spat->spat_compex, s, (iters == 0), 1))) {
  229. if (spat->spat_compex.numsubs)
  230. s = spat->spat_compex.subbase;
  231. dstr = str_new(m-s);
  232. str_nset(dstr,s,m-s);
  233. astore(ary, iters++, dstr);
  234. if (iters > 10000)
  235. fatal("Substitution loop?\n");
  236. s = spat->spat_compex.subend[0];
  237. }
  238. if (*s) { /* ignore field after final "whitespace" */
  239. dstr = str_new(0); /* if they interpolate, it's null anyway */
  240. str_set(dstr,s);
  241. astore(ary, iters++, dstr);
  242. }
  243. else {
  244. while (iters > 0 && !*str_get(afetch(ary,iters-1)))
  245. iters--;
  246. }
  247. if (retary) {
  248. sarg = (STR**)safemalloc((iters+2)*sizeof(STR*));
  249. sarg[0] = Nullstr;
  250. sarg[iters+1] = Nullstr;
  251. for (i = 1; i <= iters; i++)
  252. sarg[i] = afetch(ary,i-1);
  253. *retary = sarg;
  254. }
  255. return iters;
  256. }
  257. void
  258. do_join(arg,delim,str)
  259. register ARG *arg;
  260. register char *delim;
  261. register STR *str;
  262. {
  263. STR **tmpary; /* must not be register */
  264. register STR **elem;
  265. (void)eval(arg[2].arg_ptr.arg_arg,&tmpary);
  266. elem = tmpary+1;
  267. if (*elem)
  268. str_sset(str,*elem++);
  269. for (; *elem; elem++) {
  270. str_cat(str,delim);
  271. str_scat(str,*elem);
  272. }
  273. STABSET(str);
  274. safefree((char*)tmpary);
  275. }
  276. bool
  277. do_open(stab,name)
  278. STAB *stab;
  279. register char *name;
  280. {
  281. FILE *fp;
  282. int len = strlen(name);
  283. register STIO *stio = stab->stab_io;
  284. while (len && isspace(name[len-1]))
  285. name[--len] = '\0';
  286. if (!stio)
  287. stio = stab->stab_io = stio_new();
  288. if (stio->fp) {
  289. if (stio->type == '|')
  290. pclose(stio->fp);
  291. else if (stio->type != '-')
  292. fclose(stio->fp);
  293. stio->fp = Nullfp;
  294. }
  295. stio->type = *name;
  296. if (*name == '|') {
  297. for (name++; isspace(*name); name++) ;
  298. fp = popen(name,"w");
  299. }
  300. else if (*name == '>' && name[1] == '>') {
  301. for (name += 2; isspace(*name); name++) ;
  302. fp = fopen(name,"a");
  303. }
  304. else if (*name == '>') {
  305. for (name++; isspace(*name); name++) ;
  306. if (strEQ(name,"-")) {
  307. fp = stdout;
  308. stio->type = '-';
  309. }
  310. else
  311. fp = fopen(name,"w");
  312. }
  313. else {
  314. if (*name == '<') {
  315. for (name++; isspace(*name); name++) ;
  316. if (strEQ(name,"-")) {
  317. fp = stdin;
  318. stio->type = '-';
  319. }
  320. else
  321. fp = fopen(name,"r");
  322. }
  323. else if (name[len-1] == '|') {
  324. name[--len] = '\0';
  325. while (len && isspace(name[len-1]))
  326. name[--len] = '\0';
  327. for (; isspace(*name); name++) ;
  328. fp = popen(name,"r");
  329. stio->type = '|';
  330. }
  331. else {
  332. stio->type = '<';
  333. for (; isspace(*name); name++) ;
  334. if (strEQ(name,"-")) {
  335. fp = stdin;
  336. stio->type = '-';
  337. }
  338. else
  339. fp = fopen(name,"r");
  340. }
  341. }
  342. if (!fp)
  343. return FALSE;
  344. if (stio->type != '|' && stio->type != '-') {
  345. if (fstat(fileno(fp),&statbuf) < 0) {
  346. fclose(fp);
  347. return FALSE;
  348. }
  349. if ((statbuf.st_mode & S_IFMT) != S_IFREG &&
  350. (statbuf.st_mode & S_IFMT) != S_IFCHR) {
  351. fclose(fp);
  352. return FALSE;
  353. }
  354. }
  355. stio->fp = fp;
  356. return TRUE;
  357. }
  358. FILE *
  359. nextargv(stab)
  360. register STAB *stab;
  361. {
  362. register STR *str;
  363. char *oldname;
  364. while (alen(stab->stab_array) >= 0L) {
  365. str = ashift(stab->stab_array);
  366. str_sset(stab->stab_val,str);
  367. STABSET(stab->stab_val);
  368. oldname = str_get(stab->stab_val);
  369. if (do_open(stab,oldname)) {
  370. if (inplace) {
  371. if (*inplace) {
  372. str_cat(str,inplace);
  373. #ifdef RENAME
  374. rename(oldname,str->str_ptr);
  375. #else
  376. UNLINK(str->str_ptr);
  377. link(oldname,str->str_ptr);
  378. UNLINK(oldname);
  379. #endif
  380. }
  381. sprintf(tokenbuf,">%s",oldname);
  382. do_open(argvoutstab,tokenbuf);
  383. defoutstab = argvoutstab;
  384. }
  385. str_free(str);
  386. return stab->stab_io->fp;
  387. }
  388. else
  389. fprintf(stderr,"Can't open %s\n",str_get(str));
  390. str_free(str);
  391. }
  392. if (inplace) {
  393. do_close(argvoutstab,FALSE);
  394. defoutstab = stabent("stdout",TRUE);
  395. }
  396. return Nullfp;
  397. }
  398. bool
  399. do_close(stab,explicit)
  400. STAB *stab;
  401. bool explicit;
  402. {
  403. bool retval = FALSE;
  404. register STIO *stio = stab->stab_io;
  405. if (!stio) /* never opened */
  406. return FALSE;
  407. if (stio->fp) {
  408. if (stio->type == '|')
  409. retval = (pclose(stio->fp) >= 0);
  410. else if (stio->type == '-')
  411. retval = TRUE;
  412. else
  413. retval = (fclose(stio->fp) != EOF);
  414. stio->fp = Nullfp;
  415. }
  416. if (explicit)
  417. stio->lines = 0;
  418. stio->type = ' ';
  419. return retval;
  420. }
  421. bool
  422. do_eof(stab)
  423. STAB *stab;
  424. {
  425. register STIO *stio;
  426. int ch;
  427. if (!stab)
  428. return TRUE;
  429. stio = stab->stab_io;
  430. if (!stio)
  431. return TRUE;
  432. while (stio->fp) {
  433. #ifdef STDSTDIO /* (the code works without this) */
  434. if (stio->fp->_cnt) /* cheat a little, since */
  435. return FALSE; /* this is the most usual case */
  436. #endif
  437. ch = getc(stio->fp);
  438. if (ch != EOF) {
  439. ungetc(ch, stio->fp);
  440. return FALSE;
  441. }
  442. if (stio->flags & IOF_ARGV) { /* not necessarily a real EOF yet? */
  443. if (!nextargv(stab)) /* get another fp handy */
  444. return TRUE;
  445. }
  446. else
  447. return TRUE; /* normal fp, definitely end of file */
  448. }
  449. return TRUE;
  450. }
  451. long
  452. do_tell(stab)
  453. STAB *stab;
  454. {
  455. register STIO *stio;
  456. int ch;
  457. if (!stab)
  458. return -1L;
  459. stio = stab->stab_io;
  460. if (!stio || !stio->fp)
  461. return -1L;
  462. return ftell(stio->fp);
  463. }
  464. bool
  465. do_seek(stab, pos, whence)
  466. STAB *stab;
  467. long pos;
  468. int whence;
  469. {
  470. register STIO *stio;
  471. if (!stab)
  472. return FALSE;
  473. stio = stab->stab_io;
  474. if (!stio || !stio->fp)
  475. return FALSE;
  476. return fseek(stio->fp, pos, whence) >= 0;
  477. }
  478. do_stat(arg,sarg,retary)
  479. register ARG *arg;
  480. register STR **sarg;
  481. STR ***retary;
  482. {
  483. register ARRAY *ary;
  484. static ARRAY *myarray = Null(ARRAY*);
  485. int max = 13;
  486. register int i;
  487. ary = myarray;
  488. if (!ary)
  489. myarray = ary = anew();
  490. ary->ary_fill = -1;
  491. if (arg[1].arg_type == A_LVAL) {
  492. tmpstab = arg[1].arg_ptr.arg_stab;
  493. if (!tmpstab->stab_io ||
  494. fstat(fileno(tmpstab->stab_io->fp),&statbuf) < 0) {
  495. max = 0;
  496. }
  497. }
  498. else
  499. if (stat(str_get(sarg[1]),&statbuf) < 0)
  500. max = 0;
  501. if (retary) {
  502. if (max) {
  503. apush(ary,str_nmake((double)statbuf.st_dev));
  504. apush(ary,str_nmake((double)statbuf.st_ino));
  505. apush(ary,str_nmake((double)statbuf.st_mode));
  506. apush(ary,str_nmake((double)statbuf.st_nlink));
  507. apush(ary,str_nmake((double)statbuf.st_uid));
  508. apush(ary,str_nmake((double)statbuf.st_gid));
  509. apush(ary,str_nmake((double)statbuf.st_rdev));
  510. apush(ary,str_nmake((double)statbuf.st_size));
  511. apush(ary,str_nmake((double)statbuf.st_atime));
  512. apush(ary,str_nmake((double)statbuf.st_mtime));
  513. apush(ary,str_nmake((double)statbuf.st_ctime));
  514. #ifdef STATBLOCKS
  515. apush(ary,str_nmake((double)statbuf.st_blksize));
  516. apush(ary,str_nmake((double)statbuf.st_blocks));
  517. #else
  518. apush(ary,str_make(""));
  519. apush(ary,str_make(""));
  520. #endif
  521. }
  522. sarg = (STR**)safemalloc((max+2)*sizeof(STR*));
  523. sarg[0] = Nullstr;
  524. sarg[max+1] = Nullstr;
  525. for (i = 1; i <= max; i++)
  526. sarg[i] = afetch(ary,i-1);
  527. *retary = sarg;
  528. }
  529. return max;
  530. }
  531. do_tms(retary)
  532. STR ***retary;
  533. {
  534. register ARRAY *ary;
  535. static ARRAY *myarray = Null(ARRAY*);
  536. register STR **sarg;
  537. int max = 4;
  538. register int i;
  539. ary = myarray;
  540. if (!ary)
  541. myarray = ary = anew();
  542. ary->ary_fill = -1;
  543. if (times(&timesbuf) < 0)
  544. max = 0;
  545. if (retary) {
  546. if (max) {
  547. apush(ary,str_nmake(((double)timesbuf.tms_utime)/60.0));
  548. apush(ary,str_nmake(((double)timesbuf.tms_stime)/60.0));
  549. apush(ary,str_nmake(((double)timesbuf.tms_cutime)/60.0));
  550. apush(ary,str_nmake(((double)timesbuf.tms_cstime)/60.0));
  551. }
  552. sarg = (STR**)safemalloc((max+2)*sizeof(STR*));
  553. sarg[0] = Nullstr;
  554. sarg[max+1] = Nullstr;
  555. for (i = 1; i <= max; i++)
  556. sarg[i] = afetch(ary,i-1);
  557. *retary = sarg;
  558. }
  559. return max;
  560. }
  561. do_time(tmbuf,retary)
  562. struct tm *tmbuf;
  563. STR ***retary;
  564. {
  565. register ARRAY *ary;
  566. static ARRAY *myarray = Null(ARRAY*);
  567. register STR **sarg;
  568. int max = 9;
  569. register int i;
  570. STR *str;
  571. ary = myarray;
  572. if (!ary)
  573. myarray = ary = anew();
  574. ary->ary_fill = -1;
  575. if (!tmbuf)
  576. max = 0;
  577. if (retary) {
  578. if (max) {
  579. apush(ary,str_nmake((double)tmbuf->tm_sec));
  580. apush(ary,str_nmake((double)tmbuf->tm_min));
  581. apush(ary,str_nmake((double)tmbuf->tm_hour));
  582. apush(ary,str_nmake((double)tmbuf->tm_mday));
  583. apush(ary,str_nmake((double)tmbuf->tm_mon));
  584. apush(ary,str_nmake((double)tmbuf->tm_year));
  585. apush(ary,str_nmake((double)tmbuf->tm_wday));
  586. apush(ary,str_nmake((double)tmbuf->tm_yday));
  587. apush(ary,str_nmake((double)tmbuf->tm_isdst));
  588. }
  589. sarg = (STR**)safemalloc((max+2)*sizeof(STR*));
  590. sarg[0] = Nullstr;
  591. sarg[max+1] = Nullstr;
  592. for (i = 1; i <= max; i++)
  593. sarg[i] = afetch(ary,i-1);
  594. *retary = sarg;
  595. }
  596. return max;
  597. }
  598. void
  599. do_sprintf(str,len,sarg)
  600. register STR *str;
  601. register int len;
  602. register STR **sarg;
  603. {
  604. register char *s;
  605. register char *t;
  606. bool dolong;
  607. char ch;
  608. static STR *sargnull = &str_no;
  609. str_set(str,"");
  610. len--; /* don't count pattern string */
  611. sarg++;
  612. for (s = str_get(*(sarg++)); *s; len--) {
  613. if (len <= 0 || !*sarg) {
  614. sarg = &sargnull;
  615. len = 0;
  616. }
  617. dolong = FALSE;
  618. for (t = s; *t && *t != '%'; t++) ;
  619. if (!*t)
  620. break; /* not enough % patterns, oh well */
  621. for (t++; *sarg && *t && t != s; t++) {
  622. switch (*t) {
  623. case '\0':
  624. break;
  625. case '%':
  626. ch = *(++t);
  627. *t = '\0';
  628. sprintf(buf,s);
  629. s = t;
  630. *(t--) = ch;
  631. break;
  632. case 'l':
  633. dolong = TRUE;
  634. break;
  635. case 'D': case 'X': case 'O':
  636. dolong = TRUE;
  637. /* FALL THROUGH */
  638. case 'd': case 'x': case 'o': case 'c':
  639. ch = *(++t);
  640. *t = '\0';
  641. if (dolong)
  642. sprintf(buf,s,(long)str_gnum(*(sarg++)));
  643. else
  644. sprintf(buf,s,(int)str_gnum(*(sarg++)));
  645. s = t;
  646. *(t--) = ch;
  647. break;
  648. case 'E': case 'e': case 'f': case 'G': case 'g':
  649. ch = *(++t);
  650. *t = '\0';
  651. sprintf(buf,s,str_gnum(*(sarg++)));
  652. s = t;
  653. *(t--) = ch;
  654. break;
  655. case 's':
  656. ch = *(++t);
  657. *t = '\0';
  658. sprintf(buf,s,str_get(*(sarg++)));
  659. s = t;
  660. *(t--) = ch;
  661. break;
  662. }
  663. }
  664. str_cat(str,buf);
  665. }
  666. if (*s)
  667. str_cat(str,s);
  668. STABSET(str);
  669. }
  670. bool
  671. do_print(s,fp)
  672. char *s;
  673. FILE *fp;
  674. {
  675. if (!fp || !s)
  676. return FALSE;
  677. fputs(s,fp);
  678. return TRUE;
  679. }
  680. bool
  681. do_aprint(arg,fp)
  682. register ARG *arg;
  683. register FILE *fp;
  684. {
  685. STR **tmpary; /* must not be register */
  686. register STR **elem;
  687. register bool retval;
  688. double value;
  689. (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
  690. if (arg->arg_type == O_PRTF) {
  691. do_sprintf(arg->arg_ptr.arg_str,32767,tmpary);
  692. retval = do_print(str_get(arg->arg_ptr.arg_str),fp);
  693. }
  694. else {
  695. retval = FALSE;
  696. for (elem = tmpary+1; *elem; elem++) {
  697. if (retval && ofs)
  698. do_print(ofs, fp);
  699. if (ofmt && fp) {
  700. if ((*elem)->str_nok || str_gnum(*elem) != 0.0)
  701. fprintf(fp, ofmt, str_gnum(*elem));
  702. retval = TRUE;
  703. }
  704. else
  705. retval = do_print(str_get(*elem), fp);
  706. if (!retval)
  707. break;
  708. }
  709. if (ors)
  710. retval = do_print(ors, fp);
  711. }
  712. safefree((char*)tmpary);
  713. return retval;
  714. }
  715. bool
  716. do_aexec(arg)
  717. register ARG *arg;
  718. {
  719. STR **tmpary; /* must not be register */
  720. register STR **elem;
  721. register char **a;
  722. register int i;
  723. char **argv;
  724. (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
  725. i = 0;
  726. for (elem = tmpary+1; *elem; elem++)
  727. i++;
  728. if (i) {
  729. argv = (char**)safemalloc((i+1)*sizeof(char*));
  730. a = argv;
  731. for (elem = tmpary+1; *elem; elem++) {
  732. *a++ = str_get(*elem);
  733. }
  734. *a = Nullch;
  735. execvp(argv[0],argv);
  736. safefree((char*)argv);
  737. }
  738. safefree((char*)tmpary);
  739. return FALSE;
  740. }
  741. bool
  742. do_exec(cmd)
  743. char *cmd;
  744. {
  745. STR **tmpary; /* must not be register */
  746. register char **a;
  747. register char *s;
  748. char **argv;
  749. /* see if there are shell metacharacters in it */
  750. for (s = cmd; *s; s++) {
  751. if (*s != ' ' && !isalpha(*s) && index("$&*(){}[]'\";\\|?<>~`",*s)) {
  752. execl("/bin/sh","sh","-c",cmd,0);
  753. return FALSE;
  754. }
  755. }
  756. argv = (char**)safemalloc(((s - cmd) / 2 + 2)*sizeof(char*));
  757. a = argv;
  758. for (s = cmd; *s;) {
  759. while (isspace(*s)) s++;
  760. if (*s)
  761. *(a++) = s;
  762. while (*s && !isspace(*s)) s++;
  763. if (*s)
  764. *s++ = '\0';
  765. }
  766. *a = Nullch;
  767. if (argv[0])
  768. execvp(argv[0],argv);
  769. safefree((char*)argv);
  770. return FALSE;
  771. }
  772. STR *
  773. do_push(arg,ary)
  774. register ARG *arg;
  775. register ARRAY *ary;
  776. {
  777. STR **tmpary; /* must not be register */
  778. register STR **elem;
  779. register STR *str = &str_no;
  780. (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
  781. for (elem = tmpary+1; *elem; elem++) {
  782. str = str_new(0);
  783. str_sset(str,*elem);
  784. apush(ary,str);
  785. }
  786. safefree((char*)tmpary);
  787. return str;
  788. }
  789. do_unshift(arg,ary)
  790. register ARG *arg;
  791. register ARRAY *ary;
  792. {
  793. STR **tmpary; /* must not be register */
  794. register STR **elem;
  795. register STR *str = &str_no;
  796. register int i;
  797. (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
  798. i = 0;
  799. for (elem = tmpary+1; *elem; elem++)
  800. i++;
  801. aunshift(ary,i);
  802. i = 0;
  803. for (elem = tmpary+1; *elem; elem++) {
  804. str = str_new(0);
  805. str_sset(str,*elem);
  806. astore(ary,i++,str);
  807. }
  808. safefree((char*)tmpary);
  809. }
  810. apply(type,arg,sarg)
  811. int type;
  812. register ARG *arg;
  813. STR **sarg;
  814. {
  815. STR **tmpary; /* must not be register */
  816. register STR **elem;
  817. register int i;
  818. register int val;
  819. register int val2;
  820. if (sarg)
  821. tmpary = sarg;
  822. else
  823. (void)eval(arg[1].arg_ptr.arg_arg,&tmpary);
  824. i = 0;
  825. for (elem = tmpary+1; *elem; elem++)
  826. i++;
  827. switch (type) {
  828. case O_CHMOD:
  829. if (--i > 0) {
  830. val = (int)str_gnum(tmpary[1]);
  831. for (elem = tmpary+2; *elem; elem++)
  832. if (chmod(str_get(*elem),val))
  833. i--;
  834. }
  835. break;
  836. case O_CHOWN:
  837. if (i > 2) {
  838. i -= 2;
  839. val = (int)str_gnum(tmpary[1]);
  840. val2 = (int)str_gnum(tmpary[2]);
  841. for (elem = tmpary+3; *elem; elem++)
  842. if (chown(str_get(*elem),val,val2))
  843. i--;
  844. }
  845. else
  846. i = 0;
  847. break;
  848. case O_KILL:
  849. if (--i > 0) {
  850. val = (int)str_gnum(tmpary[1]);
  851. if (val < 0)
  852. val = -val;
  853. for (elem = tmpary+2; *elem; elem++)
  854. if (kill(atoi(str_get(*elem)),val))
  855. i--;
  856. }
  857. break;
  858. case O_UNLINK:
  859. for (elem = tmpary+1; *elem; elem++)
  860. if (UNLINK(str_get(*elem)))
  861. i--;
  862. break;
  863. }
  864. if (!sarg)
  865. safefree((char*)tmpary);
  866. return i;
  867. }
  868. STR *
  869. do_subr(arg,sarg)
  870. register ARG *arg;
  871. register char **sarg;
  872. {
  873. ARRAY *savearray;
  874. STR *str;
  875. savearray = defstab->stab_array;
  876. defstab->stab_array = anew();
  877. if (arg[1].arg_flags & AF_SPECIAL)
  878. (void)do_push(arg,defstab->stab_array);
  879. else if (arg[1].arg_type != A_NULL) {
  880. str = str_new(0);
  881. str_sset(str,sarg[1]);
  882. apush(defstab->stab_array,str);
  883. }
  884. str = cmd_exec(arg[2].arg_ptr.arg_stab->stab_sub);
  885. afree(defstab->stab_array); /* put back old $_[] */
  886. defstab->stab_array = savearray;
  887. return str;
  888. }
  889. void
  890. do_assign(retstr,arg)
  891. STR *retstr;
  892. register ARG *arg;
  893. {
  894. STR **tmpary; /* must not be register */
  895. register ARG *larg = arg[1].arg_ptr.arg_arg;
  896. register STR **elem;
  897. register STR *str;
  898. register ARRAY *ary;
  899. register int i;
  900. register int lasti;
  901. char *s;
  902. (void)eval(arg[2].arg_ptr.arg_arg,&tmpary);
  903. if (arg->arg_flags & AF_COMMON) {
  904. if (*(tmpary+1)) {
  905. for (elem=tmpary+2; *elem; elem++) {
  906. *elem = str_static(*elem);
  907. }
  908. }
  909. }
  910. if (larg->arg_type == O_LIST) {
  911. lasti = larg->arg_len;
  912. for (i=1,elem=tmpary+1; i <= lasti; i++) {
  913. if (*elem)
  914. s = str_get(*(elem++));
  915. else
  916. s = "";
  917. switch (larg[i].arg_type) {
  918. case A_STAB:
  919. case A_LVAL:
  920. str = STAB_STR(larg[i].arg_ptr.arg_stab);
  921. break;
  922. case A_LEXPR:
  923. str = eval(larg[i].arg_ptr.arg_arg,Null(STR***));
  924. break;
  925. }
  926. str_set(str,s);
  927. STABSET(str);
  928. }
  929. i = elem - tmpary - 1;
  930. }
  931. else { /* should be an array name */
  932. ary = larg[1].arg_ptr.arg_stab->stab_array;
  933. for (i=0,elem=tmpary+1; *elem; i++) {
  934. str = str_new(0);
  935. if (*elem)
  936. str_sset(str,*(elem++));
  937. astore(ary,i,str);
  938. }
  939. ary->ary_fill = i - 1; /* they can get the extra ones back by */
  940. } /* setting an element larger than old fill */
  941. str_numset(retstr,(double)i);
  942. STABSET(retstr);
  943. safefree((char*)tmpary);
  944. }
  945. int
  946. do_kv(hash,kv,sarg,retary)
  947. HASH *hash;
  948. int kv;
  949. register STR **sarg;
  950. STR ***retary;
  951. {
  952. register ARRAY *ary;
  953. int max = 0;
  954. int i;
  955. static ARRAY *myarray = Null(ARRAY*);
  956. register HENT *entry;
  957. ary = myarray;
  958. if (!ary)
  959. myarray = ary = anew();
  960. ary->ary_fill = -1;
  961. hiterinit(hash);
  962. while (entry = hiternext(hash)) {
  963. max++;
  964. if (kv == O_KEYS)
  965. apush(ary,str_make(hiterkey(entry)));
  966. else
  967. apush(ary,str_make(str_get(hiterval(entry))));
  968. }
  969. if (retary) { /* array wanted */
  970. sarg = (STR**)saferealloc((char*)sarg,(max+2)*sizeof(STR*));
  971. sarg[0] = Nullstr;
  972. sarg[max+1] = Nullstr;
  973. for (i = 1; i <= max; i++)
  974. sarg[i] = afetch(ary,i-1);
  975. *retary = sarg;
  976. }
  977. return max;
  978. }
  979. STR *
  980. do_each(hash,sarg,retary)
  981. HASH *hash;
  982. register STR **sarg;
  983. STR ***retary;
  984. {
  985. static STR *mystr = Nullstr;
  986. STR *retstr;
  987. HENT *entry = hiternext(hash);
  988. if (mystr) {
  989. str_free(mystr);
  990. mystr = Nullstr;
  991. }
  992. if (retary) { /* array wanted */
  993. if (entry) {
  994. sarg = (STR**)saferealloc((char*)sarg,4*sizeof(STR*));
  995. sarg[0] = Nullstr;
  996. sarg[3] = Nullstr;
  997. sarg[1] = mystr = str_make(hiterkey(entry));
  998. retstr = sarg[2] = hiterval(entry);
  999. *retary = sarg;
  1000. }
  1001. else {
  1002. sarg = (STR**)saferealloc((char*)sarg,2*sizeof(STR*));
  1003. sarg[0] = Nullstr;
  1004. sarg[1] = retstr = Nullstr;
  1005. *retary = sarg;
  1006. }
  1007. }
  1008. else
  1009. retstr = hiterval(entry);
  1010. return retstr;
  1011. }
  1012. init_eval()
  1013. {
  1014. register int i;
  1015. #define A(e1,e2,e3) (e1+(e2<<1)+(e3<<2))
  1016. opargs[O_ITEM] = A(1,0,0);
  1017. opargs[O_ITEM2] = A(0,0,0);
  1018. opargs[O_ITEM3] = A(0,0,0);
  1019. opargs[O_CONCAT] = A(1,1,0);
  1020. opargs[O_MATCH] = A(1,0,0);
  1021. opargs[O_NMATCH] = A(1,0,0);
  1022. opargs[O_SUBST] = A(1,0,0);
  1023. opargs[O_NSUBST] = A(1,0,0);
  1024. opargs[O_ASSIGN] = A(1,1,0);
  1025. opargs[O_MULTIPLY] = A(1,1,0);
  1026. opargs[O_DIVIDE] = A(1,1,0);
  1027. opargs[O_MODULO] = A(1,1,0);
  1028. opargs[O_ADD] = A(1,1,0);
  1029. opargs[O_SUBTRACT] = A(1,1,0);
  1030. opargs[O_LEFT_SHIFT] = A(1,1,0);
  1031. opargs[O_RIGHT_SHIFT] = A(1,1,0);
  1032. opargs[O_LT] = A(1,1,0);
  1033. opargs[O_GT] = A(1,1,0);
  1034. opargs[O_LE] = A(1,1,0);
  1035. opargs[O_GE] = A(1,1,0);
  1036. opargs[O_EQ] = A(1,1,0);
  1037. opargs[O_NE] = A(1,1,0);
  1038. opargs[O_BIT_AND] = A(1,1,0);
  1039. opargs[O_XOR] = A(1,1,0);
  1040. opargs[O_BIT_OR] = A(1,1,0);
  1041. opargs[O_AND] = A(1,0,0); /* don't eval arg 2 (yet) */
  1042. opargs[O_OR] = A(1,0,0); /* don't eval arg 2 (yet) */
  1043. opargs[O_COND_EXPR] = A(1,0,0); /* don't eval args 2 or 3 */
  1044. opargs[O_COMMA] = A(1,1,0);
  1045. opargs[O_NEGATE] = A(1,0,0);
  1046. opargs[O_NOT] = A(1,0,0);
  1047. opargs[O_COMPLEMENT] = A(1,0,0);
  1048. opargs[O_WRITE] = A(1,0,0);
  1049. opargs[O_OPEN] = A(1,1,0);
  1050. opargs[O_TRANS] = A(1,0,0);
  1051. opargs[O_NTRANS] = A(1,0,0);
  1052. opargs[O_CLOSE] = A(0,0,0);
  1053. opargs[O_ARRAY] = A(1,0,0);
  1054. opargs[O_HASH] = A(1,0,0);
  1055. opargs[O_LARRAY] = A(1,0,0);
  1056. opargs[O_LHASH] = A(1,0,0);
  1057. opargs[O_PUSH] = A(1,0,0);
  1058. opargs[O_POP] = A(0,0,0);
  1059. opargs[O_SHIFT] = A(0,0,0);
  1060. opargs[O_SPLIT] = A(1,0,0);
  1061. opargs[O_LENGTH] = A(1,0,0);
  1062. opargs[O_SPRINTF] = A(1,0,0);
  1063. opargs[O_SUBSTR] = A(1,1,1);
  1064. opargs[O_JOIN] = A(1,0,0);
  1065. opargs[O_SLT] = A(1,1,0);
  1066. opargs[O_SGT] = A(1,1,0);
  1067. opargs[O_SLE] = A(1,1,0);
  1068. opargs[O_SGE] = A(1,1,0);
  1069. opargs[O_SEQ] = A(1,1,0);
  1070. opargs[O_SNE] = A(1,1,0);
  1071. opargs[O_SUBR] = A(1,0,0);
  1072. opargs[O_PRINT] = A(1,0,0);
  1073. opargs[O_CHDIR] = A(1,0,0);
  1074. opargs[O_DIE] = A(1,0,0);
  1075. opargs[O_EXIT] = A(1,0,0);
  1076. opargs[O_RESET] = A(1,0,0);
  1077. opargs[O_LIST] = A(0,0,0);
  1078. opargs[O_EOF] = A(0,0,0);
  1079. opargs[O_TELL] = A(0,0,0);
  1080. opargs[O_SEEK] = A(0,1,1);
  1081. opargs[O_LAST] = A(1,0,0);
  1082. opargs[O_NEXT] = A(1,0,0);
  1083. opargs[O_REDO] = A(1,0,0);
  1084. opargs[O_GOTO] = A(1,0,0);
  1085. opargs[O_INDEX] = A(1,1,0);
  1086. opargs[O_TIME] = A(0,0,0);
  1087. opargs[O_TMS] = A(0,0,0);
  1088. opargs[O_LOCALTIME] = A(1,0,0);
  1089. opargs[O_GMTIME] = A(1,0,0);
  1090. opargs[O_STAT] = A(1,0,0);
  1091. opargs[O_CRYPT] = A(1,1,0);
  1092. opargs[O_EXP] = A(1,0,0);
  1093. opargs[O_LOG] = A(1,0,0);
  1094. opargs[O_SQRT] = A(1,0,0);
  1095. opargs[O_INT] = A(1,0,0);
  1096. opargs[O_PRTF] = A(1,0,0);
  1097. opargs[O_ORD] = A(1,0,0);
  1098. opargs[O_SLEEP] = A(1,0,0);
  1099. opargs[O_FLIP] = A(1,0,0);
  1100. opargs[O_FLOP] = A(0,1,0);
  1101. opargs[O_KEYS] = A(0,0,0);
  1102. opargs[O_VALUES] = A(0,0,0);
  1103. opargs[O_EACH] = A(0,0,0);
  1104. opargs[O_CHOP] = A(1,0,0);
  1105. opargs[O_FORK] = A(1,0,0);
  1106. opargs[O_EXEC] = A(1,0,0);
  1107. opargs[O_SYSTEM] = A(1,0,0);
  1108. opargs[O_OCT] = A(1,0,0);
  1109. opargs[O_HEX] = A(1,0,0);
  1110. opargs[O_CHMOD] = A(1,0,0);
  1111. opargs[O_CHOWN] = A(1,0,0);
  1112. opargs[O_KILL] = A(1,0,0);
  1113. opargs[O_RENAME] = A(1,1,0);
  1114. opargs[O_UNLINK] = A(1,0,0);
  1115. opargs[O_UMASK] = A(1,0,0);
  1116. opargs[O_UNSHIFT] = A(1,0,0);
  1117. opargs[O_LINK] = A(1,1,0);
  1118. opargs[O_REPEAT] = A(1,1,0);
  1119. opargs[O_EVAL] = A(1,0,0);
  1120. }
  1121. #ifdef VOIDSIG
  1122. static void (*ihand)();
  1123. static void (*qhand)();
  1124. #else
  1125. static int (*ihand)();
  1126. static int (*qhand)();
  1127. #endif
  1128. STR *
  1129. eval(arg,retary)
  1130. register ARG *arg;
  1131. STR ***retary; /* where to return an array to, null if nowhere */
  1132. {
  1133. register STR *str;
  1134. register int anum;
  1135. register int optype;
  1136. register int maxarg;
  1137. double value;
  1138. STR *quicksarg[5];
  1139. register STR **sarg = quicksarg;
  1140. register char *tmps;
  1141. char *tmps2;
  1142. int argflags;
  1143. long tmplong;
  1144. FILE *fp;
  1145. STR *tmpstr;
  1146. FCMD *form;
  1147. STAB *stab;
  1148. ARRAY *ary;
  1149. bool assigning = FALSE;
  1150. double exp(), log(), sqrt(), modf();
  1151. char *crypt(), *getenv();
  1152. if (!arg)
  1153. return &str_no;
  1154. str = arg->arg_ptr.arg_str;
  1155. optype = arg->arg_type;
  1156. maxarg = arg->arg_len;
  1157. if (maxarg > 3 || retary) {
  1158. sarg = (STR **)safemalloc((maxarg+2) * sizeof(STR*));
  1159. }
  1160. #ifdef DEBUGGING
  1161. if (debug & 8) {
  1162. deb("%s (%lx) %d args:\n",opname[optype],arg,maxarg);
  1163. }
  1164. debname[dlevel] = opname[optype][0];
  1165. debdelim[dlevel++] = ':';
  1166. #endif
  1167. for (anum = 1; anum <= maxarg; anum++) {
  1168. argflags = arg[anum].arg_flags;
  1169. if (argflags & AF_SPECIAL)
  1170. continue;
  1171. re_eval:
  1172. switch (arg[anum].arg_type) {
  1173. default:
  1174. sarg[anum] = &str_no;
  1175. #ifdef DEBUGGING
  1176. tmps = "NULL";
  1177. #endif
  1178. break;
  1179. case A_EXPR:
  1180. #ifdef DEBUGGING
  1181. if (debug & 8) {
  1182. tmps = "EXPR";
  1183. deb("%d.EXPR =>\n",anum);
  1184. }
  1185. #endif
  1186. sarg[anum] = eval(arg[anum].arg_ptr.arg_arg, Null(STR***));
  1187. break;
  1188. case A_CMD:
  1189. #ifdef DEBUGGING
  1190. if (debug & 8) {
  1191. tmps = "CMD";
  1192. deb("%d.CMD (%lx) =>\n",anum,arg[anum].arg_ptr.arg_cmd);
  1193. }
  1194. #endif
  1195. sarg[anum] = cmd_exec(arg[anum].arg_ptr.arg_cmd);
  1196. break;
  1197. case A_STAB:
  1198. sarg[anum] = STAB_STR(arg[anum].arg_ptr.arg_stab);
  1199. #ifdef DEBUGGING
  1200. if (debug & 8) {
  1201. sprintf(buf,"STAB $%s ==",arg[anum].arg_ptr.arg_stab->stab_name);
  1202. tmps = buf;
  1203. }
  1204. #endif
  1205. break;
  1206. case A_LEXPR:
  1207. #ifdef DEBUGGING
  1208. if (debug & 8) {
  1209. tmps = "LEXPR";
  1210. deb("%d.LEXPR =>\n",anum);
  1211. }
  1212. #endif
  1213. str = eval(arg[anum].arg_ptr.arg_arg,Null(STR***));
  1214. if (!str)
  1215. fatal("panic: A_LEXPR\n");
  1216. goto do_crement;
  1217. case A_LVAL:
  1218. #ifdef DEBUGGING
  1219. if (debug & 8) {
  1220. sprintf(buf,"LVAL $%s ==",arg[anum].arg_ptr.arg_stab->stab_name);
  1221. tmps = buf;
  1222. }
  1223. #endif
  1224. str = STAB_STR(arg[anum].arg_ptr.arg_stab);
  1225. if (!str)
  1226. fatal("panic: A_LVAL\n");
  1227. do_crement:
  1228. assigning = TRUE;
  1229. if (argflags & AF_PRE) {
  1230. if (argflags & AF_UP)
  1231. str_inc(str);
  1232. else
  1233. str_dec(str);
  1234. STABSET(str);
  1235. sarg[anum] = str;
  1236. str = arg->arg_ptr.arg_str;
  1237. }
  1238. else if (argflags & AF_POST) {
  1239. sarg[anum] = str_static(str);
  1240. if (argflags & AF_UP)
  1241. str_inc(str);
  1242. else
  1243. str_dec(str);
  1244. STABSET(str);
  1245. str = arg->arg_ptr.arg_str;
  1246. }
  1247. else {
  1248. sarg[anum] = str;
  1249. }
  1250. break;
  1251. case A_ARYLEN:
  1252. sarg[anum] = str_static(&str_no);
  1253. str_numset(sarg[anum],
  1254. (double)alen(arg[anum].arg_ptr.arg_stab->stab_array));
  1255. #ifdef DEBUGGING
  1256. tmps = "ARYLEN";
  1257. #endif
  1258. break;
  1259. case A_SINGLE:
  1260. sarg[anum] = arg[anum].arg_ptr.arg_str;
  1261. #ifdef DEBUGGING
  1262. tmps = "SINGLE";
  1263. #endif
  1264. break;
  1265. case A_DOUBLE:
  1266. (void) interp(str,str_get(arg[anum].arg_ptr.arg_str));
  1267. sarg[anum] = str;
  1268. #ifdef DEBUGGING
  1269. tmps = "DOUBLE";
  1270. #endif
  1271. break;
  1272. case A_BACKTICK:
  1273. tmps = str_get(arg[anum].arg_ptr.arg_str);
  1274. fp = popen(str_get(interp(str,tmps)),"r");
  1275. tmpstr = str_new(80);
  1276. str_set(str,"");
  1277. if (fp) {
  1278. while (str_gets(tmpstr,fp) != Nullch) {
  1279. str_scat(str,tmpstr);
  1280. }
  1281. statusvalue = pclose(fp);
  1282. }
  1283. else
  1284. statusvalue = -1;
  1285. str_free(tmpstr);
  1286. sarg[anum] = str;
  1287. #ifdef DEBUGGING
  1288. tmps = "BACK";
  1289. #endif
  1290. break;
  1291. case A_READ:
  1292. fp = Nullfp;
  1293. last_in_stab = arg[anum].arg_ptr.arg_stab;
  1294. if (last_in_stab->stab_io) {
  1295. fp = last_in_stab->stab_io->fp;
  1296. if (!fp && (last_in_stab->stab_io->flags & IOF_ARGV)) {
  1297. if (last_in_stab->stab_io->flags & IOF_START) {
  1298. last_in_stab->stab_io->flags &= ~IOF_START;
  1299. last_in_stab->stab_io->lines = 0;
  1300. if (alen(last_in_stab->stab_array) < 0L) {
  1301. tmpstr = str_make("-"); /* assume stdin */
  1302. apush(last_in_stab->stab_array, tmpstr);
  1303. }
  1304. }
  1305. fp = nextargv(last_in_stab);
  1306. if (!fp) /* Note: fp != last_in_stab->stab_io->fp */
  1307. do_close(last_in_stab,FALSE); /* now it does */
  1308. }
  1309. }
  1310. keepgoing:
  1311. if (!fp)
  1312. sarg[anum] = &str_no;
  1313. else if (!str_gets(str,fp)) {
  1314. if (last_in_stab->stab_io->flags & IOF_ARGV) {
  1315. fp = nextargv(last_in_stab);
  1316. if (fp)
  1317. goto keepgoing;
  1318. do_close(last_in_stab,FALSE);
  1319. last_in_stab->stab_io->flags |= IOF_START;
  1320. }
  1321. if (fp == stdin) {
  1322. clearerr(fp);
  1323. }
  1324. sarg[anum] = &str_no;
  1325. break;
  1326. }
  1327. else {
  1328. last_in_stab->stab_io->lines++;
  1329. sarg[anum] = str;
  1330. }
  1331. #ifdef DEBUGGING
  1332. tmps = "READ";
  1333. #endif
  1334. break;
  1335. }
  1336. #ifdef DEBUGGING
  1337. if (debug & 8)
  1338. deb("%d.%s = '%s'\n",anum,tmps,str_peek(sarg[anum]));
  1339. #endif
  1340. }
  1341. switch (optype) {
  1342. case O_ITEM:
  1343. if (str != sarg[1])
  1344. str_sset(str,sarg[1]);
  1345. STABSET(str);
  1346. break;
  1347. case O_ITEM2:
  1348. if (str != sarg[2])
  1349. str_sset(str,sarg[2]);
  1350. STABSET(str);
  1351. break;
  1352. case O_ITEM3:
  1353. if (str != sarg[3])
  1354. str_sset(str,sarg[3]);
  1355. STABSET(str);
  1356. break;
  1357. case O_CONCAT:
  1358. if (str != sarg[1])
  1359. str_sset(str,sarg[1]);
  1360. str_scat(str,sarg[2]);
  1361. STABSET(str);
  1362. break;
  1363. case O_REPEAT:
  1364. if (str != sarg[1])
  1365. str_sset(str,sarg[1]);
  1366. anum = (long)str_gnum(sarg[2]);
  1367. if (anum >= 1) {
  1368. tmpstr = str_new(0);
  1369. str_sset(tmpstr,str);
  1370. for (anum--; anum; anum--)
  1371. str_scat(str,tmpstr);
  1372. }
  1373. else
  1374. str_sset(str,&str_no);
  1375. STABSET(str);
  1376. break;
  1377. case O_MATCH:
  1378. str_set(str, do_match(str_get(sarg[1]),arg) ? Yes : No);
  1379. STABSET(str);
  1380. break;
  1381. case O_NMATCH:
  1382. str_set(str, do_match(str_get(sarg[1]),arg) ? No : Yes);
  1383. STABSET(str);
  1384. break;
  1385. case O_SUBST:
  1386. value = (double) do_subst(str, arg);
  1387. str = arg->arg_ptr.arg_str;
  1388. goto donumset;
  1389. case O_NSUBST:
  1390. str_set(arg->arg_ptr.arg_str, do_subst(str, arg) ? No : Yes);
  1391. str = arg->arg_ptr.arg_str;
  1392. break;
  1393. case O_ASSIGN:
  1394. if (arg[2].arg_flags & AF_SPECIAL)
  1395. do_assign(str,arg);
  1396. else {
  1397. if (str != sarg[2])
  1398. str_sset(str, sarg[2]);
  1399. STABSET(str);
  1400. }
  1401. break;
  1402. case O_CHOP:
  1403. tmps = str_get(str);
  1404. tmps += str->str_cur - (str->str_cur != 0);
  1405. str_set(arg->arg_ptr.arg_str,tmps); /* remember last char */
  1406. *tmps = '\0'; /* wipe it out */
  1407. str->str_cur = tmps - str->str_ptr;
  1408. str->str_nok = 0;
  1409. str = arg->arg_ptr.arg_str;
  1410. break;
  1411. case O_MULTIPLY:
  1412. value = str_gnum(sarg[1]);
  1413. value *= str_gnum(sarg[2]);
  1414. goto donumset;
  1415. case O_DIVIDE:
  1416. value = str_gnum(sarg[1]);
  1417. value /= str_gnum(sarg[2]);
  1418. goto donumset;
  1419. case O_MODULO:
  1420. value = str_gnum(sarg[1]);
  1421. value = (double)(((long)value) % (long)str_gnum(sarg[2]));
  1422. goto donumset;
  1423. case O_ADD:
  1424. value = str_gnum(sarg[1]);
  1425. value += str_gnum(sarg[2]);
  1426. goto donumset;
  1427. case O_SUBTRACT:
  1428. value = str_gnum(sarg[1]);
  1429. value -= str_gnum(sarg[2]);
  1430. goto donumset;
  1431. case O_LEFT_SHIFT:
  1432. value = str_gnum(sarg[1]);
  1433. value = (double)(((long)value) << (long)str_gnum(sarg[2]));
  1434. goto donumset;
  1435. case O_RIGHT_SHIFT:
  1436. value = str_gnum(sarg[1]);
  1437. value = (double)(((long)value) >> (long)str_gnum(sarg[2]));
  1438. goto donumset;
  1439. case O_LT:
  1440. value = str_gnum(sarg[1]);
  1441. value = (double)(value < str_gnum(sarg[2]));
  1442. goto donumset;
  1443. case O_GT:
  1444. value = str_gnum(sarg[1]);
  1445. value = (double)(value > str_gnum(sarg[2]));
  1446. goto donumset;
  1447. case O_LE:
  1448. value = str_gnum(sarg[1]);
  1449. value = (double)(value <= str_gnum(sarg[2]));
  1450. goto donumset;
  1451. case O_GE:
  1452. value = str_gnum(sarg[1]);
  1453. value = (double)(value >= str_gnum(sarg[2]));
  1454. goto donumset;
  1455. case O_EQ:
  1456. value = str_gnum(sarg[1]);
  1457. value = (double)(value == str_gnum(sarg[2]));
  1458. goto donumset;
  1459. case O_NE:
  1460. value = str_gnum(sarg[1]);
  1461. value = (double)(value != str_gnum(sarg[2]));
  1462. goto donumset;
  1463. case O_BIT_AND:
  1464. value = str_gnum(sarg[1]);
  1465. value = (double)(((long)value) & (long)str_gnum(sarg[2]));
  1466. goto donumset;
  1467. case O_XOR:
  1468. value = str_gnum(sarg[1]);
  1469. value = (double)(((long)value) ^ (long)str_gnum(sarg[2]));
  1470. goto donumset;
  1471. case O_BIT_OR:
  1472. value = str_gnum(sarg[1]);
  1473. value = (double)(((long)value) | (long)str_gnum(sarg[2]));
  1474. goto donumset;
  1475. case O_AND:
  1476. if (str_true(sarg[1])) {
  1477. anum = 2;
  1478. optype = O_ITEM2;
  1479. maxarg = 0;
  1480. argflags = arg[anum].arg_flags;
  1481. goto re_eval;
  1482. }
  1483. else {
  1484. if (assigning) {
  1485. str_sset(str, sarg[1]);
  1486. STABSET(str);
  1487. }
  1488. else
  1489. str = sarg[1];
  1490. break;
  1491. }
  1492. case O_OR:
  1493. if (str_true(sarg[1])) {
  1494. if (assigning) {
  1495. str_set(str, sarg[1]);
  1496. STABSET(str);
  1497. }
  1498. else
  1499. str = sarg[1];
  1500. break;
  1501. }
  1502. else {
  1503. anum = 2;
  1504. optype = O_ITEM2;
  1505. maxarg = 0;
  1506. argflags = arg[anum].arg_flags;
  1507. goto re_eval;
  1508. }
  1509. case O_COND_EXPR:
  1510. anum = (str_true(sarg[1]) ? 2 : 3);
  1511. optype = (anum == 2 ? O_ITEM2 : O_ITEM3);
  1512. maxarg = 0;
  1513. argflags = arg[anum].arg_flags;
  1514. goto re_eval;
  1515. case O_COMMA:
  1516. str = sarg[2];
  1517. break;
  1518. case O_NEGATE:
  1519. value = -str_gnum(sarg[1]);
  1520. goto donumset;
  1521. case O_NOT:
  1522. value = (double) !str_true(sarg[1]);
  1523. goto donumset;
  1524. case O_COMPLEMENT:
  1525. value = (double) ~(long)str_gnum(sarg[1]);
  1526. goto donumset;
  1527. case O_SELECT:
  1528. if (arg[1].arg_type == A_LVAL)
  1529. defoutstab = arg[1].arg_ptr.arg_stab;
  1530. else
  1531. defoutstab = stabent(str_get(sarg[1]),TRUE);
  1532. if (!defoutstab->stab_io)
  1533. defoutstab->stab_io = stio_new();
  1534. curoutstab = defoutstab;
  1535. str_set(str,curoutstab->stab_io->fp ? Yes : No);
  1536. STABSET(str);
  1537. break;
  1538. case O_WRITE:
  1539. if (maxarg == 0)
  1540. stab = defoutstab;
  1541. else if (arg[1].arg_type == A_LVAL)
  1542. stab = arg[1].arg_ptr.arg_stab;
  1543. else
  1544. stab = stabent(str_get(sarg[1]),TRUE);
  1545. if (!stab->stab_io) {
  1546. str_set(str, No);
  1547. STABSET(str);
  1548. break;
  1549. }
  1550. curoutstab = stab;
  1551. fp = stab->stab_io->fp;
  1552. debarg = arg;
  1553. if (stab->stab_io->fmt_stab)
  1554. form = stab->stab_io->fmt_stab->stab_form;
  1555. else
  1556. form = stab->stab_form;
  1557. if (!form || !fp) {
  1558. str_set(str, No);
  1559. STABSET(str);
  1560. break;
  1561. }
  1562. format(&outrec,form);
  1563. do_write(&outrec,stab->stab_io);
  1564. if (stab->stab_io->flags & IOF_FLUSH)
  1565. fflush(fp);
  1566. str_set(str, Yes);
  1567. STABSET(str);
  1568. break;
  1569. case O_OPEN:
  1570. if (do_open(arg[1].arg_ptr.arg_stab,str_get(sarg[2]))) {
  1571. str_set(str, Yes);
  1572. arg[1].arg_ptr.arg_stab->stab_io->lines = 0;
  1573. }
  1574. else
  1575. str_set(str, No);
  1576. STABSET(str);
  1577. break;
  1578. case O_TRANS:
  1579. value = (double) do_trans(str,arg);
  1580. str = arg->arg_ptr.arg_str;
  1581. goto donumset;
  1582. case O_NTRANS:
  1583. str_set(arg->arg_ptr.arg_str, do_trans(str,arg) == 0 ? Yes : No);
  1584. str = arg->arg_ptr.arg_str;
  1585. break;
  1586. case O_CLOSE:
  1587. str_set(str,
  1588. do_close(arg[1].arg_ptr.arg_stab,TRUE) ? Yes : No );
  1589. STABSET(str);
  1590. break;
  1591. case O_EACH:
  1592. str_sset(str,do_each(arg[1].arg_ptr.arg_stab->stab_hash,sarg,retary));
  1593. retary = Null(STR***); /* do_each already did retary */
  1594. STABSET(str);
  1595. break;
  1596. case O_VALUES:
  1597. case O_KEYS:
  1598. value = (double) do_kv(arg[1].arg_ptr.arg_stab->stab_hash,
  1599. optype,sarg,retary);
  1600. retary = Null(STR***); /* do_keys already did retary */
  1601. goto donumset;
  1602. case O_ARRAY:
  1603. if (maxarg == 1) {
  1604. ary = arg[1].arg_ptr.arg_stab->stab_array;
  1605. maxarg = ary->ary_fill;
  1606. if (retary) { /* array wanted */
  1607. sarg =
  1608. (STR **)saferealloc((char*)sarg,(maxarg+3)*sizeof(STR*));
  1609. for (anum = 0; anum <= maxarg; anum++) {
  1610. sarg[anum+1] = str = afetch(ary,anum);
  1611. }
  1612. maxarg++;
  1613. }
  1614. else
  1615. str = afetch(ary,maxarg);
  1616. }
  1617. else
  1618. str = afetch(arg[2].arg_ptr.arg_stab->stab_array,
  1619. ((int)str_gnum(sarg[1])) - arybase);
  1620. if (!str)
  1621. return &str_no;
  1622. break;
  1623. case O_HASH:
  1624. tmpstab = arg[2].arg_ptr.arg_stab; /* XXX */
  1625. str = hfetch(tmpstab->stab_hash,str_get(sarg[1]));
  1626. if (!str)
  1627. return &str_no;
  1628. break;
  1629. case O_LARRAY:
  1630. anum = ((int)str_gnum(sarg[1])) - arybase;
  1631. str = afetch(arg[2].arg_ptr.arg_stab->stab_array,anum);
  1632. if (!str || str == &str_no) {
  1633. str = str_new(0);
  1634. astore(arg[2].arg_ptr.arg_stab->stab_array,anum,str);
  1635. }
  1636. break;
  1637. case O_LHASH:
  1638. tmpstab = arg[2].arg_ptr.arg_stab;
  1639. str = hfetch(tmpstab->stab_hash,str_get(sarg[1]));
  1640. if (!str) {
  1641. str = str_new(0);
  1642. hstore(tmpstab->stab_hash,str_get(sarg[1]),str);
  1643. }
  1644. if (tmpstab == envstab) { /* heavy wizardry going on here */
  1645. str->str_link.str_magic = tmpstab;/* str is now magic */
  1646. envname = savestr(str_get(sarg[1]));
  1647. /* he threw the brick up into the air */
  1648. }
  1649. else if (tmpstab == sigstab) { /* same thing, only different */
  1650. str->str_link.str_magic = tmpstab;
  1651. signame = savestr(str_get(sarg[1]));
  1652. }
  1653. break;
  1654. case O_PUSH:
  1655. if (arg[1].arg_flags & AF_SPECIAL)
  1656. str = do_push(arg,arg[2].arg_ptr.arg_stab->stab_array);
  1657. else {
  1658. str = str_new(0); /* must copy the STR */
  1659. str_sset(str,sarg[1]);
  1660. apush(arg[2].arg_ptr.arg_stab->stab_array,str);
  1661. }
  1662. break;
  1663. case O_POP:
  1664. str = apop(arg[1].arg_ptr.arg_stab->stab_array);
  1665. if (!str)
  1666. return &str_no;
  1667. #ifdef STRUCTCOPY
  1668. *(arg->arg_ptr.arg_str) = *str;
  1669. #else
  1670. bcopy((char*)str, (char*)arg->arg_ptr.arg_str, sizeof *str);
  1671. #endif
  1672. safefree((char*)str);
  1673. str = arg->arg_ptr.arg_str;
  1674. break;
  1675. case O_SHIFT:
  1676. str = ashift(arg[1].arg_ptr.arg_stab->stab_array);
  1677. if (!str)
  1678. return &str_no;
  1679. #ifdef STRUCTCOPY
  1680. *(arg->arg_ptr.arg_str) = *str;
  1681. #else
  1682. bcopy((char*)str, (char*)arg->arg_ptr.arg_str, sizeof *str);
  1683. #endif
  1684. safefree((char*)str);
  1685. str = arg->arg_ptr.arg_str;
  1686. break;
  1687. case O_SPLIT:
  1688. value = (double) do_split(str_get(sarg[1]),arg[2].arg_ptr.arg_spat,retary);
  1689. retary = Null(STR***); /* do_split already did retary */
  1690. goto donumset;
  1691. case O_LENGTH:
  1692. value = (double) str_len(sarg[1]);
  1693. goto donumset;
  1694. case O_SPRINTF:
  1695. sarg[maxarg+1] = Nullstr;
  1696. do_sprintf(str,arg->arg_len,sarg);
  1697. break;
  1698. case O_SUBSTR:
  1699. anum = ((int)str_gnum(sarg[2])) - arybase;
  1700. for (tmps = str_get(sarg[1]); *tmps && anum > 0; tmps++,anum--) ;
  1701. anum = (int)str_gnum(sarg[3]);
  1702. if (anum >= 0 && strlen(tmps) > anum)
  1703. str_nset(str, tmps, anum);
  1704. else
  1705. str_set(str, tmps);
  1706. break;
  1707. case O_JOIN:
  1708. if (arg[2].arg_flags & AF_SPECIAL && arg[2].arg_type == A_EXPR)
  1709. do_join(arg,str_get(sarg[1]),str);
  1710. else
  1711. ajoin(arg[2].arg_ptr.arg_stab->stab_array,str_get(sarg[1]),str);
  1712. break;
  1713. case O_SLT:
  1714. tmps = str_get(sarg[1]);
  1715. value = (double) strLT(tmps,str_get(sarg[2]));
  1716. goto donumset;
  1717. case O_SGT:
  1718. tmps = str_get(sarg[1]);
  1719. value = (double) strGT(tmps,str_get(sarg[2]));
  1720. goto donumset;
  1721. case O_SLE:
  1722. tmps = str_get(sarg[1]);
  1723. value = (double) strLE(tmps,str_get(sarg[2]));
  1724. goto donumset;
  1725. case O_SGE:
  1726. tmps = str_get(sarg[1]);
  1727. value = (double) strGE(tmps,str_get(sarg[2]));
  1728. goto donumset;
  1729. case O_SEQ:
  1730. tmps = str_get(sarg[1]);
  1731. value = (double) strEQ(tmps,str_get(sarg[2]));
  1732. goto donumset;
  1733. case O_SNE:
  1734. tmps = str_get(sarg[1]);
  1735. value = (double) strNE(tmps,str_get(sarg[2]));
  1736. goto donumset;
  1737. case O_SUBR:
  1738. str_sset(str,do_subr(arg,sarg));
  1739. STABSET(str);
  1740. break;
  1741. case O_PRTF:
  1742. case O_PRINT:
  1743. if (maxarg <= 1)
  1744. stab = defoutstab;
  1745. else {
  1746. stab = arg[2].arg_ptr.arg_stab;
  1747. if (!stab)
  1748. stab = defoutstab;
  1749. }
  1750. if (!stab->stab_io)
  1751. value = 0.0;
  1752. else if (arg[1].arg_flags & AF_SPECIAL)
  1753. value = (double)do_aprint(arg,stab->stab_io->fp);
  1754. else {
  1755. value = (double)do_print(str_get(sarg[1]),stab->stab_io->fp);
  1756. if (ors && optype == O_PRINT)
  1757. do_print(ors, stab->stab_io->fp);
  1758. }
  1759. if (stab->stab_io->flags & IOF_FLUSH)
  1760. fflush(stab->stab_io->fp);
  1761. goto donumset;
  1762. case O_CHDIR:
  1763. tmps = str_get(sarg[1]);
  1764. if (!tmps || !*tmps)
  1765. tmps = getenv("HOME");
  1766. if (!tmps || !*tmps)
  1767. tmps = getenv("LOGDIR");
  1768. value = (double)(chdir(tmps) >= 0);
  1769. goto donumset;
  1770. case O_DIE:
  1771. tmps = str_get(sarg[1]);
  1772. if (!tmps || !*tmps)
  1773. exit(1);
  1774. fatal("%s\n",str_get(sarg[1]));
  1775. value = 0.0;
  1776. goto donumset;
  1777. case O_EXIT:
  1778. exit((int)str_gnum(sarg[1]));
  1779. value = 0.0;
  1780. goto donumset;
  1781. case O_RESET:
  1782. str_reset(str_get(sarg[1]));
  1783. value = 1.0;
  1784. goto donumset;
  1785. case O_LIST:
  1786. if (maxarg > 0)
  1787. str = sarg[maxarg]; /* unwanted list, return last item */
  1788. else
  1789. str = &str_no;
  1790. break;
  1791. case O_EOF:
  1792. str_set(str, do_eof(maxarg > 0 ? arg[1].arg_ptr.arg_stab : last_in_stab) ? Yes : No);
  1793. STABSET(str);
  1794. break;
  1795. case O_TELL:
  1796. value = (double)do_tell(maxarg > 0 ? arg[1].arg_ptr.arg_stab : last_in_stab);
  1797. goto donumset;
  1798. break;
  1799. case O_SEEK:
  1800. value = str_gnum(sarg[2]);
  1801. str_set(str, do_seek(arg[1].arg_ptr.arg_stab,
  1802. (long)value, (int)str_gnum(sarg[3]) ) ? Yes : No);
  1803. STABSET(str);
  1804. break;
  1805. case O_REDO:
  1806. case O_NEXT:
  1807. case O_LAST:
  1808. if (maxarg > 0) {
  1809. tmps = str_get(sarg[1]);
  1810. while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
  1811. strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
  1812. #ifdef DEBUGGING
  1813. if (debug & 4) {
  1814. deb("(Skipping label #%d %s)\n",loop_ptr,
  1815. loop_stack[loop_ptr].loop_label);
  1816. }
  1817. #endif
  1818. loop_ptr--;
  1819. }
  1820. #ifdef DEBUGGING
  1821. if (debug & 4) {
  1822. deb("(Found label #%d %s)\n",loop_ptr,
  1823. loop_stack[loop_ptr].loop_label);
  1824. }
  1825. #endif
  1826. }
  1827. if (loop_ptr < 0)
  1828. fatal("Bad label: %s\n", maxarg > 0 ? tmps : "<null>");
  1829. longjmp(loop_stack[loop_ptr].loop_env, optype);
  1830. case O_GOTO:/* shudder */
  1831. goto_targ = str_get(sarg[1]);
  1832. longjmp(top_env, 1);
  1833. case O_INDEX:
  1834. tmps = str_get(sarg[1]);
  1835. if (!(tmps2 = instr(tmps,str_get(sarg[2]))))
  1836. value = (double)(-1 + arybase);
  1837. else
  1838. value = (double)(tmps2 - tmps + arybase);
  1839. goto donumset;
  1840. case O_TIME:
  1841. value = (double) time(0);
  1842. goto donumset;
  1843. case O_TMS:
  1844. value = (double) do_tms(retary);
  1845. retary = Null(STR***); /* do_tms already did retary */
  1846. goto donumset;
  1847. case O_LOCALTIME:
  1848. tmplong = (long) str_gnum(sarg[1]);
  1849. value = (double) do_time(localtime(&tmplong),retary);
  1850. retary = Null(STR***); /* do_localtime already did retary */
  1851. goto donumset;
  1852. case O_GMTIME:
  1853. tmplong = (long) str_gnum(sarg[1]);
  1854. value = (double) do_time(gmtime(&tmplong),retary);
  1855. retary = Null(STR***); /* do_gmtime already did retary */
  1856. goto donumset;
  1857. case O_STAT:
  1858. value = (double) do_stat(arg,sarg,retary);
  1859. retary = Null(STR***); /* do_stat already did retary */
  1860. goto donumset;
  1861. case O_CRYPT:
  1862. tmps = str_get(sarg[1]);
  1863. str_set(str,crypt(tmps,str_get(sarg[2])));
  1864. break;
  1865. case O_EXP:
  1866. value = exp(str_gnum(sarg[1]));
  1867. goto donumset;
  1868. case O_LOG:
  1869. value = log(str_gnum(sarg[1]));
  1870. goto donumset;
  1871. case O_SQRT:
  1872. value = sqrt(str_gnum(sarg[1]));
  1873. goto donumset;
  1874. case O_INT:
  1875. modf(str_gnum(sarg[1]),&value);
  1876. goto donumset;
  1877. case O_ORD:
  1878. value = (double) *str_get(sarg[1]);
  1879. goto donumset;
  1880. case O_SLEEP:
  1881. tmps = str_get(sarg[1]);
  1882. time(&tmplong);
  1883. if (!tmps || !*tmps)
  1884. sleep((32767<<16)+32767);
  1885. else
  1886. sleep(atoi(tmps));
  1887. value = (double)tmplong;
  1888. time(&tmplong);
  1889. value = ((double)tmplong) - value;
  1890. goto donumset;
  1891. case O_FLIP:
  1892. if (str_true(sarg[1])) {
  1893. str_numset(str,0.0);
  1894. anum = 2;
  1895. arg->arg_type = optype = O_FLOP;
  1896. maxarg = 0;
  1897. arg[2].arg_flags &= ~AF_SPECIAL;
  1898. arg[1].arg_flags |= AF_SPECIAL;
  1899. argflags = arg[anum].arg_flags;
  1900. goto re_eval;
  1901. }
  1902. str_set(str,"");
  1903. break;
  1904. case O_FLOP:
  1905. str_inc(str);
  1906. if (str_true(sarg[2])) {
  1907. arg->arg_type = O_FLIP;
  1908. arg[1].arg_flags &= ~AF_SPECIAL;
  1909. arg[2].arg_flags |= AF_SPECIAL;
  1910. str_cat(str,"E0");
  1911. }
  1912. break;
  1913. case O_FORK:
  1914. value = (double)fork();
  1915. goto donumset;
  1916. case O_SYSTEM:
  1917. if (anum = vfork()) {
  1918. ihand = signal(SIGINT, SIG_IGN);
  1919. qhand = signal(SIGQUIT, SIG_IGN);
  1920. while ((maxarg = wait(&argflags)) != anum && maxarg != -1)
  1921. ;
  1922. if (maxarg == -1)
  1923. argflags = -1;
  1924. signal(SIGINT, ihand);
  1925. signal(SIGQUIT, qhand);
  1926. value = (double)argflags;
  1927. goto donumset;
  1928. }
  1929. /* FALL THROUGH */
  1930. case O_EXEC:
  1931. if (arg[1].arg_flags & AF_SPECIAL)
  1932. value = (double)do_aexec(arg);
  1933. else {
  1934. value = (double)do_exec(str_get(sarg[1]));
  1935. }
  1936. goto donumset;
  1937. case O_HEX:
  1938. maxarg = 4;
  1939. goto snarfnum;
  1940. case O_OCT:
  1941. maxarg = 3;
  1942. snarfnum:
  1943. anum = 0;
  1944. tmps = str_get(sarg[1]);
  1945. for (;;) {
  1946. switch (*tmps) {
  1947. default:
  1948. goto out;
  1949. case '8': case '9':
  1950. if (maxarg != 4)
  1951. goto out;
  1952. /* FALL THROUGH */
  1953. case '0': case '1': case '2': case '3': case '4':
  1954. case '5': case '6': case '7':
  1955. anum <<= maxarg;
  1956. anum += *tmps++ & 15;
  1957. break;
  1958. case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
  1959. case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
  1960. if (maxarg != 4)
  1961. goto out;
  1962. anum <<= 4;
  1963. anum += (*tmps++ & 7) + 9;
  1964. break;
  1965. case 'x':
  1966. maxarg = 4;
  1967. tmps++;
  1968. break;
  1969. }
  1970. }
  1971. out:
  1972. value = (double)anum;
  1973. goto donumset;
  1974. case O_CHMOD:
  1975. case O_CHOWN:
  1976. case O_KILL:
  1977. case O_UNLINK:
  1978. if (arg[1].arg_flags & AF_SPECIAL)
  1979. value = (double)apply(optype,arg,Null(STR**));
  1980. else {
  1981. sarg[2] = Nullstr;
  1982. value = (double)apply(optype,arg,sarg);
  1983. }
  1984. goto donumset;
  1985. case O_UMASK:
  1986. value = (double)umask((int)str_gnum(sarg[1]));
  1987. goto donumset;
  1988. case O_RENAME:
  1989. tmps = str_get(sarg[1]);
  1990. #ifdef RENAME
  1991. value = (double)(rename(tmps,str_get(sarg[2])) >= 0);
  1992. #else
  1993. tmps2 = str_get(sarg[2]);
  1994. UNLINK(tmps2);
  1995. if (!(anum = link(tmps,tmps2)))
  1996. anum = UNLINK(tmps);
  1997. value = (double)(anum >= 0);
  1998. #endif
  1999. goto donumset;
  2000. case O_LINK:
  2001. tmps = str_get(sarg[1]);
  2002. value = (double)(link(tmps,str_get(sarg[2])) >= 0);
  2003. goto donumset;
  2004. case O_UNSHIFT:
  2005. ary = arg[2].arg_ptr.arg_stab->stab_array;
  2006. if (arg[1].arg_flags & AF_SPECIAL)
  2007. do_unshift(arg,ary);
  2008. else {
  2009. str = str_new(0); /* must copy the STR */
  2010. str_sset(str,sarg[1]);
  2011. aunshift(ary,1);
  2012. astore(ary,0,str);
  2013. }
  2014. value = (double)(ary->ary_fill + 1);
  2015. break;
  2016. case O_EVAL:
  2017. str_sset(str,
  2018. do_eval(arg[1].arg_type != A_NULL ? sarg[1] : defstab->stab_val) );
  2019. STABSET(str);
  2020. break;
  2021. }
  2022. #ifdef DEBUGGING
  2023. dlevel--;
  2024. if (debug & 8)
  2025. deb("%s RETURNS \"%s\"\n",opname[optype],str_get(str));
  2026. #endif
  2027. goto freeargs;
  2028. donumset:
  2029. str_numset(str,value);
  2030. STABSET(str);
  2031. #ifdef DEBUGGING
  2032. dlevel--;
  2033. if (debug & 8)
  2034. deb("%s RETURNS \"%f\"\n",opname[optype],value);
  2035. #endif
  2036. freeargs:
  2037. if (sarg != quicksarg) {
  2038. if (retary) {
  2039. if (optype == O_LIST)
  2040. sarg[0] = &str_no;
  2041. else
  2042. sarg[0] = Nullstr;
  2043. sarg[maxarg+1] = Nullstr;
  2044. *retary = sarg; /* up to them to free it */
  2045. }
  2046. else
  2047. safefree(sarg);
  2048. }
  2049. return str;
  2050. nullarray:
  2051. maxarg = 0;
  2052. #ifdef DEBUGGING
  2053. dlevel--;
  2054. if (debug & 8)
  2055. deb("%s RETURNS ()\n",opname[optype],value);
  2056. #endif
  2057. goto freeargs;
  2058. }