Incorporate rosapps. 0.3.15 was branched somewhat incorrectly so rosapps is not synce...
[reactos.git] / modules / rosapps / applications / net / ncftp / Strn / Strntok.c
1 /* Strntok.c */
2
3 #include <string.h>
4 #include "Strn.h"
5
6 /* This version of Strtok differs from the regular ANSI strtok in that
7 * an empty token can be returned, and consecutive delimiters are not
8 * ignored like ANSI does. Example:
9 *
10 * Parse String = ",,mike,gleason,-West Interactive,402-573-1000"
11 * Delimiters = ",-"
12 *
13 * (ANSI strtok:)
14 * strtok 1=[mike] length=4
15 * strtok 2=[gleason] length=7
16 * strtok 3=[West Interactive] length=16
17 * strtok 4=[402] length=3
18 * strtok 5=[573] length=3
19 * strtok 6=[1000] length=4
20 *
21 * (Strtok:)
22 * Strtok 1=[] length=0
23 * Strtok 2=[] length=0
24 * Strtok 3=[mike] length=4
25 * Strtok 4=[gleason] length=7
26 * Strtok 5=[] length=0
27 * Strtok 6=[West Interactive] length=16
28 * Strtok 7=[402] length=3
29 * Strtok 8=[573] length=3
30 * Strtok 9=[1000] length=4
31 *
32 */
33
34 char *
35 Strtok(char *buf, const char *delims)
36 {
37 static char *p = NULL;
38 char *start, *end;
39
40 if (buf != NULL) {
41 p = buf;
42 } else {
43 if (p == NULL)
44 return (NULL); /* No more tokens. */
45 }
46 for (start = p, end = p; ; end++) {
47 if (*end == '\0') {
48 p = NULL; /* This is the last token. */
49 break;
50 }
51 if (strchr(delims, (int) *end) != NULL) {
52 *end++ = '\0';
53 p = end;
54 break;
55 }
56 }
57 return (start);
58 } /* Strtok */
59
60
61
62
63 /* This is a bounds-safe version of Strtok, where you also pass a pointer
64 * to the token to write into, and its size. Using the example above,
65 * with a char token[8], you get the following. Notice that the token
66 * is not overrun, and is always nul-terminated:
67 *
68 * Strntok 1=[] length=0
69 * Strntok 2=[] length=0
70 * Strntok 3=[mike] length=4
71 * Strntok 4=[gleason] length=7
72 * Strntok 5=[] length=0
73 * Strntok 6=[West In] length=7
74 * Strntok 7=[402] length=3
75 * Strntok 8=[573] length=3
76 * Strntok 9=[1000] length=4
77 */
78
79 int
80 Strntok(char *dstTokenStart, size_t tokenSize, char *buf, const char *delims)
81 {
82 static char *p = NULL;
83 char *end;
84 char *lim;
85 char *dst;
86 int len;
87
88 dst = dstTokenStart;
89 lim = dst + tokenSize - 1; /* Leave room for nul byte. */
90
91 if (buf != NULL) {
92 p = buf;
93 } else {
94 if (p == NULL) {
95 *dst = '\0';
96 return (-1); /* No more tokens. */
97 }
98 }
99
100 for (end = p; ; end++) {
101 if (*end == '\0') {
102 p = NULL; /* This is the last token. */
103 break;
104 }
105 if (strchr(delims, (int) *end) != NULL) {
106 ++end;
107 p = end;
108 break;
109 }
110 if (dst < lim) /* Don't overrun token size. */
111 *dst++ = *end;
112 }
113 *dst = '\0';
114 len = (int) (dst - dstTokenStart); /* Return length of token. */
115
116 #if (STRN_ZERO_PAD == 1)
117 /* Pad with zeros. */
118 for (++dst; dst <= lim; )
119 *dst++ = 0;
120 #endif /* STRN_ZERO_PAD */
121
122 return (len);
123 } /* Strntok */
124
125
126
127 #ifdef TESTING_STRTOK
128 #include <stdio.h>
129
130 void
131 main(int argc, char **argv)
132 {
133 char buf[256];
134 int i;
135 char *t;
136 char token[8];
137 int tokenLen;
138
139 if (argc < 3) {
140 fprintf(stderr, "Usage: test \"buffer,with,delims\" <delimiters>\n");
141 exit(1);
142 }
143 strcpy(buf, argv[1]);
144 i = 1;
145 t = strtok(buf, argv[2]);
146 if (t == NULL)
147 exit(0);
148 do {
149 printf("strtok %d=[%s] length=%d\n", i, t, (int) strlen(t));
150 t = strtok(NULL, argv[2]);
151 ++i;
152 } while (t != NULL);
153
154 printf("------------------------------------------------\n");
155 strcpy(buf, argv[1]);
156 i = 1;
157 t = Strtok(buf, argv[2]);
158 if (t == NULL)
159 exit(0);
160 do {
161 printf("Strtok %d=[%s] length=%d\n", i, t, (int) strlen(t));
162 t = Strtok(NULL, argv[2]);
163 ++i;
164 } while (t != NULL);
165
166 printf("------------------------------------------------\n");
167 strcpy(buf, argv[1]);
168 i = 1;
169 tokenLen = Strntok(token, sizeof(token), buf, argv[2]);
170 if (tokenLen < 0)
171 exit(0);
172 do {
173 printf("Strntok %d=[%s] length=%d\n", i, token, tokenLen);
174 tokenLen = Strntok(token, sizeof(token), NULL, argv[2]);
175 ++i;
176 } while (tokenLen >= 0);
177 exit(0);
178 }
179 #endif