1 /* 2 * TurboXSL XML+XSLT processing library 3 * Main include for internal use. Interface functions and types 4 * are in global turboxsl.h include 5 * 6 * (c) Egor Voznessenski, voznyak@mail.ru 7 * 8 * $Id$ 9 * 10 **/ 11 12 #ifndef LTR_XSL_H_ 13 #define LTR_XSL_H_ 14 15 #include <stdio.h> 16 17 #include "turboxsl.h" 18 #include "strings.h" 19 #include "xmldict.h" 20 #include "templates.h" 21 #include "threadpool.h" 22 #include "allocator.h" 23 #include "external_cache.h" 24 #include "concurrent_dictionary.h" 25 #include "shared_variable.h" 26 #include "logger.h" 27 28 typedef enum {VAL_NULL=0, VAL_BOOL, VAL_INT, VAL_NUMBER, VAL_STRING, VAL_NODESET} RVALUE_TYPE; 29 30 typedef struct _rval { 31 RVALUE_TYPE type; 32 union { 33 long integer; 34 double number; 35 char *string; 36 XMLNODE *nodeset; 37 } v; 38 } RVALUE; 39 40 typedef XMLNODE XPATH_EXPR; 41 42 typedef enum {XML_FLAG_CDATA=1,XML_FLAG_NOESCAPE=2,XML_FLAG_SORTNUMBER=4,XML_FLAG_DESCENDING=8,XML_FLAG_LOWER=16} XML_FLAG; 43 44 typedef enum {EMPTY_NODE=0, ELEMENT_NODE, TEXT_NODE, ATTRIBUTE_NODE, PI_NODE, COMMENT_NODE, INFO_NODE, XPATH_NODE_VAR, XPATH_NODE_NOT, 45 XPATH_NODE_OR, XPATH_NODE_AND, XPATH_NODE_EQ, XPATH_NODE_NE, XPATH_NODE_LT, XPATH_NODE_GT, XPATH_NODE_CALL, KEY_NODE, 46 XPATH_NODE_LE, XPATH_NODE_GE, XPATH_NODE_ADD, XPATH_NODE_SUB, XPATH_NODE_MUL, XPATH_NODE_DIV, XPATH_NODE_MOD, 47 XPATH_NODE_FILTER, XPATH_NODE_ALL, XPATH_NODE_ATTR, XPATH_NODE_ROOT, XPATH_NODE_PARENT, XPATH_NODE_SELF, XPATH_NODE_ANCESTOR, 48 XPATH_NODE_FOLLOWING_SIBLING, XPATH_NODE_PRECEDING_SIBLING, XPATH_NODE_PRECEDING, XPATH_NODE_FOLLOWING, XPATH_NODE_SELECT, 49 XPATH_NODE_ATTR_ALL, XPATH_NODE_INT, XPATH_NODE_CONTEXT, XPATH_NODE_DESCENDANT, XPATH_NODE_DESCENDANT_OR_SELF, 50 XPATH_NODE_UNION, XPATH_NODE_ANCESTOR_OR_SELF 51 } NODETYPE; 52 53 struct _xmlnode { 54 struct _xmlnode *parent; 55 struct _xmlnode *next; 56 struct _xmlnode *prev; 57 struct _xmlnode *children; 58 struct _xmlnode *attributes; 59 struct _xmlnode *original; 60 XML_FLAG flags; 61 unsigned position; 62 unsigned order; 63 void *uid; 64 XPATH_EXPR *compiled; 65 RVALUE extra; 66 unsigned line; 67 char *file; 68 XMLSTRING name; 69 XMLSTRING content; 70 NODETYPE type; 71 memory_allocator *allocator; 72 }; 73 74 typedef struct _cbt { 75 char *name; 76 void (*func)(); 77 }CB_TABLE; 78 79 typedef struct _var { 80 char *name; 81 RVALUE extra; 82 } XSL_VARIABLE; 83 84 struct _globaldata { 85 memory_allocator *allocator; 86 concurrent_dictionary *urldict; 87 XMLDICT *revisions; 88 XMLDICT *group_rights; 89 CB_TABLE *perl_functions; // linear search for functions - small number and sorted by usage statistics 90 unsigned perl_cb_max; 91 unsigned perl_cb_ptr; 92 char *(*perl_cb_dispatcher)(void *fun,char **args,void *interpreter); 93 void (*perl_urlcode)(); 94 void *interpreter; 95 external_cache *cache; 96 XSL_VARIABLE *vars; 97 unsigned var_max; 98 unsigned var_pos; 99 }; 100 101 typedef enum {XSL_FLAG_OUTPUT=1, XSL_FLAG_OMIT_DESC=2, XSL_FLAG_STANDALONE=4, XSL_FLAG_INDENT=8, XSL_FLAG_MODE_SET=16} XSL_FLAG; 102 typedef enum {MODE_NONE=0, MODE_XML, MODE_HTML, MODE_TEXT} OUTPUT_MODE; 103 104 struct _context { 105 XSLTGLOBALDATA *gctx; 106 threadpool *pool; 107 memory_allocator *allocator; 108 char *cache_key_prefix; 109 char *url_local_prefix; 110 XMLDICT *user_rights; 111 XMLDICT *parallel_instructions; 112 XMLDICT *url_code_parameters; 113 void *task_graph; // TODO fix dependency graph 114 template_map *templates; 115 XMLDICT *named_templ; // templates for call'ing 116 XMLNODE *root_node; 117 XMLNODE *stylesheet; 118 CB_TABLE *functions; // linear search for functions - small number and sorted by usage statistics 119 unsigned cb_max; 120 unsigned cb_ptr; 121 XSL_FLAG flags; 122 unsigned rawout; 123 XSL_VARIABLE *vars; // Global (per conversion context) variables 124 unsigned var_max; // + 125 unsigned var_pos; // + 126 concurrent_dictionary *expressions; 127 char **sort_keys; // sort tables for reuse. XXX must be rewritten to avoid conflicts (currently works because of rare use) 128 XMLNODE **sort_nodes; // + 129 unsigned sort_size; // + 130 char *charset; // Just links to strings allocated and freed with global hash. No need to free 131 XMLSTRING doctype_public; // + 132 XMLSTRING doctype_system; // + 133 XMLSTRING media_type; // + 134 XMLSTRING encoding; // + -- This one is not really useful now since only UTF-8 is supported 135 XMLNODE *keys; // xsl:key data 136 XMLNODE *formats; // xsl:decimal-format data 137 pthread_mutex_t lock; 138 OUTPUT_MODE outmode; 139 }; 140 141 typedef enum {DEFAULT, DENY, SINGLE} TEMPLATE_TASK_MODE; 142 143 typedef struct template_context_ { 144 TRANSFORM_CONTEXT *context; 145 XMLNODE *instruction; 146 XMLNODE *result; 147 XMLNODE *document_node; 148 XMLNODE *parameters; 149 XMLNODE *local_variables; 150 XMLSTRING mode; 151 shared_variable *workers; 152 TEMPLATE_TASK_MODE task_mode; 153 } template_context; 154 155 XMLNODE *xml_parse_file(XSLTGLOBALDATA *gctx, char *file, int has_allocator); 156 XMLNODE *xml_parse_string(XSLTGLOBALDATA *gctx, char *string, int has_allocator); 157 158 /********************** nodes.c -- nodes operations *****************/ 159 void xml_unlink_node(XMLNODE *node); 160 XMLNODE *xml_new_node(TRANSFORM_CONTEXT *pctx, XMLSTRING name, NODETYPE type); 161 XMLNODE *xml_append_child(TRANSFORM_CONTEXT *pctx, XMLNODE *node, NODETYPE type); 162 void xml_add_child(XMLNODE *node,XMLNODE *child); 163 164 int is_node_parallel(XMLNODE *node); 165 166 /********************** transform.c -- XSLT mainloop ****************/ 167 void apply_xslt_template(template_context *context); 168 void process_one_node(template_context *context); 169 170 XMLNODE *find_first_node(XMLNODE *n); 171 XMLSTRING xml_eval_string(TRANSFORM_CONTEXT *pctx, XMLNODE *locals, XMLNODE *source, XMLNODE *foreval); 172 173 void copy_node_to_result_rec(TRANSFORM_CONTEXT *pctx, XMLNODE *locals, XMLNODE *context, XMLNODE *parent, XMLNODE *src); 174 175 XMLSTRING xml_get_attr(XMLNODE *node, XMLSTRING name); 176 char *get_absolute_path(XMLNODE *node, char *name); 177 178 XMLNODE *find_template(TRANSFORM_CONTEXT *pctx, XMLNODE *source, XMLSTRING mode); 179 XMLNODE *template_byname(TRANSFORM_CONTEXT *pctx, XMLSTRING name); 180 void precompile_templates(TRANSFORM_CONTEXT *pctx, XMLNODE *node); 181 void precompile_variables(TRANSFORM_CONTEXT *pctx, XMLNODE *stylesheet, XMLNODE *doc); 182 void get_variable_rv(TRANSFORM_CONTEXT *pctx, XMLNODE *vars, XMLSTRING name, RVALUE *rv); 183 void free_variables(TRANSFORM_CONTEXT *pctx); 184 185 void do_local_var(TRANSFORM_CONTEXT *pctx, XMLNODE *vars, XMLNODE *doc, XMLNODE *var); 186 void add_local_var(TRANSFORM_CONTEXT *pctx, XMLNODE *vars, XMLSTRING name, XMLNODE *params); 187 char *xsl_get_global_key(TRANSFORM_CONTEXT *pctx, char *first, char *second); 188 189 XMLNODE *copy_variables(TRANSFORM_CONTEXT *context, XMLNODE *variables); 190 191 /************************* xpath.c -- xpath compilator ************************/ 192 void xpath_execute_scalar(TRANSFORM_CONTEXT *pctx, XMLNODE *locals, XMLNODE *etree, XMLNODE *current, RVALUE *res); 193 194 void xpath_eval_expression(TRANSFORM_CONTEXT *pctx, XMLNODE *locals, XMLNODE *current, XMLSTRING expr, RVALUE *res); 195 int xpath_eval_boolean(TRANSFORM_CONTEXT *pctx, XMLNODE *locals, XMLNODE *current, XMLNODE *expr); 196 char *xpath_eval_string(TRANSFORM_CONTEXT *pctx, XMLNODE *locals, XMLNODE *current, XMLNODE *expr); 197 XMLNODE *xpath_eval_selection(TRANSFORM_CONTEXT *pctx, XMLNODE *locals, XMLNODE *current, XMLNODE *expr); 198 void xpath_eval_node(TRANSFORM_CONTEXT *pctx, XMLNODE *locals, XMLNODE *current, XMLSTRING expr, RVALUE *this); 199 200 XMLNODE *xpath_find_expr(TRANSFORM_CONTEXT *pctx, XMLSTRING expr); 201 XMLNODE *xpath_sort_selection(TRANSFORM_CONTEXT *pctx, XMLNODE *locals, XMLNODE *selection, XMLNODE *sort); 202 XMLNODE *xpath_in_selection(XMLNODE *sel, XMLSTRING name); 203 void xpath_free_selection(TRANSFORM_CONTEXT *pctx, XMLNODE *sel); 204 XMLNODE *xpath_compile(TRANSFORM_CONTEXT *pctx, char *expr); 205 XMLNODE *xpath_filter(TRANSFORM_CONTEXT *pctx, XMLNODE *locals, XMLNODE *nodeset, XMLNODE *expr); 206 XMLNODE *add_to_selection(XMLNODE *prev, XMLNODE *src, unsigned int *position); 207 XMLNODE *xpath_nodeset_copy(TRANSFORM_CONTEXT *pctx, XMLNODE *src); 208 209 XMLSTRING xml_process_string(TRANSFORM_CONTEXT *pctx, XMLNODE *locals, XMLNODE *src, XMLSTRING s); 210 211 212 /************************* rvalue.c -- rvalues operations ************************/ 213 void rval_init(RVALUE *rv); 214 void rval_free(RVALUE *rv); 215 int rval2bool(RVALUE *rv); 216 char *rval2string(RVALUE *rv); 217 double rval2number(RVALUE *rv); 218 int rval_equal(RVALUE *left, RVALUE *right, unsigned eq); 219 int rval_less(RVALUE *left, RVALUE *right); 220 int rval_less_or_equal(RVALUE *left, RVALUE *right); 221 int rval_greater(RVALUE *left, RVALUE *right); 222 int rval_greater_or_equal(RVALUE *left, RVALUE *right); 223 224 int match(char **eptr, char *str); 225 int x_can_number(char *p); 226 int x_is_ws(char c); 227 int x_is_namechar(char c); 228 int x_is_selchar(char c); 229 int xml_strcmp(const char *l, const char *r); 230 int xml_strcasecmp(char *l, char *r); 231 char *xml_strdup(const char *s); 232 char *xml_new_string(const char *s, size_t length); 233 char *node2string(XMLNODE *node); 234 char *nodes2string(XMLNODE *node); 235 236 void xmls_add_char(XMLSTRING s, char c); // appends a char to xmlstring 237 void xmls_add_utf(XMLSTRING s, unsigned u); // appends unicode value to xmlstring 238 void xmls_append(XMLSTRING s, XMLSTRING value); 239 void xmls_add_str(XMLSTRING s, const char *d); // appends a string to xmlstring 240 char *xmls_detach(XMLSTRING s); // frees xmlstring, returns content to be freed later 241 242 short *utf2ws(char *s); 243 244 void output_node_rec(XMLNODE *node, XMLSTRING rtext, TRANSFORM_CONTEXT *ctx); 245 246 void xpath_setup_functions(TRANSFORM_CONTEXT *pctx); 247 void xpath_call_dispatcher(TRANSFORM_CONTEXT *pctx, XMLNODE *locals, char *fname, XMLNODE *args, XMLNODE *current, RVALUE *res); 248 249 #endif