/gnu/lib/libf2c/libI77/rdfmt.c

https://github.com/avsm/src · C · 615 lines · 585 code · 20 blank · 10 comment · 170 complexity · 71aa4fd2b4d47b8ddf7afa328d9ca926 MD5 · raw file

  1. #include "config.h"
  2. #include <ctype.h>
  3. #include "f2c.h"
  4. #include "fio.h"
  5. extern int f__cursor;
  6. #undef abs
  7. #undef min
  8. #undef max
  9. #include <stdlib.h>
  10. #include "fmt.h"
  11. #include "fp.h"
  12. static int
  13. rd_Z (Uint * n, int w, ftnlen len)
  14. {
  15. long x[9];
  16. char *s, *s0, *s1, *se, *t;
  17. int ch, i, w1, w2;
  18. static char hex[256];
  19. static int one = 1;
  20. int bad = 0;
  21. if (!hex['0'])
  22. {
  23. s = "0123456789";
  24. while ((ch = *s++))
  25. hex[ch] = ch - '0' + 1;
  26. s = "ABCDEF";
  27. while ((ch = *s++))
  28. hex[ch] = hex[ch + 'a' - 'A'] = ch - 'A' + 11;
  29. }
  30. s = s0 = (char *) x;
  31. s1 = (char *) &x[4];
  32. se = (char *) &x[8];
  33. if (len > 4 * (ftnlen) sizeof (long))
  34. return errno = 117;
  35. while (w)
  36. {
  37. GET (ch);
  38. if (ch == ',' || ch == '\n')
  39. break;
  40. w--;
  41. if (ch > ' ')
  42. {
  43. if (!hex[ch & 0xff])
  44. bad++;
  45. *s++ = ch;
  46. if (s == se)
  47. {
  48. /* discard excess characters */
  49. for (t = s0, s = s1; t < s1;)
  50. *t++ = *s++;
  51. s = s1;
  52. }
  53. }
  54. }
  55. if (bad)
  56. return errno = 115;
  57. w = (int) len;
  58. w1 = s - s0;
  59. w2 = (w1 + 1) >> 1;
  60. t = (char *) n;
  61. if (*(char *) &one)
  62. {
  63. /* little endian */
  64. t += w - 1;
  65. i = -1;
  66. }
  67. else
  68. i = 1;
  69. for (; w > w2; t += i, --w)
  70. *t = 0;
  71. if (!w)
  72. return 0;
  73. if (w < w2)
  74. s0 = s - (w << 1);
  75. else if (w1 & 1)
  76. {
  77. *t = hex[*s0++ & 0xff] - 1;
  78. if (!--w)
  79. return 0;
  80. t += i;
  81. }
  82. do
  83. {
  84. *t = (hex[*s0 & 0xff] - 1) << 4 | (hex[s0[1] & 0xff] - 1);
  85. t += i;
  86. s0 += 2;
  87. }
  88. while (--w);
  89. return 0;
  90. }
  91. static int
  92. rd_I (Uint * n, int w, ftnlen len, register int base)
  93. {
  94. int ch, sign;
  95. longint x = 0;
  96. if (w <= 0)
  97. goto have_x;
  98. for (;;)
  99. {
  100. GET (ch);
  101. if (ch != ' ')
  102. break;
  103. if (!--w)
  104. goto have_x;
  105. }
  106. sign = 0;
  107. switch (ch)
  108. {
  109. case ',':
  110. case '\n':
  111. w = 0;
  112. goto have_x;
  113. case '-':
  114. sign = 1;
  115. case '+':
  116. break;
  117. default:
  118. if (ch >= '0' && ch <= '9')
  119. {
  120. x = ch - '0';
  121. break;
  122. }
  123. goto have_x;
  124. }
  125. while (--w)
  126. {
  127. GET (ch);
  128. if (ch >= '0' && ch <= '9')
  129. {
  130. x = x * base + ch - '0';
  131. continue;
  132. }
  133. if (ch != ' ')
  134. {
  135. if (ch == '\n' || ch == ',')
  136. w = 0;
  137. break;
  138. }
  139. if (f__cblank)
  140. x *= base;
  141. }
  142. if (sign)
  143. x = -x;
  144. have_x:
  145. if (len == sizeof (integer))
  146. n->il = x;
  147. else if (len == sizeof (char))
  148. n->ic = (char) x;
  149. #ifdef Allow_TYQUAD
  150. else if (len == sizeof (longint))
  151. n->ili = x;
  152. #endif
  153. else
  154. n->is = (short) x;
  155. if (w)
  156. {
  157. while (--w)
  158. GET (ch);
  159. return errno = 115;
  160. }
  161. return 0;
  162. }
  163. static int
  164. rd_L (ftnint * n, int w, ftnlen len)
  165. {
  166. int ch, dot, lv;
  167. if (w <= 0)
  168. goto bad;
  169. for (;;)
  170. {
  171. GET (ch);
  172. --w;
  173. if (ch != ' ')
  174. break;
  175. if (!w)
  176. goto bad;
  177. }
  178. dot = 0;
  179. retry:
  180. switch (ch)
  181. {
  182. case '.':
  183. if (dot++ || !w)
  184. goto bad;
  185. GET (ch);
  186. --w;
  187. goto retry;
  188. case 't':
  189. case 'T':
  190. lv = 1;
  191. break;
  192. case 'f':
  193. case 'F':
  194. lv = 0;
  195. break;
  196. default:
  197. bad:
  198. for (; w > 0; --w)
  199. GET (ch);
  200. /* no break */
  201. case ',':
  202. case '\n':
  203. return errno = 116;
  204. }
  205. /* The switch statement that was here
  206. didn't cut it: It broke down for targets
  207. where sizeof(char) == sizeof(short). */
  208. if (len == sizeof (char))
  209. *(char *) n = (char) lv;
  210. else if (len == sizeof (short))
  211. *(short *) n = (short) lv;
  212. else
  213. *n = lv;
  214. while (w-- > 0)
  215. {
  216. GET (ch);
  217. if (ch == ',' || ch == '\n')
  218. break;
  219. }
  220. return 0;
  221. }
  222. static int
  223. rd_F (ufloat * p, int w, int d, ftnlen len)
  224. {
  225. char s[FMAX + EXPMAXDIGS + 4];
  226. register int ch;
  227. register char *sp, *spe, *sp1;
  228. double x;
  229. int scale1, se;
  230. long e, exp;
  231. sp1 = sp = s;
  232. spe = sp + FMAX;
  233. exp = -d;
  234. x = 0.;
  235. do
  236. {
  237. GET (ch);
  238. w--;
  239. }
  240. while (ch == ' ' && w);
  241. switch (ch)
  242. {
  243. case '-':
  244. *sp++ = ch;
  245. sp1++;
  246. spe++;
  247. case '+':
  248. if (!w)
  249. goto zero;
  250. --w;
  251. GET (ch);
  252. }
  253. while (ch == ' ')
  254. {
  255. blankdrop:
  256. if (!w--)
  257. goto zero;
  258. GET (ch);
  259. }
  260. while (ch == '0')
  261. {
  262. if (!w--)
  263. goto zero;
  264. GET (ch);
  265. }
  266. if (ch == ' ' && f__cblank)
  267. goto blankdrop;
  268. scale1 = f__scale;
  269. while (isdigit (ch))
  270. {
  271. digloop1:
  272. if (sp < spe)
  273. *sp++ = ch;
  274. else
  275. ++exp;
  276. digloop1e:
  277. if (!w--)
  278. goto done;
  279. GET (ch);
  280. }
  281. if (ch == ' ')
  282. {
  283. if (f__cblank)
  284. {
  285. ch = '0';
  286. goto digloop1;
  287. }
  288. goto digloop1e;
  289. }
  290. if (ch == '.')
  291. {
  292. exp += d;
  293. if (!w--)
  294. goto done;
  295. GET (ch);
  296. if (sp == sp1)
  297. { /* no digits yet */
  298. while (ch == '0')
  299. {
  300. skip01:
  301. --exp;
  302. skip0:
  303. if (!w--)
  304. goto done;
  305. GET (ch);
  306. }
  307. if (ch == ' ')
  308. {
  309. if (f__cblank)
  310. goto skip01;
  311. goto skip0;
  312. }
  313. }
  314. while (isdigit (ch))
  315. {
  316. digloop2:
  317. if (sp < spe)
  318. {
  319. *sp++ = ch;
  320. --exp;
  321. }
  322. digloop2e:
  323. if (!w--)
  324. goto done;
  325. GET (ch);
  326. }
  327. if (ch == ' ')
  328. {
  329. if (f__cblank)
  330. {
  331. ch = '0';
  332. goto digloop2;
  333. }
  334. goto digloop2e;
  335. }
  336. }
  337. switch (ch)
  338. {
  339. default:
  340. break;
  341. case '-':
  342. se = 1;
  343. goto signonly;
  344. case '+':
  345. se = 0;
  346. goto signonly;
  347. case 'e':
  348. case 'E':
  349. case 'd':
  350. case 'D':
  351. if (!w--)
  352. goto bad;
  353. GET (ch);
  354. while (ch == ' ')
  355. {
  356. if (!w--)
  357. goto bad;
  358. GET (ch);
  359. }
  360. se = 0;
  361. switch (ch)
  362. {
  363. case '-':
  364. se = 1;
  365. case '+':
  366. signonly:
  367. if (!w--)
  368. goto bad;
  369. GET (ch);
  370. }
  371. while (ch == ' ')
  372. {
  373. if (!w--)
  374. goto bad;
  375. GET (ch);
  376. }
  377. if (!isdigit (ch))
  378. goto bad;
  379. e = ch - '0';
  380. for (;;)
  381. {
  382. if (!w--)
  383. {
  384. ch = '\n';
  385. break;
  386. }
  387. GET (ch);
  388. if (!isdigit (ch))
  389. {
  390. if (ch == ' ')
  391. {
  392. if (f__cblank)
  393. ch = '0';
  394. else
  395. continue;
  396. }
  397. else
  398. break;
  399. }
  400. e = 10 * e + ch - '0';
  401. if (e > EXPMAX && sp > sp1)
  402. goto bad;
  403. }
  404. if (se)
  405. exp -= e;
  406. else
  407. exp += e;
  408. scale1 = 0;
  409. }
  410. switch (ch)
  411. {
  412. case '\n':
  413. case ',':
  414. break;
  415. default:
  416. bad:
  417. return (errno = 115);
  418. }
  419. done:
  420. if (sp > sp1)
  421. {
  422. while (*--sp == '0')
  423. ++exp;
  424. if (exp -= scale1)
  425. sprintf (sp + 1, "e%ld", exp);
  426. else
  427. sp[1] = 0;
  428. x = atof (s);
  429. }
  430. zero:
  431. if (len == sizeof (real))
  432. p->pf = x;
  433. else
  434. p->pd = x;
  435. return (0);
  436. }
  437. static int
  438. rd_A (char *p, ftnlen len)
  439. {
  440. int i, ch;
  441. for (i = 0; i < len; i++)
  442. {
  443. GET (ch);
  444. *p++ = VAL (ch);
  445. }
  446. return (0);
  447. }
  448. static int
  449. rd_AW (char *p, int w, ftnlen len)
  450. {
  451. int i, ch;
  452. if (w >= len)
  453. {
  454. for (i = 0; i < w - len; i++)
  455. GET (ch);
  456. for (i = 0; i < len; i++)
  457. {
  458. GET (ch);
  459. *p++ = VAL (ch);
  460. }
  461. return (0);
  462. }
  463. for (i = 0; i < w; i++)
  464. {
  465. GET (ch);
  466. *p++ = VAL (ch);
  467. }
  468. for (i = 0; i < len - w; i++)
  469. *p++ = ' ';
  470. return (0);
  471. }
  472. static int
  473. rd_H (int n, char *s)
  474. {
  475. int i, ch;
  476. for (i = 0; i < n; i++)
  477. if ((ch = (*f__getn) ()) < 0)
  478. return (ch);
  479. else
  480. *s++ = ch == '\n' ? ' ' : ch;
  481. return (1);
  482. }
  483. static int
  484. rd_POS (char *s)
  485. {
  486. char quote;
  487. int ch;
  488. quote = *s++;
  489. for (; *s; s++)
  490. if (*s == quote && *(s + 1) != quote)
  491. break;
  492. else if ((ch = (*f__getn) ()) < 0)
  493. return (ch);
  494. else
  495. *s = ch == '\n' ? ' ' : ch;
  496. return (1);
  497. }
  498. int
  499. rd_ed (struct syl * p, char *ptr, ftnlen len)
  500. {
  501. int ch;
  502. for (; f__cursor > 0; f__cursor--)
  503. if ((ch = (*f__getn) ()) < 0)
  504. return (ch);
  505. if (f__cursor < 0)
  506. {
  507. if (f__recpos + f__cursor < 0) /*err(elist->cierr,110,"fmt") */
  508. f__cursor = -f__recpos; /* is this in the standard? */
  509. if (f__external == 0)
  510. {
  511. extern char *f__icptr;
  512. f__icptr += f__cursor;
  513. }
  514. else if (f__curunit && f__curunit->useek)
  515. FSEEK (f__cf, (off_t) f__cursor, SEEK_CUR);
  516. else
  517. err (f__elist->cierr, 106, "fmt");
  518. f__recpos += f__cursor;
  519. f__cursor = 0;
  520. }
  521. switch (p->op)
  522. {
  523. default:
  524. fprintf (stderr, "rd_ed, unexpected code: %d\n", p->op);
  525. sig_die (f__fmtbuf, 1);
  526. case IM:
  527. case I:
  528. ch = rd_I ((Uint *) ptr, p->p1, len, 10);
  529. break;
  530. /* O and OM don't work right for character, double, complex, */
  531. /* or doublecomplex, and they differ from Fortran 90 in */
  532. /* showing a minus sign for negative values. */
  533. case OM:
  534. case O:
  535. ch = rd_I ((Uint *) ptr, p->p1, len, 8);
  536. break;
  537. case L:
  538. ch = rd_L ((ftnint *) ptr, p->p1, len);
  539. break;
  540. case A:
  541. ch = rd_A (ptr, len);
  542. break;
  543. case AW:
  544. ch = rd_AW (ptr, p->p1, len);
  545. break;
  546. case E:
  547. case EE:
  548. case D:
  549. case G:
  550. case GE:
  551. case F:
  552. ch = rd_F ((ufloat *) ptr, p->p1, p->p2.i[0], len);
  553. break;
  554. /* Z and ZM assume 8-bit bytes. */
  555. case ZM:
  556. case Z:
  557. ch = rd_Z ((Uint *) ptr, p->p1, len);
  558. break;
  559. }
  560. if (ch == 0)
  561. return (ch);
  562. else if (ch == EOF)
  563. return (EOF);
  564. if (f__cf)
  565. clearerr (f__cf);
  566. return (errno);
  567. }
  568. int
  569. rd_ned (struct syl * p)
  570. {
  571. switch (p->op)
  572. {
  573. default:
  574. fprintf (stderr, "rd_ned, unexpected code: %d\n", p->op);
  575. sig_die (f__fmtbuf, 1);
  576. case APOS:
  577. return (rd_POS (p->p2.s));
  578. case H:
  579. return (rd_H (p->p1, p->p2.s));
  580. case SLASH:
  581. return ((*f__donewrec) ());
  582. case TR:
  583. case X:
  584. f__cursor += p->p1;
  585. return (1);
  586. case T:
  587. f__cursor = p->p1 - f__recpos - 1;
  588. return (1);
  589. case TL:
  590. f__cursor -= p->p1;
  591. if (f__cursor < -f__recpos) /* TL1000, 1X */
  592. f__cursor = -f__recpos;
  593. return (1);
  594. }
  595. }