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
00036
00037
00038
00039
00040
00041
00042
00043 #include <sys/types.h>
00044
00045 #include <stdlib.h>
00046 #include <string.h>
00047 #include <ctype.h>
00048
00049 #include <pro/uxml.h>
00050
00055
00056 #ifndef MAX_UXMLTAG_SIZE
00057
00062 #define MAX_UXMLTAG_SIZE 512
00063 #endif
00064
00065 #ifndef MAX_UXMLTKN_SIZE
00066
00073 #define MAX_UXMLTKN_SIZE 64
00074 #endif
00075
00076 static int UxmlReadTag(FILE * stream, char *data, size_t size)
00077 {
00078 int rc = -1;
00079 int ch;
00080 int qc = 0;
00081 int state = 1;
00082 char *dp = NULL;
00083
00084 while (state) {
00085 ch = fgetc(stream);
00086 if (ch == EOF || ch == 0) {
00087 break;
00088 }
00089 switch (state) {
00090 case 1:
00091
00092 if (ch == '<') {
00093
00094 dp = data;
00095 state = 4;
00096 } else if (ch == '"' || ch == '\'') {
00097
00098 qc = ch;
00099 state++;
00100 }
00101 break;
00102 case 2:
00103
00104 case 5:
00105
00106 if (ch == qc) {
00107
00108 state--;
00109 }
00110 break;
00111 case 3:
00112
00113 if (isspace(ch)) {
00114 ch = 0;
00115 break;
00116 }
00117 state = 4;
00118
00119 case 4:
00120
00121 if (ch == '>') {
00122 rc = 0;
00123 state = 0;
00124 } else if (ch == '"' || ch == '\'') {
00125 qc = ch;
00126 state++;
00127 } else if (isspace(ch)) {
00128 ch = ' ';
00129 state = 3;
00130 }
00131 break;
00132 }
00133 if (dp && ch) {
00134 if (size > 1) {
00135 size--;
00136 *dp++ = ch;
00137 } else {
00138 break;
00139 }
00140 }
00141 }
00142 if (dp) {
00143 *dp = 0;
00144 }
00145 return rc;
00146 }
00147
00193 UXML_NODE *UxmlParseStream(FILE * stream, char **f_tags, char **f_attr)
00194 {
00195 char *tag;
00196 char *tkn;
00197 char *tp;
00198 UXML_NODE *root = NULL;
00199 UXML_NODE *node = NULL;
00200 UXML_NODE *nn;
00201
00202
00203 if ((tag = malloc(MAX_UXMLTAG_SIZE)) == NULL) {
00204 return NULL;
00205 }
00206
00207 if ((tkn = malloc(MAX_UXMLTKN_SIZE)) == NULL) {
00208 free(tag);
00209 return NULL;
00210 }
00211 for (;;) {
00212
00213 if (UxmlReadTag(stream, tag, MAX_UXMLTAG_SIZE)) {
00214
00215 break;
00216 }
00217
00218 if ((tp = UxmlParseTag(tag + 1, tkn, MAX_UXMLTKN_SIZE)) != NULL) {
00219 if (isalpha(*tkn) && UxmlFilterMatch(tkn, f_tags)) {
00220
00221
00222
00223 if ((nn = UxmlNodeCreate(tkn)) == NULL) {
00224 break;
00225 }
00226 if (root == NULL) {
00227
00228 root = nn;
00229 node = nn;
00230 } else if (node == NULL) {
00231
00232 node = UxmlTreeAddSibling(root, nn);
00233 } else {
00234
00235 node = UxmlTreeAddChild(node, nn);
00236 }
00237
00238 for (;;) {
00239 if ((tp = UxmlParseTag(tp, tkn, MAX_UXMLTKN_SIZE)) == NULL || *tkn == '>') {
00240
00241 break;
00242 }
00243 if (isalpha(*tkn) && UxmlFilterMatch(tkn, f_attr)) {
00244 size_t len = strlen(tkn) + 1;
00245 char *name = malloc(len);
00246
00247 if (name) {
00248 memcpy(name, tkn, len);
00249 if ((tp = UxmlParseTag(tp, tkn, MAX_UXMLTKN_SIZE)) == NULL || *tkn != '=') {
00250 break;
00251 }
00252 if ((tp = UxmlParseTag(tp, tkn, MAX_UXMLTKN_SIZE)) == NULL || *tkn == '>') {
00253 break;
00254 }
00255 UxmlNodeAddAttrib(node, name, tkn);
00256 free(name);
00257 }
00258 }
00259 }
00260 } else if (*tkn == '/') {
00261
00262
00263
00264 tp = UxmlParseTag(tp, tkn, MAX_UXMLTKN_SIZE);
00265 if (tp && node && strcasecmp(node->xmln_name, tkn) == 0) {
00266 node = node->xmln_parent;
00267 }
00268 }
00269 }
00270 }
00271
00272 free(tag);
00273 free(tkn);
00274
00275 return root;
00276 }
00277