62 #define KMP_STR_BUF_INVARIANT(b) \ 64 KMP_DEBUG_ASSERT((b)->str != NULL); \ 65 KMP_DEBUG_ASSERT((b)->size >= sizeof((b)->bulk)); \ 66 KMP_DEBUG_ASSERT((b)->size % sizeof((b)->bulk) == 0); \ 67 KMP_DEBUG_ASSERT((unsigned)(b)->used < (b)->size); \ 69 (b)->size == sizeof((b)->bulk) ? (b)->str == &(b)->bulk[0] : 1); \ 70 KMP_DEBUG_ASSERT((b)->size > sizeof((b)->bulk) ? (b)->str != &(b)->bulk[0] \ 74 void __kmp_str_buf_clear(kmp_str_buf_t *buffer) {
75 KMP_STR_BUF_INVARIANT(buffer);
76 if (buffer->used > 0) {
80 KMP_STR_BUF_INVARIANT(buffer);
83 void __kmp_str_buf_reserve(kmp_str_buf_t *buffer,
int size) {
84 KMP_STR_BUF_INVARIANT(buffer);
85 KMP_DEBUG_ASSERT(size >= 0);
87 if (buffer->size < (
unsigned int)size) {
91 }
while (buffer->size < (
unsigned int)size);
94 if (buffer->str == &buffer->bulk[0]) {
95 buffer->str = (
char *)KMP_INTERNAL_MALLOC(buffer->size);
96 if (buffer->str == NULL) {
97 KMP_FATAL(MemoryAllocFailed);
99 KMP_MEMCPY_S(buffer->str, buffer->size, buffer->bulk, buffer->used + 1);
101 buffer->str = (
char *)KMP_INTERNAL_REALLOC(buffer->str, buffer->size);
102 if (buffer->str == NULL) {
103 KMP_FATAL(MemoryAllocFailed);
109 KMP_DEBUG_ASSERT(buffer->size > 0);
110 KMP_DEBUG_ASSERT(buffer->size >= (
unsigned)size);
111 KMP_STR_BUF_INVARIANT(buffer);
114 void __kmp_str_buf_detach(kmp_str_buf_t *buffer) {
115 KMP_STR_BUF_INVARIANT(buffer);
118 if (buffer->size <=
sizeof(buffer->bulk)) {
119 buffer->str = (
char *)KMP_INTERNAL_MALLOC(buffer->size);
120 if (buffer->str == NULL) {
121 KMP_FATAL(MemoryAllocFailed);
123 KMP_MEMCPY_S(buffer->str, buffer->size, buffer->bulk, buffer->used + 1);
127 void __kmp_str_buf_free(kmp_str_buf_t *buffer) {
128 KMP_STR_BUF_INVARIANT(buffer);
129 if (buffer->size >
sizeof(buffer->bulk)) {
130 KMP_INTERNAL_FREE(buffer->str);
132 buffer->str = buffer->bulk;
133 buffer->size =
sizeof(buffer->bulk);
135 KMP_STR_BUF_INVARIANT(buffer);
138 void __kmp_str_buf_cat(kmp_str_buf_t *buffer,
char const *str,
int len) {
139 KMP_STR_BUF_INVARIANT(buffer);
140 KMP_DEBUG_ASSERT(str != NULL);
141 KMP_DEBUG_ASSERT(len >= 0);
142 __kmp_str_buf_reserve(buffer, buffer->used + len + 1);
143 KMP_MEMCPY(buffer->str + buffer->used, str, len);
144 buffer->str[buffer->used + len] = 0;
146 KMP_STR_BUF_INVARIANT(buffer);
149 void __kmp_str_buf_vprint(kmp_str_buf_t *buffer,
char const *format,
151 KMP_STR_BUF_INVARIANT(buffer);
154 int const free = buffer->size - buffer->used;
171 __va_copy(_args, args);
172 #define args _args // Substitute args with its copy, _args. 173 #endif // KMP_OS_WINDOWS 174 rc = KMP_VSNPRINTF(buffer->str + buffer->used, free, format, args);
176 #undef args // Remove substitution. 178 #endif // KMP_OS_WINDOWS 182 if (rc >= 0 && rc < free) {
190 size = buffer->used + rc + 1;
193 size = buffer->size * 2;
197 __kmp_str_buf_reserve(buffer, size);
202 KMP_DEBUG_ASSERT(buffer->size > 0);
203 KMP_STR_BUF_INVARIANT(buffer);
206 void __kmp_str_buf_print(kmp_str_buf_t *buffer,
char const *format, ...) {
208 va_start(args, format);
209 __kmp_str_buf_vprint(buffer, format, args);
215 void __kmp_str_buf_print_size(kmp_str_buf_t *buf,
size_t size) {
216 char const *names[] = {
"",
"k",
"M",
"G",
"T",
"P",
"E",
"Z",
"Y"};
217 int const units =
sizeof(names) /
sizeof(
char const *);
220 while ((size % 1024 == 0) && (u + 1 < units)) {
226 __kmp_str_buf_print(buf,
"%" KMP_SIZE_T_SPEC
"%s", size, names[u]);
229 void __kmp_str_fname_init(kmp_str_fname_t *fname,
char const *path) {
237 fname->path = __kmp_str_format(
"%s", path);
241 if (KMP_OS_WINDOWS) {
242 __kmp_str_replace(fname->path,
'\\',
'/');
244 fname->dir = __kmp_str_format(
"%s", fname->path);
245 slash = strrchr(fname->dir,
'/');
246 if (KMP_OS_WINDOWS &&
248 char first = TOLOWER(fname->dir[0]);
249 if (
'a' <= first && first <= 'z' && fname->dir[1] ==
':') {
250 slash = &fname->dir[1];
253 base = (slash == NULL ? fname->dir : slash + 1);
254 fname->base = __kmp_str_format(
"%s", base);
260 void __kmp_str_fname_free(kmp_str_fname_t *fname) {
261 __kmp_str_free(CCAST(
char const **, &fname->path));
262 __kmp_str_free(CCAST(
char const **, &fname->dir));
263 __kmp_str_free(CCAST(
char const **, &fname->base));
266 int __kmp_str_fname_match(kmp_str_fname_t
const *fname,
char const *pattern) {
270 if (pattern != NULL) {
271 kmp_str_fname_t ptrn;
272 __kmp_str_fname_init(&ptrn, pattern);
273 dir_match = strcmp(ptrn.dir,
"*/") == 0 ||
274 (fname->dir != NULL && __kmp_str_eqf(fname->dir, ptrn.dir));
275 base_match = strcmp(ptrn.base,
"*") == 0 ||
276 (fname->base != NULL && __kmp_str_eqf(fname->base, ptrn.base));
277 __kmp_str_fname_free(&ptrn);
280 return dir_match && base_match;
283 kmp_str_loc_t __kmp_str_loc_init(
char const *psource,
int init_fname) {
292 if (psource != NULL) {
299 loc._bulk = __kmp_str_format(
"%s", psource);
303 __kmp_str_split(str,
';', &dummy, &str);
304 __kmp_str_split(str,
';', &loc.file, &str);
305 __kmp_str_split(str,
';', &loc.func, &str);
306 __kmp_str_split(str,
';', &line, &str);
307 __kmp_str_split(str,
';', &col, &str);
311 loc.line = atoi(line);
325 __kmp_str_fname_init(&loc.fname, init_fname ? loc.file : NULL);
330 void __kmp_str_loc_free(kmp_str_loc_t *loc) {
331 __kmp_str_fname_free(&loc->fname);
332 __kmp_str_free(CCAST(
const char **, &(loc->_bulk)));
347 result = (_stricmp(lhs, rhs) == 0);
349 result = (strcmp(lhs, rhs) == 0);
385 char *__kmp_str_format(
395 buffer = (
char *)KMP_INTERNAL_MALLOC(size);
396 if (buffer == NULL) {
397 KMP_FATAL(MemoryAllocFailed);
402 va_start(args, format);
403 rc = KMP_VSNPRINTF(buffer, size, format, args);
407 if (rc >= 0 && rc < size) {
422 buffer = (
char *)KMP_INTERNAL_REALLOC(buffer, size);
423 if (buffer == NULL) {
424 KMP_FATAL(MemoryAllocFailed);
431 void __kmp_str_free(
char const **str) {
432 KMP_DEBUG_ASSERT(str != NULL);
433 KMP_INTERNAL_FREE(CCAST(
char *, *str));
442 int __kmp_str_match(
char const *target,
int len,
char const *data) {
444 if (target == NULL || data == NULL) {
447 for (i = 0; target[i] && data[i]; ++i) {
448 if (TOLOWER(target[i]) != TOLOWER(data[i])) {
452 return ((len > 0) ? i >= len : (!target[i] && (len || !data[i])));
455 int __kmp_str_match_false(
char const *data) {
457 __kmp_str_match(
"false", 1, data) || __kmp_str_match(
"off", 2, data) ||
458 __kmp_str_match(
"0", 1, data) || __kmp_str_match(
".false.", 2, data) ||
459 __kmp_str_match(
".f.", 2, data) || __kmp_str_match(
"no", 1, data);
463 int __kmp_str_match_true(
char const *data) {
465 __kmp_str_match(
"true", 1, data) || __kmp_str_match(
"on", 2, data) ||
466 __kmp_str_match(
"1", 1, data) || __kmp_str_match(
".true.", 2, data) ||
467 __kmp_str_match(
".t.", 2, data) || __kmp_str_match(
"yes", 1, data);
471 void __kmp_str_replace(
char *str,
char search_for,
char replace_with) {
474 found = strchr(str, search_for);
476 *found = replace_with;
477 found = strchr(found + 1, search_for);
481 void __kmp_str_split(
char *str,
489 char *ptr = strchr(str, delim);
505 char *__kmp_str_token(
516 *buf += strspn(*buf, delim);
519 *buf += strcspn(*buf, delim);
527 token = strtok_r(str, delim, buf);
532 int __kmp_str_to_int(
char const *str,
char sentinel) {
538 for (t = str; *t !=
'\0'; ++t) {
539 if (*t < '0' || *t >
'9')
541 result = (result * 10) + (*t -
'0');
561 factor = (1024 * 1024);
570 if (result > (INT_MAX / factor))
575 return (*t != 0 ? 0 : result);
585 void __kmp_str_to_size(
599 KMP_DEBUG_ASSERT(str != NULL);
602 while (str[i] ==
' ' || str[i] ==
'\t') {
607 if (str[i] <
'0' || str[i] >
'9') {
608 *error = KMP_I18N_STR(NotANumber);
612 digit = str[i] -
'0';
613 overflow = overflow || (value > (KMP_SIZE_T_MAX - digit) / 10);
614 value = (value * 10) + digit;
616 }
while (str[i] >=
'0' && str[i] <=
'9');
619 while (str[i] ==
' ' || str[i] ==
'\t') {
624 #define _case(ch, exp) \ 626 case ch - ('a' - 'A'): { \ 627 size_t shift = (exp)*10; \ 629 if (shift < sizeof(size_t) * 8) { \ 630 factor = (size_t)(1) << shift; \ 647 if (str[i] ==
'b' || str[i] ==
'B') {
653 if (!(str[i] ==
' ' || str[i] ==
'\t' || str[i] == 0)) {
654 *error = KMP_I18N_STR(BadUnit);
663 overflow = overflow || (value > (KMP_SIZE_T_MAX / factor));
667 while (str[i] ==
' ' || str[i] ==
'\t') {
672 *error = KMP_I18N_STR(IllegalCharacters);
677 *error = KMP_I18N_STR(ValueTooLarge);
678 *out = KMP_SIZE_T_MAX;
686 void __kmp_str_to_uint(
696 KMP_DEBUG_ASSERT(str != NULL);
699 while (str[i] ==
' ' || str[i] ==
'\t') {
704 if (str[i] <
'0' || str[i] >
'9') {
705 *error = KMP_I18N_STR(NotANumber);
709 digit = str[i] -
'0';
710 overflow = overflow || (value > (KMP_SIZE_T_MAX - digit) / 10);
711 value = (value * 10) + digit;
713 }
while (str[i] >=
'0' && str[i] <=
'9');
716 while (str[i] ==
' ' || str[i] ==
'\t') {
721 *error = KMP_I18N_STR(IllegalCharacters);
726 *error = KMP_I18N_STR(ValueTooLarge);
727 *out = (kmp_uint64)-1;