Annotation of embedaddon/php/ext/ereg/regex/split.c, revision 1.1

1.1     ! misho       1: #include <stdio.h>
        !             2: #include <string.h>
        !             3: 
        !             4: /*
        !             5:  - split - divide a string into fields, like awk split()
        !             6:  = int split(char *string, char *fields[], int nfields, char *sep);
        !             7:  */
        !             8: int                            /* number of fields, including overflow */
        !             9: split(string, fields, nfields, sep)
        !            10: char *string;
        !            11: char *fields[];                        /* list is not NULL-terminated */
        !            12: int nfields;                   /* number of entries available in fields[] */
        !            13: char *sep;                     /* "" white, "c" single char, "ab" [ab]+ */
        !            14: {
        !            15:        register char *p = string;
        !            16:        register char c;                        /* latest character */
        !            17:        register char sepc = sep[0];
        !            18:        register char sepc2;
        !            19:        register int fn;
        !            20:        register char **fp = fields;
        !            21:        register char *sepp;
        !            22:        register int trimtrail;
        !            23: 
        !            24:        /* white space */
        !            25:        if (sepc == '\0') {
        !            26:                while ((c = *p++) == ' ' || c == '\t')
        !            27:                        continue;
        !            28:                p--;
        !            29:                trimtrail = 1;
        !            30:                sep = " \t";    /* note, code below knows this is 2 long */
        !            31:                sepc = ' ';
        !            32:        } else
        !            33:                trimtrail = 0;
        !            34:        sepc2 = sep[1];         /* now we can safely pick this up */
        !            35: 
        !            36:        /* catch empties */
        !            37:        if (*p == '\0')
        !            38:                return(0);
        !            39: 
        !            40:        /* single separator */
        !            41:        if (sepc2 == '\0') {
        !            42:                fn = nfields;
        !            43:                for (;;) {
        !            44:                        *fp++ = p;
        !            45:                        fn--;
        !            46:                        if (fn == 0)
        !            47:                                break;
        !            48:                        while ((c = *p++) != sepc)
        !            49:                                if (c == '\0')
        !            50:                                        return(nfields - fn);
        !            51:                        *(p-1) = '\0';
        !            52:                }
        !            53:                /* we have overflowed the fields vector -- just count them */
        !            54:                fn = nfields;
        !            55:                for (;;) {
        !            56:                        while ((c = *p++) != sepc)
        !            57:                                if (c == '\0')
        !            58:                                        return(fn);
        !            59:                        fn++;
        !            60:                }
        !            61:                /* not reached */
        !            62:        }
        !            63: 
        !            64:        /* two separators */
        !            65:        if (sep[2] == '\0') {
        !            66:                fn = nfields;
        !            67:                for (;;) {
        !            68:                        *fp++ = p;
        !            69:                        fn--;
        !            70:                        while ((c = *p++) != sepc && c != sepc2)
        !            71:                                if (c == '\0') {
        !            72:                                        if (trimtrail && **(fp-1) == '\0')
        !            73:                                                fn++;
        !            74:                                        return(nfields - fn);
        !            75:                                }
        !            76:                        if (fn == 0)
        !            77:                                break;
        !            78:                        *(p-1) = '\0';
        !            79:                        while ((c = *p++) == sepc || c == sepc2)
        !            80:                                continue;
        !            81:                        p--;
        !            82:                }
        !            83:                /* we have overflowed the fields vector -- just count them */
        !            84:                fn = nfields;
        !            85:                while (c != '\0') {
        !            86:                        while ((c = *p++) == sepc || c == sepc2)
        !            87:                                continue;
        !            88:                        p--;
        !            89:                        fn++;
        !            90:                        while ((c = *p++) != '\0' && c != sepc && c != sepc2)
        !            91:                                continue;
        !            92:                }
        !            93:                /* might have to trim trailing white space */
        !            94:                if (trimtrail) {
        !            95:                        p--;
        !            96:                        while ((c = *--p) == sepc || c == sepc2)
        !            97:                                continue;
        !            98:                        p++;
        !            99:                        if (*p != '\0') {
        !           100:                                if (fn == nfields+1)
        !           101:                                        *p = '\0';
        !           102:                                fn--;
        !           103:                        }
        !           104:                }
        !           105:                return(fn);
        !           106:        }
        !           107: 
        !           108:        /* n separators */
        !           109:        fn = 0;
        !           110:        for (;;) {
        !           111:                if (fn < nfields)
        !           112:                        *fp++ = p;
        !           113:                fn++;
        !           114:                for (;;) {
        !           115:                        c = *p++;
        !           116:                        if (c == '\0')
        !           117:                                return(fn);
        !           118:                        sepp = sep;
        !           119:                        while ((sepc = *sepp++) != '\0' && sepc != c)
        !           120:                                continue;
        !           121:                        if (sepc != '\0')       /* it was a separator */
        !           122:                                break;
        !           123:                }
        !           124:                if (fn < nfields)
        !           125:                        *(p-1) = '\0';
        !           126:                for (;;) {
        !           127:                        c = *p++;
        !           128:                        sepp = sep;
        !           129:                        while ((sepc = *sepp++) != '\0' && sepc != c)
        !           130:                                continue;
        !           131:                        if (sepc == '\0')       /* it wasn't a separator */
        !           132:                                break;
        !           133:                }
        !           134:                p--;
        !           135:        }
        !           136: 
        !           137:        /* not reached */
        !           138: }
        !           139: 
        !           140: #ifdef TEST_SPLIT
        !           141: 
        !           142: 
        !           143: /*
        !           144:  * test program
        !           145:  * pgm         runs regression
        !           146:  * pgm sep     splits stdin lines by sep
        !           147:  * pgm str sep splits str by sep
        !           148:  * pgm str sep n       splits str by sep n times
        !           149:  */
        !           150: int
        !           151: main(argc, argv)
        !           152: int argc;
        !           153: char *argv[];
        !           154: {
        !           155:        char buf[512];
        !           156:        register int n;
        !           157: #      define  MNF     10
        !           158:        char *fields[MNF];
        !           159: 
        !           160:        if (argc > 4)
        !           161:                for (n = atoi(argv[3]); n > 0; n--) {
        !           162:                        (void) strcpy(buf, argv[1]);
        !           163:                }
        !           164:        else if (argc > 3)
        !           165:                for (n = atoi(argv[3]); n > 0; n--) {
        !           166:                        (void) strcpy(buf, argv[1]);
        !           167:                        (void) split(buf, fields, MNF, argv[2]);
        !           168:                }
        !           169:        else if (argc > 2)
        !           170:                dosplit(argv[1], argv[2]);
        !           171:        else if (argc > 1)
        !           172:                while (fgets(buf, sizeof(buf), stdin) != NULL) {
        !           173:                        buf[strlen(buf)-1] = '\0';      /* stomp newline */
        !           174:                        dosplit(buf, argv[1]);
        !           175:                }
        !           176:        else
        !           177:                regress();
        !           178: 
        !           179:        exit(0);
        !           180: }
        !           181: 
        !           182: dosplit(string, seps)
        !           183: char *string;
        !           184: char *seps;
        !           185: {
        !           186: #      define  NF      5
        !           187:        char *fields[NF];
        !           188:        register int nf;
        !           189: 
        !           190:        nf = split(string, fields, NF, seps);
        !           191:        print(nf, NF, fields);
        !           192: }
        !           193: 
        !           194: print(nf, nfp, fields)
        !           195: int nf;
        !           196: int nfp;
        !           197: char *fields[];
        !           198: {
        !           199:        register int fn;
        !           200:        register int bound;
        !           201: 
        !           202:        bound = (nf > nfp) ? nfp : nf;
        !           203:        printf("%d:\t", nf);
        !           204:        for (fn = 0; fn < bound; fn++)
        !           205:                printf("\"%s\"%s", fields[fn], (fn+1 < nf) ? ", " : "\n");
        !           206: }
        !           207: 
        !           208: #define        RNF     5               /* some table entries know this */
        !           209: struct {
        !           210:        char *str;
        !           211:        char *seps;
        !           212:        int nf;
        !           213:        char *fi[RNF];
        !           214: } tests[] = {
        !           215:        "",             " ",    0,      { "" },
        !           216:        " ",            " ",    2,      { "", "" },
        !           217:        "x",            " ",    1,      { "x" },
        !           218:        "xy",           " ",    1,      { "xy" },
        !           219:        "x y",          " ",    2,      { "x", "y" },
        !           220:        "abc def  g ",  " ",    5,      { "abc", "def", "", "g", "" },
        !           221:        "  a bcd",      " ",    4,      { "", "", "a", "bcd" },
        !           222:        "a b c d e f",  " ",    6,      { "a", "b", "c", "d", "e f" },
        !           223:        " a b c d ",    " ",    6,      { "", "a", "b", "c", "d " },
        !           224: 
        !           225:        "",             " _",   0,      { "" },
        !           226:        " ",            " _",   2,      { "", "" },
        !           227:        "x",            " _",   1,      { "x" },
        !           228:        "x y",          " _",   2,      { "x", "y" },
        !           229:        "ab _ cd",      " _",   2,      { "ab", "cd" },
        !           230:        " a_b  c ",     " _",   5,      { "", "a", "b", "c", "" },
        !           231:        "a b c_d e f",  " _",   6,      { "a", "b", "c", "d", "e f" },
        !           232:        " a b c d ",    " _",   6,      { "", "a", "b", "c", "d " },
        !           233: 
        !           234:        "",             " _~",  0,      { "" },
        !           235:        " ",            " _~",  2,      { "", "" },
        !           236:        "x",            " _~",  1,      { "x" },
        !           237:        "x y",          " _~",  2,      { "x", "y" },
        !           238:        "ab _~ cd",     " _~",  2,      { "ab", "cd" },
        !           239:        " a_b  c~",     " _~",  5,      { "", "a", "b", "c", "" },
        !           240:        "a b_c d~e f",  " _~",  6,      { "a", "b", "c", "d", "e f" },
        !           241:        "~a b c d ",    " _~",  6,      { "", "a", "b", "c", "d " },
        !           242: 
        !           243:        "",             " _~-", 0,      { "" },
        !           244:        " ",            " _~-", 2,      { "", "" },
        !           245:        "x",            " _~-", 1,      { "x" },
        !           246:        "x y",          " _~-", 2,      { "x", "y" },
        !           247:        "ab _~- cd",    " _~-", 2,      { "ab", "cd" },
        !           248:        " a_b  c~",     " _~-", 5,      { "", "a", "b", "c", "" },
        !           249:        "a b_c-d~e f",  " _~-", 6,      { "a", "b", "c", "d", "e f" },
        !           250:        "~a-b c d ",    " _~-", 6,      { "", "a", "b", "c", "d " },
        !           251: 
        !           252:        "",             "  ",   0,      { "" },
        !           253:        " ",            "  ",   2,      { "", "" },
        !           254:        "x",            "  ",   1,      { "x" },
        !           255:        "xy",           "  ",   1,      { "xy" },
        !           256:        "x y",          "  ",   2,      { "x", "y" },
        !           257:        "abc def  g ",  "  ",   4,      { "abc", "def", "g", "" },
        !           258:        "  a bcd",      "  ",   3,      { "", "a", "bcd" },
        !           259:        "a b c d e f",  "  ",   6,      { "a", "b", "c", "d", "e f" },
        !           260:        " a b c d ",    "  ",   6,      { "", "a", "b", "c", "d " },
        !           261: 
        !           262:        "",             "",     0,      { "" },
        !           263:        " ",            "",     0,      { "" },
        !           264:        "x",            "",     1,      { "x" },
        !           265:        "xy",           "",     1,      { "xy" },
        !           266:        "x y",          "",     2,      { "x", "y" },
        !           267:        "abc def  g ",  "",     3,      { "abc", "def", "g" },
        !           268:        "\t a bcd",     "",     2,      { "a", "bcd" },
        !           269:        "  a \tb\t c ", "",     3,      { "a", "b", "c" },
        !           270:        "a b c d e ",   "",     5,      { "a", "b", "c", "d", "e" },
        !           271:        "a b\tc d e f", "",     6,      { "a", "b", "c", "d", "e f" },
        !           272:        " a b c d e f ",        "",     6,      { "a", "b", "c", "d", "e f " },
        !           273: 
        !           274:        NULL,           NULL,   0,      { NULL },
        !           275: };
        !           276: 
        !           277: regress()
        !           278: {
        !           279:        char buf[512];
        !           280:        register int n;
        !           281:        char *fields[RNF+1];
        !           282:        register int nf;
        !           283:        register int i;
        !           284:        register int printit;
        !           285:        register char *f;
        !           286: 
        !           287:        for (n = 0; tests[n].str != NULL; n++) {
        !           288:                (void) strcpy(buf, tests[n].str);
        !           289:                fields[RNF] = NULL;
        !           290:                nf = split(buf, fields, RNF, tests[n].seps);
        !           291:                printit = 0;
        !           292:                if (nf != tests[n].nf) {
        !           293:                        printf("split `%s' by `%s' gave %d fields, not %d\n",
        !           294:                                tests[n].str, tests[n].seps, nf, tests[n].nf);
        !           295:                        printit = 1;
        !           296:                } else if (fields[RNF] != NULL) {
        !           297:                        printf("split() went beyond array end\n");
        !           298:                        printit = 1;
        !           299:                } else {
        !           300:                        for (i = 0; i < nf && i < RNF; i++) {
        !           301:                                f = fields[i];
        !           302:                                if (f == NULL)
        !           303:                                        f = "(NULL)";
        !           304:                                if (strcmp(f, tests[n].fi[i]) != 0) {
        !           305:                                        printf("split `%s' by `%s', field %d is `%s', not `%s'\n",
        !           306:                                                tests[n].str, tests[n].seps,
        !           307:                                                i, fields[i], tests[n].fi[i]);
        !           308:                                        printit = 1;
        !           309:                                }
        !           310:                        }
        !           311:                }
        !           312:                if (printit)
        !           313:                        print(nf, RNF, fields);
        !           314:        }
        !           315: }
        !           316: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>