/* setup all application wide items */ int xsldbgThreadInit(void) { int result = 0; fprintf(stderr, "mainInit()\n"); xsltSetGenericErrorFunc(0, xsldbgGenericErrorFunc); setThreadStatus(XSLDBG_MSG_THREAD_INIT); xsldbgSetAppFunc(qtNotifyXsldbgApp); xsldbgSetAppStateFunc(qtNotifyStateXsldbgApp); xsldbgSetTextFunc(qtNotifyTextXsldbgApp); xsldbgSetReadlineFunc(qtXslDbgShellReadline); /* create the thread */ if (pthread_create(&mythread, NULL, xsldbgThreadMain, NULL) != EAGAIN) { int counter; for (counter = 0; counter < 11; counter++){ if (getThreadStatus() != XSLDBG_MSG_THREAD_INIT) break; usleep(250000); /*guess that it will take at most 2.5 seconds to startup */ } /* xsldbg should have started by now if it can */ if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN){ fprintf(stderr, "Created thread\n"); result++; }else fprintf(stderr, "Thread did not start\n"); } else { fprintf(stderr, "Failed to create thread\n"); } return result; }
/** * 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; }
/* tell the thread to stop and free that memory !*/ void xsldbgThreadFree(void) { fprintf(stderr, "xsldbgThreadFree()\n"); if (getThreadStatus() != XSLDBG_MSG_THREAD_DEAD) { int counter; fprintf(stderr, "Killing xsldbg thread\n"); setThreadStatus(XSLDBG_MSG_THREAD_STOP); for (counter = 0; counter < 11; counter++){ if (getThreadStatus() == XSLDBG_MSG_THREAD_DEAD) break; usleep(250000); /*guess that it will take at most 2.5 seconds to stop */ } } }
/* thread has died so cleanup after it not called directly but via notifyXsldbgApp*/ void xsldbgThreadCleanupQt(void) { fprintf(stderr, "Thread has finished\n"); if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) { xsldbgThreadFree(); } /* its safe to modify threadStatus as the thread is now dead */ setThreadStatus(XSLDBG_MSG_THREAD_DEAD); }
/* put text into standard input just like we had typed it */ int fakeInput(const char *text) { int result = 0; if (!text || (getInputReady() == 1) || (getThreadStatus() != XSLDBG_MSG_THREAD_RUN)) return result; // fprintf(stderr, "\nFaking input of \"%s\"\n", text); strncpy(inputBuffer, text, sizeof(inputBuffer)); setInputReady(1); result++; 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; }
bool mthread::Thread::start() { if(getThreadStatus() == WORK) return false; _status = WORK; if(_isDetach == true) { pthread_attr_t attr; pthread_attr_init(&attr); if(pthread_attr_init(&attr) != 0 || pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) return false; return pthread_create(&_id, &attr, _threadFunc, (void *)this) == 0 && pthread_attr_destroy(&attr) == 0; } return pthread_create(&_id, NULL, _threadFunc, (void *)this) == 0; }
//------------------------------------------------------------------------ bool ThreadManagerSerial::isThreadSerialized(int id) { bool output = false; int status = getThreadStatus(id); if( (status == THREAD_STATUS_SERIAL_STOPPED) || (status == THREAD_STATUS_SERIAL_RUNNING) || (status == THREAD_STATUS_SERIAL_TO_PARALLEL_RUNNING_REQUEST) || (status == THREAD_STATUS_SERIAL_TO_PARALLEL_STOPPED_REQUEST) ) { output = true; } return output; }
/* this is where the thread get to do all its work */ void * xsldbgThreadMain(void *) { // int defaultArgc = 2; // char *defaultArgv[2]; // int i; if (getThreadStatus() != XSLDBG_MSG_THREAD_INIT){ fprintf(stderr, "xsldbg thread is not ready to be started. Or one is already running.\n"); return NULL; /* we can't start more than one thread of xsldbg */ } // defaultArgv[0] = xmlMemStrdup("xsldbg"); // defaultArgv[1] = xmlMemStrdup("--shell"); /* defaultArgv[2] = xmlMemStrdup("xsldoc.xsl"); defaultArgv[3] = xmlMemStrdup("xsldoc.xml"); */ /* for (i = 0; i < defaultArgc; i++){ if (defaultArgv[i] == NULL){ fprintf(stderr, "Start thread failed. Unable to create xsldbg arguments\n"); return NULL; } } */ xsldbgSetThreadCleanupFunc(xsldbgThreadCleanupQt); setThreadStatus(XSLDBG_MSG_THREAD_RUN); setInputStatus(XSLDBG_MSG_AWAITING_INPUT); fprintf(stderr, "Starting thread\n"); /* call the "main of xsldbg" found in debugXSL.c */ // xsldbgMain(defaultArgc, defaultArgv); xsldbgMain(0,0); fprintf(stderr, "Stopping thread\n"); /* for (i = 0; i < defaultArgc; i++){ xmlFree(defaultArgv[i]); } */ setThreadStatus(XSLDBG_MSG_THREAD_DEAD); setInputStatus(XSLDBG_MSG_PROCESSING_INPUT); notifyXsldbgApp(XSLDBG_MSG_THREAD_DEAD, NULL); return NULL; }
void * xsldbgThreadStdoutReader(void *data) { if (!stdoutIO) return data; while (getThreadStatus() == XSLDBG_MSG_THREAD_RUN){ if (fgets(outputBuffer, sizeof(outputBuffer -1), stdoutIO)){ usleep(10000); strcat(outputBuffer, "\n"); notifyTextXsldbgApp(XSLDBG_MSG_TEXTOUT, outputBuffer); }else{ fprintf(stderr, "Unable to read from stdout from xsldbg\n"); break; } } return data; }
/** * 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++; } }
//------------------------------------------------------------------------ void ThreadManagerSerial::doSerialWork() { assert(isPrimaryThread()); // iterate over threadPool and find threads running in serial // call their work and finalize functions int status; for(int i = 0; i < m_threadPoolSize; i++) { status = getThreadStatus(i); switch(status) { case THREAD_STATUS_SERIAL_RUNNING: callWorkFunctionForThread(i); break; case THREAD_STATUS_SERIAL_TO_PARALLEL_STOPPED_REQUEST: callFinalizeFunctionForThread(i); SetThreadStatus(i, THREAD_STATUS_SERIAL_TO_PARALLEL_STOPPED_REQUEST, THREAD_STATUS_STOPPED); break; case THREAD_STATUS_SERIAL_TO_PARALLEL_RUNNING_REQUEST: callFinalizeFunctionForThread(i); SetThreadStatus(i, THREAD_STATUS_SERIAL_TO_PARALLEL_RUNNING_REQUEST, THREAD_STATUS_RUNNING_REQUEST); break; default: // not in a serial state break; } } // increment the serial call count // Windows has a lightweight way to do an atomic increment InterlockedIncrement(&m_serialCalls); // yield to OS to prevent throttling yield(); }
ostream & Thread::printObjectNonConst ( ostream & theOstream, u_int4 theIndent, const char * thePrefixString ) { threadIostreamIndent indent(theIndent, thePrefixString); theOstream << "Thread: " << (const void*)this << endl << indent << " Status = \"" << getThreadStatusString() << "\" (" << int4(getThreadStatus()) << ")" << endl << indent << " Function = " << (void*)getThreadFunction() << endl << indent << " ThreadMutex: " << getMutex() << endl << indent << " ThreadStartedSemaphore: "; getThreadStartedSemaphore() . printObject ( theOstream, theIndent + 5, thePrefixString ); theOstream << endl << indent << " ThreadStoppedSemaphore: "; getThreadStoppedSemaphore() . printObject ( theOstream, theIndent + 5, thePrefixString ); theOstream << endl; return theOstream; }
/* * 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; }
/** * qtXslDbgShellReadline: * @prompt: the prompt value * * Read a string * * Returns a copy of the text inputed or NULL if EOF in stdin found. * The caller is expected to free the returned string. */ xmlChar * qtXslDbgShellReadline(xmlChar * prompt) { const char *inputReadBuff; static char last_read[DEBUG_BUFFER_SIZE] = { '\0' }; if (getThreadStatus() != XSLDBG_MSG_THREAD_RUN) { #ifdef HAVE_READLINE xmlChar *line_read; /* Get a line from the user. */ line_read = (xmlChar *) readline((char *) prompt); /* If the line has any text in it, save it on the history. */ if (line_read && *line_read) { add_history((char *) line_read); strncpy((char*)last_read, (char*)line_read, DEBUG_BUFFER_SIZE - 1); } else { /* if only <Enter>is pressed then try last saved command line */ line_read = (xmlChar *) xmlMemStrdup(last_read); } return (line_read); #else char line_read[DEBUG_BUFFER_SIZE]; if (prompt != NULL) xsltGenericError(xsltGenericErrorContext, "%s", prompt); if (!fgets(line_read, DEBUG_BUFFER_SIZE - 1, stdin)) return (NULL); line_read[DEBUG_BUFFER_SIZE - 1] = 0; /* if only <Enter>is pressed then try last saved command line */ if ((strlen(line_read) == 0) || (line_read[0] == '\n')) { strcpy(line_read, last_read); } else { strcpy(last_read, line_read); } return (xmlChar *) xmlMemStrdup(line_read); #endif } else{ setInputStatus(XSLDBG_MSG_AWAITING_INPUT); notifyXsldbgApp(XSLDBG_MSG_AWAITING_INPUT, NULL); while (getInputReady() == 0){ usleep(10000); /* have we been told to die */ if (getThreadStatus() == XSLDBG_MSG_THREAD_STOP){ fprintf(stderr, "About to stop thread\n"); xslDebugStatus = DEBUG_QUIT; return NULL; } } setInputStatus(XSLDBG_MSG_READ_INPUT); inputReadBuff = getFakeInput(); if(inputReadBuff){ notifyXsldbgApp(XSLDBG_MSG_READ_INPUT, inputReadBuff); return (xmlChar*)xmlMemStrdup(inputReadBuff); }else{ return NULL; } } }
/** * 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; }
/** * 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; }
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; }