00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "CSConfig.h"
00030 #include <inttypes.h>
00031
00032 #include <stdlib.h>
00033 #include <stdio.h>
00034 #include <string.h>
00035 #include <ctype.h>
00036
00037 #ifndef OS_WINDOWS
00038 #include <fnmatch.h>
00039 #endif
00040
00041 #include "CSDefs.h"
00042 #include "CSStrUtil.h"
00043 #include "CSMemory.h"
00044 #include "CSGlobal.h"
00045
00046 const char *cs_version()
00047 {
00048 static char version[124];
00049
00050 if (!version[0]) {
00051 snprintf(version, 124, "%s(Built %s %s)", VERSION, __DATE__, __TIME__);
00052 }
00053
00054 return version;
00055 }
00056
00057 void cs_strcpy(size_t size, char *to, const char *from, size_t len)
00058 {
00059 if (size > 0) {
00060 size--;
00061 if (len > size)
00062 len = size;
00063 memcpy(to, from, len);
00064 to[len] = 0;
00065 }
00066 }
00067
00068 void cs_strcpy(size_t size, char *to, const char *from)
00069 {
00070 if (size > 0) {
00071 size--;
00072 while (*from && size--)
00073 *to++ = *from++;
00074 *to = 0;
00075 }
00076 }
00077
00078
00079
00080
00081 void cs_strcpy_dottt(size_t size, char *d, const char *s, size_t len)
00082 {
00083 if (len+1 <= size) {
00084 cs_strcpy(size, d, s, len);
00085 return;
00086 }
00087 if (size < 5) {
00088
00089 cs_strcpy(size, d, "...");
00090 return;
00091 }
00092 memcpy(d, s, size-4);
00093 memcpy(d+size-4, "...", 3);
00094 d[size-1] = 0;
00095 }
00096
00097 void cs_strcpy_left(size_t size, char *to, const char *from, char ch)
00098 {
00099 if (size > 0) {
00100 size--;
00101 while (*from && size-- && *from != ch)
00102 *to++ = *from++;
00103 *to = 0;
00104 }
00105 }
00106
00107 void cs_strcpy_right(size_t size, char *to, const char *from, char ch)
00108 {
00109 if (size > 0) {
00110 size--;
00111 while (*from && *from != ch)
00112 from++;
00113 if (*from == ch)
00114 from++;
00115 while (*from && size-- && *from != ch)
00116 *to++ = *from++;
00117 *to = 0;
00118 }
00119 }
00120
00121 void cs_strcat(size_t size, char *to, const char *from)
00122 {
00123 while (*to && size--) to++;
00124 cs_strcpy(size, to, from);
00125 }
00126
00127 void cs_strcat(size_t size, char *to, char ch)
00128 {
00129 while (*to && size--) to++;
00130 if (size >= 1) {
00131 *to = ch;
00132 *(to+1) = 0;
00133 }
00134 }
00135
00136 void cs_strcat(char **to, const char *to_cat)
00137 {
00138 size_t len = strlen(*to) + strlen(to_cat) + 1;
00139
00140 cs_realloc((void **) to, len);
00141 strcat(*to, to_cat);
00142 }
00143
00144 void cs_strcat(size_t size, char *to, int i)
00145 {
00146 char buffer[20];
00147
00148 snprintf(buffer, 20, "%d", i);
00149 cs_strcat(size, to, buffer);
00150 }
00151
00152 void cs_strcat(size_t size, char *to, uint32_t i)
00153 {
00154 char buffer[20];
00155
00156 snprintf(buffer, 20, "%"PRIu32"", i);
00157 cs_strcat(size, to, buffer);
00158 }
00159
00160 void cs_strcat(size_t size, char *to, uint64_t i)
00161 {
00162 char buffer[40];
00163
00164 snprintf(buffer, 40, "%"PRIu64"", i);
00165 cs_strcat(size, to, buffer);
00166 }
00167
00168 void cs_strcat_left(size_t size, char *to, const char *from, char ch)
00169 {
00170 while (*to && size--) to++;
00171 cs_strcpy_left(size, to, from, ch);
00172 }
00173
00174 void cs_strcat_right(size_t size, char *to, const char *from, char ch)
00175 {
00176 while (*to && size--) to++;
00177 cs_strcpy_right(size, to, from, ch);
00178 }
00179
00180 void cs_strcat_hex(size_t size, char *to, uint64_t i)
00181 {
00182 char buffer[80];
00183
00184 snprintf(buffer, 80, "%"PRIx64"", i);
00185 cs_strcat(size, to, buffer);
00186 }
00187
00188 void cs_format_context(size_t size, char *buffer, const char *func, const char *file, int line)
00189 {
00190 char *ptr;
00191
00192 if (func) {
00193 cs_strcpy(size, buffer, func);
00194
00195 if ((ptr = strchr(buffer, '(')))
00196 *ptr = 0;
00197 cs_strcat(size, buffer, "(");
00198 }
00199 else
00200 *buffer = 0;
00201 if (file) {
00202 cs_strcat(size, buffer, cs_last_name_of_path(file));
00203 if (line) {
00204 cs_strcat(size, buffer, ":");
00205 cs_strcat(size, buffer, line);
00206 }
00207 }
00208 if (func)
00209 cs_strcat(size, buffer, ")");
00210 }
00211
00212 int cs_path_depth(const char *path)
00213 {
00214 int count = 0;
00215 while (*path) {
00216 if (IS_DIR_CHAR(*path))
00217 count++;
00218
00219 path++;
00220 }
00221 return count;
00222 }
00223
00224 static const char *find_wildcard(const char *pattern)
00225 {
00226 bool escaped = false;
00227 while (*pattern) {
00228 if ((*pattern == '*' || *pattern == '?' ) && !escaped)
00229 return pattern;
00230
00231 if (*pattern == '\\')
00232 escaped = !escaped;
00233 else
00234 escaped = false;
00235
00236 pattern++;
00237 }
00238
00239 return NULL;
00240 }
00241
00242
00243 bool cs_fixed_pattern(const char *str)
00244 {
00245 return (find_wildcard(str) == NULL);
00246 }
00247
00248 #ifdef OS_WINDOWS
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 #else
00296 bool cs_match_patern(const char *pattern, const char *str, bool ignore_case)
00297 {
00298 return (fnmatch(pattern, str, (ignore_case)?FNM_CASEFOLD:0) == 0);
00299 }
00300 #endif
00301
00302
00303 char *cs_last_name_of_path(const char *path, int count)
00304 {
00305 size_t length;
00306 const char *ptr;
00307
00308 length = strlen(path);
00309 if (!length)
00310 return((char *) path);
00311 ptr = path + length - 1;
00312 while (ptr != path) {
00313 if (IS_DIR_CHAR(*ptr)) {
00314 count--;
00315 if (!count)
00316 break;
00317 }
00318 ptr--;
00319 }
00320 if (IS_DIR_CHAR(*ptr)) ptr++;
00321 return((char *) ptr);
00322 }
00323
00324 char *cs_last_name_of_path(const char *path)
00325 {
00326 return cs_last_name_of_path(path, 1);
00327 }
00328
00329
00330 char *cs_last_directory_of_path(const char *path)
00331 {
00332 size_t length;
00333 const char *ptr;
00334
00335 length = strlen(path);
00336 if (!length)
00337 return((char *)path);
00338 ptr = path + length - 1;
00339 if (IS_DIR_CHAR(*ptr))
00340 ptr--;
00341 while (ptr != path && !IS_DIR_CHAR(*ptr)) ptr--;
00342 if (IS_DIR_CHAR(*ptr)) ptr++;
00343 return((char *)ptr);
00344 }
00345
00346 const char *cs_find_extension(const char *file_name)
00347 {
00348 const char *ptr;
00349
00350 for (ptr = file_name + strlen(file_name) - 1; ptr >= file_name; ptr--) {
00351 if (IS_DIR_CHAR(*ptr))
00352 break;
00353 if (*ptr == '.')
00354 return ptr + 1;
00355 }
00356 return NULL;
00357 }
00358
00359 void cs_remove_extension(char *file_name)
00360 {
00361 char *ptr = (char *) cs_find_extension(file_name);
00362
00363 if (ptr)
00364 *(ptr - 1) = 0;
00365 }
00366
00367 bool cs_is_extension(const char *file_name, const char *ext)
00368 {
00369 const char *ptr;
00370
00371 if ((ptr = cs_find_extension(file_name)))
00372 return strcmp(ptr, ext) == 0;
00373 return false;
00374 }
00375
00376
00377
00378
00379
00380 bool cs_remove_dir_char(char *dir_name)
00381 {
00382 size_t length;
00383
00384 length = strlen(dir_name);
00385 if (length > 1) {
00386 if (IS_DIR_CHAR(dir_name[length - 1])) {
00387 dir_name[length - 1] = '\0';
00388 return true;
00389 }
00390 }
00391 return false;
00392 }
00393
00394 void cs_remove_last_name_of_path(char *path)
00395 {
00396 char *ptr;
00397
00398 if ((ptr = cs_last_name_of_path(path)))
00399 *ptr = 0;
00400 }
00401
00402 static void cs_remove_last_directory_of_path(char *path)
00403 {
00404 char *ptr;
00405
00406 if ((ptr = cs_last_directory_of_path(path)))
00407 *ptr = 0;
00408 }
00409
00410 bool cs_add_dir_char(size_t max, char *path)
00411 {
00412 size_t slen = strlen(path);
00413
00414 if (slen >= max)
00415 return false;
00416
00417 if (slen == 0) {
00418
00419
00420
00421 return false;
00422 }
00423
00424 if (!IS_DIR_CHAR(path[slen - 1])) {
00425 path[slen] = CS_DIR_CHAR;
00426 path[slen + 1] = '\0';
00427 return true;
00428 }
00429 return false;
00430 }
00431
00432 bool cs_is_absolute(const char *path)
00433 {
00434 return IS_DIR_CHAR(*path);
00435 }
00436
00437 void cs_add_name_to_path(size_t max, char *path, const char *name)
00438 {
00439 char *end_ptr = path + max - 1;
00440
00441 cs_add_dir_char(max, path);
00442 path = path + strlen(path);
00443
00444 if (IS_DIR_CHAR(*name))
00445 name++;
00446 while (*name && !IS_DIR_CHAR(*name) && path < end_ptr)
00447 *path++ = *name++;
00448 *path = 0;
00449 }
00450
00451 const char *cs_next_name_of_path(const char *path)
00452 {
00453 if (IS_DIR_CHAR(*path))
00454 path++;
00455 while (*path && !IS_DIR_CHAR(*path))
00456 path++;
00457 if (IS_DIR_CHAR(*path))
00458 path++;
00459 return path;
00460 }
00461
00462 static void cs_adjust_absolute_path(size_t max, char *path, const char *rel_path)
00463 {
00464 while (*rel_path) {
00465 if (*rel_path == '.') {
00466 if (*(rel_path + 1) == '.') {
00467 if (!*(rel_path + 2) || IS_DIR_CHAR(*(rel_path + 2))) {
00468
00469 cs_remove_last_directory_of_path(path);
00470 goto loop;
00471 }
00472 }
00473 else {
00474 if (!*(rel_path + 1) || IS_DIR_CHAR(*(rel_path + 1)))
00475
00476 goto loop;
00477 }
00478 }
00479
00480
00481 cs_add_name_to_path(max, path, rel_path);
00482 loop:
00483 rel_path = cs_next_name_of_path(rel_path);
00484 }
00485 }
00486
00487 void cs_make_absolute_path(size_t max, char *path, const char *rel_path, const char *cwd)
00488 {
00489 if (cs_is_absolute(rel_path))
00490 cs_strcpy(max, path, rel_path);
00491 else {
00492
00493 cs_strcpy(max, path, cwd);
00494 cs_adjust_absolute_path(max, path, rel_path);
00495 }
00496 cs_remove_dir_char(path);
00497 }
00498
00499 char *cs_strdup(const char *in_str)
00500 {
00501 char *str;
00502
00503 if (!in_str)
00504 return NULL;
00505
00506 str = (char *) cs_malloc(strlen(in_str) + 1);
00507 strcpy(str, in_str);
00508 return str;
00509 }
00510
00511 char *cs_strdup(int i)
00512 {
00513 char buffer[20];
00514 char *str;
00515
00516 snprintf(buffer, 20, "%d", i);
00517 str = (char *) cs_malloc(strlen(buffer) + 1);
00518 strcpy(str, buffer);
00519 return str;
00520 }
00521
00522 char *cs_strdup(const char *in_str, size_t len)
00523 {
00524 char *str;
00525
00526 if (!in_str)
00527 return NULL;
00528
00529 str = (char *) cs_malloc(len + 1);
00530
00531
00532 size_t str_len = strlen(in_str);
00533 if (len > str_len)
00534 len = str_len;
00535
00536 memcpy(str, in_str, len);
00537 str[len] = 0;
00538 return str;
00539 }
00540
00541 bool cs_starts_with(const char *cstr, const char *w_cstr)
00542 {
00543 while (*cstr && *w_cstr) {
00544 if (*cstr != *w_cstr)
00545 return false;
00546 cstr++;
00547 w_cstr++;
00548 }
00549 return *cstr || !*w_cstr;
00550 }
00551
00552 bool cs_ends_with(const char *cstr, const char *w_cstr)
00553 {
00554 size_t len = strlen(cstr);
00555 size_t w_len = strlen(w_cstr);
00556 const char *ptr = cstr + len - 1;
00557 const char *w_ptr = w_cstr + w_len - 1;
00558
00559 if (w_len > len)
00560 return false;
00561
00562 if (w_len == 0)
00563 return false;
00564
00565 while (w_ptr >= w_cstr) {
00566 if (*w_ptr != *ptr)
00567 return false;
00568 w_ptr--;
00569 ptr--;
00570 }
00571
00572 return true;
00573 }
00574
00575 void cs_replace_string(size_t size, char *into, const char *find_str, const char *str)
00576 {
00577 char *ptr;
00578
00579 if ((ptr = strstr(into, find_str))) {
00580 size_t len = strlen(into);
00581 size_t len2 = strlen(str);
00582 size_t len3 = strlen(find_str);
00583
00584 if (len + len2 + len3 >= size)
00585 len2 = size - len;
00586
00587 memmove(ptr+len2, ptr+len3, len - (ptr + len3 - into));
00588 memcpy(ptr, str, len2);
00589 into[len + len2 - len3] = 0;
00590 }
00591 }
00592
00593 void cs_replace_string(size_t size, char *into, const char ch, const char *str)
00594 {
00595 char *ptr;
00596
00597 if ((ptr = strchr(into, ch))) {
00598 size_t len = strlen(into);
00599 size_t len2 = strlen(str);
00600
00601 if ((len + len2) > size)
00602 len2 = size - len;
00603
00604 memmove(ptr+1, ptr+len2, len - (ptr - into + 1));
00605 memcpy(ptr, str, len2);
00606 into[len + len2 - 1] = 0;
00607 }
00608 }
00609
00610 uint64_t cs_str_to_word8(const char *ptr, bool *overflow)
00611 {
00612 uint64_t value = 0;
00613
00614 if (overflow)
00615 *overflow = false;
00616 while (*ptr == '0') ptr++;
00617 if (!*ptr)
00618 value = (uint64_t) 0;
00619 else {
00620 sscanf(ptr, "%"PRIu64"", &value);
00621 if (!value && overflow)
00622 *overflow = true;
00623 }
00624 return value;
00625 }
00626
00627 int64_t cs_str_to_int8(const char *ptr, bool *overflow)
00628 {
00629 int64_t value = 0;
00630
00631 if (overflow)
00632 *overflow = false;
00633 while (*ptr == '0') ptr++;
00634 if (!*ptr)
00635 value = (int64_t) 0;
00636 else {
00637 sscanf(ptr, "%"PRId64"", &value);
00638 if (!value && overflow)
00639 *overflow = true;
00640 }
00641 return value;
00642 }
00643
00644 int64_t cs_byte_size_to_int8(const char *ptr, bool *invalid)
00645 {
00646 char *end_ptr;
00647 int64_t size;
00648
00649 if (invalid)
00650 *invalid = false;
00651
00652 while (*ptr && isspace(*ptr))
00653 ptr++;
00654
00655 if (!isdigit(*ptr) && *ptr != '.')
00656 goto failed;
00657
00658 size = (int64_t) strtod(ptr, &end_ptr);
00659
00660 ptr = end_ptr;
00661 while (*ptr && isspace(*ptr))
00662 ptr++;
00663
00664 switch (toupper(*ptr)) {
00665 case 'P':
00666 size *= (int64_t) 1024;
00667 case 'T':
00668 size *= (int64_t) 1024;
00669 case 'G':
00670 size *= (int64_t) 1024;
00671 case 'M':
00672 size *= (int64_t) 1024;
00673 case 'K':
00674 size *= (int64_t) 1024;
00675 ptr++;
00676 break;
00677 case '\0':
00678 break;
00679 default:
00680 goto failed;
00681 }
00682
00683 if (toupper(*ptr) == 'B')
00684 ptr++;
00685
00686 while (*ptr && isspace(*ptr))
00687 ptr++;
00688
00689 if (*ptr)
00690 goto failed;
00691
00692 return (int64_t) size;
00693
00694 failed:
00695 if (invalid)
00696 *invalid = true;
00697 return 0;
00698 }
00699
00700
00701 static uint32_t cs_hex_value(char ch)
00702 {
00703 u_char uch = (u_char) ch;
00704
00705 if (uch >= '0' && uch <= '9')
00706 return uch - '0';
00707 if (uch >= 'A' && uch <= 'F')
00708 return uch - 'A' + 10;
00709 if (uch >= 'a' && uch <= 'f')
00710 return uch - 'a' + 10;
00711 return 0;
00712 }
00713
00714 size_t cs_hex_to_bin(size_t size, void *v_bin, size_t len, const char *hex)
00715 {
00716 size_t tot_size = size;
00717 uint32_t val = 0;
00718 size_t shift = 0;
00719 u_char *bin = (u_char *) v_bin;
00720
00721 if (len & 1)
00722 shift = 1;
00723 for (size_t i=shift; i<len+shift && size > 0; i++) {
00724 if (i & 1) {
00725 val = val | cs_hex_value(*hex);
00726 *bin = val;
00727 bin++;
00728 size--;
00729 }
00730 else
00731 val = cs_hex_value(*hex) << 4;
00732 hex++;
00733 }
00734 return tot_size - size;
00735 }
00736
00737 size_t cs_hex_to_bin(size_t size, void *bin, const char *hex)
00738 {
00739 return cs_hex_to_bin(size, bin, strlen(hex), hex);
00740 }
00741
00742 #define HEX_DIGIT(x) ((x) <= 9 ? '0' + (x) : 'A' + ((x) - 10))
00743
00744
00745 void cs_bin_to_hex(size_t size, char *hex, size_t len, const void *v_bin)
00746 {
00747 const u_char *bin = (u_char *) v_bin;
00748 if (size == 0)
00749 return;
00750 size--;
00751 for (size_t i=0; i<len && size > 0; i++) {
00752 *hex = HEX_DIGIT(*bin >> 4);
00753 hex++;
00754 size--;
00755 if (size == 0)
00756 break;
00757 *hex = HEX_DIGIT(*bin & 0x0F);
00758 hex++;
00759 size--;
00760 bin++;
00761 }
00762 *hex = 0;
00763 }
00764
00765 void cs_strToUpper(char *ptr)
00766 {
00767 while (*ptr) {
00768 *ptr = toupper(*ptr);
00769 ptr++;
00770 }
00771 }
00772
00773 void cs_strToLower(char *ptr)
00774 {
00775 while (*ptr) {
00776 *ptr = tolower(*ptr);
00777 ptr++;
00778 }
00779 }
00780
00781
00782
00783
00784 bool cs_str_to_value(const char *ptr, uint32_t *value, uint8_t base)
00785 {
00786 char *endptr;
00787
00788 *value = strtoul(ptr, &endptr, base);
00789 return *endptr ? false : true;
00790 }
00791
00792