Skip to content

Commit cbcc350

Browse files
committed
lib/format.c: split/cleanup code
1 parent 0ec41f5 commit cbcc350

1 file changed

Lines changed: 150 additions & 90 deletions

File tree

lib/format.c

Lines changed: 150 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -227,13 +227,76 @@ parse_u(const char **pos, unsigned int *u)
227227
}
228228

229229
static int
230-
parse(const char **pos, struct strbuf *buf, struct xbps_fmt_spec *spec, struct conversion *conversion)
230+
parse_humanize(const char **pos, struct humanize *humanize)
231231
{
232+
const char *scale = "BKMGTPE";
232233
const char *p = *pos;
233-
const char *e;
234-
int r;
234+
const char *p1;
235+
236+
/* default: !humanize .8Ki:8 */
237+
humanize->width = 8;
238+
humanize->minscale = 2;
239+
humanize->flags = HN_DECIMAL|HN_IEC_PREFIXES;
240+
humanize->flags = HN_NOSPACE;
241+
242+
/* humanize[ ][.][i][width][minscale[maxscale]] */
243+
244+
if (*p == ' ') {
245+
humanize->flags &= ~HN_NOSPACE;
246+
p++;
247+
}
248+
if (*p == '.') {
249+
humanize->flags |= HN_DECIMAL;
250+
p++;
251+
}
252+
if ((*p >= '0' && *p <= '9')) {
253+
unsigned width = 0;
254+
int r = parse_u(&p, &width);
255+
if (r < 0)
256+
return r;
257+
humanize->width = width <= 12 ? width : 12;
258+
}
259+
if ((p1 = strchr(scale, *p))) {
260+
humanize->minscale = p1-scale+1;
261+
p++;
262+
if ((p1 = strchr(scale, *p))) {
263+
humanize->maxscale = p1-scale+1;
264+
p++;
265+
}
266+
}
267+
if (*p == 'i') {
268+
humanize->flags |= HN_IEC_PREFIXES;
269+
p++;
270+
}
271+
*pos = p;
272+
return 0;
273+
}
274+
275+
static int
276+
parse_conversion(const char **pos, struct conversion *conversion)
277+
{
278+
if (**pos != '!')
279+
return 0;
280+
if (strncmp(*pos + 1, "strmode", sizeof("strmode") - 1) == 0) {
281+
*pos += sizeof("strmode");
282+
conversion->type = STRMODE;
283+
return 0;
284+
} else if (strncmp(*pos + 1, "humanize", sizeof("humanize") - 1) == 0) {
285+
conversion->type = HUMANIZE;
286+
*pos += sizeof("humanize");
287+
return parse_humanize(pos, &conversion->humanize);
288+
}
289+
return -EINVAL;
290+
}
291+
292+
static int
293+
parse_spec(const char **pos, struct xbps_fmt_spec *spec)
294+
{
235295
bool fill = false;
296+
const char *p = *pos;
297+
int r;
236298

299+
/* defaults */
237300
spec->conversion = NULL;
238301
spec->fill = ' ';
239302
spec->align = '>';
@@ -242,12 +305,85 @@ parse(const char **pos, struct strbuf *buf, struct xbps_fmt_spec *spec, struct c
242305
spec->precision = 0;
243306
spec->type = '\0';
244307

308+
/* format_spec ::= [[fill]align][sign][zero][width][.precision][type] */
309+
310+
if (*p != ':')
311+
return 0;
312+
p++;
313+
314+
/* fill ::= . */
315+
if (*p && strchr("<>=", p[1])) {
316+
fill = true;
317+
spec->fill = *p;
318+
spec->align = p[1];
319+
p += 2;
320+
}
321+
322+
/* align ::= [<>=] */
323+
if (strchr("<>=", *p)) {
324+
spec->align = *p;
325+
p += 1;
326+
}
327+
328+
/* sign ::= [+-] */
329+
if (strchr("+- ", *p)) {
330+
spec->sign = *p;
331+
p += 1;
332+
}
333+
334+
/* zero ::= [0] */
335+
if (*p == '0') {
336+
if (!fill) {
337+
spec->fill = '0';
338+
spec->align = '=';
339+
}
340+
p++;
341+
}
342+
343+
/* width ::= [[0-9]+] */
344+
if ((*p >= '0' && *p <= '9')) {
345+
r = parse_u(&p, &spec->width);
346+
if (r < 0)
347+
return r;
348+
}
349+
350+
/* precision ::= ['.' [0-9]+] */
351+
if (*p == '.') {
352+
p++;
353+
r = parse_u(&p, &spec->precision);
354+
if (r < 0)
355+
return r;
356+
}
357+
358+
/* type ::= [[a-zA-Z]] */
359+
if ((*p >= 'a' && *p <= 'z') ||
360+
(*p >= 'A' && *p <= 'Z'))
361+
spec->type = *p++;
362+
363+
*pos = p;
364+
return 0;
365+
}
366+
367+
static int
368+
parse(const char **pos, struct strbuf *buf, struct xbps_fmt_spec *spec, struct conversion *conversion)
369+
{
370+
const char *p = *pos;
371+
const char *e;
372+
int r;
373+
245374
if (*p != '{')
246375
return -EINVAL;
247376
p++;
248377

249-
e = strpbrk(p, "!:}");
250-
if (!e)
378+
/* var ::= '{' name [conversion][format_spec] '}' */
379+
380+
/* name ::= [a-zA-Z0-9_-]+ */
381+
for (e = p; (*e >= 'a' && *e <= 'z') ||
382+
(*e >= 'A' && *e <= 'Z') ||
383+
(*e >= '0' && *e <= '0') ||
384+
(*e == '_' || *e == '-'); e++)
385+
;
386+
if (e == p)
251387
return -EINVAL;
252388

253389
strbuf_reset(buf);
@@ -256,92 +392,16 @@ parse(const char **pos, struct strbuf *buf, struct xbps_fmt_spec *spec, struct c
256392
return r;
257393
p = e;
258394

259-
if (*p == '!') {
260-
if (strncmp(p+1, "humanize", sizeof("humanize") - 1) == 0) {
261-
/* humanize[ ][.][i][width][minscale[maxscale]] */
262-
const char *scale = "BKMGTPE";
263-
const char *p1;
264-
p += sizeof("humanize");
265-
conversion->type = HUMANIZE;
266-
if (*p != ':' && *p != '}') {
267-
conversion->humanize.flags = HN_NOSPACE;
268-
if (*p == ' ') {
269-
conversion->humanize.flags &= ~HN_NOSPACE;
270-
p++;
271-
}
272-
if (*p == '.') {
273-
conversion->humanize.flags |= HN_DECIMAL;
274-
p++;
275-
}
276-
if ((*p >= '0' && *p <= '9')) {
277-
unsigned width = 0;
278-
r = parse_u(&p, &width);
279-
if (r < 0)
280-
return r;
281-
conversion->humanize.width = width <= 12 ? width : 12;
282-
}
283-
if ((p1 = strchr(scale, *p))) {
284-
conversion->humanize.minscale = p1-scale+1;
285-
p++;
286-
if ((p1 = strchr(scale, *p))) {
287-
conversion->humanize.maxscale = p1-scale+1;
288-
p++;
289-
}
290-
}
291-
if (*p == 'i') {
292-
conversion->humanize.flags |= HN_IEC_PREFIXES;
293-
p++;
294-
}
295-
} else {
296-
/* default: !humanize .8Ki:8 */
297-
conversion->humanize.width = 8;
298-
conversion->humanize.minscale = 2;
299-
conversion->humanize.flags = HN_DECIMAL|HN_IEC_PREFIXES;
300-
}
301-
} else if (strncmp(p+1, "strmode", sizeof("strmode") - 1) == 0) {
302-
p += sizeof("strmode");
303-
conversion->type = STRMODE;
304-
} else {
305-
return -EINVAL;
306-
}
307-
}
395+
/* conversion ::= ['!' ...] */
396+
r = parse_conversion(&p, conversion);
397+
if (r < 0)
398+
return r;
399+
400+
/* format_spec ::= [':' ...] */
401+
r = parse_spec(&p, spec);
402+
if (r < 0)
403+
return r;
308404

309-
if (*p == ':') {
310-
p++;
311-
if (*p && strchr("<>=", p[1])) {
312-
fill = true;
313-
spec->fill = *p;
314-
spec->align = p[1];
315-
p += 2;
316-
} else if (strchr("<>=", *p)) {
317-
spec->align = *p;
318-
p += 1;
319-
}
320-
if (strchr("+- ", *p)) {
321-
spec->sign = *p;
322-
p += 1;
323-
}
324-
if ((*p >= '0' && *p <= '9')) {
325-
if (*p == '0') {
326-
if (!fill) {
327-
spec->fill = '0';
328-
spec->align = '=';
329-
}
330-
p++;
331-
}
332-
r = parse_u(&p, &spec->width);
333-
if (r < 0)
334-
return r;
335-
}
336-
if (*p == '.') {
337-
p++;
338-
r = parse_u(&p, &spec->precision);
339-
if (r < 0)
340-
return r;
341-
}
342-
if (*p != '}')
343-
spec->type = *p++;
344-
}
345405
if (*p != '}')
346406
return -EINVAL;
347407
*pos = p+1;

0 commit comments

Comments
 (0)