#define _POSIX_C_SOURCE 200809L #include #include #include #include #include "zpm.h" #define DMARK fprintf(stderr, "mark %s %s:%d\n", __FILE__, __func__, __LINE__) int zpm_parse_version(const char *pstr, struct zpm_version_info *info) { int cur = 0, ch; info->verstr = pstr; info->name = 0; info->namelen = 0; info->version = 0; info->verlen = 0; info->release = -1; info->rellen = 0; info->relstr = 0; if (!pstr) { return 0; } /* skip leading whitespace */ while (isspace(pstr[cur])) { cur++; } /* get the name, if any */ if (isalpha(pstr[cur])) { info->name = pstr + cur; for (ch = pstr[cur]; ch; ch = pstr[++cur]) { if (ch == '-') { if (isdigit(pstr[cur+1])) { break; } } if (!isgraph(ch)) { break; } info->namelen++; } } while (pstr[cur] == '-') { cur++; } /* should be pointing at a digit. if not, we're done */ if (isdigit(pstr[cur])) { info->version = pstr + cur; for (ch = pstr[cur]; ch; ch = pstr[++cur]) { if (ch == '-') { break; } if (!isgraph(ch)) { break; } info->verlen++; } } while (pstr[cur] == '-') { cur++; } if (isdigit(pstr[cur])) { info->relstr = pstr + cur; while (isdigit(pstr[cur++])) { info->rellen++; } } if (info->relstr) { info->release = atoi(info->relstr); } return info->namelen || info->verlen || info->rellen; } int zpm_parse_package(char *pstr, char *name, char *ver, int *rel) { if (name) *name = 0; if (ver) *ver = 0; if (rel) *rel = 0; int havename = 0; int havever = 0; int haverel = 0; /* string - ver - rel */ /* rel is all digits */ /* possible forms: * ^(.+)-([0-9][^-]*)-([\d+])$ * ^(.+)-([0-9][^-]*)$ * ^(.+)$ * The main problem in parsing is that the package name itself * can contain a '-', so you can't just split on '-' * Also, the version can be just digits. */ /* everything up to the first '-' is in the name */ while (*pstr) { if (*pstr == '\'' || !isgraph(*pstr)) { return 0; } if (*pstr == '-' && isdigit(*(pstr+1))) { break; } if (name) { *name++ = *pstr; } pstr++; havename = 1; } if (name) *name = 0; if (*pstr == '-') { pstr++; } while (*pstr && *pstr != '-') { if (*pstr == '\'' || !isgraph(*pstr)) { return 0; } if (ver) { *ver++ = *pstr; } pstr++; havever = 1; } if (ver) *ver = 0; if (*pstr == '-') { pstr++; } /* TODO use strtol */ if (rel && *pstr) { haverel = 1; *rel = atoi(pstr); } return havename + havever + haverel; }