1 /* strtokc.c */ 2 3 #include <string.h> 4 #include "Strn.h" 5 6 char * 7 strtokc(char *parsestr, const char *delims, char **context) 8 { 9 char *cp; 10 const char *cp2; 11 char c, c2; 12 char *start; 13 14 if (parsestr == NULL) 15 start = *context; 16 else 17 start = parsestr; 18 19 if ((start == NULL) || (delims == NULL)) { 20 *context = NULL; 21 return NULL; 22 } 23 24 /* Eat leading delimiters. */ 25 for (cp = start; ; ) { 26 next1: 27 c = *cp++; 28 if (c == '\0') { 29 /* No more tokens. */ 30 *context = NULL; 31 return (NULL); 32 } 33 for (cp2 = delims; ; ) { 34 c2 = (char) *cp2++; 35 if (c2 == '\0') { 36 /* This character was not a delimiter. 37 * The token starts here. 38 */ 39 start = cp - 1; 40 goto starttok; 41 } 42 if (c2 == c) { 43 /* This char was a delimiter. */ 44 /* Skip it, look at next character. */ 45 goto next1; 46 } 47 } 48 /*NOTREACHED*/ 49 } 50 51 starttok: 52 for ( ; ; cp++) { 53 c = *cp; 54 if (c == '\0') { 55 /* Token is finished. */ 56 *context = cp; 57 break; 58 } 59 for (cp2 = delims; ; ) { 60 c2 = (char) *cp2++; 61 if (c2 == '\0') { 62 /* This character was not a delimiter. 63 * Keep it as part of current token. 64 */ 65 break; 66 } 67 if (c2 == c) { 68 /* This char was a delimiter. */ 69 /* End of token. */ 70 *cp++ = '\0'; 71 *context = cp; 72 return (start); 73 } 74 } 75 } 76 return (start); 77 } /* strtokc */ 78 79 80 81 82 /* Same as strtokc, only you specify the destination buffer to write 83 * the token in along with its size. strntokc will write to the dst 84 * buffer, always nul-terminating it. 85 * 86 * It also returns the length of the token, or zero if there was no 87 * token. This differs from strtokc, which returns a pointer to the 88 * token or NULL for no token. 89 */ 90 91 int 92 strntokc(char *dstTokenStart, size_t tokenSize, char *parsestr, const char *delims, char **context) 93 { 94 char *cp; 95 const char *cp2; 96 char c, c2; 97 char *start; 98 int len; 99 char *dst, *lim; 100 101 dst = dstTokenStart; 102 lim = dst + tokenSize - 1; /* Leave room for nul byte. */ 103 104 if (parsestr == NULL) 105 start = *context; 106 else 107 start = parsestr; 108 109 if ((start == NULL) || (delims == NULL)) { 110 *context = NULL; 111 goto done; 112 } 113 114 /* Eat leading delimiters. */ 115 for (cp = start; ; ) { 116 next1: 117 c = *cp++; 118 if (c == '\0') { 119 /* No more tokens. */ 120 *context = NULL; 121 goto done; 122 } 123 for (cp2 = delims; ; ) { 124 c2 = (char) *cp2++; 125 if (c2 == '\0') { 126 /* This character was not a delimiter. 127 * The token starts here. 128 */ 129 start = cp - 1; 130 if (dst < lim) 131 *dst++ = c; 132 goto starttok; 133 } 134 if (c2 == c) { 135 /* This char was a delimiter. */ 136 /* Skip it, look at next character. */ 137 goto next1; 138 } 139 } 140 /*NOTREACHED*/ 141 } 142 143 starttok: 144 for ( ; ; cp++) { 145 c = *cp; 146 if (c == '\0') { 147 /* Token is finished. */ 148 *context = cp; 149 break; 150 } 151 for (cp2 = delims; ; ) { 152 c2 = (char) *cp2++; 153 if (c2 == '\0') { 154 /* This character was not a delimiter. 155 * Keep it as part of current token. 156 */ 157 break; 158 } 159 if (c2 == c) { 160 /* This char was a delimiter. */ 161 /* End of token. */ 162 *cp++ = '\0'; 163 *context = cp; 164 goto done; 165 } 166 } 167 if (dst < lim) /* Don't overrun token size. */ 168 *dst++ = c; 169 } 170 171 done: 172 *dst = '\0'; 173 len = (int) (dst - dstTokenStart); /* Return length of token. */ 174 175 #if (STRN_ZERO_PAD == 1) 176 /* Pad with zeros. */ 177 for (++dst; dst <= lim; ) 178 *dst++ = 0; 179 #endif /* STRN_ZERO_PAD */ 180 181 return (len); 182 } /* strntokc */ 183 184 185 186 187 #ifdef TESTING_STRTOK 188 #include <stdio.h> 189 190 void 191 main(int argc, char **argv) 192 { 193 char buf[256]; 194 int i; 195 char *t; 196 char token[8]; 197 int tokenLen; 198 char *context; 199 200 if (argc < 3) { 201 fprintf(stderr, "Usage: test \"buffer,with,delims\" <delimiters>\n"); 202 exit(1); 203 } 204 strcpy(buf, argv[1]); 205 i = 1; 206 t = strtok(buf, argv[2]); 207 if (t == NULL) 208 exit(0); 209 do { 210 printf("strtok %d=[%s] length=%d\n", i, t, (int) strlen(t)); 211 t = strtok(NULL, argv[2]); 212 ++i; 213 } while (t != NULL); 214 215 printf("------------------------------------------------\n"); 216 strcpy(buf, argv[1]); 217 i = 1; 218 t = strtokc(buf, argv[2], &context); 219 if (t == NULL) 220 exit(0); 221 do { 222 printf("strtokc %d=[%s] length=%d\n", i, t, (int) strlen(t)); 223 t = strtokc(NULL, argv[2], &context); 224 ++i; 225 } while (t != NULL); 226 227 printf("------------------------------------------------\n"); 228 strcpy(buf, argv[1]); 229 i = 1; 230 tokenLen = strntokc(token, sizeof(token), buf, argv[2], &context); 231 if (tokenLen <= 0) 232 exit(0); 233 do { 234 printf("strntokc %d=[%s] length=%d\n", i, token, tokenLen); 235 tokenLen = strntokc(token, sizeof(token), NULL, argv[2], &context); 236 ++i; 237 } while (tokenLen > 0); 238 exit(0); 239 } 240 #endif 241