Annotation of coherent/b/lib/libc/XSTDIO/ndpobj/_dscan.c, revision 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.