Exemplo n.º 1
0
/**
 * 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;
        }
    }
}
Exemplo n.º 2
0
/**
 * xslShellReadline:
 * @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 *
xslDbgShellReadlineSimple(xmlChar * prompt)
{

  static char last_read[DEBUG_BUFFER_SIZE] = { '\0' };

#ifdef HAVE_READLINE

      xmlChar *line_read;

      if (optionsGetIntOption(OPTIONS_STDOUT) == 0){
	/* 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) {
	  char *temp = (char*)line_read;
	  add_history((char *) line_read);
	  strncpy((char*)last_read, (char*)line_read, DEBUG_BUFFER_SIZE - 1);
	  /* we must ensure that the data is free properly */
	  line_read = xmlStrdup((xmlChar*)line_read);
	  free(temp);
	} else {
	  free(line_read);
	  /* if only <Enter>is pressed then try last saved command line */
	  line_read = xmlStrdup((xmlChar*)last_read);
	}
      }else{
	/* readline library will/may  echo its output which is not wanted
	   when running in gdb mode.*/
	char line_buffer[DEBUG_BUFFER_SIZE];

	if (prompt != NULL)
	  xsltGenericError(xsltGenericErrorContext, "%s", prompt);
	if (!fgets(line_buffer, sizeof(line_buffer) - 1, stdin)){
	  line_read = NULL;
	}else{
	  line_buffer[DEBUG_BUFFER_SIZE - 1] = 0;
	  if ((strlen(line_buffer) == 0) || (line_buffer[0] == '\n')){
	    line_read = xmlStrdup((xmlChar*)last_read);
	  }else{
	    add_history((char *) line_buffer);
	    line_read = xmlStrdup((xmlChar*)line_buffer);
	    strncpy((char*)last_read, (char*)line_read, sizeof(last_read) - 1);	  	  }
	}

      }
      return (line_read);

#else
      char line_read[DEBUG_BUFFER_SIZE];

      if (prompt != NULL)
        xsltGenericError(xsltGenericErrorContext, "%s", prompt);
	  fflush(stderr);
      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')) {
	  strncpy(line_read, last_read, sizeof(line_read) - 1);
      } else {
	  strcpy(last_read, line_read);
      }
      return xmlStrdup((xmlChar*)line_read);
#endif

    }
Exemplo n.º 3
0
/**
 * 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;
}
Exemplo n.º 4
0
/**
 * 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;
}
Exemplo n.º 5
0
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;
}