/** * Parse a version string and check for invalid syntax. * * Distinguish between lax (warnings) and strict (error) parsing. * * @param rversion The parsed version. * @param string The version string to parse. * @param err The warning or error message if any. * * @retval 0 On success. * @retval -1 On failure, and err is set accordingly. */ int parseversion(struct versionrevision *rversion, const char *string, struct dpkg_error *err) { char *hyphen, *colon, *eepochcolon; const char *end, *ptr; unsigned long epoch; if (!*string) return dpkg_put_error(err, _("version string is empty")); /* Trim leading and trailing space. */ while (*string && isblank(*string)) string++; /* String now points to the first non-whitespace char. */ end = string; /* Find either the end of the string, or a whitespace char. */ while (*end && !isblank(*end)) end++; /* Check for extra chars after trailing space. */ ptr = end; while (*ptr && isblank(*ptr)) ptr++; if (*ptr) return dpkg_put_error(err, _("version string has embedded spaces")); colon= strchr(string,':'); if (colon) { epoch= strtoul(string,&eepochcolon,10); if (colon != eepochcolon) return dpkg_put_error(err, _("epoch in version is not number")); if (!*++colon) return dpkg_put_error(err, _("nothing after colon in version number")); string= colon; rversion->epoch= epoch; } else { rversion->epoch= 0; } rversion->version= nfstrnsave(string,end-string); hyphen= strrchr(rversion->version,'-'); if (hyphen) *hyphen++ = '\0'; rversion->revision= hyphen ? hyphen : ""; /* XXX: Would be faster to use something like cisversion and cisrevision. */ ptr = rversion->version; if (*ptr && !cisdigit(*ptr++)) return dpkg_put_warn(err, _("version number does not start with digit")); for (; *ptr; ptr++) { if (!cisdigit(*ptr) && !cisalpha(*ptr) && strchr(".-+~:", *ptr) == NULL) return dpkg_put_warn(err, _("invalid character in version number")); } for (ptr = rversion->revision; *ptr; ptr++) { if (!cisdigit(*ptr) && !cisalpha(*ptr) && strchr(".+~", *ptr) == NULL) return dpkg_put_warn(err, _("invalid character in revision number")); } return 0; }
/* Do a quick check if vstring is a valid versionnumber. Valid in this case * means it contains at least one digit. If an error is found increment * *errs. */ static void checkversion(const char *vstring, const char *valuename, int *errs) { const char *p; if (!vstring || !*vstring) return; for (p=vstring; *p; p++) if (cisdigit(*p)) return; fprintf(stderr, _("dpkg-deb - error: %s (`%s') doesn't contain any digits\n"), valuename, vstring); (*errs)++; }
bool json_tok_is_num(const char *buffer, const jsmntok_t *tok) { if (tok->type != JSMN_PRIMITIVE) return false; for (int i = tok->start; i < tok->end; i++) if (!cisdigit(buffer[i])) return false; return true; }
/** * Check for invalid syntax in version structure. * * The rest of the syntax has been already checked in parseversion_lax(). So * we only do the stricter checks here. * * @param rversion The version to verify. * * @return An error string, or NULL if eveyrthing was ok. */ static const char * version_strict_check(struct versionrevision *rversion) { const char *ptr; /* XXX: Would be faster to use something like cisversion and cisrevision. */ ptr = rversion->version; if (*ptr && !cisdigit(*ptr++)) return _("version number does not start with digit"); for (; *ptr; ptr++) { if (!cisdigit(*ptr) && !cisalpha(*ptr) && strchr(".-+~:", *ptr) == NULL) return _("invalid character in version number"); } for (ptr = rversion->revision; *ptr; ptr++) { if (!cisdigit(*ptr) && !cisalpha(*ptr) && strchr(".+~", *ptr) == NULL) return _("invalid character in revision number"); } return NULL; }
static int verrevcmp(const char *val, const char *ref) { if (!val) val= ""; if (!ref) ref= ""; while (*val || *ref) { int first_diff= 0; while ( (*val && !cisdigit(*val)) || (*ref && !cisdigit(*ref)) ) { int vc= order(*val), rc= order(*ref); if (vc != rc) return vc - rc; val++; ref++; } while ( *val == '0' ) val++; while ( *ref == '0' ) ref++; while (cisdigit(*val) && cisdigit(*ref)) { if (!first_diff) first_diff= *val - *ref; val++; ref++; } if (cisdigit(*val)) return 1; if (cisdigit(*ref)) return -1; if (first_diff) return first_diff; } return 0; }
static int ulist_select(const struct dirent *de) { const char *p; int l; for (p= de->d_name, l=0; *p; p++, l++) if (!cisdigit(*p)) return 0; if (l > IMPORTANTMAXLEN) ohshit(_("updates directory contains file `%.250s' whose name is too long " "(length=%d, max=%d)"), de->d_name, l, IMPORTANTMAXLEN); if (updateslength == -1) updateslength= l; else if (l != updateslength) ohshit(_("updates directory contains files with different length names " "(both %d and %d)"), l, updateslength); return 1; }
/** * Give a weight to the character to order in the version comparison. * * @param c An ASCII character. */ static int order(int c) { if (cisdigit(c)) return 0; else if (cisalpha(c)) return c; else if (c == '~') return -1; else if (c) return c + 256; else return 0; }
static char *demangle_string(char *string) { unsigned int i; const char mapfrom[] = "abfnrtv"; const char mapto[] = "\a\b\f\n\r\t\v"; if (!strchr(string, '"')) return NULL; string = strchr(string, '"') + 1; if (!strrchr(string, '"')) return NULL; *strrchr(string, '"') = '\0'; for (i = 0; i < strlen(string); i++) { if (string[i] == '\\') { char repl; unsigned len = 0; const char *p = strchr(mapfrom, string[i+1]); if (p) { repl = mapto[p - mapfrom]; len = 1; } else if (strlen(string+i+1) >= 3) { if (string[i+1] == 'x') { repl = (string[i+2]-'0')*16 + string[i+3]-'0'; len = 3; } else if (cisdigit(string[i+1])) { repl = (string[i+2]-'0')*8*8 + (string[i+3]-'0')*8 + (string[i+4]-'0'); len = 3; } } if (len == 0) { repl = string[i+1]; len = 1; } string[i] = repl; memmove(string + i + 1, string + i + len + 1, strlen(string + i + len + 1) + 1); } } return string; }
/** * Quote shell metacharacters in a string. * * This function allows passing strings to commands without splitting the * arguments, like in system(3) * * @param src The source string to escape. * * @return The new allocated string (never NULL). */ char * str_quote_meta(const char *src) { char *new_dst, *dst; new_dst = dst = m_malloc(strlen(src) * 2); while (*src) { if (!cisdigit(*src) && !cisalpha(*src)) *dst++ = '\\'; *dst++ = *src++; } *dst = '\0'; return new_dst; }
static int internal_sub(const CHAR_TYPE* s, const CHAR_TYPE* source, regmatch matches[10], CHAR_TYPE* dest) { register int length = 0; register int no; register const CHAR_TYPE* src = source; register int len = 0; register CHAR_TYPE* dst = dest; register CHAR_TYPE c; while ((c = *src++) != LIT('\0')) { if (c == LIT('&')) no = 0; else if (c == LIT('\\') && cisdigit(*src)) no = *src++ - LIT('0'); else no = -1; if (no < 0) { /* Ordinary character. */ if (c == LIT('\\') && (*src == LIT('\\') || *src == LIT('&'))) c = *src++; ++length; if(dst) *dst++ = c; } else if (matches[no].begin != -1 && matches[no].end != -1 && matches[no].end > matches[no].begin) { len = matches[no].end - matches[no].begin; length += len; if(dst) { cstrncpy(dst, s + matches[no].begin, len); dst += len; if(*(dst - 1) == LIT('\0')) return REGEXP_EEND; } } } if(dst) { *dst++ = LIT('\0'); return 1; } else return length + 1; }
void main() { char x; printf("Enter any character: "); scanf("%c", &x); if(cisalpha(x)) { if(cisupper(x)) printf("Uppercase Alphabet"); else printf("Lowercase Alphabet"); } else if(cisdigit(x)) printf("Number"); else printf("Special symbol"); }
static int verrevcmp(const char *a, const char *b) { if (a == NULL) a = ""; if (b == NULL) b = ""; while (*a || *b) { int first_diff = 0; while ((*a && !cisdigit(*a)) || (*b && !cisdigit(*b))) { int ac = order(*a); int bc = order(*b); if (ac != bc) return ac - bc; a++; b++; } while (*a == '0') a++; while (*b == '0') b++; while (cisdigit(*a) && cisdigit(*b)) { if (!first_diff) first_diff = *a - *b; a++; b++; } if (cisdigit(*a)) return 1; if (cisdigit(*b)) return -1; if (first_diff) return first_diff; } return 0; }
/* We want "finished in100 seconds to match "finished in 5 seconds". */ struct pattern *get_pattern(const char *line, struct values **vals) { enum pattern_type state = LITERAL; size_t len, i, max_parts = 3; struct pattern_part part; struct pattern *p; *vals = malloc(valsize(max_parts)); p = malloc(partsize(max_parts)); p->text = line; p->num_parts = 0; for (i = len = 0; state != TERM; i++, len++) { enum pattern_type old_state = state; bool starts_num; union val v; starts_num = (line[i] == '-' && cisdigit(line[i+1])) || cisdigit(line[i]); switch (state) { case LITERAL: if (starts_num) { state = INTEGER; break; } else if (cisspace(line[i])) { state = PRESPACES; break; } break; case PRESPACES: if (starts_num) { state = INTEGER; break; } else if (!cisspace(line[i])) { state = LITERAL; } break; case INTEGER: if (line[i] == '.') { if (cisdigit(line[i+1])) { /* Was float all along... */ state = old_state = FLOAT; } else state = LITERAL; break; } /* fall thru */ case FLOAT: if (cisspace(line[i])) { state = PRESPACES; break; } else if (!cisdigit(line[i])) { state = LITERAL; break; } break; case TERM: abort(); } if (!line[i]) state = TERM; if (state == old_state) continue; part.type = old_state; part.len = len; part.off = i - len; /* Make sure identical values memcmp in find_literal_numbers */ memset(&v, 0, sizeof(v)); if (old_state == FLOAT) { char *end; v.dval = strtod(line + part.off, &end); if (end != line + i) { warnx("Could not parse float '%.*s'", (int)len, line + i - len); } else { add_part(&p, vals, &part, &v, &max_parts); } len = 0; } else if (old_state == INTEGER) { char *end; v.ival = strtoll(line + part.off, &end, 10); if (end != line + i) { warnx("Could not parse integer '%.*s'", (int)len, line + i - len); } else { add_part(&p, vals, &part, &v, &max_parts); } len = 0; } else if (old_state == LITERAL && len > 0) { /* Since we can go to PRESPACES and back, we can * have successive literals. Collapse them. */ if (p->num_parts > 0 && p->part[p->num_parts-1].type == LITERAL) { p->part[p->num_parts-1].len += len; len = 0; continue; } add_part(&p, vals, &part, &v, &max_parts); len = 0; } } return p; }