Fri, 19 Jan 2001 09:11:16 +0000
[gaim-migrate @ 1425]
woo hoo
| 1054 | 1 | /* Standard system headers */ |
| 2 | #include <stdlib.h> | |
| 3 | #include <string.h> | |
| 4 | ||
| 5 | /* | |
| 6 | * memtok differs from strtok in a few ways: | |
| 7 | * The pointer to the buffer to be scanned AND the pointer to the delimiters are NOT NULL terminated | |
| 8 | * strings but are each a pair of a pointer and byte count (so that NIL characters can be contained | |
| 9 | * in either of these buffers! | |
| 10 | * | |
| 11 | * Also memtok does not replace the "found" delimiter with a NIL character, but places the number | |
| 12 | * of bytes delimited by that delimiter into the location of the size_t pointer to by found. | |
| 13 | * | |
| 14 | * The whole **real** point of this function was that strtok skips any repeating delimiters, but we | |
| 15 | * need a function that retuns "empty strings" should there be two delimiters in a row. | |
| 16 | * | |
| 17 | * For some sense of consistency, the byte count of the buffer to be searched through is ALSO ignored | |
| 18 | * by memtok iff the buffer to be scanned is NULL | |
| 19 | * | |
| 20 | * Here's an example: | |
| 21 | * | |
| 22 | * size_t found = 0; | |
| 23 | * char *tok = 0, *buffer = malloc (COUNT); | |
| 24 | * fill_buffer_with_some_data (buffer, COUNT); | |
| 25 | * tok = memtok (buffer, COUNT, "\000\002", 2, &found); | |
| 26 | * | |
| 27 | * if tok != NULL then the bytes from tok to (tok + found) are the token | |
| 28 | * You can then look for more tokens with: | |
| 29 | * | |
| 30 | * tok = memtok (NULL, 0, "\000\002", 2, &found); | |
| 31 | * | |
| 32 | * If tmp == NULL noone of the delimiters were found, however tmp can != NULL and found CAN == 0 | |
| 33 | * | |
| 34 | * This means that although a delimiter was found it was immediately preceded by another delimiter and | |
| 35 | * thus delimited an empty token. | |
| 36 | * | |
| 37 | * ( As it happens, if one of the delimiters you want to search for is a NIL character, you can put the | |
| 38 | * other delimiter characters in a string literal and "lie" about how many delimiter characters there are | |
| 39 | * because all string literals are NIL terminated! | |
| 40 | * | |
| 41 | * Therefor the above example could have been written: | |
| 42 | * tok = memtok (buffer, COUNT, "\002", 2, &found); | |
| 43 | * | |
| 44 | * There are also two supplimentary functions that make using these tokens easier | |
| 45 | * | |
| 46 | * memdup is akin to strdup except that instead of it looking for a NIL termination character | |
| 47 | * it simply mallocs copies the specified number of bytes | |
| 48 | * | |
| 49 | * memdupasstr does as memdup except that it mallocs 1 more byte and makes it a NIL char so that you | |
| 50 | * can treat it as a string (as long as you're sure that the memory being described by the pointer and | |
| 51 | * byte count don't already contain any NIL characters) | |
| 52 | * | |
| 53 | */ | |
| 54 | ||
| 55 | /**********************************************************************************************************************************/ | |
| 56 | /* Interface (global) functions */ | |
| 57 | /**********************************************************************************************************************************/ | |
| 58 | char *memtok(char *m, size_t bytes, const char *delims, size_t delim_count, | |
| 59 | size_t * found) | |
| 60 | { | |
| 61 | static char *mem = 0, *c = 0; | |
| 62 | static size_t offset = 0, offset_now = 0, limit = 0; | |
| 63 | ||
| 64 | if (0 != m) | |
| 65 | { | |
| 66 | mem = m; | |
| 67 | offset = 0; | |
| 68 | limit = bytes; | |
| 69 | } | |
| 70 | ||
| 71 | offset_now = offset; | |
| 72 | ||
| 73 | for (c = mem; offset < limit; ++offset, ++c) | |
| 74 | { | |
| 75 | if (0 != memchr(delims, *c, delim_count)) | |
| 76 | { | |
| 77 | static char *ret = 0; | |
| 78 | ||
| 79 | ret = mem; | |
| 80 | mem = c + 1; | |
| 81 | *found = offset - offset_now; | |
| 82 | offset_now = offset + 1; | |
| 83 | return ret; | |
| 84 | } | |
| 85 | } | |
| 86 | ||
| 87 | return 0; | |
| 88 | } | |
| 89 | ||
| 90 | char *memdup(const char *mem, size_t bytes) | |
| 91 | { | |
| 92 | char *dup = 0; | |
| 93 | ||
| 94 | if (0 < bytes && 0 != mem) | |
| 95 | { | |
| 96 | dup = malloc(bytes); | |
| 97 | memcpy(dup, mem, bytes); | |
| 98 | } | |
| 99 | ||
| 100 | return dup; | |
| 101 | } | |
| 102 | ||
| 103 | char *memdupasstr(const char *mem, size_t bytes) | |
| 104 | { | |
| 105 | char *string = 0; | |
| 106 | ||
| 107 | if (0 < bytes && 0 != mem) | |
| 108 | { | |
| 109 | string = memdup(mem, bytes + 1); | |
| 110 | string[bytes] = '\0'; | |
| 111 | } | |
| 112 | ||
| 113 | return string; | |
| 114 | } |