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 "platform.h" 22 : #include "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 7 : pattern_matches (const char *accept_pattern, 33 : const char *value) 34 : { 35 : const char *da; 36 : const char *dm; 37 : 38 7 : if (0 == strcmp ("*", 39 : accept_pattern)) 40 0 : return true; 41 7 : if (0 == strcmp (value, 42 : accept_pattern)) 43 5 : return true; 44 2 : da = strchr (accept_pattern, 45 : '/'); 46 2 : dm = strchr (value, 47 : '/'); 48 2 : if ( (NULL == da) || 49 : (NULL == dm) ) 50 0 : return false; 51 2 : if ( ( (1 == da - accept_pattern) && 52 0 : ('*' == *accept_pattern) ) || 53 2 : ( (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 2 : return false; 60 : } 61 : 62 : 63 : double 64 7 : TALER_pattern_matches (const char *pattern, 65 : const char *value) 66 : { 67 7 : char *p = GNUNET_strdup (pattern); 68 : char *sptr; 69 7 : double r = 0.0; 70 : 71 7 : for (char *tok = strtok_r (p, ",", &sptr); 72 14 : NULL != tok; 73 7 : tok = strtok_r (NULL, ",", &sptr)) 74 : { 75 : char *sptr2; 76 7 : char *lp = strtok_r (tok, ";", &sptr2); 77 7 : char *qp = strtok_r (NULL, ";", &sptr2); 78 7 : double q = 1.0; 79 : 80 7 : if (NULL == lp) 81 0 : continue; 82 7 : while (isspace ((int) *lp)) 83 0 : lp++; 84 7 : 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 7 : if (pattern_matches (lp, 95 : value)) 96 5 : r = GNUNET_MAX (r, q); 97 : } 98 7 : GNUNET_free (p); 99 7 : return r; 100 : } 101 : 102 : 103 : /* end of lang.c */