📄 regex_internal.c
字号:
#if DEBUG assert (pstr->valid_len > 0);#endif } else { /* No, skip all characters until IDX. */ pstr->valid_len = 0;#ifdef RE_ENABLE_I18N if (MB_CUR_MAX > 1) { int wcs_idx; wint_t wc; pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx; for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx) pstr->wcs[wcs_idx] = WEOF; if (pstr->trans && wc <= 0xff) wc = pstr->trans[wc]; pstr->tip_context = (IS_WIDE_WORD_CHAR (wc) ? CONTEXT_WORD : ((newline && IS_WIDE_NEWLINE (wc)) ? CONTEXT_NEWLINE : 0)); } else#endif /* RE_ENABLE_I18N */ { int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1]; if (pstr->trans) c = pstr->trans[c]; pstr->tip_context = (IS_WORD_CHAR (c) ? CONTEXT_WORD : ((newline && IS_NEWLINE (c)) ? CONTEXT_NEWLINE : 0)); } } if (!MBS_CASE_ALLOCATED (pstr)) { pstr->mbs_case += offset; /* In case of !MBS_ALLOCATED && !MBS_CASE_ALLOCATED. */ if (!MBS_ALLOCATED (pstr)) pstr->mbs += offset; } } pstr->raw_mbs_idx = idx; pstr->len -= offset; pstr->stop -= offset; /* Then build the buffers. */#ifdef RE_ENABLE_I18N if (MB_CUR_MAX > 1) { if (pstr->icase) build_wcs_upper_buffer (pstr); else build_wcs_buffer (pstr); } else#endif /* RE_ENABLE_I18N */ { if (pstr->icase) build_upper_buffer (pstr); else if (pstr->trans != NULL) re_string_translate_buffer (pstr); } pstr->cur_idx = 0; return REG_NOERROR;}static voidre_string_destruct (pstr) re_string_t *pstr;{#ifdef RE_ENABLE_I18N re_free (pstr->wcs);#endif /* RE_ENABLE_I18N */ if (MBS_ALLOCATED (pstr)) re_free (pstr->mbs); if (MBS_CASE_ALLOCATED (pstr)) re_free (pstr->mbs_case);}/* Return the context at IDX in INPUT. */static unsigned intre_string_context_at (input, idx, eflags, newline_anchor) const re_string_t *input; int idx, eflags, newline_anchor;{ int c; if (idx < 0 || idx == input->len) { if (idx < 0) /* In this case, we use the value stored in input->tip_context, since we can't know the character in input->mbs[-1] here. */ return input->tip_context; else /* (idx == input->len) */ return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF : CONTEXT_NEWLINE | CONTEXT_ENDBUF); }#ifdef RE_ENABLE_I18N if (MB_CUR_MAX > 1) { wint_t wc; int wc_idx = idx; while(input->wcs[wc_idx] == WEOF) {#ifdef DEBUG /* It must not happen. */ assert (wc_idx >= 0);#endif --wc_idx; if (wc_idx < 0) return input->tip_context; } wc = input->wcs[wc_idx]; if (IS_WIDE_WORD_CHAR (wc)) return CONTEXT_WORD; return (newline_anchor && IS_WIDE_NEWLINE (wc)) ? CONTEXT_NEWLINE : 0; } else#endif { c = re_string_byte_at (input, idx); if (IS_WORD_CHAR (c)) return CONTEXT_WORD; return (newline_anchor && IS_NEWLINE (c)) ? CONTEXT_NEWLINE : 0; }}/* Functions for set operation. */static reg_errcode_tre_node_set_alloc (set, size) re_node_set *set; int size;{ set->alloc = size; set->nelem = 0; set->elems = re_malloc (int, size); if (BE (set->elems == NULL, 0)) return REG_ESPACE; return REG_NOERROR;}static reg_errcode_tre_node_set_init_1 (set, elem) re_node_set *set; int elem;{ set->alloc = 1; set->nelem = 1; set->elems = re_malloc (int, 1); if (BE (set->elems == NULL, 0)) { set->alloc = set->nelem = 0; return REG_ESPACE; } set->elems[0] = elem; return REG_NOERROR;}static reg_errcode_tre_node_set_init_2 (set, elem1, elem2) re_node_set *set; int elem1, elem2;{ set->alloc = 2; set->elems = re_malloc (int, 2); if (BE (set->elems == NULL, 0)) return REG_ESPACE; if (elem1 == elem2) { set->nelem = 1; set->elems[0] = elem1; } else { set->nelem = 2; if (elem1 < elem2) { set->elems[0] = elem1; set->elems[1] = elem2; } else { set->elems[0] = elem2; set->elems[1] = elem1; } } return REG_NOERROR;}static reg_errcode_tre_node_set_init_copy (dest, src) re_node_set *dest; const re_node_set *src;{ dest->nelem = src->nelem; if (src->nelem > 0) { dest->alloc = dest->nelem; dest->elems = re_malloc (int, dest->alloc); if (BE (dest->elems == NULL, 0)) { dest->alloc = dest->nelem = 0; return REG_ESPACE; } memcpy (dest->elems, src->elems, src->nelem * sizeof (int)); } else re_node_set_init_empty (dest); return REG_NOERROR;}/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to DEST. Return value indicate the error code or REG_NOERROR if succeeded. Note: We assume dest->elems is NULL, when dest->alloc is 0. */static reg_errcode_tre_node_set_add_intersect (dest, src1, src2) re_node_set *dest; const re_node_set *src1, *src2;{ int i1, i2, id; if (src1->nelem > 0 && src2->nelem > 0) { if (src1->nelem + src2->nelem + dest->nelem > dest->alloc) { dest->alloc = src1->nelem + src2->nelem + dest->nelem; dest->elems = re_realloc (dest->elems, int, dest->alloc); if (BE (dest->elems == NULL, 0)) return REG_ESPACE; } } else return REG_NOERROR; for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;) { if (src1->elems[i1] > src2->elems[i2]) { ++i2; continue; } if (src1->elems[i1] == src2->elems[i2]) { while (id < dest->nelem && dest->elems[id] < src2->elems[i2]) ++id; if (id < dest->nelem && dest->elems[id] == src2->elems[i2]) ++id; else { memmove (dest->elems + id + 1, dest->elems + id, sizeof (int) * (dest->nelem - id)); dest->elems[id++] = src2->elems[i2++]; ++dest->nelem; } } ++i1; } return REG_NOERROR;}/* Calculate the union set of the sets SRC1 and SRC2. And store it to DEST. Return value indicate the error code or REG_NOERROR if succeeded. */static reg_errcode_tre_node_set_init_union (dest, src1, src2) re_node_set *dest; const re_node_set *src1, *src2;{ int i1, i2, id; if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0) { dest->alloc = src1->nelem + src2->nelem; dest->elems = re_malloc (int, dest->alloc); if (BE (dest->elems == NULL, 0)) return REG_ESPACE; } else { if (src1 != NULL && src1->nelem > 0) return re_node_set_init_copy (dest, src1); else if (src2 != NULL && src2->nelem > 0) return re_node_set_init_copy (dest, src2); else re_node_set_init_empty (dest); return REG_NOERROR; } for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;) { if (src1->elems[i1] > src2->elems[i2]) { dest->elems[id++] = src2->elems[i2++]; continue; } if (src1->elems[i1] == src2->elems[i2]) ++i2; dest->elems[id++] = src1->elems[i1++]; } if (i1 < src1->nelem) { memcpy (dest->elems + id, src1->elems + i1, (src1->nelem - i1) * sizeof (int)); id += src1->nelem - i1; } else if (i2 < src2->nelem) { memcpy (dest->elems + id, src2->elems + i2, (src2->nelem - i2) * sizeof (int)); id += src2->nelem - i2; } dest->nelem = id; return REG_NOERROR;}/* Calculate the union set of the sets DEST and SRC. And store it to DEST. Return value indicate the error code or REG_NOERROR if succeeded. */static reg_errcode_tre_node_set_merge (dest, src) re_node_set *dest; const re_node_set *src;{ int si, di; if (src == NULL || src->nelem == 0) return REG_NOERROR; if (dest->alloc < src->nelem + dest->nelem) { int *new_buffer; dest->alloc = 2 * (src->nelem + dest->alloc); new_buffer = re_realloc (dest->elems, int, dest->alloc); if (BE (new_buffer == NULL, 0)) return REG_ESPACE; dest->elems = new_buffer; } for (si = 0, di = 0 ; si < src->nelem && di < dest->nelem ;) { int cp_from, ncp, mid, right, src_elem = src->elems[si]; /* Binary search the spot we will add the new element. */ right = dest->nelem; while (di < right) { mid = (di + right) / 2; if (dest->elems[mid] < src_elem) di = mid + 1; else right = mid; } if (di >= dest->nelem) break; if (dest->elems[di] == src_elem) { /* Skip since, DEST already has the element. */ ++di; ++si; continue; } /* Skip the src elements which are less than dest->elems[di]. */ cp_from = si; while (si < src->nelem && src->elems[si] < dest->elems[di]) ++si; /* Copy these src elements. */ ncp = si - cp_from; memmove (dest->elems + di + ncp, dest->elems + di, sizeof (int) * (dest->nelem - di)); memcpy (dest->elems + di, src->elems + cp_from, sizeof (int) * ncp); /* Update counters. */ di += ncp; dest->nelem += ncp; } /* Copy remaining src elements. */ if (si < src->nelem) { memcpy (dest->elems + di, src->elems + si, sizeof (int) * (src->nelem - si)); dest->nelem += src->nelem - si; } return REG_NOERROR;}/* Insert the new element ELEM to the re_node_set* SET. return 0 if SET already has ELEM, return -1 if an error is occured, return 1 otherwise. */static intre_node_set_insert (set, elem) re_node_set *set; int elem;{ int idx, right, mid; /* In case of the set is empty. */ if (set->elems == NULL || set->alloc == 0) { if (BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1)) return 1; else return -1; } /* Binary search the spot we will add the new element. */ idx = 0; right = set->nelem; while (idx < right) { mid = (idx + right) / 2; if (set->elems[mid] < elem) idx = mid + 1; else right = mid; } /* Realloc if we need. */ if (set->alloc < set->nelem + 1) { int *new_array; set->alloc = set->alloc * 2; new_array = re_malloc (int, set->alloc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -