blob: 9ddcb156beeded45eec101a25e81b3dd3f91bc45 [file] [log] [blame]
James Kuszmaul82f6c042021-01-17 11:30:16 -08001/**
2 * @file prm.c Generic parameter decoding
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6#include <re_types.h>
7#include <re_fmt.h>
8
9
10/**
11 * Check if a semicolon separated parameter is present
12 *
13 * @param pl PL string to search
14 * @param pname Parameter name
15 *
16 * @return true if found, false if not found
17 */
18bool fmt_param_exists(const struct pl *pl, const char *pname)
19{
20 struct pl semi, eop;
21 char expr[128];
22
23 if (!pl || !pname)
24 return false;
25
26 (void)re_snprintf(expr, sizeof(expr),
27 "[;]*[ \t\r\n]*%s[ \t\r\n;=]*",
28 pname);
29
30 if (re_regex(pl->p, pl->l, expr, &semi, NULL, &eop))
31 return false;
32
33 if (!eop.l && eop.p < pl->p + pl->l)
34 return false;
35
36 return semi.l > 0 || pl->p == semi.p;
37}
38
39
40/**
41 * Fetch a semicolon separated parameter from a PL string
42 *
43 * @param pl PL string to search
44 * @param pname Parameter name
45 * @param val Parameter value, set on return
46 *
47 * @return true if found, false if not found
48 */
49bool fmt_param_get(const struct pl *pl, const char *pname, struct pl *val)
50{
51 struct pl semi;
52 char expr[128];
53
54 if (!pl || !pname)
55 return false;
56
57 (void)re_snprintf(expr, sizeof(expr),
58 "[;]*[ \t\r\n]*%s[ \t\r\n]*=[ \t\r\n]*[~ \t\r\n;]+",
59 pname);
60
61 if (re_regex(pl->p, pl->l, expr, &semi, NULL, NULL, NULL, val))
62 return false;
63
64 return semi.l > 0 || pl->p == semi.p;
65}
66
67
68/**
69 * Apply a function handler for each semicolon separated parameter
70 *
71 * @param pl PL string to search
72 * @param ph Parameter handler
73 * @param arg Handler argument
74 */
75void fmt_param_apply(const struct pl *pl, fmt_param_h *ph, void *arg)
76{
77 struct pl prmv, prm, semi, name, val;
78
79 if (!pl || !ph)
80 return;
81
82 prmv = *pl;
83
84 while (!re_regex(prmv.p, prmv.l, "[ \t\r\n]*[~;]+[;]*",
85 NULL, &prm, &semi)) {
86
87 pl_advance(&prmv, semi.p + semi.l - prmv.p);
88
89 if (re_regex(prm.p, prm.l,
90 "[^ \t\r\n=]+[ \t\r\n]*[=]*[ \t\r\n]*[~ \t\r\n]*",
91 &name, NULL, NULL, NULL, &val))
92 break;
93
94 ph(&name, &val, arg);
95 }
96}