📄 xmlregexp.c
字号:
return(NULL);
}
stringRemap = xmlMalloc(ret->nbAtoms * sizeof(int));
if (stringRemap == NULL) {
xmlRegexpErrMemory(ctxt, "compiling regexp");
xmlFree(stringMap);
xmlFree(stateRemap);
xmlFree(ret);
return(NULL);
}
for (i = 0;i < ret->nbAtoms;i++) {
if ((ret->atoms[i]->type == XML_REGEXP_STRING) &&
(ret->atoms[i]->quant == XML_REGEXP_QUANT_ONCE)) {
value = ret->atoms[i]->valuep;
for (j = 0;j < nbatoms;j++) {
if (xmlStrEqual(stringMap[j], value)) {
stringRemap[i] = j;
break;
}
}
if (j >= nbatoms) {
stringRemap[i] = nbatoms;
stringMap[nbatoms] = xmlStrdup(value);
if (stringMap[nbatoms] == NULL) {
for (i = 0;i < nbatoms;i++)
xmlFree(stringMap[i]);
xmlFree(stringRemap);
xmlFree(stringMap);
xmlFree(stateRemap);
xmlFree(ret);
return(NULL);
}
nbatoms++;
}
} else {
xmlFree(stateRemap);
xmlFree(stringRemap);
for (i = 0;i < nbatoms;i++)
xmlFree(stringMap[i]);
xmlFree(stringMap);
xmlFree(ret);
return(NULL);
}
}
#ifdef DEBUG_COMPACTION
printf("Final: %d atoms\n", nbatoms);
#endif
transitions = (int *) xmlMalloc((nbstates + 1) *
(nbatoms + 1) * sizeof(int));
if (transitions == NULL) {
xmlFree(stateRemap);
xmlFree(stringRemap);
xmlFree(stringMap);
xmlFree(ret);
return(NULL);
}
memset(transitions, 0, (nbstates + 1) * (nbatoms + 1) * sizeof(int));
/*
* Allocate the transition table. The first entry for each
* state corresponds to the state type.
*/
transdata = NULL;
for (i = 0;i < ret->nbStates;i++) {
int stateno, atomno, targetno, prev;
xmlRegStatePtr state;
xmlRegTransPtr trans;
stateno = stateRemap[i];
if (stateno == -1)
continue;
state = ret->states[i];
transitions[stateno * (nbatoms + 1)] = state->type;
for (j = 0;j < state->nbTrans;j++) {
trans = &(state->trans[j]);
if ((trans->to == -1) || (trans->atom == NULL))
continue;
atomno = stringRemap[trans->atom->no];
if ((trans->atom->data != NULL) && (transdata == NULL)) {
transdata = (void **) xmlMalloc(nbstates * nbatoms *
sizeof(void *));
if (transdata != NULL)
memset(transdata, 0,
nbstates * nbatoms * sizeof(void *));
else {
xmlRegexpErrMemory(ctxt, "compiling regexp");
break;
}
}
targetno = stateRemap[trans->to];
/*
* if the same atom can generate transitions to 2 different
* states then it means the automata is not determinist and
* the compact form can't be used !
*/
prev = transitions[stateno * (nbatoms + 1) + atomno + 1];
if (prev != 0) {
if (prev != targetno + 1) {
ret->determinist = 0;
#ifdef DEBUG_COMPACTION
printf("Indet: state %d trans %d, atom %d to %d : %d to %d\n",
i, j, trans->atom->no, trans->to, atomno, targetno);
printf(" previous to is %d\n", prev);
#endif
ret->determinist = 0;
if (transdata != NULL)
xmlFree(transdata);
xmlFree(transitions);
xmlFree(stateRemap);
xmlFree(stringRemap);
for (i = 0;i < nbatoms;i++)
xmlFree(stringMap[i]);
xmlFree(stringMap);
goto not_determ;
}
} else {
#if 0
printf("State %d trans %d: atom %d to %d : %d to %d\n",
i, j, trans->atom->no, trans->to, atomno, targetno);
#endif
transitions[stateno * (nbatoms + 1) + atomno + 1] =
targetno + 1; /* to avoid 0 */
if (transdata != NULL)
transdata[stateno * nbatoms + atomno] =
trans->atom->data;
}
}
}
ret->determinist = 1;
#ifdef DEBUG_COMPACTION
/*
* Debug
*/
for (i = 0;i < nbstates;i++) {
for (j = 0;j < nbatoms + 1;j++) {
printf("%02d ", transitions[i * (nbatoms + 1) + j]);
}
printf("\n");
}
printf("\n");
#endif
/*
* Cleanup of the old data
*/
if (ret->states != NULL) {
for (i = 0;i < ret->nbStates;i++)
xmlRegFreeState(ret->states[i]);
xmlFree(ret->states);
}
ret->states = NULL;
ret->nbStates = 0;
if (ret->atoms != NULL) {
for (i = 0;i < ret->nbAtoms;i++)
xmlRegFreeAtom(ret->atoms[i]);
xmlFree(ret->atoms);
}
ret->atoms = NULL;
ret->nbAtoms = 0;
ret->compact = transitions;
ret->transdata = transdata;
ret->stringMap = stringMap;
ret->nbstrings = nbatoms;
ret->nbstates = nbstates;
xmlFree(stateRemap);
xmlFree(stringRemap);
}
not_determ:
ctxt->string = NULL;
ctxt->nbStates = 0;
ctxt->states = NULL;
ctxt->nbAtoms = 0;
ctxt->atoms = NULL;
ctxt->nbCounters = 0;
ctxt->counters = NULL;
return(ret);
}
/**
* xmlRegNewParserCtxt:
* @string: the string to parse
*
* Allocate a new regexp parser context
*
* Returns the new context or NULL in case of error
*/
static xmlRegParserCtxtPtr
xmlRegNewParserCtxt(const xmlChar *string) {
xmlRegParserCtxtPtr ret;
ret = (xmlRegParserCtxtPtr) xmlMalloc(sizeof(xmlRegParserCtxt));
if (ret == NULL)
return(NULL);
memset(ret, 0, sizeof(xmlRegParserCtxt));
if (string != NULL)
ret->string = xmlStrdup(string);
ret->cur = ret->string;
ret->neg = 0;
ret->error = 0;
ret->determinist = -1;
return(ret);
}
/**
* xmlRegNewRange:
* @ctxt: the regexp parser context
* @neg: is that negative
* @type: the type of range
* @start: the start codepoint
* @end: the end codepoint
*
* Allocate a new regexp range
*
* Returns the new range or NULL in case of error
*/
static xmlRegRangePtr
xmlRegNewRange(xmlRegParserCtxtPtr ctxt,
int neg, xmlRegAtomType type, int start, int end) {
xmlRegRangePtr ret;
ret = (xmlRegRangePtr) xmlMalloc(sizeof(xmlRegRange));
if (ret == NULL) {
xmlRegexpErrMemory(ctxt, "allocating range");
return(NULL);
}
ret->neg = neg;
ret->type = type;
ret->start = start;
ret->end = end;
return(ret);
}
/**
* xmlRegFreeRange:
* @range: the regexp range
*
* Free a regexp range
*/
static void
xmlRegFreeRange(xmlRegRangePtr range) {
if (range == NULL)
return;
if (range->blockName != NULL)
xmlFree(range->blockName);
xmlFree(range);
}
/**
* xmlRegNewAtom:
* @ctxt: the regexp parser context
* @type: the type of atom
*
* Allocate a new regexp range
*
* Returns the new atom or NULL in case of error
*/
static xmlRegAtomPtr
xmlRegNewAtom(xmlRegParserCtxtPtr ctxt, xmlRegAtomType type) {
xmlRegAtomPtr ret;
ret = (xmlRegAtomPtr) xmlMalloc(sizeof(xmlRegAtom));
if (ret == NULL) {
xmlRegexpErrMemory(ctxt, "allocating atom");
return(NULL);
}
memset(ret, 0, sizeof(xmlRegAtom));
ret->type = type;
ret->quant = XML_REGEXP_QUANT_ONCE;
ret->min = 0;
ret->max = 0;
return(ret);
}
/**
* xmlRegFreeAtom:
* @atom: the regexp atom
*
* Free a regexp atom
*/
static void
xmlRegFreeAtom(xmlRegAtomPtr atom) {
int i;
if (atom == NULL)
return;
for (i = 0;i < atom->nbRanges;i++)
xmlRegFreeRange(atom->ranges[i]);
if (atom->ranges != NULL)
xmlFree(atom->ranges);
if ((atom->type == XML_REGEXP_STRING) && (atom->valuep != NULL))
xmlFree(atom->valuep);
if ((atom->type == XML_REGEXP_BLOCK_NAME) && (atom->valuep != NULL))
xmlFree(atom->valuep);
xmlFree(atom);
}
static xmlRegStatePtr
xmlRegNewState(xmlRegParserCtxtPtr ctxt) {
xmlRegStatePtr ret;
ret = (xmlRegStatePtr) xmlMalloc(sizeof(xmlRegState));
if (ret == NULL) {
xmlRegexpErrMemory(ctxt, "allocating state");
return(NULL);
}
memset(ret, 0, sizeof(xmlRegState));
ret->type = XML_REGEXP_TRANS_STATE;
ret->mark = XML_REGEXP_MARK_NORMAL;
return(ret);
}
/**
* xmlRegFreeState:
* @state: the regexp state
*
* Free a regexp state
*/
static void
xmlRegFreeState(xmlRegStatePtr state) {
if (state == NULL)
return;
if (state->trans != NULL)
xmlFree(state->trans);
xmlFree(state);
}
/**
* xmlRegFreeParserCtxt:
* @ctxt: the regexp parser context
*
* Free a regexp parser context
*/
static void
xmlRegFreeParserCtxt(xmlRegParserCtxtPtr ctxt) {
int i;
if (ctxt == NULL)
return;
if (ctxt->string != NULL)
xmlFree(ctxt->string);
if (ctxt->states != NULL) {
for (i = 0;i < ctxt->nbStates;i++)
xmlRegFreeState(ctxt->states[i]);
xmlFree(ctxt->states);
}
if (ctxt->atoms != NULL) {
for (i = 0;i < ctxt->nbAtoms;i++)
xmlRegFreeAtom(ctxt->atoms[i]);
xmlFree(ctxt->atoms);
}
if (ctxt->counters != NULL)
xmlFree(ctxt->counters);
xmlFree(ctxt);
}
/************************************************************************
* *
* Display of Data structures *
* *
************************************************************************/
static void
xmlRegPrintAtomType(FILE *output, xmlRegAtomType type) {
switch (type) {
case XML_REGEXP_EPSILON:
fprintf(output, "epsilon "); break;
case XML_REGEXP_CHARVAL:
fprintf(output, "charval "); break;
case XML_REGEXP_RANGES:
fprintf(output, "ranges "); break;
case XML_REGEXP_SUBREG:
fprintf(output, "subexpr "); break;
case XML_REGEXP_STRING:
fprintf(output, "string "); break;
case XML_REGEXP_ANYCHAR:
fprintf(output, "anychar "); break;
case XML_REGEXP_ANYSPACE:
fprintf(output, "anyspace "); break;
case XML_REGEXP_NOTSPACE:
fprintf(output, "notspace "); break;
case XML_REGEXP_INITNAME:
fprintf(output, "initname "); break;
case XML_REGEXP_NOTINITNAME:
fprintf(output, "notinitname "); break;
case XML_REGEXP_NAMECHAR:
fprintf(output, "namechar "); break;
case XML_REGEXP_NOTNAMECHAR:
fprintf(output, "notnamechar "); break;
case XML_REGEXP_DECIMAL:
fprintf(output, "decimal "); break;
case XML_REGEXP_NOTDECIMAL:
fprintf(output, "notdecimal "); break;
case XML_REGEXP_REALCHAR:
fprintf(output, "realchar "); break;
case XML_REGEXP_NOTREALCHAR:
fprintf(output, "notrealchar "); break;
case XML_REGEXP_LETTER:
fprintf(output, "LETTER "); break;
case XML_REGEXP_LETTER_UPPERCASE:
fprintf(output, "LETTER_UPPERCASE "); break;
case XML_REGEXP_LETTER_LOWERCASE:
fprintf(output, "LETTER_LOWERCASE "); break;
case XML_REGEXP_LETTER_TITLECASE:
fprintf(output, "LETTER_TITLECASE "); break;
case XML_REGEXP_LETTER_MODIFIER:
fprintf(output, "LETTER_MODIFIER "); break;
case XML_REGEXP_LETTER_OTHERS:
fprintf(output, "LETTER_OTHERS "); break;
case XML_REGEXP_MARK:
fprintf(output, "MARK "); break;
case XML_REGEXP_MARK_NONSPACING:
fprintf(output, "MARK_NONSPACING "); break;
case XML_REGEXP_MARK_SPACECOMBINING:
fprintf(output, "MARK_SPACECOMBINING "); break;
case XML_REGEXP_MARK_ENCLOSING:
fprintf(output, "MARK_ENCLOSING "); break;
case XML_REGEXP_NUMBER:
fprintf(output, "NUMBER "); break;
case XML_REGEXP_NUMBER_DECIMAL:
fprintf(output, "NUMBER_DECIMAL "); break;
case XML_REGEXP_NUMBER_LETTER:
fprintf(output, "NUMBER_LETTER "); break;
case XML_REGEXP_NUMBER_OTHERS:
fprintf(output, "NUMBER_OTHERS "); break;
case XML_REGEXP_PUNCT:
fprintf(output, "PUNCT "); break;
case XML_REGEXP_PUNCT_CONNECTOR:
fprintf(output, "PUNCT_CONNECTOR "); break;
case XML_REGEXP_PUNCT_DASH:
fprintf(output, "PUNCT_DASH "); break;
case XML_REGEXP_PUNCT_OPEN:
fprintf(output, "PUNCT_OPEN "); break;
case XML_REGEXP_PUNCT_CLOSE:
fprintf(output, "PUNCT_CLOSE "); break;
case XML_REGEXP_PUNCT_INITQUOTE:
fprintf(output, "PUNCT_INITQUOTE "); break;
case XML_REGEXP_PUNCT_FINQUOTE:
fprintf(output, "PUNCT_FINQUOTE "); break;
case XML_REGEXP_PUNCT_OTHERS:
fprintf(output, "PUNCT_OTHERS "); break;
case XML_REGEXP_SEPAR:
fprintf(output, "SEPAR "); break;
case XML_REGEXP_SEPAR_SPACE:
fprintf(output, "SEPAR_SPACE "); break;
case XML_REGEXP_SEPAR_LINE:
fprintf(output, "SEPAR_LINE "); break;
case XML_REGEXP_SEPAR_PARA:
fprintf(output, "SEPAR_PARA "); break;
case XML_REGEXP_SYMBOL:
fprintf(output, "SYMBOL "); break;
case XML_REGEXP_SYMBOL_MATH:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -