mi_parser.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <stdio.h>
00036 #include <string.h>
00037 #include <ctype.h>
00038
00039 #include "../../str.h"
00040 #include "../../dprint.h"
00041 #include "../../mi/mi.h"
00042 #include "../../mem/mem.h"
00043 #include "fifo_fnc.h"
00044 #include "mi_fifo.h"
00045 #include "mi_parser.h"
00046
00047 static char *mi_parse_buffer = 0;
00048 static unsigned int mi_parse_buffer_len = 0;
00049
00050
00051 int mi_parser_init( unsigned int size )
00052 {
00053 mi_parse_buffer_len = size;
00054 mi_parse_buffer = pkg_malloc(size);
00055
00056 if(!mi_parse_buffer){
00057 LM_ERR("pkg_malloc cannot allocate any more memory!\n");
00058 return -1;
00059 }
00060
00061 return 0;
00062 }
00063
00064
00065
00066
00067
00068
00069
00070 static inline int mi_parse_node( FILE *stream, str *buf, str *name, str *value)
00071 {
00072 char *p, *pmax;
00073 char *start;
00074 char *mark_nsp;
00075 int line_len;
00076
00077
00078 do {
00079 if (mi_read_line( buf->s, buf->len, stream, &line_len)<0) {
00080 LM_ERR("failed to read from fifo\n");
00081 return -1;
00082 }
00083 if (line_len == 1){
00084 LM_DBG("end of fifo input tree\n");
00085 return 1;
00086 }
00087
00088 start = buf->s;
00089 pmax = buf->s + line_len - 1;
00090
00091
00092 for( ; start<pmax && isspace((int)*start) ; start++ );
00093 } while ( start==pmax );
00094
00095
00096 name->s = value->s = 0;
00097 name->len = value->len = 0;
00098
00099 mark_nsp = 0;
00100
00101
00102 if (*start!='"') {
00103
00104 p = mark_nsp = start;
00105 while ( p!=pmax && ( (p[0]!=MI_ATTR_VAL_SEP1) || (p+1==pmax)
00106 || p[1]!=MI_ATTR_VAL_SEP2) ) {
00107 if (!isspace((int)*p)) {
00108 if (*p=='"')
00109 goto parse_err;
00110 mark_nsp = p;
00111 }
00112 p++;
00113 }
00114
00115 if (p!=pmax) {
00116
00117 if (p==start) {
00118
00119 } else {
00120 name->s = start;
00121 name->len = mark_nsp - start + 1;
00122 }
00123
00124 p += 2;
00125
00126 LM_DBG("attr name <%.*s> found\n",
00127 name->len, name->s);
00128
00129
00130 for( ; p!=pmax && isspace((int)*p) ; p++);
00131
00132 if (p==pmax) {
00133
00134 goto done;
00135 }
00136
00137
00138 if (*p!='"') {
00139 for( start=p ; p!=pmax ; p++ ) {
00140 if (!isspace((int)*p)) {
00141 if (*p=='"')
00142 goto parse_err;
00143 mark_nsp = p;
00144 }
00145 }
00146 value->s = start;
00147 value->len = mark_nsp + 1 - start;
00148 goto done;
00149 }
00150
00151 } else {
00152
00153 value->s = start;
00154 value->len = mark_nsp + 1 - start;
00155 goto done;
00156 }
00157 } else {
00158 p = start;
00159 }
00160
00161 start = p+1;
00162 value->s = start;
00163
00164 do {
00165 p = start;
00166
00167 while (p<pmax) {
00168 if (*p=='"') {
00169 if (start+1!=p && *(p-1)=='\\') {
00170
00171 memmove( p-1, p, pmax-p);
00172 pmax--;
00173 } else {
00174
00175 value->len = p - value->s;
00176
00177 for( p++ ; p!=pmax && isspace((int)*p) ; p++);
00178 if (p!=pmax)
00179 goto parse_err;
00180
00181 goto done;
00182 }
00183 } else {
00184 p++;
00185 }
00186 }
00187
00188
00189 p++;
00190 buf->len -= p - buf->s;
00191 buf->s = p;
00192
00193
00194 if (mi_read_line( buf->s, buf->len, stream, &line_len)<0) {
00195 LM_ERR("failed to re-read from fifo\n");
00196 return -1;
00197 }
00198 if (line_len == 1) {
00199 LM_DBG("end of fifo input tree\n");
00200 return -2;
00201 }
00202
00203 start = buf->s;
00204 pmax = buf->s + line_len - 1;
00205 } while(1);
00206
00207 done:
00208 buf->len -= p - buf->s;
00209 buf->s = p;
00210 return 0;
00211 parse_err:
00212 LM_ERR("parse error around %c\n",*p);
00213 return -1;
00214 }
00215
00216
00217
00218 struct mi_root * mi_parse_tree(FILE *stream) {
00219 struct mi_root *root;
00220 struct mi_node *node;
00221 str name;
00222 str value;
00223 str buf;
00224 int ret;
00225
00226 buf.s = mi_parse_buffer;
00227 buf.len= mi_parse_buffer_len;
00228
00229 root = init_mi_tree(0,0,0);
00230 if (!root) {
00231 LM_ERR("the MI tree cannot be initialized!\n");
00232 goto error;
00233 }
00234 node = &root->node;
00235
00236 name.s = value.s = 0;
00237 name.len = value.len = 0;
00238
00239
00240 while ( (ret=mi_parse_node(stream, &buf, &name, &value))>=0 ) {
00241 if (ret==1)
00242 return root;
00243
00244 LM_DBG("adding node <%.*s> ; val <%.*s>\n",
00245 name.len,name.s, value.len,value.s);
00246
00247 if(!add_mi_node_child(node,0,name.s,name.len,value.s,value.len)){
00248 LM_ERR("cannot add the child node to the MI tree\n");
00249 goto error;
00250 }
00251 }
00252
00253 LM_ERR("Parse error!\n");
00254 if (ret==-1) {
00255
00256 do {
00257 mi_read_line(mi_parse_buffer,mi_parse_buffer_len,stream,&ret);
00258 }while(ret>1);
00259 }
00260
00261 error:
00262 if (root)
00263 free_mi_tree(root);
00264 return 0;
00265 }
00266
00267