Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2020 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file lang.c
18 : * @brief Utility functions for parsing and matching RFC 7231 language strings.
19 : * @author Christian Grothoff
20 : */
21 : #include "taler/platform.h"
22 : #include "taler/taler_util.h"
23 :
24 : /**
25 : * Check if @a value matches the @a accept_pattern.
26 : *
27 : * @param accept_pattern a pattern like "[text|STAR/]*[text|STAR]"
28 : * @param value the value to match
29 : * @return true if @a value matches the @a accept_pattern
30 : */
31 : static bool
32 3 : pattern_matches (const char *accept_pattern,
33 : const char *value)
34 : {
35 : const char *da;
36 : const char *dm;
37 :
38 3 : if (0 == strcmp ("*",
39 : accept_pattern))
40 0 : return true;
41 3 : if (0 == strcmp (value,
42 : accept_pattern))
43 3 : return true;
44 0 : da = strchr (accept_pattern,
45 : '/');
46 0 : dm = strchr (value,
47 : '/');
48 0 : if ( (NULL == da) ||
49 : (NULL == dm) )
50 0 : return false;
51 0 : if ( ( (1 == da - accept_pattern) &&
52 0 : ('*' == *accept_pattern) ) ||
53 0 : ( (da - accept_pattern == dm - value) &&
54 0 : (0 == strncasecmp (accept_pattern,
55 : value,
56 0 : da - accept_pattern)) ) )
57 0 : return pattern_matches (da + 1,
58 : dm + 1);
59 0 : return false;
60 : }
61 :
62 :
63 : double
64 3 : TALER_pattern_matches (const char *pattern,
65 : const char *value)
66 : {
67 3 : char *p = GNUNET_strdup (pattern);
68 : char *sptr;
69 3 : double r = 0.0;
70 :
71 3 : for (char *tok = strtok_r (p, ",", &sptr);
72 6 : NULL != tok;
73 3 : tok = strtok_r (NULL, ",", &sptr))
74 : {
75 : char *sptr2;
76 3 : char *lp = strtok_r (tok, ";", &sptr2);
77 3 : char *qp = strtok_r (NULL, ";", &sptr2);
78 3 : double q = 1.0;
79 :
80 3 : if (NULL == lp)
81 0 : continue;
82 3 : while (isspace ((int) *lp))
83 0 : lp++;
84 3 : while (NULL != qp)
85 : {
86 0 : while (isspace ((int) *qp))
87 0 : qp++;
88 0 : if (1 == sscanf (qp,
89 : "q=%lf",
90 : &q))
91 0 : break;
92 0 : qp = strtok_r (NULL, ";", &sptr2);
93 : }
94 3 : if (pattern_matches (lp,
95 : value))
96 3 : r = GNUNET_MAX (r, q);
97 : }
98 3 : GNUNET_free (p);
99 3 : return r;
100 : }
101 :
102 :
103 : /* end of lang.c */
|