Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenextra.c
Go to the documentation of this file.
00001 /* 00002 * extra.c: Implementation of non-standard features 00003 * 00004 * Reference: 00005 * Michael Kay "XSLT Programmer's Reference" pp 637-643 00006 * The node-set() extension function 00007 * 00008 * See Copyright for the status of this software. 00009 * 00010 * daniel@veillard.com 00011 */ 00012 00013 #define IN_LIBXSLT 00014 #include "libxslt.h" 00015 00016 #include <string.h> 00017 #ifdef HAVE_TIME_H 00018 #include <time.h> 00019 #endif 00020 #ifdef HAVE_STDLIB_H 00021 #include <stdlib.h> 00022 #endif 00023 00024 #include <libxml/xmlmemory.h> 00025 #include <libxml/tree.h> 00026 #include <libxml/hash.h> 00027 #include <libxml/xmlerror.h> 00028 #include <libxml/parserInternals.h> 00029 #include "xslt.h" 00030 #include "xsltInternals.h" 00031 #include "xsltutils.h" 00032 #include "extensions.h" 00033 #include "variables.h" 00034 #include "transform.h" 00035 #include "extra.h" 00036 #include "preproc.h" 00037 00038 #ifdef WITH_XSLT_DEBUG 00039 #define WITH_XSLT_DEBUG_EXTRA 00040 #endif 00041 00042 /************************************************************************ 00043 * * 00044 * Handling of XSLT debugging * 00045 * * 00046 ************************************************************************/ 00047 00057 void 00058 xsltDebug(xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED, 00059 xmlNodePtr inst ATTRIBUTE_UNUSED, 00060 xsltStylePreCompPtr comp ATTRIBUTE_UNUSED) 00061 { 00062 int i, j; 00063 00064 xsltGenericError(xsltGenericErrorContext, "Templates:\n"); 00065 for (i = 0, j = ctxt->templNr - 1; ((i < 15) && (j >= 0)); i++, j--) { 00066 xsltGenericError(xsltGenericErrorContext, "#%d ", i); 00067 if (ctxt->templTab[j]->name != NULL) 00068 xsltGenericError(xsltGenericErrorContext, "name %s ", 00069 ctxt->templTab[j]->name); 00070 if (ctxt->templTab[j]->match != NULL) 00071 xsltGenericError(xsltGenericErrorContext, "name %s ", 00072 ctxt->templTab[j]->match); 00073 if (ctxt->templTab[j]->mode != NULL) 00074 xsltGenericError(xsltGenericErrorContext, "name %s ", 00075 ctxt->templTab[j]->mode); 00076 xsltGenericError(xsltGenericErrorContext, "\n"); 00077 } 00078 xsltGenericError(xsltGenericErrorContext, "Variables:\n"); 00079 for (i = 0, j = ctxt->varsNr - 1; ((i < 15) && (j >= 0)); i++, j--) { 00080 xsltStackElemPtr cur; 00081 00082 if (ctxt->varsTab[j] == NULL) 00083 continue; 00084 xsltGenericError(xsltGenericErrorContext, "#%d\n", i); 00085 cur = ctxt->varsTab[j]; 00086 while (cur != NULL) { 00087 if (cur->comp == NULL) { 00088 xsltGenericError(xsltGenericErrorContext, 00089 "corrupted !!!\n"); 00090 } else if (cur->comp->type == XSLT_FUNC_PARAM) { 00091 xsltGenericError(xsltGenericErrorContext, "param "); 00092 } else if (cur->comp->type == XSLT_FUNC_VARIABLE) { 00093 xsltGenericError(xsltGenericErrorContext, "var "); 00094 } 00095 if (cur->name != NULL) 00096 xsltGenericError(xsltGenericErrorContext, "%s ", 00097 cur->name); 00098 else 00099 xsltGenericError(xsltGenericErrorContext, "noname !!!!"); 00100 #ifdef LIBXML_DEBUG_ENABLED 00101 if (cur->value != NULL) { 00102 xmlXPathDebugDumpObject(stdout, cur->value, 1); 00103 } else { 00104 xsltGenericError(xsltGenericErrorContext, "NULL !!!!"); 00105 } 00106 #endif 00107 xsltGenericError(xsltGenericErrorContext, "\n"); 00108 cur = cur->next; 00109 } 00110 00111 } 00112 } 00113 00114 /************************************************************************ 00115 * * 00116 * Classic extensions as described by M. Kay * 00117 * * 00118 ************************************************************************/ 00119 00130 void 00131 xsltFunctionNodeSet(xmlXPathParserContextPtr ctxt, int nargs){ 00132 if (nargs != 1) { 00133 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 00134 "node-set() : expects one result-tree arg\n"); 00135 ctxt->error = XPATH_INVALID_ARITY; 00136 return; 00137 } 00138 if ((ctxt->value == NULL) || 00139 ((ctxt->value->type != XPATH_XSLT_TREE) && 00140 (ctxt->value->type != XPATH_NODESET))) { 00141 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 00142 "node-set() invalid arg expecting a result tree\n"); 00143 ctxt->error = XPATH_INVALID_TYPE; 00144 return; 00145 } 00146 if (ctxt->value->type == XPATH_XSLT_TREE) { 00147 ctxt->value->type = XPATH_NODESET; 00148 } 00149 } 00150 00151 00152 /* 00153 * Okay the following really seems unportable and since it's not 00154 * part of any standard I'm not too ashamed to do this 00155 */ 00156 #if defined(linux) || defined(__sun) 00157 #if defined(HAVE_MKTIME) && defined(HAVE_LOCALTIME) && defined(HAVE_ASCTIME) 00158 #define WITH_LOCALTIME 00159 00171 static void 00172 xsltFunctionLocalTime(xmlXPathParserContextPtr ctxt, int nargs) { 00173 xmlXPathObjectPtr obj; 00174 char *str; 00175 char digits[5]; 00176 char result[29]; 00177 long int field; 00178 time_t gmt, lmt; 00179 struct tm gmt_tm; 00180 struct tm *local_tm; 00181 00182 if (nargs != 1) { 00183 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 00184 "localTime() : invalid number of args %d\n", nargs); 00185 ctxt->error = XPATH_INVALID_ARITY; 00186 return; 00187 } 00188 00189 obj = valuePop(ctxt); 00190 00191 if (obj->type != XPATH_STRING) { 00192 obj = xmlXPathConvertString(obj); 00193 } 00194 if (obj == NULL) { 00195 valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); 00196 return; 00197 } 00198 00199 str = (char *) obj->stringval; 00200 00201 /* str = "$Date$" */ 00202 memset(digits, 0, sizeof(digits)); 00203 strncpy(digits, str+7, 4); 00204 field = strtol(digits, NULL, 10); 00205 gmt_tm.tm_year = field - 1900; 00206 00207 memset(digits, 0, sizeof(digits)); 00208 strncpy(digits, str+12, 2); 00209 field = strtol(digits, NULL, 10); 00210 gmt_tm.tm_mon = field - 1; 00211 00212 memset(digits, 0, sizeof(digits)); 00213 strncpy(digits, str+15, 2); 00214 field = strtol(digits, NULL, 10); 00215 gmt_tm.tm_mday = field; 00216 00217 memset(digits, 0, sizeof(digits)); 00218 strncpy(digits, str+18, 2); 00219 field = strtol(digits, NULL, 10); 00220 gmt_tm.tm_hour = field; 00221 00222 memset(digits, 0, sizeof(digits)); 00223 strncpy(digits, str+21, 2); 00224 field = strtol(digits, NULL, 10); 00225 gmt_tm.tm_min = field; 00226 00227 memset(digits, 0, sizeof(digits)); 00228 strncpy(digits, str+24, 2); 00229 field = strtol(digits, NULL, 10); 00230 gmt_tm.tm_sec = field; 00231 00232 /* Now turn gmt_tm into a time. */ 00233 gmt = mktime(&gmt_tm); 00234 00235 00236 /* 00237 * FIXME: it's been too long since I did manual memory management. 00238 * (I swore never to do it again.) Does this introduce a memory leak? 00239 */ 00240 local_tm = localtime(&gmt); 00241 00242 /* 00243 * Calling localtime() has the side-effect of setting timezone. 00244 * After we know the timezone, we can adjust for it 00245 */ 00246 lmt = gmt - timezone; 00247 00248 /* 00249 * FIXME: it's been too long since I did manual memory management. 00250 * (I swore never to do it again.) Does this introduce a memory leak? 00251 */ 00252 local_tm = localtime(&lmt); 00253 00254 /* 00255 * Now convert local_tm back into a string. This doesn't introduce 00256 * a memory leak, so says asctime(3). 00257 */ 00258 00259 str = asctime(local_tm); /* "Tue Jun 26 05:02:16 2001" */ 00260 /* 0123456789 123456789 123 */ 00261 00262 memset(result, 0, sizeof(result)); /* "Thu, 26 Jun 2001" */ 00263 /* 0123456789 12345 */ 00264 00265 strncpy(result, str, 20); 00266 strcpy(result+20, "???"); /* tzname doesn't work, fake it */ 00267 strncpy(result+23, str+19, 5); 00268 00269 /* Ok, now result contains the string I want to send back. */ 00270 valuePush(ctxt, xmlXPathNewString((xmlChar *)result)); 00271 } 00272 #endif 00273 #endif /* linux or sun */ 00274 00275 00283 void 00284 xsltRegisterExtras(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED) { 00285 xsltRegisterAllExtras(); 00286 } 00287 00293 void 00294 xsltRegisterAllExtras (void) { 00295 xsltRegisterExtModuleFunction((const xmlChar *) "node-set", 00296 XSLT_LIBXSLT_NAMESPACE, 00297 xsltFunctionNodeSet); 00298 xsltRegisterExtModuleFunction((const xmlChar *) "node-set", 00299 XSLT_SAXON_NAMESPACE, 00300 xsltFunctionNodeSet); 00301 xsltRegisterExtModuleFunction((const xmlChar *) "node-set", 00302 XSLT_XT_NAMESPACE, 00303 xsltFunctionNodeSet); 00304 #ifdef WITH_LOCALTIME 00305 xsltRegisterExtModuleFunction((const xmlChar *) "localTime", 00306 XSLT_NORM_SAXON_NAMESPACE, 00307 xsltFunctionLocalTime); 00308 #endif 00309 xsltRegisterExtModuleElement((const xmlChar *) "debug", 00310 XSLT_LIBXSLT_NAMESPACE, 00311 NULL, 00312 (xsltTransformFunction) xsltDebug); 00313 xsltRegisterExtModuleElement((const xmlChar *) "output", 00314 XSLT_SAXON_NAMESPACE, 00315 xsltDocumentComp, 00316 (xsltTransformFunction) xsltDocumentElem); 00317 xsltRegisterExtModuleElement((const xmlChar *) "write", 00318 XSLT_XALAN_NAMESPACE, 00319 xsltDocumentComp, 00320 (xsltTransformFunction) xsltDocumentElem); 00321 xsltRegisterExtModuleElement((const xmlChar *) "document", 00322 XSLT_XT_NAMESPACE, 00323 xsltDocumentComp, 00324 (xsltTransformFunction) xsltDocumentElem); 00325 xsltRegisterExtModuleElement((const xmlChar *) "document", 00326 XSLT_NAMESPACE, 00327 xsltDocumentComp, 00328 (xsltTransformFunction) xsltDocumentElem); 00329 } Generated on Sun May 27 2012 04:19:36 for ReactOS by
1.7.6.1
|