/** * xslDbgShellPrintStyleSheets: * @arg: The stylesheets of interests and in UTF-8, is NULL for all stylsheets * * Print stylesheets that can be found in loaded stylsheet * * Returns 1 on success, * 0 otherwise */ int xslDbgShellPrintStyleSheets(xmlChar * arg) { Q_UNUSED(arg); printCounter = 0; if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) { notifyListStart(XSLDBG_MSG_SOURCE_CHANGED); walkStylesheets((xmlHashScanner) xslDbgShellPrintStylesheetsHelper, NULL, filesGetStylesheet()); notifyListSend(); notifyListStart(XSLDBG_MSG_INCLUDED_SOURCE_CHANGED); walkIncludes((xmlHashScanner) xslDbgShellPrintStylesheetsHelper2, NULL, filesGetStylesheet()); notifyListSend(); } else { walkStylesheets((xmlHashScanner) xslDbgShellPrintStylesheetsHelper, NULL, filesGetStylesheet()); walkIncludes((xmlHashScanner) xslDbgShellPrintStylesheetsHelper2, NULL, filesGetStylesheet()); if (printCounter != 0) xsldbgGenericErrorFunc(i18n("\tTotal of %n XSLT stylesheet found.", "\tTotal of %n XSLT stylesheets found.", printCounter) + QString("\n")); else /* strange but possible */ xsldbgGenericErrorFunc(i18n("\tNo XSLT stylesheets found.\n")); } return 1; /* always succeed */ }
/** * xslDbgShellShowParam: * @arg: Not used * * Print list of current paramters * * Returns 1 on success, * 0 otherwise */ int xslDbgShellShowParam(xmlChar * arg) { Q_UNUSED(arg); int result = 0; static const char *errorPrompt = I18N_NOOP("Unable to print parameters"); if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) { int paramIndex = 0; int itemCount = arrayListCount(optionsGetParamItemList()); notifyListStart(XSLDBG_MSG_PARAMETER_CHANGED); if (itemCount > 0) { parameterItemPtr paramItem = NULL; while (paramIndex < itemCount) { paramItem = (parameterItemPtr) arrayListGet(optionsGetParamItemList(), paramIndex++); if (paramItem != NULL) notifyListQueue(paramItem); } } notifyListSend(); result = 1; } else { if (optionsPrintParamList()) result = 1; else xsldbgGenericErrorFunc(QString("Error: %1\n").arg(i18n(errorPrompt))); xsldbgGenericErrorFunc("\n"); } return result; }
/** * breakPointPrint: * @breakPtr: A valid break point * * Print the details of @breakPtr * * Returns 1 if successful, * 0 otherwise */ int breakPointPrint(breakPointPtr breakPtr) { int result = 0; const char *breakStatusText[2] = { I18N_NOOP("disabled"), I18N_NOOP("enabled") }; const char *breakTemplate=""; const char *breakMode = ""; const char *breakStatus; if (!breakPtr) return result; if (breakPtr->templateName){ if (breakPtr->modeName) breakMode = (const char*)breakPtr->modeName; breakTemplate = (const char*)breakPtr->templateName; } breakStatus = breakStatusText[breakPtr->flags & BREAKPOINT_ENABLED]; if (breakPtr->url) xsldbgGenericErrorFunc(i18n("Breakpoint %1 %2 for template: \"%3\" mode: \"%4\" in file \"%5\" at line %6").arg(breakPtr->id).arg(i18n(breakStatus)).arg(xsldbgText(breakTemplate)).arg(xsldbgText(breakMode)).arg(xsldbgUrl(breakPtr->url)).arg(breakPtr->lineNo)); else xsldbgGenericErrorFunc(i18n("Breakpoint %1 %2 for template: \"%3\" mode: \"%4\"").arg(breakPtr->id).arg(i18n(breakStatus)).arg(xsldbgText(breakTemplate)).arg(xsldbgText(breakMode))); return ++result; }
int xslDbgShellCat(xsltTransformContextPtr styleCtxt, xmlShellCtxtPtr ctxt, xmlChar * arg) { xmlXPathObjectPtr list; int result = 0; static const char * QUIET_STR = "-q"; bool silenceCtxtErrors = false; if ((arg == NULL) || (xmlStrLen(arg) == 0)) arg = (xmlChar *) "."; /* Do we quietly ingore style context errors */ if (strncasecmp((char*)arg, QUIET_STR, strlen(QUIET_STR))== 0){ silenceCtxtErrors = true; arg = arg + strlen(QUIET_STR); while (isspace(*arg)){ arg++; } } if (!styleCtxt || !ctxt || !ctxt->node) { if (!(!xsldbgReachedFirstTemplate && silenceCtxtErrors)) xsldbgGenericErrorFunc(i18n("Warning: Unable to print expression. No stylesheet was properly loaded.\n")); return 0; } if ((arg == NULL) || (xmlStrLen(arg) == 0)) arg = (xmlChar *) "."; ctxt->pctxt->node = ctxt->node; if (!styleCtxt) { list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt); } else { xmlNodePtr savenode = styleCtxt->xpathCtxt->node; ctxt->pctxt->node = ctxt->node; styleCtxt->xpathCtxt->node = ctxt->node; if (!xmlXPathNsLookup(styleCtxt->xpathCtxt, (xmlChar *) "xsl")) xmlXPathRegisterNs(styleCtxt->xpathCtxt, (xmlChar *) "xsl", XSLT_NAMESPACE); list = xmlXPathEval((xmlChar *) arg, styleCtxt->xpathCtxt); styleCtxt->xpathCtxt->node = savenode; } if (list != NULL) { result = printXPathObject(list, arg); xmlXPathFreeObject(list); } else { xsldbgGenericErrorFunc(i18n("Error: XPath %1 results in an empty Node Set.\n").arg(xsldbgText(arg))); } ctxt->pctxt->node = NULL; return result; }
/** * printTemplateHelper: * @templ: Is valid * @verbose: Either 1 or 0 * @templateCount: Is valid * @count: Is valid * @templateName: template name to print, may be NULL * * This display the templates in the same order as they are in the * stylesheet. If verbose is 1 then print more information * For each template found @templateCount is increased * For each printed template @printCount is increased */ void printTemplateHelper(xsltTemplatePtr templ, int verbose, int *templateCount, int *count, xmlChar * templateName) { xmlChar *name, *defaultUrl = (xmlChar *) "<n/a>"; const xmlChar *url; if (!templ) return; *templateCount = *templateCount + 1; printTemplateHelper(templ->next, verbose, templateCount, count, templateName); if (templ->elem && templ->elem->doc && templ->elem->doc->URL) { url = templ->elem->doc->URL; } else { url = defaultUrl; } if (templ->match) name = xmlStrdup(templ->match); else name = fullQName(templ->nameURI, templ->name); if (name) { if (templateName && (xmlStrcmp(templateName, name) != 0)) { /* search for template name supplied failed */ /* empty */ } else { xmlChar *modeTemp = NULL; *count = *count + 1; if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) { notifyListQueue(templ); } else { modeTemp = fullQName(templ->modeURI, templ->mode); if (verbose) xsldbgGenericErrorFunc(i18n(" template: \"%1\" mode: \"%2\" in file \"%3\" at line %4\n").arg(xsldbgText(name)).arg(xsldbgText(modeTemp)).arg(xsldbgUrl(url)).arg(xmlGetLineNo(templ->elem))); else xsldbgGenericErrorFunc(QString("\"%s\" ").arg(xsldbgText(name))); if (modeTemp) xmlFree(modeTemp); } } xmlFree(name); } }
/** * xslDbgEntities: * * Print list of entites found * * Returns 1 on sucess, * 0 otherwise */ int xslDbgEntities(void) { int result = 0; if (filesEntityList()) { int entityIndex; entityInfoPtr entInfo; if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) { /* notify that we are starting new list of entity names */ notifyListStart(XSLDBG_MSG_ENTITIY_CHANGED); for (entityIndex = 0; entityIndex < arrayListCount(filesEntityList()); entityIndex++) { entInfo = (entityInfoPtr) arrayListGet(filesEntityList(), entityIndex); if (entInfo) notifyListQueue(entInfo); } notifyListSend(); result = 1; } else { for (entityIndex = 0; entityIndex < arrayListCount(filesEntityList()); entityIndex++) { entInfo = (entityInfoPtr) arrayListGet(filesEntityList(), entityIndex); if (entInfo) { /* display identifier of an XML entity */ xsldbgGenericErrorFunc(i18n("Entity %1 ").arg(xsldbgText(entInfo->SystemID))); if (entInfo->PublicID) xsldbgGenericErrorFunc(xsldbgText(entInfo->PublicID)); xsldbgGenericErrorFunc("\n"); } } if (arrayListCount(filesEntityList()) == 0) { xsldbgGenericErrorFunc(i18n("No external General Parsed entities present.\n")); } else { xsldbgGenericErrorFunc(i18n("\tTotal of %n entity found.", "\tTotal of %n entities found.", arrayListCount(filesEntityList())) + QString("\n")); } result = 1; } } return result; }
/** * xslDbgCatToFile: * @node : Is valid * @file : Is valid * * Send the results of cat command in @node to @file */ void xslDbgCatToFile(xmlNodePtr node, FILE * file) { if (!node || !file) return; /* assume that HTML usage is enabled */ if (node->doc->type == XML_HTML_DOCUMENT_NODE) { if (node->type == XML_HTML_DOCUMENT_NODE) htmlDocDump(file, (htmlDocPtr) node); else htmlNodeDumpFile(file, node->doc, node); } else if (node->type == XML_DOCUMENT_NODE) { /* turn off encoding for the moment and just dump UTF-8 * which will be converted by xsldbgGeneralErrorFunc */ xmlDocPtr doc = (xmlDocPtr) node; const xmlChar *encoding = doc->encoding; if (encoding) { xsldbgGenericErrorFunc(i18n("Information: Temporarily setting document's encoding to UTF-8. Previously was %1.\n").arg(xsldbgText(encoding))); } doc->encoding = (xmlChar *) "UTF-8"; xmlDocDump(file, (xmlDocPtr) node); doc->encoding = encoding; } else { xmlElemDump(file, node->doc, node); } }
/** * xslDbgShellOutput: * @arg : Is valid, either a local file name which will be expanded * if needed, or a "file://" protocol URI * * Set the output file name to use * * Returns 1 on success, * 0 otherwise */ int xslDbgShellOutput(const xmlChar *arg) { int result = 0; if (arg && (xmlStrLen(arg) > 0)){ if (!xmlStrnCmp(arg, "file:/", 6)){ /* convert URI to local file name */ xmlChar *outputFileName = filesURItoFileName(arg); if (outputFileName){ optionsSetStringOption(OPTIONS_OUTPUT_FILE_NAME, outputFileName); notifyXsldbgApp(XSLDBG_MSG_FILE_CHANGED, 0L); xmlFree(outputFileName); result = 1; } } else if (xmlStrEqual(arg, (xmlChar*)"-")) { optionsSetStringOption(OPTIONS_OUTPUT_FILE_NAME, NULL); notifyXsldbgApp(XSLDBG_MSG_FILE_CHANGED, 0L); result = 1; } else if (!xmlStrnCmp(arg, "ftp://", 6) || !xmlStrnCmp(arg, "http://", 7)){ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("output")); return 0; } else { /* assume that we were provided a local file name * that may need expanding */ xmlChar *expandedName = filesExpandName(arg); // The output file must not be the same as our SOURCE or DATA file if (expandedName && (!xmlStrEqual(optionsGetStringOption(OPTIONS_SOURCE_FILE_NAME), expandedName)) && (!xmlStrEqual(optionsGetStringOption(OPTIONS_DATA_FILE_NAME), expandedName)) ){ optionsSetStringOption(OPTIONS_OUTPUT_FILE_NAME, expandedName); notifyXsldbgApp(XSLDBG_MSG_FILE_CHANGED, 0L); xmlFree(expandedName); result = 1; }else{ xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("output")); } } } else { xsldbgGenericErrorFunc(i18n("Error: Missing arguments for the command %1.\n").arg("output")); } return result; }
/** * xslDbgShellPrintList: * @ctxt: The current shell context * @arg: What xpath to display and in UTF-8 * @dir: If 1 print in dir mode?, * otherwise ls mode * * Print list of nodes in either ls or dir format * * Returns 1 on success, * 0 otherwise */ int xslDbgShellPrintList(xmlShellCtxtPtr ctxt, xmlChar * arg, int dir) { xmlXPathObjectPtr list; int result = 0; if (!ctxt || !arg) { #ifdef WITH_XSLDBG_DEBUG_PROCESS xsltGenericError(xsltGenericErrorContext, "Error: NULL arguments provided\n"); #endif return result; } if (arg[0] == 0) { if (dir) xmlShellDir(ctxt, NULL, ctxt->node, NULL); else xmlShellList(ctxt, NULL, ctxt->node, NULL); result = 1; /*assume that this worked */ } else { ctxt->pctxt->node = ctxt->node; ctxt->pctxt->node = ctxt->node; if (!xmlXPathNsLookup(ctxt->pctxt, (xmlChar *) "xsl")) xmlXPathRegisterNs(ctxt->pctxt, (xmlChar *) "xsl", XSLT_NAMESPACE); list = xmlXPathEval(arg, ctxt->pctxt); if (list != NULL) { switch (list->type) { case XPATH_NODESET:{ int indx; for (indx = 0; indx < list->nodesetval->nodeNr; indx++) { if (dir) xmlShellList(ctxt, NULL, list->nodesetval-> nodeTab[indx], NULL); else xmlShellList(ctxt, NULL, list->nodesetval-> nodeTab[indx], NULL); } result = 1; break; } default: xmlShellPrintXPathError(list->type, (char *) arg); } xmlXPathFreeObject(list); } else { xsldbgGenericErrorFunc(i18n("Error: XPath %1 results in an empty Node Set.\n").arg(xsldbgText(arg))); } ctxt->pctxt->node = NULL; } return result; }
/** * xslDbgShellAddParam: * @arg: A string comprised of two words separated by * one or more spaces which are in UTF-8 * * Add a libxslt parameter to be sent to libxslt later on * * Returns 1 on success, * 0 otherwise */ int xslDbgShellAddParam(xmlChar * arg) { int result = 0; parameterItemPtr paramItem = NULL; static const char *errorPrompt = I18N_NOOP("Failed to add parameter"); xmlChar *opts[2]; if (!arg) { xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("addparam")); }else{ if ((xmlStrLen(arg) > 1) && splitString(arg, 2, opts) == 2) { int count; for (count = 0; count < arrayListCount(optionsGetParamItemList()); count++){ paramItem = (parameterItemPtr)arrayListGet(optionsGetParamItemList(), count); if (paramItem != NULL){ if (xmlStrCmp(opts[0], paramItem->name) == 0){ /* parameter exist just update its value */ if (paramItem->value) xmlFree(paramItem->value); paramItem->value = xmlStrdup(opts[1]); return 1; } } } paramItem = optionsParamItemNew(opts[0], opts[1]); result = arrayListAdd(optionsGetParamItemList(), paramItem); } else { xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("addparam")); } } if (!result) xsldbgGenericErrorFunc(QString("Error: %1\n").arg(i18n(errorPrompt))); else { xsldbgGenericErrorFunc("\n"); } return result; }
/* * xslDbgShellPrintNames: * Print a name of variable found by scanning variable table * It is used by print_variable function. * @payload : Global variable of type xsltStackElemPtr * @data : not used * @name : the variable name */ void * xslDbgShellPrintNames(void *payload, void *data, xmlChar * name) { Q_UNUSED(payload); Q_UNUSED(data); if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) { notifyListQueue(payload); } else if (payload && name) { xmlChar * fullQualifiedName = nodeViewBuffer; xsltStackElemPtr item = (xsltStackElemPtr)payload; if (item->nameURI == NULL){ snprintf((char*)fullQualifiedName, sizeof(nodeViewBuffer), "$%s", item->name); }else{ snprintf((char*)fullQualifiedName, sizeof(nodeViewBuffer), "$%s:%s", item->nameURI, item->name); } if (printVariableValue == 0){ xsldbgGenericErrorFunc(i18n(" Global %1\n").arg(xsldbgText(fullQualifiedName))); }else{ if (item->computed == 1){ xsldbgGenericErrorFunc(i18n(" Global ")); printXPathObject(item->value, fullQualifiedName); }else if (item->tree){ xsldbgGenericErrorFunc(i18n(" Global = %1\n").arg(xsldbgText(fullQualifiedName))); xslDbgCatToFile(item->tree, stderr); }else if (item->select){ xsldbgGenericErrorFunc(i18n(" Global = %1\n%2").arg(xsldbgText(fullQualifiedName)).arg(xsldbgText(item->select))); }else{ /* can't find a value give only a variable name an error message */ xsldbgGenericErrorFunc(i18n(" Global = %1\n%2").arg(xsldbgText(fullQualifiedName)).arg(i18n("Warning: No value assigned to variable.\n"))); } xsltGenericError(xsltGenericErrorContext, "\n\032\032\n"); } varCount++; } return NULL; }
/** * xslDbgSystem: * @arg : Is valid * * Print what a system file @arg maps to via the current xml catalog * * Returns 1 on sucess, * 0 otherwise */ int xslDbgSystem(const xmlChar * arg) { int result = 0; xmlChar *name; if (!arg || (xmlStrlen(arg) == 0)) { #ifdef WITH_XSLDBG_DEBUG_PROCESS xsltGenericError(xsltGenericErrorContext, "Error: NULL argument provided\n"); #endif return result; } name = xmlCatalogResolveSystem(arg); if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) { if (name) { notifyXsldbgApp(XSLDBG_MSG_RESOLVE_CHANGE, name); result = 1; xmlFree(name); } else { notifyXsldbgApp(XSLDBG_MSG_RESOLVE_CHANGE, ""); xsldbgGenericErrorFunc(i18n("SystemID \"%1\" was not found in current catalog.\n").arg(xsldbgText(arg))); } } else { if (name) { xsldbgGenericErrorFunc(i18n("SystemID \"%1\" maps to: \"%2\"\n").arg(xsldbgText(arg)).arg(xsldbgText(name))); xmlFree(name); result = 1; } else { xsldbgGenericErrorFunc(i18n("SystemID \"%1\" was not found in current catalog.\n").arg(xsldbgText(arg))); } } return result; }
/** * xslDbgShellPrintStylesheetsHelper2: * @payload :valid xmlNodePtr of included stylesheet * @data : not used * name : not used * * Print out the stylesheet name from the stylesheet given to * us via walkIncludes */ void xslDbgShellPrintStylesheetsHelper2(void *payload, void *data, xmlChar * name) { Q_UNUSED(data); Q_UNUSED(name); xmlNodePtr node = (xmlNodePtr) payload; if (node && node->doc && node->doc->URL) { if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) notifyListQueue(payload); else /* display the URL of stylesheet */ xsldbgGenericErrorFunc(i18n(" Stylesheet %1\n").arg(xsldbgUrl(node->doc->URL))); printCounter++; } }
/** * xslDbgEncoding: * @arg: Is valid encoding supported by libxml2 * * Set current encoding to use for output to standard output * * Returns 1 on sucess, * 0 otherwise */ int xslDbgEncoding(xmlChar * arg) { int result = 0; xmlChar *opts[2]; if (!arg) { #ifdef WITH_XSLDBG_DEBUG_PROCESS xsltGenericError(xsltGenericErrorContext, "Error: NULL argument provided\n"); #endif return result; } if (splitString(arg, 1, opts) == 1) { if (filesSetEncoding((char *) opts[0])) { optionsSetStringOption(OPTIONS_ENCODING, opts[0]); result = 1; } } else xsldbgGenericErrorFunc(i18n("Error: Missing arguments for the command %1.\n").arg("encoding")); return result; }
/** * xslDbgShellDelParam: * @arg: A single white space trimmed parameter number to look for * * Delet a libxslt parameter to be sent to libxslt later on * * Returns 1 if able to delete parameter @name, * 0 otherwise */ int xslDbgShellDelParam(xmlChar * arg) { int result = 0; static const char *errorPrompt = I18N_NOOP("Failed to delete parameter"); long paramId; xmlChar *opts[2]; if (!arg) { xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("delparam")); }else{ if (xmlStrLen(arg) > 0) { if (splitString(arg, 1, opts) == 1) { if ((xmlStrlen(opts[0]) == 0) || !sscanf((char *) opts[0], "%ld", ¶mId)) { xsldbgGenericErrorFunc(i18n("Error: Unable to parse %1 as a line number.\n").arg(xsldbgText(opts[0]))); } else { result = arrayListDelete(optionsGetParamItemList(), paramId); if (!result) xsldbgGenericErrorFunc(i18n("Error: Unable to find parameter %1.\n").arg(paramId)); } } else { xsldbgGenericErrorFunc(i18n("Error: Invalid arguments for the command %1.\n").arg("delparam")); } } else { /* Delete all parameters */ arrayListEmpty(optionsGetParamItemList()); result = 1; } } if (!result) xsldbgGenericErrorFunc(QString("Error: %1\n").arg(i18n(errorPrompt))); else xsldbgGenericErrorFunc("\n"); return result; }
/** * breakPointAdd: * @url: Non-null, non-empty file name that has been loaded by * debugger * @lineNumber: @lineNumber >= 0 and is available in url specified and * points to an xml element * @templateName: The template name of breakPoint or NULL * @modeName : The mode of breakpoint or NULL * @type: Valid BreakPointTypeEnum * * Add break point at file and line number specified * * Returns 1 if successful, * 0 otherwise */ int breakPointAdd(const xmlChar * url, long lineNumber, const xmlChar * templateName, const xmlChar * modeName, BreakPointTypeEnum type) { int result = 0, breakPointType = type; xmlHashTablePtr breakPointHash = NULL; /* hash of breakPoints */ breakPointPtr breakPtr; if (!breakList) { #ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS xsltGenericError(xsltGenericErrorContext, "Error: Breakpoints structures not initialized\n"); #endif return result; } if (!url || (lineNumber == -1)) { #ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS xsltGenericError(xsltGenericErrorContext, "Error: Invalid url or line number to breakPointAdd\n"); #endif return result; } /* if breakpoint already exists then don;t add it */ if (breakPointIsPresent(url, lineNumber)) { #ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS xsltGenericError(xsltGenericErrorContext, "Warning: Breakpoint at file %s: line %d exists\n", url, lineNumber); #endif return result; } breakPtr = breakPointItemNew(); if (breakPtr) { breakPtr->url = (xmlChar *) xmlMemStrdup((char *) url); breakPtr->lineNo = lineNumber; if (templateName) breakPtr->templateName = xmlStrdup( templateName); else breakPtr->templateName = NULL; if (modeName) breakPtr->modeName = xmlStrdup(modeName); else breakPtr->modeName = NULL; breakPtr->type = BreakPointTypeEnum(breakPointType); /* add new breakPoint to the right hash table */ breakPointHash = breakPointGetLineNoHash(lineNumber); if (breakPointHash) { result = lineNoItemAdd(breakPointHash, breakPtr); } else { /* Grow breakList size */ int lineIndex; int newEntries = breakList->count; xmlHashTablePtr hash; result = 1; if ((lineNumber < breakList->count) && breakList->count) { #ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS xsltGenericError(xsltGenericErrorContext, "Error: Unable to find breakpoint line hash at %d\n", lineNumber); #endif } else { if (breakList->count + newEntries < lineNumber) newEntries = lineNumber - breakList->count + 1; #ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS /* * xsltGenericError(xsltGenericErrorContext, * "Size of line list was %d adding %d entries\n", * breakList->count, newEntries); */ #endif lineIndex = 0; while ((lineIndex < newEntries) && result) { hash = lineNoItemNew(); if (hash) { result = result && arrayListAdd(breakList, hash); } else { result = 0; #ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS xsltGenericError(xsltGenericErrorContext, "Error: Unable to create hash table breakPoint list: memory error\n"); #endif return result; } lineIndex++; } /* find the newly added hashtable of breakpoints */ breakPointHash = breakPointGetLineNoHash(lineNumber); if (breakPointHash) { result = lineNoItemAdd(breakPointHash, breakPtr); } else { #ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS xsltGenericError(xsltGenericErrorContext, "Error: Unable to create new breakPoint:interal error\n"); #endif return result; } } } } else { #ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS xsltGenericError(xsltGenericErrorContext, "Error: Unable to create new breakPoint: memory error\n"); #endif } if (result && (optionsGetIntOption(OPTIONS_GDB) > 1) && (xsldbgValidateBreakpoints != BREAKPOINTS_BEING_VALIDATED)){ breakPointPrint(breakPtr); xsldbgGenericErrorFunc("\n"); } return result; }
static int printXPathObject(xmlXPathObjectPtr item, xmlChar* xPath){ int result = 0; if (item){ switch (item->type) { case XPATH_BOOLEAN: xsltGenericError(xsltGenericErrorContext, "= %s\n%s\n", xPath, xmlBoolToText(item->boolval)); result = 1; break; case XPATH_NUMBER: xsltGenericError(xsltGenericErrorContext, "= %s\n%0g\n", xPath, item->floatval); result = 1; break; /* case XPATH_NODESET:*/ default:{ /* We may need to convert this XPath to a string, plus ensure that we print required the number of lines of text */ int indx; const char *fileName = filesTempFileName(0); FILE *file = NULL; if (!fileName) break; file = fopen(fileName, "w+"); if (!file) { xsldbgGenericErrorFunc(i18n("Error: Unable to save temporary results to %1.\n").arg(xsldbgText(fileName))); break; } else { fprintf(file, "= %s\n", xPath); switch(item->type){ case XPATH_NODESET: if (item->nodesetval){ for (indx = 0; indx < item->nodesetval->nodeNr; indx++){ xslDbgCatToFile(item->nodesetval-> nodeTab[indx], file); } } else { xsldbgGenericErrorFunc(i18n("Error: XPath %1 results in an empty Node Set.\n").arg(xsldbgText(xPath))); } break; case XPATH_STRING: if (item->stringval) fprintf(file, "\'%s\'", item->stringval); else fprintf(file, "%s", i18n("NULL string value supplied.").utf8().data()); break; default:{ xmlXPathObjectPtr tempObj = xmlXPathObjectCopy(item); if (tempObj) tempObj = xmlXPathConvertString(tempObj); if (tempObj && tempObj->stringval){ fprintf(file, "%s", tempObj->stringval); }else{ fprintf(file, "%s", i18n("Unable to convert XPath to string.").utf8().data()); } if (tempObj) xmlXPathFreeObject(tempObj); } break; fprintf(file,"\n"); } /* inner switch statement */ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) { fclose(file); file = NULL; /* send the data to application */ notifyXsldbgApp(XSLDBG_MSG_FILEOUT, fileName); } else { int lineCount = 0, gdbModeEnabled = 0; /* save the value of option to speed things up * a bit */ gdbModeEnabled = optionsGetIntOption(OPTIONS_GDB); rewind(file); /* when gdb mode is enable then only print the first * GDB_LINES_TO_PRINT lines */ while (!feof(file)) { if (fgets ((char *) nodeViewBuffer, sizeof(nodeViewBuffer), file)) xsltGenericError (xsltGenericErrorContext, "%s", nodeViewBuffer); if (gdbModeEnabled) { lineCount++; /* there is an overhead of two lines * when print expression values */ if (lineCount == GDB_LINES_TO_PRINT + 2) { xsltGenericError (xsltGenericErrorContext, "..."); break; } } } xsltGenericError (xsltGenericErrorContext, "\n"); } if (file) fclose(file); result = 1; break; } } } } return result; }
/** * xslDbgShellPrintVariable: * @styleCtxt: The current stylesheet context * @arg: The name of variable to look for '$' prefix is optional and in UTF-8 * @type: A valid VariableTypeEnum * * Print the value variable specified by args. * * Returns 1 on success, * 0 otherwise */ int xslDbgShellPrintVariable(xsltTransformContextPtr styleCtxt, xmlChar * arg, VariableTypeEnum type) { int result = 0; /* command argument to include both name and its value */ static const char * FULLNAME_STR = "-f"; /* Quietly exit if an invalid stylesheet is provided */ static const char * QUIET_STR = "-q"; bool silenceCtxtErrors = false; if (!arg) { #ifdef WITH_XSLDBG_DEBUG_PROCESS xsltGenericError(xsltGenericErrorContext, "Error: NULL argument provided\n"); #endif return result; } varCount = 0; /* Do we quietly ingore style context errors */ if (strncasecmp((char*)arg, QUIET_STR, strlen(QUIET_STR))== 0){ silenceCtxtErrors = true; arg = arg + strlen(QUIET_STR); while (isspace(*arg)){ arg++; } } if (!styleCtxt) { if (!(!xsldbgReachedFirstTemplate && silenceCtxtErrors)) xsldbgGenericErrorFunc(i18n("Error: Debugger has no files loaded or libxslt has not reached a template.\nTry reloading files or taking more steps.\n")); return result; } /* Do we include the name as well as its value */ if (strncasecmp((char*)arg, FULLNAME_STR, strlen(FULLNAME_STR))== 0){ printVariableValue = 1; arg = arg + strlen(FULLNAME_STR); while (isspace(*arg)){ arg++; } } if (arg[0] == 0) { /* list variables of type requested */ if (type == DEBUG_GLOBAL_VAR) { if (styleCtxt->globalVars) { if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) { notifyListStart(XSLDBG_MSG_GLOBALVAR_CHANGED); /* list global variables */ xmlHashScan(styleCtxt->globalVars, (xmlHashScanner) xslDbgShellPrintNames, NULL); notifyListSend(); } else /* list global variables */ xmlHashScan(styleCtxt->globalVars, (xmlHashScanner) xslDbgShellPrintNames, NULL); result = 1; /* ensure that the locals follow imediately after the * globals when in gdb mode */ if (optionsGetIntOption(OPTIONS_GDB) == 0) xsltGenericError(xsltGenericErrorContext, "\n"); } else { if (getThreadStatus() != XSLDBG_MSG_THREAD_RUN) { /* Don't show this message when running as a thread as it * is annoying */ xsldbgGenericErrorFunc(i18n("Error: Libxslt has not initialized variables yet; try stepping to a template.\n")); } else { /* send an empty list */ notifyListStart(XSLDBG_MSG_GLOBALVAR_CHANGED); notifyListSend(); result = 1; } } } else { /* list local variables */ if (styleCtxt->varsNr && styleCtxt->varsTab) { if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) { notifyListStart(XSLDBG_MSG_LOCALVAR_CHANGED); for (int i = styleCtxt->varsNr; i > styleCtxt->varsBase; i--) { xsltStackElemPtr item = styleCtxt->varsTab[i-1]; while (item) { notifyListQueue(item); item = item->next; } } notifyListSend(); } else { xmlChar * fullQualifiedName = nodeViewBuffer; for (int i = styleCtxt->varsNr; i > styleCtxt->varsBase; i--) { xsltStackElemPtr item = styleCtxt->varsTab[i-1]; while (item) { if (item->name) { if (item->nameURI == NULL){ snprintf((char*)fullQualifiedName, sizeof(nodeViewBuffer), "$%s", item->name); }else{ snprintf((char*)fullQualifiedName, sizeof(nodeViewBuffer), "$%s:%s", item->nameURI, item->name); } if (printVariableValue == 0){ xsldbgGenericErrorFunc(i18n(" Local %1").arg(xsldbgText(fullQualifiedName))); }else{ if (item->computed == 1){ xsldbgGenericErrorFunc(i18n(" Local ")); printXPathObject(item->value, fullQualifiedName); }else if (item->tree){ xsldbgGenericErrorFunc(i18n(" Local = %1\n").arg(xsldbgText(fullQualifiedName))); xslDbgCatToFile(item->tree, stderr); }else if (item->select){ xsldbgGenericErrorFunc(i18n(" Local = %1\n%2").arg(xsldbgText(fullQualifiedName)).arg(xsldbgText(item->select))); }else{ /* can't find a value give only a variable name and an error */ xsldbgGenericErrorFunc(i18n(" Local = %1\n%2").arg(xsldbgText(fullQualifiedName)).arg(i18n("Warning: No value assigned to variable.\n"))); } } xsltGenericError(xsltGenericErrorContext, "\n\032\032\n"); } item = item->next; } } } result = 1; xsltGenericError(xsltGenericErrorContext, "\n"); } else { if (getThreadStatus() != XSLDBG_MSG_THREAD_RUN) { /* Don't show this message when running as a thread as it * is annoying */ xsldbgGenericErrorFunc(i18n("Error: Libxslt has not initialized variables yet; try stepping past the xsl:param elements in the template.\n")); } else { /* send an empty list */ notifyListStart(XSLDBG_MSG_LOCALVAR_CHANGED); notifyListSend(); result = 1; } } } } else { /* Display the value of variable */ if (arg[0] == '$') { printXPathObject(xmlXPathEval(arg, styleCtxt->xpathCtxt), arg); xsltGenericError(xsltGenericErrorContext, "\032\032\n"); } else { xmlStrCpy(nodeViewBuffer, "$"); xmlStrCat(nodeViewBuffer, arg); printXPathObject(xmlXPathEval((xmlChar*)nodeViewBuffer,styleCtxt->xpathCtxt), (xmlChar*)nodeViewBuffer); xsltGenericError(xsltGenericErrorContext, "\032\032\n"); } } printVariableValue = 0; return result; }
/** * debugHandleDebugger: * @cur : source node being executed * @node : data node being processed * @templ : temlate that applies to node * @ctxt : the xslt transform context * * If either cur or node are a breakpoint, or xslDebugStatus in state * where debugging must occcur at this time then transfer control * to the debugXSLBreak function */ void debugHandleDebugger(xmlNodePtr cur, xmlNodePtr node, xsltTemplatePtr templ, xsltTransformContextPtr ctxt) { if (!cur && !node) { xsldbgGenericErrorFunc(i18n("Error: XSLT source and XML data are empty. Cannot enter the debugger.\n")); } else { if (optionsGetIntOption(OPTIONS_GDB)){ int doValidation = 0; switch(xsldbgValidateBreakpoints){ case BREAKPOINTS_ARE_VALID: if (!filesGetStylesheet() || !filesGetMainDoc()) { xsldbgValidateBreakpoints = BREAKPOINTS_NEED_VALIDATION; doValidation = 1; } break; case BREAKPOINTS_NEED_VALIDATION: if (filesGetStylesheet() && filesGetMainDoc() && templ){ xsldbgValidateBreakpoints = BREAKPOINTS_BEING_VALIDATED; doValidation = 1; } break; case BREAKPOINTS_BEING_VALIDATED: /*should never be in the state for any length of time */ #ifdef WITH_XSLDBG_DEBUG_BREAKPOINTS xsltGenericError(xsltGenericErrorContext, "Error: Unexpected breakpoint validation state %d", xsldbgValidateBreakpoints); #endif break; } if (doValidation){ /* breakpoints will either be marked as orphaned or not as needed */ xsldbgValidateBreakpoints = BREAKPOINTS_BEING_VALIDATED; walkBreakPoints((xmlHashScanner) xslDbgShellValidateBreakPoint, ctxt); if (filesGetStylesheet() && filesGetMainDoc() && templ){ xsldbgValidateBreakpoints = BREAKPOINTS_ARE_VALID; }else{ xsldbgValidateBreakpoints = BREAKPOINTS_NEED_VALIDATION; } } } switch (xslDebugStatus) { /* A temparary stopping point */ case DEBUG_WALK: case DEBUG_TRACE: /* only allow breakpoints at xml elements */ if (xmlGetLineNo(cur) != -1) debugXSLBreak(cur, node, templ, ctxt); break; case DEBUG_STOP: xslDebugStatus = DEBUG_CONT; /* only allow breakpoints at xml elements */ if (xmlGetLineNo(cur) != -1) debugXSLBreak(cur, node, templ, ctxt); break; case DEBUG_STEP: /* only allow breakpoints at xml elements */ if (xmlGetLineNo(cur) != -1) debugXSLBreak(cur, node, templ, ctxt); break; case DEBUG_CONT: { breakPointPtr breakPtr = NULL; xmlChar *baseUri = NULL; if (cur) { breakPtr = breakPointGet(cur->doc->URL, xmlGetLineNo(cur)); if (breakPtr && (breakPtr->flags & BREAKPOINT_ENABLED) ){ debugXSLBreak(cur, node, templ, ctxt); return; } } if (node) { baseUri = filesGetBaseUri(node); if (baseUri != NULL) { breakPtr = breakPointGet(baseUri, xmlGetLineNo(node)); } else { breakPtr = breakPointGet(node->doc->URL, xmlGetLineNo(node)); } if (breakPtr) { if (breakPtr->flags & BREAKPOINT_ENABLED) { debugXSLBreak(cur, node, templ, ctxt); } } if (baseUri) xmlFree(baseUri); } } break; } } }
int xslDbgShellSetVariable(xsltTransformContextPtr styleCtxt, xmlChar * arg) { int result = 0, showUsage = 0; xmlChar *name, *nameURI, *selectExpr, *opts[3]; if (!styleCtxt) { xsldbgGenericErrorFunc(i18n("Error: Stylesheet is not valid.\n")); return result; } if (!arg) { #ifdef WITH_XSLDBG_DEBUG_PROCESS xsltGenericError(xsltGenericErrorContext, "Error: NULL argument provided\n"); #endif return result; } if (xmlStrLen(arg) > 1) { if (splitString(arg, 2, opts) == 2) { nameURI = NULL; /* ignore any "$" prefix as user probably didn't mean that "$" is part of variable name*/ if (*opts[0] =='$'){ opts[0] = opts[0] + 1; } name = xmlSplitQName2(opts[0], &nameURI); if (name == NULL) name = xmlStrdup(opts[0]); selectExpr = xmlStrdup(opts[1]); if (name && selectExpr) { xsltStackElemPtr def = NULL; if (styleCtxt->varsBase) { /* try finding varaible in stack */ xsltStackElemPtr item = styleCtxt->varsTab[styleCtxt->varsBase]; while (item) { if ((xmlStrCmp(name, item->name) == 0) && (item->nameURI == NULL || (xmlStrCmp(name, item->nameURI) == 0))) { def = item; break; } item = item->next; } } if (def == NULL) def = (xsltStackElemPtr) xmlHashLookup2(styleCtxt->globalVars, name, nameURI); if (def != NULL) { if (def->select) { /* we've found the variable so change it */ xmlFree((void*)def->select); def->select = selectExpr; if (def->comp->comp) xmlXPathFreeCompExpr(def->comp->comp); def->comp->comp = xmlXPathCompile(def->select); if (def->value) xmlXPathFreeObject(def->value); def->value = xmlXPathEval(def->select, styleCtxt->xpathCtxt); result = 1; } else { xmlFree(selectExpr); xsldbgGenericErrorFunc(i18n("Error: Cannot change a variable that does not use the select attribute.\n")); } } else xsldbgGenericErrorFunc(i18n("Error: Variable %1 was not found.\n").arg(xsldbgText(name))); xmlFree(name); } else xsldbgGenericErrorFunc(i18n("Error: Out of memory.\n")); } else { showUsage = 1; } if (showUsage == 1) xsldbgGenericErrorFunc(i18n("Error: Invalid arguments to command %1.\n").arg("set")); } return result; }
/** * xslDbgShellPrintTemplateNames: * @styleCtxt: Is valid * @ctxt: Not used * @arg: Not used * @verbose: If 1 then print extra messages about templates found, * otherwise print normal messages only * @allFiles: If 1 then look for all templates in stylsheets found in * @styleCtxt * otherwise look in the stylesheet found by * debugXSLBreak function * * Print out the list of template names found that match critieria * * Returns 1 on success, * 0 otherwise */ int xslDbgShellPrintTemplateNames(xsltTransformContextPtr styleCtxt, xmlShellCtxtPtr ctxt, xmlChar * arg, int verbose, int allFiles) { Q_UNUSED(ctxt); int templateCount = 0, printedTemplateCount = 0; int result = 0; xsltStylesheetPtr curStyle; xsltTemplatePtr templ; if (xmlStrLen(arg) == 0) { arg = NULL; } else { allFiles = 1; /* make sure we find it if we can */ } if (!styleCtxt) { xsldbgGenericErrorFunc(i18n("Error: Stylesheet is not valid.\n")); return result; } if (allFiles) curStyle = styleCtxt->style; else { /* try to find files in the current stylesheet */ /* root copy is set to the stylesheet found by debugXSLBreak */ if (debugXSLGetTemplate()) curStyle = debugXSLGetTemplate()->style; else curStyle = NULL; } if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) { notifyListStart(XSLDBG_MSG_TEMPLATE_CHANGED); while (curStyle) { templ = curStyle->templates; /* print them out in the order their in the file */ printTemplateHelper(templ, verbose, &templateCount, &printedTemplateCount, arg); if (curStyle->next) curStyle = curStyle->next; else curStyle = curStyle->imports; } notifyListSend(); } else { xsltGenericError(xsltGenericErrorContext, "\n"); while (curStyle) { templ = curStyle->templates; /* print them out in the order their in the file */ printTemplateHelper(templ, verbose, &templateCount, &printedTemplateCount, arg); xsltGenericError(xsltGenericErrorContext, "\n"); if (curStyle->next) curStyle = curStyle->next; else curStyle = curStyle->imports; } if (templateCount == 0) { xsldbgGenericErrorFunc(i18n("\tNo XSLT templates found.\n")); } else { xsldbgGenericErrorFunc(i18n("\tTotal of %n XSLT template found", "\tTotal of %n XSLT templates found", templateCount) + QString("\n")); xsldbgGenericErrorFunc(i18n("\tTotal of %n XSLT template printed", "\tTotal of %n XSLT templates printed", printedTemplateCount) + QString("\n")); } } result = 1; return result; }