fmt.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. #include "f2c.h"
  2. #include "fio.h"
  3. #include "fmt.h"
  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif
  7. #define skip(s) while(*s==' ') s++
  8. #ifdef interdata
  9. #define SYLMX 300
  10. #endif
  11. #ifdef pdp11
  12. #define SYLMX 300
  13. #endif
  14. #ifdef vax
  15. #define SYLMX 300
  16. #endif
  17. #ifndef SYLMX
  18. #define SYLMX 300
  19. #endif
  20. #define GLITCH '\2'
  21. /* special quote character for stu */
  22. extern flag f__cblank,f__cplus; /*blanks in I and compulsory plus*/
  23. static struct syl f__syl[SYLMX];
  24. int f__parenlvl,f__pc,f__revloc;
  25. #ifdef KR_headers
  26. #define Const /*nothing*/
  27. #else
  28. #define Const const
  29. #endif
  30. static
  31. #ifdef KR_headers
  32. char *ap_end(s) char *s;
  33. #else
  34. const char *ap_end(const char *s)
  35. #endif
  36. { char quote;
  37. quote= *s++;
  38. for(;*s;s++)
  39. { if(*s!=quote) continue;
  40. if(*++s!=quote) return(s);
  41. }
  42. if(f__elist->cierr) {
  43. errno = 100;
  44. return(NULL);
  45. }
  46. f__fatal(100, "bad string");
  47. /*NOTREACHED*/ return 0;
  48. }
  49. static int
  50. #ifdef KR_headers
  51. op_gen(a,b,c,d)
  52. #else
  53. op_gen(int a, int b, int c, int d)
  54. #endif
  55. { struct syl *p= &f__syl[f__pc];
  56. if(f__pc>=SYLMX)
  57. { fprintf(stderr,"format too complicated:\n");
  58. sig_die(f__fmtbuf, 1);
  59. }
  60. p->op=a;
  61. p->p1=b;
  62. p->p2.i[0]=c;
  63. p->p2.i[1]=d;
  64. return(f__pc++);
  65. }
  66. #ifdef KR_headers
  67. static char *f_list();
  68. static char *gt_num(s,n,n1) char *s; int *n, n1;
  69. #else
  70. static const char *f_list(const char*);
  71. static const char *gt_num(const char *s, int *n, int n1)
  72. #endif
  73. { int m=0,f__cnt=0;
  74. char c;
  75. for(c= *s;;c = *s)
  76. { if(c==' ')
  77. { s++;
  78. continue;
  79. }
  80. if(c>'9' || c<'0') break;
  81. m=10*m+c-'0';
  82. f__cnt++;
  83. s++;
  84. }
  85. if(f__cnt==0) {
  86. if (!n1)
  87. s = 0;
  88. *n=n1;
  89. }
  90. else *n=m;
  91. return(s);
  92. }
  93. static
  94. #ifdef KR_headers
  95. char *f_s(s,curloc) char *s;
  96. #else
  97. const char *f_s(const char *s, int curloc)
  98. #endif
  99. {
  100. skip(s);
  101. if(*s++!='(')
  102. {
  103. return(NULL);
  104. }
  105. if(f__parenlvl++ ==1) f__revloc=curloc;
  106. if(op_gen(RET1,curloc,0,0)<0 ||
  107. (s=f_list(s))==NULL)
  108. {
  109. return(NULL);
  110. }
  111. skip(s);
  112. return(s);
  113. }
  114. static int
  115. #ifdef KR_headers
  116. ne_d(s,p) char *s,**p;
  117. #else
  118. ne_d(const char *s, const char **p)
  119. #endif
  120. { int n,x,sign=0;
  121. struct syl *sp;
  122. switch(*s)
  123. {
  124. default:
  125. return(0);
  126. case ':': (void) op_gen(COLON,0,0,0); break;
  127. case '$':
  128. (void) op_gen(NONL, 0, 0, 0); break;
  129. case 'B':
  130. case 'b':
  131. if(*++s=='z' || *s == 'Z') (void) op_gen(BZ,0,0,0);
  132. else (void) op_gen(BN,0,0,0);
  133. break;
  134. case 'S':
  135. case 's':
  136. if(*(s+1)=='s' || *(s+1) == 'S')
  137. { x=SS;
  138. s++;
  139. }
  140. else if(*(s+1)=='p' || *(s+1) == 'P')
  141. { x=SP;
  142. s++;
  143. }
  144. else x=S;
  145. (void) op_gen(x,0,0,0);
  146. break;
  147. case '/': (void) op_gen(SLASH,0,0,0); break;
  148. case '-': sign=1;
  149. case '+': s++; /*OUTRAGEOUS CODING TRICK*/
  150. case '0': case '1': case '2': case '3': case '4':
  151. case '5': case '6': case '7': case '8': case '9':
  152. if (!(s=gt_num(s,&n,0))) {
  153. bad: *p = 0;
  154. return 1;
  155. }
  156. switch(*s)
  157. {
  158. default:
  159. return(0);
  160. case 'P':
  161. case 'p': if(sign) n= -n; (void) op_gen(P,n,0,0); break;
  162. case 'X':
  163. case 'x': (void) op_gen(X,n,0,0); break;
  164. case 'H':
  165. case 'h':
  166. sp = &f__syl[op_gen(H,n,0,0)];
  167. sp->p2.s = (char*)s + 1;
  168. s+=n;
  169. break;
  170. }
  171. break;
  172. case GLITCH:
  173. case '"':
  174. case '\'':
  175. sp = &f__syl[op_gen(APOS,0,0,0)];
  176. sp->p2.s = (char*)s;
  177. if((*p = ap_end(s)) == NULL)
  178. return(0);
  179. return(1);
  180. case 'T':
  181. case 't':
  182. if(*(s+1)=='l' || *(s+1) == 'L')
  183. { x=TL;
  184. s++;
  185. }
  186. else if(*(s+1)=='r'|| *(s+1) == 'R')
  187. { x=TR;
  188. s++;
  189. }
  190. else x=T;
  191. if (!(s=gt_num(s+1,&n,0)))
  192. goto bad;
  193. s--;
  194. (void) op_gen(x,n,0,0);
  195. break;
  196. case 'X':
  197. case 'x': (void) op_gen(X,1,0,0); break;
  198. case 'P':
  199. case 'p': (void) op_gen(P,1,0,0); break;
  200. }
  201. s++;
  202. *p=s;
  203. return(1);
  204. }
  205. static int
  206. #ifdef KR_headers
  207. e_d(s,p) char *s,**p;
  208. #else
  209. e_d(const char *s, const char **p)
  210. #endif
  211. { int i,im,n,w,d,e,found=0,x=0;
  212. Const char *sv=s;
  213. s=gt_num(s,&n,1);
  214. (void) op_gen(STACK,n,0,0);
  215. switch(*s++)
  216. {
  217. default: break;
  218. case 'E':
  219. case 'e': x=1;
  220. case 'G':
  221. case 'g':
  222. found=1;
  223. if (!(s=gt_num(s,&w,0))) {
  224. bad:
  225. *p = 0;
  226. return 1;
  227. }
  228. if(w==0) break;
  229. if(*s=='.') {
  230. if (!(s=gt_num(s+1,&d,0)))
  231. goto bad;
  232. }
  233. else d=0;
  234. if(*s!='E' && *s != 'e')
  235. (void) op_gen(x==1?E:G,w,d,0); /* default is Ew.dE2 */
  236. else {
  237. if (!(s=gt_num(s+1,&e,0)))
  238. goto bad;
  239. (void) op_gen(x==1?EE:GE,w,d,e);
  240. }
  241. break;
  242. case 'O':
  243. case 'o':
  244. i = O;
  245. im = OM;
  246. goto finish_I;
  247. case 'Z':
  248. case 'z':
  249. i = Z;
  250. im = ZM;
  251. goto finish_I;
  252. case 'L':
  253. case 'l':
  254. found=1;
  255. if (!(s=gt_num(s,&w,0)))
  256. goto bad;
  257. if(w==0) break;
  258. (void) op_gen(L,w,0,0);
  259. break;
  260. case 'A':
  261. case 'a':
  262. found=1;
  263. skip(s);
  264. if(*s>='0' && *s<='9')
  265. { s=gt_num(s,&w,1);
  266. if(w==0) break;
  267. (void) op_gen(AW,w,0,0);
  268. break;
  269. }
  270. (void) op_gen(A,0,0,0);
  271. break;
  272. case 'F':
  273. case 'f':
  274. if (!(s=gt_num(s,&w,0)))
  275. goto bad;
  276. found=1;
  277. if(w==0) break;
  278. if(*s=='.') {
  279. if (!(s=gt_num(s+1,&d,0)))
  280. goto bad;
  281. }
  282. else d=0;
  283. (void) op_gen(F,w,d,0);
  284. break;
  285. case 'D':
  286. case 'd':
  287. found=1;
  288. if (!(s=gt_num(s,&w,0)))
  289. goto bad;
  290. if(w==0) break;
  291. if(*s=='.') {
  292. if (!(s=gt_num(s+1,&d,0)))
  293. goto bad;
  294. }
  295. else d=0;
  296. (void) op_gen(D,w,d,0);
  297. break;
  298. case 'I':
  299. case 'i':
  300. i = I;
  301. im = IM;
  302. finish_I:
  303. if (!(s=gt_num(s,&w,0)))
  304. goto bad;
  305. found=1;
  306. if(w==0) break;
  307. if(*s!='.')
  308. { (void) op_gen(i,w,0,0);
  309. break;
  310. }
  311. if (!(s=gt_num(s+1,&d,0)))
  312. goto bad;
  313. (void) op_gen(im,w,d,0);
  314. break;
  315. }
  316. if(found==0)
  317. { f__pc--; /*unSTACK*/
  318. *p=sv;
  319. return(0);
  320. }
  321. *p=s;
  322. return(1);
  323. }
  324. static
  325. #ifdef KR_headers
  326. char *i_tem(s) char *s;
  327. #else
  328. const char *i_tem(const char *s)
  329. #endif
  330. { const char *t;
  331. int n,curloc;
  332. if(*s==')') return(s);
  333. if(ne_d(s,&t)) return(t);
  334. if(e_d(s,&t)) return(t);
  335. s=gt_num(s,&n,1);
  336. if((curloc=op_gen(STACK,n,0,0))<0) return(NULL);
  337. return(f_s(s,curloc));
  338. }
  339. static
  340. #ifdef KR_headers
  341. char *f_list(s) char *s;
  342. #else
  343. const char *f_list(const char *s)
  344. #endif
  345. {
  346. for(;*s!=0;)
  347. { skip(s);
  348. if((s=i_tem(s))==NULL) return(NULL);
  349. skip(s);
  350. if(*s==',') s++;
  351. else if(*s==')')
  352. { if(--f__parenlvl==0)
  353. {
  354. (void) op_gen(REVERT,f__revloc,0,0);
  355. return(++s);
  356. }
  357. (void) op_gen(GOTO,0,0,0);
  358. return(++s);
  359. }
  360. }
  361. return(NULL);
  362. }
  363. int
  364. #ifdef KR_headers
  365. pars_f(s) char *s;
  366. #else
  367. pars_f(const char *s)
  368. #endif
  369. {
  370. f__parenlvl=f__revloc=f__pc=0;
  371. if(f_s(s,0) == NULL)
  372. {
  373. return(-1);
  374. }
  375. return(0);
  376. }
  377. #define STKSZ 10
  378. int f__cnt[STKSZ],f__ret[STKSZ],f__cp,f__rp;
  379. flag f__workdone, f__nonl;
  380. static int
  381. #ifdef KR_headers
  382. type_f(n)
  383. #else
  384. type_f(int n)
  385. #endif
  386. {
  387. switch(n)
  388. {
  389. default:
  390. return(n);
  391. case RET1:
  392. return(RET1);
  393. case REVERT: return(REVERT);
  394. case GOTO: return(GOTO);
  395. case STACK: return(STACK);
  396. case X:
  397. case SLASH:
  398. case APOS: case H:
  399. case T: case TL: case TR:
  400. return(NED);
  401. case F:
  402. case I:
  403. case IM:
  404. case A: case AW:
  405. case O: case OM:
  406. case L:
  407. case E: case EE: case D:
  408. case G: case GE:
  409. case Z: case ZM:
  410. return(ED);
  411. }
  412. }
  413. #ifdef KR_headers
  414. integer do_fio(number,ptr,len) ftnint *number; ftnlen len; char *ptr;
  415. #else
  416. integer do_fio(ftnint *number, char *ptr, ftnlen len)
  417. #endif
  418. { struct syl *p;
  419. int n,i;
  420. for(i=0;i<*number;i++,ptr+=len)
  421. {
  422. loop: switch(type_f((p= &f__syl[f__pc])->op))
  423. {
  424. default:
  425. fprintf(stderr,"unknown code in do_fio: %d\n%s\n",
  426. p->op,f__fmtbuf);
  427. err(f__elist->cierr,100,"do_fio");
  428. case NED:
  429. if((*f__doned)(p))
  430. { f__pc++;
  431. goto loop;
  432. }
  433. f__pc++;
  434. continue;
  435. case ED:
  436. if(f__cnt[f__cp]<=0)
  437. { f__cp--;
  438. f__pc++;
  439. goto loop;
  440. }
  441. if(ptr==NULL)
  442. return((*f__doend)());
  443. f__cnt[f__cp]--;
  444. f__workdone=1;
  445. if((n=(*f__doed)(p,ptr,len))>0)
  446. errfl(f__elist->cierr,errno,"fmt");
  447. if(n<0)
  448. err(f__elist->ciend,(EOF),"fmt");
  449. continue;
  450. case STACK:
  451. f__cnt[++f__cp]=p->p1;
  452. f__pc++;
  453. goto loop;
  454. case RET1:
  455. f__ret[++f__rp]=p->p1;
  456. f__pc++;
  457. goto loop;
  458. case GOTO:
  459. if(--f__cnt[f__cp]<=0)
  460. { f__cp--;
  461. f__rp--;
  462. f__pc++;
  463. goto loop;
  464. }
  465. f__pc=1+f__ret[f__rp--];
  466. goto loop;
  467. case REVERT:
  468. f__rp=f__cp=0;
  469. f__pc = p->p1;
  470. if(ptr==NULL)
  471. return((*f__doend)());
  472. if(!f__workdone) return(0);
  473. if((n=(*f__dorevert)()) != 0) return(n);
  474. goto loop;
  475. case COLON:
  476. if(ptr==NULL)
  477. return((*f__doend)());
  478. f__pc++;
  479. goto loop;
  480. case NONL:
  481. f__nonl = 1;
  482. f__pc++;
  483. goto loop;
  484. case S:
  485. case SS:
  486. f__cplus=0;
  487. f__pc++;
  488. goto loop;
  489. case SP:
  490. f__cplus = 1;
  491. f__pc++;
  492. goto loop;
  493. case P: f__scale=p->p1;
  494. f__pc++;
  495. goto loop;
  496. case BN:
  497. f__cblank=0;
  498. f__pc++;
  499. goto loop;
  500. case BZ:
  501. f__cblank=1;
  502. f__pc++;
  503. goto loop;
  504. }
  505. }
  506. return(0);
  507. }
  508. int
  509. en_fio(Void)
  510. { ftnint one=1;
  511. return(do_fio(&one,(char *)NULL,(ftnint)0));
  512. }
  513. VOID
  514. fmt_bg(Void)
  515. {
  516. f__workdone=f__cp=f__rp=f__pc=f__cursor=0;
  517. f__cnt[0]=f__ret[0]=0;
  518. }
  519. #ifdef __cplusplus
  520. }
  521. #endif