scanf.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. #include <stdlib.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <ctype.h>
  5. #include <string.h>
  6. #ifdef __STDC__
  7. #include <stdarg.h>
  8. #define va_strt va_start
  9. #else
  10. #include <varargs.h>
  11. #define va_strt(p,i) va_start(p)
  12. #endif
  13. #ifdef L_scanf
  14. #ifdef __STDC__
  15. int scanf(const char * fmt, ...)
  16. #else
  17. int scanf(fmt, va_alist)
  18. __const char *fmt;
  19. va_dcl
  20. #endif
  21. {
  22. va_list ptr;
  23. int rv;
  24. va_strt(ptr, fmt);
  25. rv = vfscanf(stdin,fmt,ptr);
  26. va_end(ptr);
  27. return rv;
  28. }
  29. #endif
  30. #ifdef L_sscanf
  31. #ifdef __STDC__
  32. int sscanf(const char * sp, const char * fmt, ...)
  33. #else
  34. int sscanf(sp, fmt, va_alist)
  35. __const char * sp;
  36. __const char *fmt;
  37. va_dcl
  38. #endif
  39. {
  40. FILE string[1] =
  41. {
  42. {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1,
  43. _IOFBF | __MODE_READ}
  44. };
  45. va_list ptr;
  46. int rv;
  47. va_strt(ptr, fmt);
  48. string->bufpos = (unsigned char *)((void*)sp);
  49. rv = vfscanf(string,fmt,ptr);
  50. va_end(ptr);
  51. return rv;
  52. }
  53. #endif
  54. #ifdef L_fscanf
  55. #ifdef __STDC__
  56. int fscanf(FILE * fp, const char * fmt, ...)
  57. #else
  58. int fscanf(fp, fmt, va_alist)
  59. FILE * fp;
  60. __const char *fmt;
  61. va_dcl
  62. #endif
  63. {
  64. va_list ptr;
  65. int rv;
  66. va_strt(ptr, fmt);
  67. rv = vfscanf(fp,fmt,ptr);
  68. va_end(ptr);
  69. return rv;
  70. }
  71. #endif
  72. #ifdef L_vscanf
  73. int vscanf(fmt, ap)
  74. __const char *fmt;
  75. va_list ap;
  76. {
  77. return vfscanf(stdin,fmt,ap);
  78. }
  79. #endif
  80. #ifdef L_vsscanf
  81. int vsscanf(__const char *sp, __const char *fmt, va_list ap)
  82. {
  83. FILE string[1] =
  84. {
  85. {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1,
  86. _IOFBF | __MODE_READ}
  87. };
  88. string->bufpos = (unsigned char *)((void*)sp);
  89. return vfscanf(string,fmt,ap);
  90. }
  91. #endif
  92. #ifdef L_vfscanf
  93. #if FLOATS
  94. int _vfscanf_fp_ref = 1;
  95. #else
  96. int _vfscanf_fp_ref = 0;
  97. #endif
  98. /* #define skip() do{c=getc(fp); if (c<1) goto done;}while(isspace(c))*/
  99. #define skip() while(isspace(c)) { if ((c=getc(fp))<1) goto done; }
  100. #if FLOATS
  101. /* fp scan actions */
  102. #define F_NADA 0 /* just change state */
  103. #define F_SIGN 1 /* set sign */
  104. #define F_ESIGN 2 /* set exponent's sign */
  105. #define F_INT 3 /* adjust integer part */
  106. #define F_FRAC 4 /* adjust fraction part */
  107. #define F_EXP 5 /* adjust exponent part */
  108. #define F_QUIT 6
  109. #define NSTATE 8
  110. #define FS_INIT 0 /* initial state */
  111. #define FS_SIGNED 1 /* saw sign */
  112. #define FS_DIGS 2 /* saw digits, no . */
  113. #define FS_DOT 3 /* saw ., no digits */
  114. #define FS_DD 4 /* saw digits and . */
  115. #define FS_E 5 /* saw 'e' */
  116. #define FS_ESIGN 6 /* saw exp's sign */
  117. #define FS_EDIGS 7 /* saw exp's digits */
  118. #define FC_DIG 0
  119. #define FC_DOT 1
  120. #define FC_E 2
  121. #define FC_SIGN 3
  122. /* given transition,state do what action? */
  123. int fp_do[][NSTATE] = {
  124. {F_INT,F_INT,F_INT,
  125. F_FRAC,F_FRAC,
  126. F_EXP,F_EXP,F_EXP}, /* see digit */
  127. {F_NADA,F_NADA,F_NADA,
  128. F_QUIT,F_QUIT,F_QUIT,F_QUIT,F_QUIT}, /* see '.' */
  129. {F_QUIT,F_QUIT,
  130. F_NADA,F_QUIT,F_NADA,
  131. F_QUIT,F_QUIT,F_QUIT}, /* see e/E */
  132. {F_SIGN,F_QUIT,F_QUIT,F_QUIT,F_QUIT,
  133. F_ESIGN,F_QUIT,F_QUIT}, /* see sign */
  134. };
  135. /* given transition,state what is new state? */
  136. int fp_ns[][NSTATE] = {
  137. {FS_DIGS,FS_DIGS,FS_DIGS,
  138. FS_DD,FS_DD,
  139. FS_EDIGS,FS_EDIGS,FS_EDIGS}, /* see digit */
  140. {FS_DOT,FS_DOT,FS_DD,
  141. }, /* see '.' */
  142. {0,0,
  143. FS_E,0,FS_E,
  144. }, /* see e/E */
  145. {FS_SIGNED,0,0,0,0,
  146. FS_ESIGN,0,0}, /* see sign */
  147. };
  148. /* which states are valid terminators? */
  149. int fp_sval[NSTATE] = {
  150. 0,0,1,0,1,0,0,1
  151. };
  152. #endif
  153. int
  154. vfscanf(fp, fmt, ap)
  155. register FILE *fp;
  156. register const char *fmt;
  157. va_list ap;
  158. {
  159. register long n;
  160. register int c, width, lval, cnt = 0;
  161. int store, neg, base, wide1, endnull, rngflag, c2;
  162. register unsigned char *p;
  163. unsigned char delim[128], digits[17], *q;
  164. #if FLOATS
  165. long frac, expo;
  166. int eneg, fraclen, fstate, trans;
  167. double fx, fp_scan();
  168. #endif
  169. if (!*fmt)
  170. return (0);
  171. c = getc(fp);
  172. while (c > 0)
  173. {
  174. store = 0;
  175. if (*fmt == '%')
  176. {
  177. n = 0;
  178. width = -1;
  179. wide1 = 1;
  180. base = 10;
  181. lval = (sizeof(long) == sizeof(int));
  182. store = 1;
  183. endnull = 1;
  184. neg = -1;
  185. strcpy(delim, "\011\012\013\014\015 ");
  186. strcpy(digits, "0123456789ABCDEF");
  187. if (fmt[1] == '*')
  188. {
  189. endnull = store = 0;
  190. ++fmt;
  191. }
  192. while (isdigit(*++fmt))/* width digit(s) */
  193. {
  194. if (width == -1)
  195. width = 0;
  196. wide1 = width = (width * 10) + (*fmt - '0');
  197. }
  198. --fmt;
  199. fmtnxt:
  200. ++fmt;
  201. switch (tolower(*fmt)) /* tolower() is a MACRO! */
  202. {
  203. case '*':
  204. endnull = store = 0;
  205. goto fmtnxt;
  206. case 'l': /* long data */
  207. lval = 1;
  208. goto fmtnxt;
  209. case 'h': /* short data */
  210. lval = 0;
  211. goto fmtnxt;
  212. case 'i': /* any-base numeric */
  213. base = 0;
  214. goto numfmt;
  215. case 'b': /* unsigned binary */
  216. base = 2;
  217. goto numfmt;
  218. case 'o': /* unsigned octal */
  219. base = 8;
  220. goto numfmt;
  221. case 'x': /* unsigned hexadecimal */
  222. base = 16;
  223. goto numfmt;
  224. case 'd': /* SIGNED decimal */
  225. neg = 0;
  226. /* FALL-THRU */
  227. case 'u': /* unsigned decimal */
  228. numfmt:skip();
  229. if (isupper(*fmt))
  230. lval = 1;
  231. if (!base)
  232. {
  233. base = 10;
  234. neg = 0;
  235. if (c == '%')
  236. {
  237. base = 2;
  238. goto skip1;
  239. }
  240. else if (c == '0')
  241. {
  242. c = getc(fp);
  243. if (c < 1)
  244. goto savnum;
  245. if ((c != 'x')
  246. && (c != 'X'))
  247. {
  248. base = 8;
  249. digits[8] = '\0';
  250. goto zeroin;
  251. }
  252. base = 16;
  253. goto skip1;
  254. }
  255. }
  256. if ((neg == 0) && (base == 10)
  257. && ((neg = (c == '-')) || (c == '+')))
  258. {
  259. skip1:
  260. c = getc(fp);
  261. if (c < 1)
  262. goto done;
  263. }
  264. digits[base] = '\0';
  265. p = ((unsigned char *)
  266. strchr(digits, toupper(c)));
  267. if ((!c || !p) && width)
  268. goto done;
  269. while (p && width-- && c)
  270. {
  271. n = (n * base) + (p - digits);
  272. c = getc(fp);
  273. zeroin:
  274. p = ((unsigned char *)
  275. strchr(digits, toupper(c)));
  276. }
  277. savnum:
  278. if (store)
  279. {
  280. if (neg == 1)
  281. n = -n;
  282. if (lval)
  283. *va_arg(ap, long*) = n;
  284. else
  285. *va_arg(ap, short*) = n;
  286. ++cnt;
  287. }
  288. break;
  289. #if FLOATS
  290. case 'e': /* float */
  291. case 'f':
  292. case 'g':
  293. skip();
  294. fprintf(stderr,"LIBM:SCANF");
  295. if (isupper(*fmt))
  296. lval = 1;
  297. fstate = FS_INIT;
  298. neg = 0;
  299. eneg = 0;
  300. n = 0;
  301. frac = 0;
  302. expo = 0;
  303. fraclen = 0;
  304. while (c && width--)
  305. {
  306. if (c >= '0' && c <= '9')
  307. trans = FC_DIG;
  308. else if (c == '.')
  309. trans = FC_DOT;
  310. else if (c == '+' || c == '-')
  311. trans = FC_SIGN;
  312. else if (tolower(c) == 'e')
  313. trans = FC_E;
  314. else
  315. goto fdone;
  316. switch (fp_do[trans][fstate])
  317. {
  318. case F_SIGN:
  319. neg = (c == '-');
  320. break;
  321. case F_ESIGN:
  322. eneg = (c == '-');
  323. break;
  324. case F_INT:
  325. n = 10 * n + (c - '0');
  326. break;
  327. case F_FRAC:
  328. frac = 10 * frac + (c - '0');
  329. fraclen++;
  330. break;
  331. case F_EXP:
  332. expo = 10 * expo + (c - '0');
  333. break;
  334. case F_QUIT:
  335. goto fdone;
  336. }
  337. fstate = fp_ns[trans][fstate];
  338. c = getc(fp);
  339. }
  340. fdone:
  341. if (!fp_sval[fstate])
  342. goto done;
  343. if (store)
  344. {
  345. fx = fp_scan(neg, eneg, n, frac, expo, fraclen);
  346. if (lval)
  347. *va_arg(ap, double *) = fx;
  348. else
  349. *va_arg(ap, float *) = fx;
  350. ++cnt;
  351. }
  352. break;
  353. #else
  354. case 'e': /* float */
  355. case 'f':
  356. case 'g':
  357. fprintf(stderr, "LIBC:SCANF");
  358. exit(-1);
  359. #endif
  360. case 'c': /* character data */
  361. width = wide1;
  362. lval = endnull = 0;
  363. delim[0] = '\0';
  364. goto strproc;
  365. case '[': /* string w/ delimiter set */
  366. /* get delimiters */
  367. p = delim;
  368. if (*++fmt == '^')
  369. {
  370. fmt++;
  371. lval = 0;
  372. }
  373. else
  374. lval = 1;
  375. rngflag = 2;
  376. if ((*fmt == ']') || (*fmt == '-'))
  377. {
  378. *p++ = *fmt++;
  379. rngflag = 0;
  380. }
  381. while (*fmt != ']')
  382. {
  383. if (*fmt == '\0')
  384. goto done;
  385. switch (rngflag)
  386. {
  387. case 1:
  388. c2 = *(p - 2);
  389. if (c2 <= *fmt)
  390. {
  391. p -= 2;
  392. while (c2 < *fmt)
  393. *p++ = c2++;
  394. rngflag = 2;
  395. break;
  396. }
  397. /* fall thru intentional */
  398. case 0:
  399. rngflag = (*fmt == '-');
  400. break;
  401. case 2:
  402. rngflag = 0;
  403. }
  404. *p++ = *fmt++;
  405. }
  406. *p = '\0';
  407. goto strproc;
  408. case 's': /* string data */
  409. lval = 0;
  410. skip();
  411. strproc:
  412. /* process string */
  413. p = va_arg(ap, unsigned char *);
  414. /* if the 1st char fails, match fails */
  415. if (width)
  416. {
  417. q = ((unsigned char *)
  418. strchr(delim, c));
  419. if ((c < 1) || lval == (q==0))
  420. {
  421. if (endnull)
  422. *p = '\0';
  423. goto done;
  424. }
  425. }
  426. for (;;) /* FOREVER */
  427. {
  428. if (store)
  429. *p++ = c;
  430. if (((c = getc(fp)) < 1) ||
  431. (--width == 0))
  432. break;
  433. q = ((unsigned char *)
  434. strchr(delim, c));
  435. if (lval == (q==0))
  436. break;
  437. }
  438. if (store)
  439. {
  440. if (endnull)
  441. *p = '\0';
  442. ++cnt;
  443. }
  444. break;
  445. case '\0': /* early EOS */
  446. --fmt;
  447. /* FALL THRU */
  448. default:
  449. goto cmatch;
  450. }
  451. }
  452. else if (isspace(*fmt)) /* skip whitespace */
  453. {
  454. skip();
  455. }
  456. else
  457. { /* normal match char */
  458. cmatch:
  459. if (c != *fmt)
  460. break;
  461. c = getc(fp);
  462. }
  463. if (!*++fmt)
  464. break;
  465. }
  466. done: /* end of scan */
  467. if ((c == EOF) && (cnt == 0))
  468. return (EOF);
  469. if( c != EOF )
  470. ungetc(c, fp);
  471. return (cnt);
  472. }
  473. #endif