00001
00002
00003
00004
00005
00006
00007
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include "dtd.h"
00011 #include "parser.h"
00012
00013 #ifdef XMLNS
00014
00024 static xmlns *
00025 xmlns_push(dtd_parser *p, const ichar *ns, const ochar *url)
00026 { sgml_environment *env = p->environments;
00027 dtd_symbol *n = (*ns ? dtd_add_symbol(p->dtd, ns) : (dtd_symbol *)NULL);
00028 dtd_symbol *u = dtd_add_symbol(p->dtd, url);
00029
00030
00031 if ( p->on_xmlns )
00032 (*p->on_xmlns)(p, n, u);
00033
00034 if ( env )
00035 { xmlns *x = sgml_malloc(sizeof(*n));
00036
00037 x->name = n;
00038 x->url = u;
00039 x->next = env->xmlns;
00040 env->xmlns = x;
00041
00042 return x;
00043 }
00044
00045 return NULL;
00046 }
00047
00053 void
00054 xmlns_free(sgml_environment *env)
00055 { xmlns *n, *next;
00056
00057 for(n = env->xmlns; n; n = next)
00058 { next = n->next;
00059
00060 sgml_free(n);
00061 }
00062 }
00063
00069 xmlns *
00070 xmlns_find(sgml_environment *env, dtd_symbol *ns)
00071 { for(; env; env = env->parent)
00072 { xmlns *n;
00073
00074 for(n=env->xmlns; n; n = n->next)
00075 { if ( n->name == ns )
00076 return n;
00077 }
00078 }
00079
00080 return NULL;
00081 }
00082
00089 static ichar *
00090 isxmlns(const ichar *s, int nschr)
00091 { if ( s[0]=='x' && s[1]=='m' && s[2]=='l' && s[3] =='n'&& s[4]=='s' )
00092 { if ( !s[5] )
00093 return (ichar *)s+5;
00094 if ( s[5] == nschr )
00095 return (ichar *)s+6;
00096 }
00097
00098 return NULL;
00099 }
00100
00101
00105 void
00106 update_xmlns(dtd_parser *p, dtd_element *e, int natts, sgml_attribute *atts)
00107 { dtd_attr_list *al;
00108 int nschr = p->dtd->charfunc->func[CF_NS];
00109
00110 for(al=e->attributes; al; al=al->next)
00111 { dtd_attr *a = al->attribute;
00112 const ichar *name = a->name->name;
00113
00114 if ( (name = isxmlns(name, nschr)) &&
00115 a->type == AT_CDATA &&
00116 (a->def == AT_FIXED || a->def == AT_DEFAULT) )
00117 xmlns_push(p, name, a->att_def.cdata);
00118 }
00119
00120 for( ; natts-- > 0; atts++ )
00121 { const ichar *name = atts->definition->name->name;
00122
00123 if ( (name=isxmlns(name, nschr)) && atts->definition->type == AT_CDATA )
00124 xmlns_push(p, name, atts->value.cdata);
00125 }
00126 }
00127
00128
00141 int
00142 xmlns_resolve_attribute(dtd_parser *p, dtd_symbol *id,
00143 const ichar **local, const ichar **url)
00144 { dtd *dtd = p->dtd;
00145 int nschr = dtd->charfunc->func[CF_NS];
00146 ichar buf[MAXNMLEN];
00147 ichar *o = buf;
00148 ichar *s;
00149 xmlns *ns;
00150
00151 for(s=id->name; *s; s++)
00152 { if ( *s == nschr )
00153 { dtd_symbol *n;
00154
00155 *o = '\0';
00156 *local = s+1;
00157 n = dtd_add_symbol(dtd, buf);
00158
00159 if ( istrprefix("xml", buf) )
00160 { *url = n->name;
00161 return TRUE;
00162 } else if ( (ns = xmlns_find(p->environments, n)) )
00163 { if ( ns->url->name[0] )
00164 *url = ns->url->name;
00165 else
00166 *url = NULL;
00167 return TRUE;
00168 } else
00169 { *url = n->name;
00170 gripe(ERC_EXISTENCE, "namespace", n->name);
00171 return FALSE;
00172 }
00173 }
00174 *o++ = *s;
00175 }
00176
00177 *local = id->name;
00178
00179 if ( (p->flags & SGML_PARSER_QUALIFY_ATTS) &&
00180 (ns = p->environments->thisns) && ns->url->name[0] )
00181 *url = ns->url->name;
00182 else
00183 *url = NULL;
00184
00185 return TRUE;
00186 }
00187
00188
00197 int
00198 xmlns_resolve_element(dtd_parser *p, const ichar **local, const ichar **url)
00199 { sgml_environment *e;
00200
00201 if ( (e=p->environments) )
00202 { dtd_symbol *id = e->element->name;
00203 dtd *dtd = p->dtd;
00204 int nschr = dtd->charfunc->func[CF_NS];
00205 ichar buf[MAXNMLEN];
00206 ichar *o = buf;
00207 ichar *s;
00208 xmlns *ns;
00209
00210 for(s=id->name; *s; s++)
00211 { if ( *s == nschr )
00212 { dtd_symbol *n;
00213
00214 *o = '\0';
00215 *local = s+1;
00216 n = dtd_add_symbol(dtd, buf);
00217
00218 if ( (ns = xmlns_find(p->environments, n)) )
00219 { if ( ns->url->name[0] )
00220 *url = ns->url->name;
00221 else
00222 *url = NULL;
00223 e->thisns = ns;
00224 return TRUE;
00225 } else
00226 { *url = n->name;
00227 gripe(ERC_EXISTENCE, "namespace", n->name);
00228 e->thisns = xmlns_push(p, n->name, n->name);
00229 return FALSE;
00230 }
00231 }
00232 *o++ = *s;
00233 }
00234
00235 *local = id->name;
00236
00237 if ( (ns = xmlns_find(p->environments, NULL)) )
00238 { if ( ns->url->name[0] )
00239 *url = ns->url->name;
00240 else
00241 *url = NULL;
00242 e->thisns = ns;
00243 } else
00244 { *url = NULL;
00245 e->thisns = NULL;
00246 }
00247
00248 return TRUE;
00249 } else
00250 return FALSE;
00251 }
00252
00253
00254 #endif
00255