fallthrough; case'\0': return length; default: goto out_err; /* two-letter suffices */ case'k': case'K':
length <<= 10; break; case'm': case'M':
length <<= 20; break; case'g': case'G':
length <<= 30; break; case't': case'T':
length <<= 40; break;
} /* we want the cases to match */ if (islower(c)) { if (strcmp(p, "b") != 0) goto out_err;
} else { if (strcmp(p, "B") != 0) goto out_err;
} return length;
out_err: return -1;
}
/* Character class matching */ staticbool __match_charclass(constchar *pat, char c, constchar **npat)
{ bool complement = false, ret = true;
if (*pat == '!') {
complement = true;
pat++;
} if (*pat++ == c) /* First character is special */ goto end;
while (*pat && *pat != ']') { /* Matching */ if (*pat == '-' && *(pat + 1) != ']') { /* Range */ if (*(pat - 1) <= c && c <= *(pat + 1)) goto end; if (*(pat - 1) > *(pat + 1)) goto error;
pat += 2;
} elseif (*pat++ == c) goto end;
} if (!*pat) goto error;
ret = false;
end: while (*pat && *pat != ']') /* Searching closing */
pat++; if (!*pat) goto error;
*npat = pat + 1; return complement ? !ret : ret;
error: returnfalse;
}
/* Glob/lazy pattern matching */ staticbool __match_glob(constchar *str, constchar *pat, bool ignore_space, bool case_ins)
{ while (*str && *pat && *pat != '*') { if (ignore_space) { /* Ignore spaces for lazy matching */ if (isspace(*str)) {
str++; continue;
} if (isspace(*pat)) {
pat++; continue;
}
} if (*pat == '?') { /* Matches any single character */
str++;
pat++; continue;
} elseif (*pat == '[') /* Character classes/Ranges */ if (__match_charclass(pat + 1, *str, &pat)) {
str++; continue;
} else returnfalse; elseif (*pat == '\\') /* Escaped char match as normal char */
pat++; if (case_ins) { if (tolower(*str) != tolower(*pat)) returnfalse;
} elseif (*str != *pat) returnfalse;
str++;
pat++;
} /* Check wild card */ if (*pat == '*') { while (*pat == '*')
pat++; if (!*pat) /* Tail wild card matches all */ returntrue; while (*str) if (__match_glob(str++, pat, ignore_space, case_ins)) returntrue;
} return !*str && !*pat;
}
/** * strglobmatch - glob expression pattern matching * @str: the target string to match * @pat: the pattern string to match * * This returns true if the @str matches @pat. @pat can includes wildcards * ('*','?') and character classes ([CHARS], complementation and ranges are * also supported). Also, this supports escape character ('\') to use special * characters as normal character. * * Note: if @pat syntax is broken, this always returns false.
*/ bool strglobmatch(constchar *str, constchar *pat)
{ return __match_glob(str, pat, false, false);
}
/** * strlazymatch - matching pattern strings lazily with glob pattern * @str: the target string to match * @pat: the pattern string to match * * This is similar to strglobmatch, except this ignores spaces in * the target string.
*/ bool strlazymatch(constchar *str, constchar *pat)
{ return __match_glob(str, pat, true, false);
}
/** * strtailcmp - Compare the tail of two strings * @s1: 1st string to be compared * @s2: 2nd string to be compared * * Return 0 if whole of either string is same as another's tail part.
*/ int strtailcmp(constchar *s1, constchar *s2)
{ int i1 = strlen(s1); int i2 = strlen(s2); while (--i1 >= 0 && --i2 >= 0) { if (s1[i1] != s2[i2]) return s1[i1] - s2[i2];
} return 0;
}
char *asprintf_expr_inout_ints(constchar *var, bool in, size_t nints, int *ints)
{ /* * FIXME: replace this with an expression using log10() when we * find a suitable implementation, maybe the one in the dvb drivers... * * "%s == %d || " = log10(MAXINT) * 2 + 8 chars for the operators
*/
size_t size = nints * 28 + 1; /* \0 */
size_t i, printed = 0; char *expr = malloc(size);
/* Like strpbrk(), but not break if it is right after a backslash (escaped) */ char *strpbrk_esc(char *str, constchar *stopset)
{ char *ptr;
do {
ptr = strpbrk(str, stopset); if (!ptr) { /* stopset not in str. */ break;
} if (ptr == str) { /* stopset character is first in str. */ break;
} if (ptr == str + 1 && str[0] != '\\') { /* stopset chacter is second and wasn't preceded by a '\'. */ break;
}
str = ptr + 1;
} while (ptr[-1] == '\\' && ptr[-2] != '\\');
return ptr;
}
/* Like strpbrk_esc(), but not break if it is quoted with single/double quotes */ char *strpbrk_esq(char *str, constchar *stopset)
{ char *_stopset = NULL; char *ptr; constchar *squote = "'"; constchar *dquote = "\"";
if (asprintf(&_stopset, "%s%c%c", stopset, *squote, *dquote) < 0) return NULL;
do {
ptr = strpbrk_esc(str, _stopset); if (!ptr) break; if (*ptr == *squote)
ptr = strpbrk_esc(ptr + 1, squote); elseif (*ptr == *dquote)
ptr = strpbrk_esc(ptr + 1, dquote); else break;
str = ptr + 1;
} while (ptr);
free(_stopset); return ptr;
}
/* Like strdup, but do not copy a single backslash */ char *strdup_esc(constchar *str)
{ char *s, *d, *p, *ret = strdup(str);
if (!ret) return NULL;
d = strchr(ret, '\\'); if (!d) return ret;
s = d + 1; do { if (*s == '\0') {
*d = '\0'; break;
}
p = strchr(s + 1, '\\'); if (p) {
memmove(d, s, p - s);
d += p - s;
s = p + 1;
} else
memmove(d, s, strlen(s) + 1);
} while (p);
return ret;
}
/* Remove backslash right before quote and return next quote address. */ staticchar *remove_consumed_esc(char *str, int len, int quote)
{ char *ptr = str, *end = str + len;
while (*ptr != quote && ptr < end) { if (*ptr == '\\' && *(ptr + 1) == quote) {
memmove(ptr, ptr + 1, end - (ptr + 1)); /* now *ptr is `quote`. */
end--;
}
ptr++;
}
return *ptr == quote ? ptr : NULL;
}
/* * Like strdup_esc, but keep quoted string as it is (and single backslash * before quote is removed). If there is no closed quote, return NULL.
*/ char *strdup_esq(constchar *str)
{ char *d, *ret;
/* If there is no quote, return normal strdup_esc() */
d = strpbrk_esc((char *)str, "\"'"); if (!d) return strdup_esc(str);
ret = strdup(str); if (!ret) return NULL;
d = ret; do {
d = strpbrk(d, "\\\"\'"); if (!d) break;
if (*d == '"' || *d == '\'') { /* This is non-escaped quote */ int quote = *d; int len = strlen(d + 1) + 1;
/* * Remove the start quote and remove consumed escape (backslash * before quote) and remove the end quote. If there is no end * quote, it is the input error.
*/
memmove(d, d + 1, len);
d = remove_consumed_esc(d, len, quote); if (!d) goto error;
memmove(d, d + 1, strlen(d + 1) + 1);
} if (*d == '\\') {
memmove(d, d + 1, strlen(d + 1) + 1); if (*d == '\\') { /* double backslash -- keep the second one. */
d++;
}
}
} while (*d != '\0');
return ret;
error:
free(ret); return NULL;
}
unsignedint hex(char c)
{ if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; return c - 'A' + 10;
}
/* * Replace all occurrences of character 'needle' in string 'haystack' with * string 'replace' * * The new string could be longer so a new string is returned which must be * freed.
*/ char *strreplace_chars(char needle, constchar *haystack, constchar *replace)
{ int replace_len = strlen(replace); char *new_s, *to; constchar *loc = strchr(haystack, needle); constchar *from = haystack; int num = 0;
/* Count occurrences */ while (loc) {
loc = strchr(loc + 1, needle);
num++;
}
/* Allocate enough space for replacements and reset first location */
new_s = malloc(strlen(haystack) + (num * (replace_len - 1) + 1)); if (!new_s) return NULL;
loc = strchr(haystack, needle);
to = new_s;
while (loc) { /* Copy original string up to found char and update positions */
memcpy(to, from, 1 + loc - from);
to += loc - from;
from = loc + 1;
/* Copy replacement string and update positions */
memcpy(to, replace, replace_len);
to += replace_len;
/* needle next occurrence or end of string */
loc = strchr(from, needle);
}
/* Copy any remaining chars + null */
strcpy(to, from);
return new_s;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.27 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.