source: roaraudio/libroar/keyval.c @ 5482:ba865ae62928

Last change on this file since 5482:ba865ae62928 was 5482:ba865ae62928, checked in by phi, 12 years ago

support quoted strings

File size: 3.7 KB
Line 
1//keyval.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2012
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38struct roar_keyval * roar_keyval_lookup (struct roar_keyval *  kv, const char * key, ssize_t len, int casesens) {
39 int (*sc)(const char *s1, const char *s2) = strcasecmp;
40 ssize_t i;
41
42 if ( kv == NULL || key == NULL ) {
43  roar_err_set(ROAR_ERROR_FAULT);
44  return NULL;
45 }
46
47 if ( casesens )
48  sc = strcmp;
49
50 for (i = 0; len != -1 ? (i < len) : kv[i].key != NULL; i++) {
51  if ( !sc(key, kv[i].key) )
52   return &(kv[i]);
53 }
54
55 roar_err_set(ROAR_ERROR_NOENT);
56 return NULL;
57}
58
59static inline int is_in (const char c, const char * delm) {
60 for (; *delm != 0; delm++)
61  if ( *delm == c )
62   return 1;
63
64 return 0;
65}
66
67static inline void skip_char(char * str) {
68 memmove(str, str+1, roar_mm_strlen(str));
69}
70
71ssize_t              roar_keyval_split  (struct roar_keyval ** kv, char * str, const char * fdel, const char * kdel, int quotes) {
72 struct roar_keyval * kvs;
73 int    pos = -1;
74 size_t len =  0;
75 char * sp;
76 char quote =  0;
77 int last_was_seg = 0;
78
79 if ( kv == NULL || str == NULL ) {
80  roar_err_set(ROAR_ERROR_FAULT);
81  return -1;
82 }
83
84 if ( fdel == NULL )
85  fdel = " \t,";
86
87 if ( kdel == NULL )
88  kdel = "=:";
89
90 // count num of segements:
91 for (sp = str; *sp != 0; sp++) {
92  if ( quote ) {
93   if ( *sp == quote )
94    quote = 0;
95  } else if ( quotes && (*sp == '\'' || *sp == '\"') ) {
96   quote = *sp;
97  } else {
98   if ( last_was_seg ) {
99    last_was_seg = !is_in(*sp, fdel);
100   } else {
101    if ( !is_in(*sp, fdel) ) {
102     last_was_seg = 1;
103     len++;
104    }
105   }
106  }
107 }
108
109 kvs = roar_mm_malloc(sizeof(struct roar_keyval)*(len+1));
110
111 if ( kvs == NULL )
112  return -1;
113
114 *kv = kvs;
115
116 // End of Array Mark:
117 kvs[len].key   = NULL;
118 kvs[len].value = NULL;
119
120 // do the acctual filling:
121 last_was_seg = 0;
122
123 for (sp = str; *sp != 0; sp++) {
124  if ( quote ) {
125   if ( *sp == quote ) {
126    skip_char(sp);
127    quote = 0;
128   } else {
129    continue;
130   }
131  } else if ( quotes && (*sp == '\'' || *sp == '\"') ) {
132   quote = *sp;
133   skip_char(sp);
134   continue;
135  }
136
137  if ( last_was_seg ) {
138   if ( is_in(*sp, fdel) ) {
139    last_was_seg = 0;
140    *sp = 0;
141   } else {
142    last_was_seg = 1;
143    if ( kvs[pos].value == NULL && is_in(*sp, kdel) ) {
144     *sp = 0;
145     kvs[pos].value = sp+1;
146    }
147   }
148  } else {
149   if ( !is_in(*sp, fdel) ) {
150    last_was_seg = 1;
151    pos++;
152    kvs[pos].key   = sp;
153    kvs[pos].value = NULL;
154   }
155  }
156 }
157
158 return len;
159}
160
161//ll
Note: See TracBrowser for help on using the repository browser.