~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to regex/split.c

Removed reference to aio.h - we don't reference its use anywhere.

Show diffs side-by-side

added added

removed removed

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