예제 #1
0
/**
 * 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;
}
예제 #2
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)++;
}
예제 #3
0
파일: json.c 프로젝트: cdecker/lightning
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;
}
예제 #4
0
파일: parsehelp.c 프로젝트: Minipig/dpkg
/**
 * 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;
}
예제 #5
0
파일: autoref.c 프로젝트: ellguth/apt-dater
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;
}
예제 #6
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;
}
예제 #7
0
파일: version.c 프로젝트: nisc-code/dpkg
/**
 * 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;
}
예제 #8
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;
}
예제 #9
0
파일: string.c 프로젝트: smcv/dpkg
/**
 * 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;
}
예제 #10
0
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;
}
예제 #11
0
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");

}
예제 #12
0
파일: version.c 프로젝트: nisc-code/dpkg
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;
}
예제 #13
0
파일: stats.c 프로젝트: carriercomm/stats
/* 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;
}