📄 genutils.c
字号:
} } else{ if(*str == '\"'){ quoted = ! quoted; continue; } if(word){ *(word++) = *str; } } } if(word) *word = '\0'; return(first_nospace(str)); }Int32fprintwordq( FILE *file, UChar *word){ Int32 i; if(! word) i = fprintf(file, "\"\""); else if(word_count(word) != 1) i = fprintf(file, "\"%s\"", word); else i = fprintf(file, "%s", word); return(i);}Int32sprintwordq( UChar *str, UChar *word){ Int32 i; if(! word) i = sprintf(str, "\"\""); else if(word_count(word) != 1) i = sprintf(str, "\"%s\"", word); else i = sprintf(str, "%s", word); return(i);}Int32ffindword( FILE *fp, UChar *string){ UChar d[200]; do{ if(fscanword(fp, d) == EOF) return((Int32) EOF); } while(strcmp(d, string) != 0); return(NO_ERROR);}#ifndef HAVE_STRRSTR /* exists in HP-UX (!) */UChar *strrstr(UChar * string, UChar * substr){ Int32 len, sublen; UChar *cptr; if(!string || !substr) return(NULL); len = strlen(string); sublen = strlen(substr); if(len < sublen || len == 0 || sublen == 0) return(NULL); for(cptr = string + len - sublen; cptr >= string; cptr--) if(*cptr == substr[0]) if(!strncmp(cptr, substr, sublen)) return(cptr); return(NULL);}#endif#ifndef HAVE_STRCASECMPInt32strcasecmp(UChar * str1, UChar * str2){ UChar c1, c2; Int32 res; if(!str1 && !str2) return(0); if(!str2) return(1); if(!str1) return(-1); forever{ c1 = tolower(*str1++); c2 = tolower(*str2++); if (c1 == '\0' || c2 == '\0' || c1 != c2) return((Int32) c1 - (Int32) c2); }}#endif#ifndef HAVE_STRNCASECMPInt32strncasecmp(UChar * str1, UChar * str2, int maxcnt){ UChar c1, c2; Int32 res; if(!str1 && !str2) return(0); if(!str2) return(1); if(!str1) return(-1); while(0 < maxcnt--){ c1 = tolower(*str1++); c2 = tolower(*str2++); if (c1 == '\0' || c2 == '\0' || c1 != c2) return((Int32) c1 - (Int32) c2); } return(0);}#endif#ifndef HAVE_STRCASESTRUChar *strcasestr(UChar * str1, UChar * str2){ UChar *result = NULL, *lstr1, *lstr2, *cptr; if(!str1 || !str2){ errno = EINVAL; return(NULL); } lstr1 = strdup(str1); lstr2 = strdup(str2); if(!lstr1 || !lstr2) GETOUT; for(cptr = lstr1; *cptr; cptr++) *cptr = tolower(*cptr); for(cptr = lstr2; *cptr; cptr++) *cptr = tolower(*cptr); cptr = strstr(lstr1, lstr2); if(cptr) result = str1 + (cptr - lstr1); getout: ZFREE(lstr1); ZFREE(lstr2); return(result);}#endifUChar *strword(UChar * str, Int32 n){ Int32 numw, l; UChar *cptr; if(!str){ errno = EINVAL; return(NULL); } while(*str && isspace(*str)) str++; numw = word_count(str); if(numw < 1) return(NULL); if(n < 0) n += numw; if(n < 0 || n >= numw){ errno = ERANGE; return(NULL); } while(n > 0){ while(*str && !isspace(*str)) str++; while(*str && isspace(*str)) str++; n--; } for(cptr = str; *cptr && !isspace(*cptr); cptr++); l = cptr - str; cptr = NEWP(UChar, l + 1); if(cptr){ strncpy(cptr, str, l); cptr[l] = '\0'; } return(cptr);}/* * Takes a string of (potentially quoted) words <str>, and returns a malloc'd * copy of the n'th word (zero-indexed) in the string. * * If <n> is positive, the count is done from the beginning of the string. * If <n> is negative, the count is done from the end of the string. * * Returns NULL on error or if there are no words in <str>. On error, * errno is also set. */UChar *strwordq(UChar * str, Int32 n){ Int32 numw, l; UChar *cptr; if(!str){ errno = EINVAL; return(NULL); } while(*str && isspace(*str)) str++; numw = word_countq(str); if(numw < 1) return(NULL); if(n < 0) n += numw; if(n < 0 || n >= numw){ errno = ERANGE; return(NULL); } while(n > 0){ str = sscanwordq(str, NULL); n--; } /* * At this point, str points the n'th word. Determine the length of the * word, not including any trailing whitespace. Then allocate a buffer * of that length, and copy the word into that buffer, finally returning * the buffer. */ cptr = sscanwordq(str, NULL); l = cptr - str; while(isspace(str[l - 1])) l--; cptr = NEWP(UChar, l + 1); if(cptr) sscanwordq(str, cptr); return(cptr);}inttrailingint(UChar * str){ int mul = 1, r = 0; str += strlen(str) - 1; while(isspace(*str)) str--; while(isdigit(*str)){ r += mul * (*str - '0'); mul *= 10; str--; } return(r);}Flagchop(UChar * line){ UChar *cptr; if(!line) return(NO); cptr = line + strlen(line) - 1; if(cptr >= line && *cptr == '\n'){ *cptr = '\0'; return(YES); } return(NO);}UChar *word_skip(UChar * cptr, Int32 num, Int32 walk){ Int32 dir; if(walk < 0) num = - num; if(num == 0){ dir = (isspace(*cptr) ? 1 : -1); } else{ dir = (num > 0 ? 1 : -1); num = (num > 0 ? num - 1 : - num); } if(walk > 0){ walk = 1; } else{ walk = -1; dir = - dir; } forever{ while(*cptr && !isspace(*cptr)) cptr += dir; while(*cptr && isspace(*cptr)) cptr += walk; if(num == 0) break; if(dir * walk < 0){ cptr -= walk; while(*cptr && isspace(*cptr)) cptr -= walk; } num--; } return(cptr);}Int32ffindwordb(FILE *fp, UChar *string) { UChar c; Int32 word_len; Int32 i; if (!fp || !string) return (EINVAL); word_len = strlen((char*)string); do { /* Erstes gesuchtes Zeichen finden */ do { if (fread(&c, sizeof(UChar), 1, fp) < 1) return (Int32)EOF; } while (c != string[0]); /* Erstes Zeichen gefunden, stimmt der Rest auch? */ for (i = 1; i < word_len && string[i-1] == c; i++) { if (fread(&c, sizeof(UChar), 1, fp) < 1) return (Int32)EOF; } /* for */ } while(i < word_len); return(NO_ERROR); } Int32ishn(UChar * str){ UChar c; while( (c = *(str++)) ){ if(!ishnchr(c)) return(0); } return(1);}Int32isfqhn(UChar * str){ UChar c; while( (c = *(str++)) ){ if(!isfqhnchr(c)) return(0); } return(1);}Int32minmax( Real64 *array, Int32 nr, Real64 *min, Real64 *max){ Int32 i; Real64 mini, maxi; if(nr <= 0) return(-1); mini = maxi = *array; for(i = 1; i < nr; i++){ if(*(array + i) > maxi) maxi = *(array + i); if(*(array + i) < mini) mini = *(array + i); } if(min) *min = mini; if(max) *max = maxi; return(NO_ERROR);}Int32strint(UChar * cptr, Int32 * r){ int i1, n; n = -1; if(!cptr || !r){ errno = EFAULT; return(-1); } if(sscanf(cptr, "%d%n", &i1, &n) < 1){ errno = EINVAL; return(-1); } *r = (Int32) i1; return(n);}Int32ffindchr(FILE * fp, UChar c){ UChar a; do{ if(fread(&a, sizeof(UChar), 1, fp) < 1) return((Int32) EOF); } while (c != a); return(NO_ERROR);}/* * Returns the number of words in <line>. This routine does not understand * quoting (words are strictly a sequence of non-whitespace characters). */Int32word_count(UChar * line){ Int32 i = 0, nr = 0; for (;;) { while (ISSPACE(line[i])) { if (line[i] == '\n' || line[i] == '\0') return (nr); i++; } if (line[i] == '\0') return (nr); nr++; while (!ISSPACE(line[i])) i++; }}/* * Counts the number of (potentially quoted) words in the string <line>. * Returns the count, or -1 on error. */Int32word_countq(UChar * line){ Int32 n; if(!line){ errno = EINVAL; return(-1); } n = 0; while(line){ if( (line = sscanwordq(line, NULL)) ) n++; } return(n);}static void__q_sort__( void *p1, void *p2, Uns32 size, UChar *array, void *buffer, Int32 (*str_cmp_func)(void *, void *)){ UChar *ptr1 = (UChar *) p1, *ptr2 = (UChar *) p2; Int32 forward = 1; if(ptr1 + size < ptr2){ memcpy(buffer, ptr2, size); do{ if(forward){ if(str_cmp_func(ptr1, buffer) > 0){ memcpy(ptr2, ptr1, size); forward = 0; } } else{ if(str_cmp_func(ptr2, buffer) < 0){ memcpy(ptr1, ptr2, size); forward = 1; } } if(forward) ptr1 += size; else ptr2 -= size; }while(ptr1 < ptr2); memcpy(ptr1, buffer, size); if((UChar *) p1 < ptr1 - size) __q_sort__(p1, ptr1 - size, size, array, buffer, str_cmp_func); if(ptr1 + size < (UChar *) p2) __q_sort__(ptr1 + size, p2, size, array, buffer, str_cmp_func); } else if(ptr1 + size == ptr2){ if(str_cmp_func(p1, p2) > 0){ memcpy(buffer, p1, size); memcpy(p1, p2, size); memcpy(p2, buffer, size); } }}void q_sort( void *base, Uns32 nel, Uns32 width, Int32 (*comp)(void *, void *)){ UChar *buffer, *array; if(nel < 2) return; array = (UChar *) base; buffer = NEWP(UChar, width); if(! buffer) return; nel--; if(nel == 1){ if(comp(array, array + width) > 0){ memcpy(buffer, array, width); memcpy(array, array + width, width); memcpy(array + width, buffer, width); } } else __q_sort__(array, array + nel * width, width, array, buffer, comp); free(buffer);}#define MODE_B_SEARCH 0#define MODE_B_LOCATE 1static void *_b_search_func( void *key, void *base, Uns32 nel, Uns32 size, Int32 (*comp)(void *, void *), Uns32 mode){ Int32 i, lowest, uppest, mid; UChar *upptr, *midptr; if(! size || ! key || ! base || ! comp || nel < 0) return(NULL); if(nel == 0) return(mode == MODE_B_LOCATE ? base : NULL); i = comp(key, base); if(! i) return(base); if(i < 0) return(mode == MODE_B_LOCATE ? base : NULL); if(nel == 1) return(mode == MODE_B_LOCATE ? (UChar *) base + size : NULL); uppest = nel - 1; upptr = (UChar *) base + uppest * size; i = comp(key, upptr); if(! i) return(upptr); if(i > 0) return(mode == MODE_B_LOCATE ? upptr + size : NULL); lowest = 0; while(uppest > lowest + 1){ mid = (uppest + lowest) >> 1; midptr = (UChar *) base + mid * size; i = comp(key, midptr); if(! i) return(midptr); if(i < 0) uppest = mid; else lowest = mid; } return(mode == MODE_B_LOCATE ? (UChar *) base + uppest * size : NULL);}void *b_search( void *key, void *base, Uns32 nel, Uns32 size, Int32 (*comp)(void *, void *)){ return(_b_search_func(key, base, nel, size, comp, MODE_B_SEARCH));}void *b_locate( void *key, void *base, Uns32 nel, Uns32 size, Int32 (*comp)(void *, void *)){ return(_b_search_func(key, base, nel, size, comp, MODE_B_LOCATE));}void *l_find( void *key, void *base, Uns32 *nelp, Uns32 width, Int32 (*comp)(void *, void *)){ UChar *ptr, *eptr; eptr = ((UChar *) base) + (*nelp * width); for(ptr = (UChar *) base; ptr < eptr; ptr += width){ if(comp(ptr, key) == 0) return(ptr); } return(NULL);}void *l_search( void *key, void *base, Uns32 *nelp, Uns32 width, Int32 (*comp)(void *, void *)){ UChar *ptr, *eptr; eptr = ((UChar *) base) + (*nelp * width); for(ptr = (UChar *) base; ptr < eptr; ptr += width){ if(comp(ptr, key) == 0) return(ptr); } (*nelp)++; base = realloc_forced(base, (*nelp * width)); eptr = ((UChar *) base) + width * (*nelp - 1); memcpy(eptr, key, width); return((void *) eptr);}#define PSIZE 200/* * Reads a line of data of arbitrary length from <fp> and returns the * result as a malloc'd buffer. Returns NULL on error. */UChar *fget_alloc_str(FILE * fp){ UChar piece[PSIZE]; UChar *line, *cptr; Int32 newlen, oldlen, plen; line = NULL; oldlen = 0; forever{ cptr = fgets(piece, PSIZE, fp); if(!cptr) return(line); plen = strlen(piece); if(line){ newlen = strlen(line) + plen + 1; line = SRENEWP(line, UChar, newlen, oldlen); oldlen = newlen; } else{ newlen = oldlen = plen + 1; line = SNEWP(UChar, newlen); if(line) line[0] = '\0'; } if(!line) return(NULL); strcat(line, piece); if(newlen > 1 && plen > 0) if(piece[plen - 1] == '\n' || (line[newlen - 2] != '\n' && plen < PSIZE - 1)) return(line); }}/* same as fget_alloc_str, but reuses malloc'ed memory space that *sptr * points to, if not NULL. The number of malloc'ed bytes is maintained * in *num_alloced. If many lines are to be read, using this function * is more efficient than fget_alloc_str. Returns a value < 0 on EOF * or error. Typical example (with fp already being initialized): * * UChar *line = NULL; * Int32 numchars = 0; * * while(!feof(fp)){ * if(fget_realloc_str(fp, &line, &numchars)) * continue; * ... do sth. with line ... * } */Int32fget_realloc_str(FILE * fp, UChar ** sptr, Int32 * num_alloced){ UChar piece[PSIZE]; UChar *cptr; Int32 newlen, plen, slen, n_all; Flag got_sth = NO; if(!sptr){ errno = EINVAL; return(-1); } slen = n_all = 0; if(*sptr) *sptr[0] = '\0'; if(num_alloced) n_all = *num_alloced; forever{ cptr = fgets(piece, PSIZE, fp); if(!cptr) break; got_sth = YES; plen = strlen(piece); newlen = slen + plen + 1; if(*sptr){ if(newlen > n_all){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -