]> pd.if.org Git - zpackage/blob - lib/parse.c
2451e3f007b332a9b49926313fa75c31c0020f7a
[zpackage] / lib / parse.c
1 #define _POSIX_C_SOURCE 200809L
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <ctype.h>
7
8 #include "zpm.h"
9
10 #define DMARK fprintf(stderr, "mark %s %s:%d\n", __FILE__, __func__, __LINE__)
11
12 int zpm_parse_version(const char *pstr, struct zpm_version_info *info) {
13         int cur = 0, ch;
14
15         info->verstr = pstr;
16         info->name = 0;
17         info->namelen = 0;
18         info->version = 0;
19         info->verlen = 0;
20         info->release = -1;
21         info->rellen = 0;
22         info->relstr = 0;
23
24         if (!pstr) {
25                 return 0;
26         }
27
28         /* skip leading whitespace */
29         while (isspace(pstr[cur])) {
30                 cur++;
31         }
32
33         /* get the name, if any */
34         if (isalpha(pstr[cur])) {
35                 info->name = pstr + cur;
36                 for (ch = pstr[cur]; ch; ch = pstr[++cur]) {
37                         if (ch == '-') {
38                                 if (isdigit(pstr[cur+1])) {
39                                         break;
40                                 }
41                         }
42                         if (!isgraph(ch)) {
43                                 break;
44                         }
45                         info->namelen++;
46                 }
47         }
48
49         while (pstr[cur] == '-') {
50                 cur++;
51         }
52
53         /* should be pointing at a digit.  if not, we're done */
54         if (isdigit(pstr[cur])) {
55                 info->version = pstr + cur;
56                 for (ch = pstr[cur]; ch; ch = pstr[++cur]) {
57                         if (ch == '-') {
58                                 break;
59                         }
60                         if (!isgraph(ch)) {
61                                 break;
62                         }
63                         info->verlen++;
64                 }
65         }
66
67         while (pstr[cur] == '-') {
68                 cur++;
69         }
70
71         if (isdigit(pstr[cur])) {
72                 info->relstr = pstr + cur;
73                 while (isdigit(pstr[cur++])) {
74                         info->rellen++;
75                 }
76         }
77
78         if (info->relstr) {
79                 info->release = atoi(info->relstr);
80         }
81
82         return info->namelen || info->verlen || info->rellen;
83 }
84
85 int zpm_parse_package(char *pstr, char *name, char *ver, int *rel) {
86         if (name) *name = 0;
87         if (ver) *ver = 0;
88         if (rel) *rel = 0;
89         int havename = 0;
90         int havever = 0;
91         int haverel = 0;
92
93         /* string - ver - rel */
94         /* rel is all digits */
95         /* possible forms:
96          * ^(.+)-([0-9][^-]*)-([\d+])$
97          * ^(.+)-([0-9][^-]*)$
98          * ^(.+)$
99          * The main problem in parsing is that the package name itself
100          * can contain a '-', so you can't just split on '-'
101          * Also, the version can be just digits.
102          */
103
104         /* everything up to the first '-' is in the name */
105         while (*pstr) {
106                 if (*pstr == '\'' || !isgraph(*pstr)) {
107                         return 0;
108                 }
109                 if (*pstr == '-' && isdigit(*(pstr+1))) {
110                         break;
111                 }
112                 if (name) {
113                         *name++ = *pstr;
114                 }
115                 pstr++;
116                 havename = 1;
117         }
118         if (name) *name = 0;
119         if (*pstr == '-') {
120                 pstr++;
121         }
122         while (*pstr && *pstr != '-') {
123                 if (*pstr == '\'' || !isgraph(*pstr)) {
124                         return 0;
125                 }
126                 if (ver) {
127                         *ver++ = *pstr;
128                 }
129                 pstr++;
130                 havever = 1;
131         }
132         if (ver) *ver = 0;
133         if (*pstr == '-') {
134                 pstr++;
135         }
136         /* TODO use strtol */
137         if (rel && *pstr) {
138                 haverel = 1;
139                 *rel = atoi(pstr);
140         }
141
142         return havename + havever + haverel;
143 }