static void XSLPattern_OP_IGEq(xmlXPathParserContextPtr pctx, int nargs) { xmlChar *arg1, *arg2; XSLPATTERN_CHECK_ARGS(2); arg2 = xmlXPathPopString(pctx); arg1 = xmlXPathPopString(pctx); xmlXPathReturnBoolean(pctx, xmlStrcasecmp(arg1, arg2) >= 0); xmlFree(arg1); xmlFree(arg2); }
static void exsltRegexpTestFunction (xmlXPathParserContextPtr ctxt, int nargs) { xmlChar *haystack, *regexp_middle, *regexp, *flagstr; int rc = 0, flags, global, ovector[3]; if ((nargs < 1) || (nargs > 3)) { xmlXPathSetArityError(ctxt); return; } if(nargs > 2) { flagstr = xmlXPathPopString(ctxt); if (xmlXPathCheckError(ctxt) || (flagstr == NULL)) { return; } } else { flagstr = xmlStrdup(""); } regexp_middle = xmlXPathPopString(ctxt); if (xmlXPathCheckError(ctxt) || (regexp_middle == NULL)) { xmlFree(flagstr); return; } haystack = xmlXPathPopString(ctxt); if (xmlXPathCheckError(ctxt) || (haystack == NULL)) { xmlFree(regexp_middle); xmlFree(flagstr); return; } /* build the regexp */ regexp = xmlStrdup("\\A"); regexp = xmlStrcat(regexp, regexp_middle); regexp = xmlStrcat(regexp, "\\Z"); exsltRegexpFlagsFromString(flagstr, &global, &flags); rc = exsltRegexpExecute(ctxt, haystack, regexp, flags, ovector, sizeof(ovector)/sizeof(int)); fail: if (flagstr != NULL) xmlFree(flagstr); if (regexp != NULL) xmlFree(regexp); if (regexp_middle != NULL) xmlFree(regexp_middle); if (haystack != NULL) xmlFree(haystack); xmlXPathReturnBoolean(ctxt, (rc > 0)); }
static void XSLPattern_end(xmlXPathParserContextPtr pctx, int nargs) { double pos, last; XSLPATTERN_CHECK_ARGS(0); xmlXPathPositionFunction(pctx, 0); pos = xmlXPathPopNumber(pctx); xmlXPathLastFunction(pctx, 0); last = xmlXPathPopNumber(pctx); xmlXPathReturnBoolean(pctx, pos == last); }
/** This extension function is designed to be used in a sanity test with an * XPath expression like this: * "//entry[ fd:unbalanced-braces(.//orth | .//tr | .//note | .//def | .//q) ]" * Before its use, a namespace prefix like "fd" has to be bound to * FREEDICT_EDITOR_NAMESPACE. */ static void freedict_xpath_extension_unbalanced_braces( xmlXPathParserContextPtr ctxt, const int nargs) { if(nargs != 1) { xmlXPathSetArityError(ctxt); return; } xmlNodeSetPtr ns = xmlXPathPopNodeSet(ctxt); if(xmlXPathCheckError(ctxt) || !ns) { xmlXPathFreeNodeSet(ns); return; } // function that does the actual parsing // returns TRUE if a brace of the string in c does not have // a corresponding brace gboolean contains_unbalanced_braces(xmlChar *c) { if(!c) return FALSE; char stack[100]; int stackend = sizeof(stack); // returns FALSE on stack full gboolean cub_push(const char b) { if(!stackend) { g_printerr(G_STRLOC ": Too many open braces"); return FALSE; } stack[--stackend] = b; return TRUE; } gchar cub_pop() { // stack is empty if(stackend>=sizeof(stack)) return 'E'; return stack[stackend++]; } do { switch(*c) { case '(': if(!cub_push('(')) return TRUE; break; case '[': if(!cub_push('[')) return TRUE; break; case '{': if(!cub_push('{')) return TRUE; break; case ')': if(cub_pop()!='(') return TRUE;break; case ']': if(cub_pop()!='[') return TRUE;break; case '}': if(cub_pop()!='{') return TRUE;break; // all other characters are skipped } c++; } while(*c); // braces left open? if(cub_pop()!='E') return TRUE; // this string is well formed in regard of braces return FALSE; } int result = FALSE; int i; for(i=0; i < xmlXPathNodeSetGetLength(ns); i++) { xmlNodePtr n = xmlXPathNodeSetItem(ns, i); xmlChar* c = xmlNodeGetContent(n); if(!c) continue; result = contains_unbalanced_braces(c); xmlFree(c); if(result) break; } if(ns) xmlXPathFreeNodeSet(ns); xmlXPathReturnBoolean(ctxt, result); }