Annotation of coherent/b/lib/libc/XSTDIO/ndpobj/_dscan.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * libc/stdio/_dscan.c
                      3:  * ANSI-compliant C standard i/o library internals.
                      4:  * _dscan(), _dassign()
                      5:  * ANSI 4.9.6.2.
                      6:  * Floating point support for _scanf().
                      7:  * Kept in a separate source to allow scanf() et al. to link
                      8:  * without floating point support.
                      9:  */
                     10: 
                     11: #include <stdio.h>
                     12: #include <stdlib.h>
                     13: 
                     14: #if    0
                     15: #include <locale.h>
                     16: #else
                     17: #define        _decimal_point  '.'
                     18: #endif
                     19: 
                     20: /* Compile-time options. */
                     21: #define        LONGDOUBLE      0       /* iff sizeof(double) != sizeof(long double) */
                     22: 
                     23: /*
                     24:  * Read an ASCII floating point number
                     25:  * containing at most 'width' characters from 'fp' into 'buf'.
                     26:  * Convert the result using strtod() and store it through *dp.
                     27:  * Return the number of characters read.
                     28:  * Use the finite state machine shown below.  In the diagram,
                     29:  *     states are in (parens)
                     30:  *     inputs are in [brackets]
                     31:  * For all inputs not shown, transition is to (end) state.
                     32:  *                                 --
                     33:  *                               /    \
                     34:  *                              v      \
                     35:  *                ----------> [0-9] -> (3)
                     36:  *              /               ^       | \
                     37:  *             /               /        |  \
                     38:  *            /               /         v   \
                     39:  *           /               /         [.]   \               ->[+-] -
                     40:  *          /               /           |     \             /         \
                     41:  *         /               /            |      \           /           \
                     42:  *        /               /             v       v         /             v
                     43:  *     (0) --> [+-] -> (1)             (4) --> [Ee] -> (6) -> [0-9] -> (7)
                     44:  *        \           /               /         ^               ^      /
                     45:  *         \         /               /         /                 \    /
                     46:  *          \       /               /         /                    --
                     47:  *           \     /               /         /
                     48:  *            \   /               /         /
                     49:  *             \ /               /         /
                     50:  *              v               v         /
                     51:  *             [.] --> (2) -> [0-9] -> (5)
                     52:  *                              ^      /
                     53:  *                               \    /
                     54:  *                                 --
                     55:  * This cannot be done correctly with the single character pushback
                     56:  * guaranteed by ungetc(); for example, rejecting "+y", "1Ex" or "1E+x"
                     57:  * requires two or three character pushback.
                     58:  */
                     59: int
                     60: _dscan(buf, fp, width, dp) register char *buf; FILE *fp; int width; double *dp;
                     61: {
                     62:        register int c, state, count;
                     63:        register char *cp;
                     64: 
                     65:        cp = buf;
                     66:        for (state = count = 0; count < width; ++count) {
                     67:                *cp++ = c = getc(fp);
                     68:                switch (c) {
                     69:                case '+':
                     70:                case '-':
                     71:                        if (state != 0 && state != 6)
                     72:                                break;
                     73:                        state++;
                     74:                        continue;
                     75:                case '0':
                     76:                case '1':
                     77:                case '2':
                     78:                case '3':
                     79:                case '4':
                     80:                case '5':
                     81:                case '6':
                     82:                case '7':
                     83:                case '8':
                     84:                case '9':
                     85:                        if (state == 0 || state == 1 || state == 3)
                     86:                                state = 3;
                     87:                        else if (state == 2 || state == 4 || state == 5)
                     88:                                state = 5;
                     89:                        else if (state == 6 || state == 7)
                     90:                                state = 7;
                     91:                        else
                     92:                                break;
                     93:                        continue;
                     94:                case 'E':
                     95:                case 'e':
                     96:                        if (state < 3 || 5 < state)
                     97:                                break;
                     98:                        state = 6;
                     99:                        continue;
                    100:                default:
                    101:                        if (c != _decimal_point)
                    102:                                break;
                    103:                        if (state <= 1)
                    104:                                state = 2;
                    105:                        else if (state == 3)
                    106:                                state++;
                    107:                        else
                    108:                                break;
                    109:                        continue;
                    110:                }
                    111:                --cp;
                    112:                ungetc(c, fp);
                    113:                break;
                    114:        }
                    115:        *cp = '\0';
                    116:        *dp = strtod(buf, (char **)NULL);
                    117:        return ((int)(cp - buf));
                    118: }
                    119: 
                    120: /*
                    121:  * Assign *dp through *vp, width depending on flag.
                    122:  */
                    123: void
                    124: _dassign(vp, dp, flag) Void *vp; double *dp; int flag;
                    125: {
                    126: #if    LONGDOUBLE
                    127:        if (flag == 'L')
                    128:                *(long double *)vp = (long double)*dp;
                    129:        else if (flag == 'l')
                    130: #else
                    131:        if (flag == 'L' || flag == 'l')
                    132: #endif
                    133:                *(double *)vp = *dp;
                    134:        else
                    135:                *(float *)vp = (float)*dp;
                    136: }
                    137: 
                    138: /* end of libc/stdio/_dscan.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.