libopkg: support https_proxy
[project/opkg-lede.git] / libopkg / parse_util.c
1 /* parse_util.c - the opkg package management system
2
3 Copyright (C) 2009 Ubiq Technologies <graham.gower@gmail.com>
4
5 Steven M. Ayer
6 Copyright (C) 2002 Compaq Computer Corporation
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17 */
18
19 #include <ctype.h>
20
21 #include "opkg_utils.h"
22 #include "libbb/libbb.h"
23
24 #include "parse_util.h"
25 #include "pkg_parse.h"
26
27 int is_field(const char *type, const char *line)
28 {
29 if (!strncmp(line, type, strlen(type)))
30 return 1;
31 return 0;
32 }
33
34 char *parse_simple(const char *type, const char *line)
35 {
36 char *field = trim_xstrdup(line + strlen(type) + 1);
37 if (strlen(field) == 0) {
38 free(field);
39 return NULL;
40 }
41 return field;
42 }
43
44 /*
45 * Parse a comma separated string into an array.
46 */
47 char **parse_list(const char *raw, unsigned int *count, const char sep,
48 int skip_field)
49 {
50 char **depends = NULL;
51 const char *start, *end;
52 int line_count = 0;
53
54 /* skip past the "Field:" marker */
55 if (!skip_field) {
56 while (*raw && *raw != ':')
57 raw++;
58 raw++;
59 }
60
61 if (line_is_blank(raw)) {
62 *count = line_count;
63 return NULL;
64 }
65
66 while (*raw) {
67 depends = xrealloc(depends, sizeof(char *) * (line_count + 1));
68
69 while (isspace(*raw))
70 raw++;
71
72 start = raw;
73 while (*raw != sep && *raw)
74 raw++;
75 end = raw;
76
77 while (end > start && isspace(*end))
78 end--;
79
80 if (sep == ' ')
81 end++;
82
83 depends[line_count] = xstrndup(start, end - start);
84
85 line_count++;
86 if (*raw == sep)
87 raw++;
88 }
89
90 *count = line_count;
91 return depends;
92 }
93
94 int
95 parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE * fp,
96 uint mask, char **buf0, size_t buf0len)
97 {
98 int ret, lineno;
99 char *buf, *nl;
100 size_t buflen;
101
102 lineno = 1;
103 ret = 0;
104
105 buflen = buf0len;
106 buf = *buf0;
107 buf[0] = '\0';
108
109 while (1) {
110 if (fgets(buf, (int)buflen, fp) == NULL) {
111 if (ferror(fp)) {
112 opkg_perror(ERROR, "fgets");
113 ret = -1;
114 } else if (strlen(*buf0) == buf0len - 1) {
115 opkg_msg(ERROR, "Missing new line character"
116 " at end of file!\n");
117 parse_line(item, *buf0, mask);
118 }
119 break;
120 }
121
122 nl = strchr(buf, '\n');
123 if (nl == NULL) {
124 if (strlen(buf) < buflen - 1) {
125 /*
126 * Line could be exactly buflen-1 long and
127 * missing a newline, but we won't know until
128 * fgets fails to read more data.
129 */
130 opkg_msg(ERROR, "Missing new line character"
131 " at end of file!\n");
132 parse_line(item, *buf0, mask);
133 break;
134 }
135 if (buf0len >= EXCESSIVE_LINE_LEN) {
136 opkg_msg(ERROR, "Excessively long line at "
137 "%d. Corrupt file?\n", lineno);
138 ret = -1;
139 break;
140 }
141
142 /*
143 * Realloc and point buf past the data already read,
144 * at the NULL terminator inserted by fgets.
145 * |<--------------- buf0len ----------------->|
146 * | |<------- buflen ---->|
147 * |---------------------|---------------------|
148 * buf0 buf
149 */
150 buflen = buf0len + 1;
151 buf0len *= 2;
152 *buf0 = xrealloc(*buf0, buf0len);
153 buf = *buf0 + buflen - 2;
154
155 continue;
156 }
157
158 *nl = '\0';
159
160 lineno++;
161
162 if (parse_line(item, *buf0, mask))
163 break;
164
165 buf = *buf0;
166 buflen = buf0len;
167 buf[0] = '\0';
168 }
169
170 return ret;
171 }