/*! @decl array(string) split(string s) *! Works as @[match], but returns an array of the strings that *! matched the subregexps. Subregexps are those contained in "( )" in *! the regexp. Subregexps that were not matched will contain zero. *! If the total regexp didn't match, zero is returned. *! *! @bugs *! You can currently only have 39 subregexps. *! *! @bugs *! The current implementation doesn't support searching *! in strings containing the NUL character or any *! wide character. *! *! @seealso *! @[match] */ static void regexp_split(INT32 args) { struct pike_string *s; struct regexp *r; get_all_args("Regexp.SimpleRegexp->split", args, "%S", &s); if(pike_regexec(r=THIS->regexp, s->str)) { int i,j; add_ref(s); pop_n_elems(args); for(j=i=1;i<NSUBEXP;i++) { if(!r->startp[i] || !r->endp[i]) { push_int(0); }else{ push_string(make_shared_binary_string(r->startp[i], r->endp[i]-r->startp[i])); j=i; } } if(j<i-1) pop_n_elems(i-j-1); push_array(aggregate_array(j)); free_string(s); }else{ pop_n_elems(args); push_int(0); } }
static void pextsAttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname, int type, int def, const xmlChar *defaultValue, xmlEnumerationPtr tree) { int nenum; DBG_FUNC_ENTER(); if (CB_ABSENT(attributeDeclSAX)) { DBG_FUNC_LEAVE(); return; } THIS->ctxt = (xmlParserCtxtPtr)ctx; push_object(this_object()); safe_push_text(elem); safe_push_text(fullname); push_int(type); push_int(def); safe_push_text(defaultValue); push_svalue(&THIS->user_data); if (tree) { xmlEnumerationPtr tmp = tree; struct array *arr; nenum = 0; while (tree) { safe_push_text(tmp->name); tmp = tmp->next; nenum++; } arr = aggregate_array(nenum); push_array(arr); } else push_int(0); CB_CALL(attributeDeclSAX, 8); pop_stack(); DBG_FUNC_LEAVE(); }
/* Split the string according to the regexp */ void f_pcre_split(INT32 args) { struct array *arr; /* Result array */ struct pike_string *data; /* Data to split */ pcre_extra *extra = NULL; /* result from study, if enabled */ pcre *re = NULL; /* compiled regexp */ char *pp; /* Pointer... */ int opts = 0; /* Match options */ int *ovector, ovecsize; /* Subpattern storage */ int ret; /* Result codes */ int i, e; /* Counter variable */ if(THIS->regexp == NULL) Pike_error("PCRE.Regexp not initialized.\n"); get_all_args("PCRE.Regexp->split", args, "%S", &data); switch(args) { case 2: switch(Pike_sp[-1].type) { case T_STRING: opts = parse_options(Pike_sp[-1].u.string->str, NULL); if(opts < 0) Pike_error("PCRE.Regexp->split(): Unknown option modifier '%c'.\n", -opts); break; case T_INT: if(Pike_sp[-1].u.integer == 0) { break; } /* Fallthrough */ default: Pike_error("Bad argument 2 to PCRE.Regexp->split() - expected string.\n"); break; } /* Fallthrough */ case 1: if(Pike_sp[-args].type != T_STRING || Pike_sp[-args].u.string->size_shift > 0) { Pike_error("PCRE.Regexp->match(): Invalid argument 1. Expected 8-bit string.\n"); } data = Pike_sp[-args].u.string; break; default: Pike_error("PCRE.Regexp->match(): Invalid number of arguments. Expected 1 or 2.\n"); } re = THIS->regexp; extra = THIS->extra; /* Calculate the size of the offsets array, and allocate memory for it. */ pcre_fullinfo(re, extra, PCRE_INFO_CAPTURECOUNT, &ovecsize); ovecsize = (ovecsize + 1) * 3; ovector = (int *)malloc(ovecsize * sizeof(int)); if(ovector == NULL) Pike_error("PCRE.Regexp->split(): Out of memory.\n"); /* Do the pattern matching */ ret = pcre_exec(re, extra, data->str, data->len, 0, opts, ovector, ovecsize); switch(ret) { case PCRE_ERROR_NOMATCH: pop_n_elems(args); push_int(0); break; case PCRE_ERROR_NULL: Pike_error("Invalid argumens passed to pcre_exec.\n"); case PCRE_ERROR_BADOPTION: Pike_error("Invalid options sent to pcre_exec.\n"); case PCRE_ERROR_BADMAGIC: Pike_error("Invalid magic number.\n"); case PCRE_ERROR_UNKNOWN_NODE: Pike_error("Unknown node encountered. PCRE bug or memory error.\n"); case PCRE_ERROR_NOMEMORY: Pike_error("Out of memory during execution.\n"); default: pop_n_elems(args); switch(ret) { case 1: /* No submatches, be Pike Regexp compatible */ push_int(0); arr = aggregate_array(1); break; default: e = ret * 2; for (i = 2; i < e ; i += 2) { push_string(make_shared_binary_string(data->str + ovector[i], (int)(ovector[i+1] - ovector[i]))); } arr = aggregate_array(ret-1); } push_array(arr); break; } free(ovector); }