Lines Matching refs:cd
49 #define NLBLOCK cd /* Block containing newline information */
921 expand_workspace(compile_data *cd)
924 int newsize = cd->workspace_size * 2;
927 if (cd->workspace_size >= COMPILE_WORK_SIZE_MAX ||
928 newsize - cd->workspace_size < WORK_SIZE_SAFETY_MARGIN)
933 memcpy(newspace, cd->start_workspace, cd->workspace_size * sizeof(pcre_uchar));
934 cd->hwm = (pcre_uchar *)newspace + (cd->hwm - cd->start_workspace);
935 if (cd->workspace_size > COMPILE_WORK_SIZE)
936 (PUBL(free))((void *)cd->start_workspace);
937 cd->start_workspace = newspace;
938 cd->workspace_size = newsize;
1725 cd the "compile data" structure
1736 find_fixedlength(pcre_uchar *code, BOOL utf, BOOL atend, compile_data *cd,
1765 d = find_fixedlength(cc + ((op == OP_CBRA)? IMM2_SIZE : 0), utf, atend, cd,
1797 cs = ce = (pcre_uchar *)cd->start_code + GET(cc, 1); /* Start subpattern */
1808 d = find_fixedlength(cs + IMM2_SIZE, utf, atend, cd, &this_recurse);
2389 cd contains pointers to tables etc.
2397 BOOL utf, compile_data *cd, recurse_check *recurses)
2429 const pcre_uchar *scode = cd->start_code + GET(code, 1);
2434 when called to scan a completed pattern by setting cd->start_workspace to
2437 if (cd->start_workspace != NULL)
2440 for (tcode = cd->start_workspace; tcode < cd->hwm; tcode += LINK_SIZE)
2441 if ((int)GET(tcode, 0) == (int)(code + 1 - cd->start_code)) return TRUE;
2469 if (could_be_empty_branch(scode, endcode, utf, cd, &this_recurse))
2525 if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd,
2765 cd pointers to tables etc
2772 branch_chain *bcptr, BOOL utf, compile_data *cd)
2776 if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd, NULL))
3113 cd static compile data
3120 compare_opcodes(const pcre_uchar *code, BOOL utf, const compile_data *cd,
3211 if (!compare_opcodes(code, utf, cd, base_list, base_end, rec_limit))
3232 if (!compare_opcodes(next_code, utf, cd, base_list, base_end, rec_limit))
3244 code = get_chr_property_list(code, utf, cd->fcc, list);
3313 set2 = (pcre_uint8 *)(cd->cbits + cbit_digit);
3320 set2 = (pcre_uint8 *)(cd->cbits + cbit_space);
3327 set2 = (pcre_uint8 *)(cd->cbits + cbit_word);
3520 if (chr < 256 && (cd->ctypes[chr] & ctype_digit) != 0) return FALSE;
3524 if (chr > 255 || (cd->ctypes[chr] & ctype_digit) == 0) return FALSE;
3528 if (chr < 256 && (cd->ctypes[chr] & ctype_space) != 0) return FALSE;
3532 if (chr > 255 || (cd->ctypes[chr] & ctype_space) == 0) return FALSE;
3536 if (chr < 255 && (cd->ctypes[chr] & ctype_word) != 0) return FALSE;
3540 if (chr > 255 || (cd->ctypes[chr] & ctype_word) == 0) return FALSE;
3653 cd static compile data
3659 auto_possessify(pcre_uchar *code, BOOL utf, const compile_data *cd)
3683 get_chr_property_list(code, utf, cd->fcc, list) : NULL;
3687 if (end != NULL && compare_opcodes(end, utf, cd, list, end, &rec_limit))
3739 end = get_chr_property_list(code, utf, cd->fcc, list);
3744 if (compare_opcodes(end, utf, cd, list, end, &rec_limit))
4013 cd contains pointers to tables etc.
4020 adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
4029 for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm;
4033 if (cd->start_code + offset == ptr + 1) break;
4039 if (hc >= cd->hwm)
4042 if (cd->start_code + offset >= group) PUT(ptr, 1, offset + adjust);
4050 for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm;
4070 cd pointers to tables etc
4076 auto_callout(pcre_uchar *code, const pcre_uchar *ptr, compile_data *cd)
4080 PUT(code, 0, (int)(ptr - cd->start_pattern)); /* Pattern offset */
4098 cd pointers to tables etc
4104 complete_callout(pcre_uchar *previous_callout, const pcre_uchar *ptr, compile_data *cd)
4106 int length = (int)(ptr - cd->start_pattern - GET(previous_callout, 2));
4192 cd contains pointers to tables etc.
4202 compile_data *cd, pcre_uint32 start, pcre_uint32 end)
4228 if (rc > 0) n8 += add_list_to_class(classbits, uchardptr, options, cd,
4245 else n8 += add_to_class(classbits, uchardptr, options, cd, oc, od);
4255 SETBIT(classbits, cd->fcc[c]);
4354 cd contains pointers to tables etc.
4366 compile_data *cd, const pcre_uint32 *p, unsigned int except)
4375 n8 += add_to_class(classbits, uchardptr, options, cd, p[0], p[n]);
4395 cd contains pointers to tables etc.
4404 int options, compile_data *cd, const pcre_uint32 *p)
4409 n8 += add_to_class(classbits, uchardptr, options, cd, 0, p[0] - 1);
4413 n8 += add_to_class(classbits, uchardptr, options, cd, p[0] + 1,
4443 cd contains pointers to tables etc.
4457 compile_data *cd, int *lengthptr)
4589 if (code > cd->hwm) cd->hwm = code; /* High water info */
4591 if (code > cd->start_workspace + cd->workspace_size -
4642 else if (cd->hwm > cd->start_workspace + cd->workspace_size)
4663 complete_callout(previous_callout, ptr, cd);
4669 code = auto_callout(code, ptr, cd);
4683 while (MAX_255(c) && (cd->ctypes[c] & ctype_space) != 0) c = *(++ptr);
4689 { /* IS_NEWLINE sets cd->nllen. */
4690 ptr += cd->nllen;
4715 complete_callout(previous_callout, ptr, cd);
4725 code = auto_callout(code, ptr, cd);
4785 item_hwm_offset = cd->hwm - cd->start_workspace;
4806 if ((cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
4837 item_hwm_offset = cd->hwm - cd->start_workspace;
4878 (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
4977 register const pcre_uint8 *cbits = cd->cbits;
5133 escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options,
5156 cd->cbits;
5213 (void)add_list_to_class(classbits, &class_uchardata, options, cd,
5219 cd, PRIV(hspace_list));
5223 (void)add_list_to_class(classbits, &class_uchardata, options, cd,
5229 cd, PRIV(vspace_list));
5291 if (c == CHAR_CR || c == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF;
5344 descape = check_escape(&ptr, &d, errorcodeptr, cd->bracount, options, TRUE);
5390 if (d == CHAR_CR || d == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF;
5393 add_to_class(classbits, &class_uchardata, options, cd, c, d);
5485 add_to_class(classbits, &class_uchardata, options, cd, c, c);
5656 while (MAX_255(*p) && (cd->ctypes[*p] & ctype_space) != 0) p++;
5662 { /* IS_NEWLINE sets cd->nllen. */
5663 p += cd->nllen;
5713 if (lengthptr == NULL && cd->hwm >= cd->start_workspace + LINK_SIZE)
5715 int offset = GET(cd->hwm, -LINK_SIZE);
5716 if (offset == previous + 1 - cd->start_code)
5717 PUT(cd->hwm, -LINK_SIZE, offset + 1 + LINK_SIZE);
5765 reqcharflags = req_caseopt | cd->req_varyopt;
6030 adjust_recurse(previous, 1, utf, cd, item_hwm_offset);
6054 adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, item_hwm_offset);
6117 size_t this_hwm_offset = cd->hwm - cd->start_workspace;
6120 while (cd->hwm > cd->start_workspace + cd->workspace_size -
6124 *errorcodeptr = expand_workspace(cd);
6128 for (hc = (pcre_uchar *)cd->start_workspace + base_hwm_offset;
6129 hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
6132 PUT(cd->hwm, 0, GET(hc, 0) + len);
6133 cd->hwm += LINK_SIZE;
6180 size_t this_hwm_offset = cd->hwm - cd->start_workspace;
6201 while (cd->hwm > cd->start_workspace + cd->workspace_size -
6205 *errorcodeptr = expand_workspace(cd);
6209 for (hc = (pcre_uchar *)cd->start_workspace + base_hwm_offset;
6210 hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
6213 PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
6214 cd->hwm += LINK_SIZE;
6289 if (could_be_empty_branch(scode, ketcode, utf, cd, NULL))
6318 adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, item_hwm_offset);
6452 adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, item_hwm_offset);
6501 adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, item_hwm_offset);
6520 cd->req_varyopt |= reqvary;
6550 || (MAX_255(ptr[1]) && ((cd->ctypes[ptr[1]] & ctype_letter) != 0))))
6559 while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_letter) != 0) ptr++;
6604 cd->had_accept = TRUE;
6605 for (oc = cd->open_caps; oc != NULL; oc = oc->next)
6611 (cd->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT;
6655 cd->external_flags |= PCRE_HASTHEN;
6662 cd->had_pruneorskip = TRUE;
6682 item_hwm_offset = cd->hwm - cd->start_workspace;
6700 cd->dupgroups = TRUE; /* Record (?| encountered */
6750 cd->iscondassert = TRUE;
6824 if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_word) == 0)
6830 while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0)
6864 cd->bracount - recno + 1 : recno + cd->bracount;
6865 if (recno <= 0 || recno > cd->final_bracount)
6871 if (recno > cd->top_backref) cd->top_backref = recno;
6877 slot = cd->name_table;
6878 for (i = 0; i < cd->names_found; i++)
6881 slot += cd->name_entry_size;
6889 if (i < cd->names_found)
6894 if (recno > cd->top_backref) cd->top_backref = recno;
6895 for (; i < cd->names_found; i++)
6897 slot += cd->name_entry_size;
6975 cd->assert_depth += 1;
6997 cd->assert_depth += 1;
7007 cd->assert_depth += 1;
7013 cd->assert_depth += 1;
7018 if (MAX_255(ptr[1]) && (cd->ctypes[ptr[1]] & ctype_word) != 0)
7055 PUT(code, 0, (int)(ptr - cd->start_pattern + 1)); /* Pattern offset */
7091 while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
7103 pcre_uint32 number = cd->bracount + 1;
7111 if (cd->names_found >= MAX_NAME_COUNT)
7117 if (namelen + IMM2_SIZE + 1 > cd->name_entry_size)
7119 cd->name_entry_size = namelen + IMM2_SIZE + 1;
7134 ng = cd->named_groups;
7135 for (i = 0; i < cd->names_found; i++, ng++)
7146 cd->dupnames = TRUE; /* Duplicate names exist */
7155 if (i >= cd->names_found) /* Not a duplicate with same number */
7159 if (cd->names_found >= cd->named_group_list_size)
7161 int newsize = cd->named_group_list_size * 2;
7171 memcpy(newspace, cd->named_groups,
7172 cd->named_group_list_size * sizeof(named_group));
7173 if (cd->named_group_list_size > NAMED_GROUP_LIST_SIZE)
7174 (PUBL(free))((void *)cd->named_groups);
7175 cd->named_groups = newspace;
7176 cd->named_group_list_size = newsize;
7179 cd->named_groups[cd->names_found].name = name;
7180 cd->named_groups[cd->names_found].length = namelen;
7181 cd->named_groups[cd->names_found].number = number;
7182 cd->names_found++;
7209 while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
7242 if (!is_recurse) cd->namedrefcount++;
7270 if (cd->dupgroups) *lengthptr += 4 + 4*LINK_SIZE;
7279 ng = cd->named_groups;
7280 for (i = 0; i < cd->names_found; i++, ng++)
7288 for (oc = cd->open_caps; oc != NULL; oc = oc->next)
7308 slot = cd->name_table;
7309 for (i = 0; i < cd->names_found; i++)
7314 slot += cd->name_entry_size;
7317 if (i < cd->names_found)
7336 if (lengthptr == NULL && cd->dupnames)
7340 pcre_uchar *cslot = slot + cd->name_entry_size;
7342 for (i++; i < cd->names_found; i++)
7346 cslot += cd->name_entry_size;
7353 item_hwm_offset = cd->hwm - cd->start_workspace;
7360 for (; slot < cslot; slot += cd->name_entry_size)
7364 cd->backref_map |= (recno < 32)? (1 << recno) : 1;
7365 if (recno > cd->top_backref) cd->top_backref = recno;
7371 for (oc = cd->open_caps; oc != NULL; oc = oc->next)
7458 recno = cd->bracount - recno + 1;
7472 recno += cd->bracount;
7480 item_hwm_offset = cd->hwm - cd->start_workspace;
7481 called = cd->start_code;
7494 called = PRIV(find_bracket)(cd->start_code, utf, recno);
7500 if (recno > cd->final_bracount)
7510 called = cd->start_code + recno;
7511 if (cd->hwm >= cd->start_workspace + cd->workspace_size -
7514 *errorcodeptr = expand_workspace(cd);
7517 PUTINC(cd->hwm, 0, (int)(code + 1 - cd->start_code));
7530 could_be_empty(called, code, bcptr, utf, cd))
7542 PUT(code, 1, (int)(called - cd->start_code));
7567 cd->external_flags |= PCRE_JCHANGED;
7594 If the code pointer is not (cd->start_code + 1 + LINK_SIZE), we are
7610 if (code == cd->start_code + 1 + LINK_SIZE &&
7613 cd->external_options = newoptions;
7654 cd->bracount += 1;
7655 PUT2(code, 1+LINK_SIZE, cd->bracount);
7662 if ((cd->parens_depth += 1) > PARENS_NEST_LIMIT)
7673 group whose condition is an assertion, cd->iscondassert is set. We unset it
7677 cd->iscondassert)
7680 cd->iscondassert = FALSE;
7685 item_hwm_offset = cd->hwm - cd->start_workspace;
7690 tempreqvary = cd->req_varyopt; /* Save value before bracket */
7691 tempbracount = cd->bracount; /* Save value before bracket */
7710 cd, /* Tables block */
7716 cd->parens_depth -= 1;
7721 if (bravalue == OP_ONCE && cd->bracount <= tempbracount)
7725 cd->assert_depth -= 1;
7892 escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options, FALSE);
7934 item_hwm_offset = cd->hwm - cd->start_workspace; /* Normally this is set when '(' is read */
8002 item_hwm_offset = cd->hwm - cd->start_workspace;
8005 cd->backref_map |= (recno < 32)? (1 << recno) : 1;
8006 if (recno > cd->top_backref) cd->top_backref = recno;
8012 for (oc = cd->open_caps; oc != NULL; oc = oc->next)
8032 item_hwm_offset = cd->hwm - cd->start_workspace;
8058 cd->max_lookbehind == 0)
8059 cd->max_lookbehind = 1;
8073 item_hwm_offset = cd->hwm - cd->start_workspace;
8117 item_hwm_offset = cd->hwm - cd->start_workspace;
8147 cd->external_flags |= PCRE_HASCRORLF;
8172 reqcharflags = cd->req_varyopt;
8190 reqcharflags = req_caseopt | cd->req_varyopt;
8235 cd points to the data block with tables pointers etc.
8248 branch_chain *bcptr, compile_data *cd, int *lengthptr)
8283 save_hwm_offset = cd->hwm - cd->start_workspace;
8309 capitem.next = cd->open_caps;
8311 cd->open_caps = &capitem;
8321 orig_bracount = max_bracount = cd->bracount;
8327 if (reset_bracount) cd->bracount = orig_bracount;
8344 cond_depth, cd, (lengthptr == NULL)? NULL : &length))
8353 if (cd->bracount > max_bracount) max_bracount = cd->bracount;
8426 FALSE, cd, NULL);
8430 cd->check_lookbehind = TRUE;
8441 if (fixed_length > cd->max_lookbehind)
8442 cd->max_lookbehind = fixed_length;
8483 if (cd->open_caps->flag)
8487 (options & PCRE_UTF8) != 0, cd, save_hwm_offset);
8498 cd->open_caps = cd->open_caps->next;
8503 cd->bracount = max_bracount;
8590 cd points to the compile data block
8598 compile_data *cd, int atomcount)
8610 if (!is_anchored(scode, bracket_map, cd, atomcount)) return FALSE;
8620 if (!is_anchored(scode, new_map, cd, atomcount)) return FALSE;
8627 if (!is_anchored(scode, bracket_map, cd, atomcount)) return FALSE;
8634 if (!is_anchored(scode, bracket_map, cd, atomcount + 1))
8645 if (scode[1] != OP_ALLANY || (bracket_map & cd->backref_map) != 0 ||
8646 atomcount > 0 || cd->had_pruneorskip)
8680 cd points to the compile data
8688 compile_data *cd, int atomcount)
8715 if (!is_startline(scode, bracket_map, cd, atomcount)) return FALSE;
8729 if (!is_startline(scode, bracket_map, cd, atomcount)) return FALSE;
8739 if (!is_startline(scode, new_map, cd, atomcount)) return FALSE;
8746 if (!is_startline(scode, bracket_map, cd, atomcount)) return FALSE;
8753 if (!is_startline(scode, bracket_map, cd, atomcount + 1)) return FALSE;
8764 if (scode[1] != OP_ANY || (bracket_map & cd->backref_map) != 0 ||
8765 atomcount > 0 || cd->had_pruneorskip)
8890 cd the compile data block
8899 add_name(compile_data *cd, const pcre_uchar *name, int length,
8903 pcre_uchar *slot = cd->name_table;
8905 for (i = 0; i < cd->names_found; i++)
8918 memmove(slot + cd->name_entry_size, slot,
8919 IN_UCHARS((cd->names_found - i) * cd->name_entry_size));
8925 slot += cd->name_entry_size;
8931 cd->names_found++;
9012 compile_data *cd = &compile_block;
9058 cd->lcc = tables + lcc_offset;
9059 cd->fcc = tables + fcc_offset;
9060 cd->cbits = tables + cbits_offset;
9061 cd->ctypes = tables + ctypes_offset;
9078 cd->external_flags = 0; /* Initialize here for LIMIT_MATCH/RECURSION */
9125 cd->external_flags |= PCRE_MLSET;
9144 cd->external_flags |= PCRE_RLSET;
9244 cd->nltype = NLTYPE_ANYCRLF;
9248 cd->nltype = NLTYPE_ANY;
9252 cd->nltype = NLTYPE_FIXED;
9255 cd->nllen = 2;
9256 cd->nl[0] = (newline >> 8) & 255;
9257 cd->nl[1] = newline & 255;
9261 cd->nllen = 1;
9262 cd->nl[0] = newline;
9270 cd->top_backref = 0;
9271 cd->backref_map = 0;
9288 cd->bracount = cd->final_bracount = 0;
9289 cd->names_found = 0;
9290 cd->name_entry_size = 0;
9291 cd->name_table = NULL;
9292 cd->dupnames = FALSE;
9293 cd->dupgroups = FALSE;
9294 cd->namedrefcount = 0;
9295 cd->start_code = cworkspace;
9296 cd->hwm = cworkspace;
9297 cd->iscondassert = FALSE;
9298 cd->start_workspace = cworkspace;
9299 cd->workspace_size = COMPILE_WORK_SIZE;
9300 cd->named_groups = named_groups;
9301 cd->named_group_list_size = NAMED_GROUP_LIST_SIZE;
9302 cd->start_pattern = (const pcre_uchar *)pattern;
9303 cd->end_pattern = (const pcre_uchar *)(pattern + STRLEN_UC((const pcre_uchar *)pattern));
9304 cd->req_varyopt = 0;
9305 cd->parens_depth = 0;
9306 cd->assert_depth = 0;
9307 cd->max_lookbehind = 0;
9308 cd->external_options = options;
9309 cd->open_caps = NULL;
9313 been put into the cd block so that they can be changed if an option setting is
9321 (void)compile_regex(cd->external_options, &code, &ptr, &errorcode, FALSE,
9323 cd, &length);
9327 (int)(cd->hwm - cworkspace)));
9337 value of cd->names_found and cd->name_entry_size. */
9340 (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar);
9359 re->options = cd->external_options;
9360 re->flags = cd->external_flags;
9366 re->name_entry_size = cd->name_entry_size;
9367 re->name_count = cd->names_found;
9384 cd->final_bracount = cd->bracount; /* Save for checking forward references */
9385 cd->parens_depth = 0;
9386 cd->assert_depth = 0;
9387 cd->bracount = 0;
9388 cd->max_lookbehind = 0;
9389 cd->name_table = (pcre_uchar *)re + re->name_table_offset;
9390 codestart = cd->name_table + re->name_entry_size * re->name_count;
9391 cd->start_code = codestart;
9392 cd->hwm = (pcre_uchar *)(cd->start_workspace);
9393 cd->iscondassert = FALSE;
9394 cd->req_varyopt = 0;
9395 cd->had_accept = FALSE;
9396 cd->had_pruneorskip = FALSE;
9397 cd->check_lookbehind = FALSE;
9398 cd->open_caps = NULL;
9403 if (cd->names_found > 0)
9405 int i = cd->names_found;
9406 named_group *ng = cd->named_groups;
9407 cd->names_found = 0;
9409 add_name(cd, ng->name, ng->length, ng->number);
9410 if (cd->named_group_list_size > NAMED_GROUP_LIST_SIZE)
9411 (PUBL(free))((void *)cd->named_groups);
9422 &firstchar, &firstcharflags, &reqchar, &reqcharflags, NULL, cd, NULL);
9423 re->top_bracket = cd->bracount;
9424 re->top_backref = cd->top_backref;
9425 re->max_lookbehind = cd->max_lookbehind;
9426 re->flags = cd->external_flags | PCRE_MODE;
9428 if (cd->had_accept)
9457 if (cd->hwm > cd->start_workspace)
9461 while (errorcode == 0 && cd->hwm > cd->start_workspace)
9464 cd->hwm -= LINK_SIZE;
9465 offset = GET(cd->hwm, 0);
9490 if (cd->workspace_size > COMPILE_WORK_SIZE)
9491 (PUBL(free))((void *)cd->start_workspace);
9492 cd->start_workspace = NULL;
9509 auto_possessify(temp, utf, cd);
9520 if (errorcode == 0 && cd->check_lookbehind)
9540 cd, NULL);
9549 if (fixed_length > cd->max_lookbehind) cd->max_lookbehind = fixed_length;
9582 if (is_anchored(codestart, 0, cd, 0)) re->options |= PCRE_ANCHORED;
9604 if (cd->fcc[re->first_char] != re->first_char)
9613 && cd->fcc[re->first_char] != re->first_char)
9620 else if (is_startline(codestart, 0, cd, 0)) re->flags |= PCRE_STARTLINE;
9646 if (cd->fcc[re->req_char] != re->req_char)
9654 if (MAX_255(re->req_char) && cd->fcc[re->req_char] != re->req_char)
9714 if (could_be_empty_branch(codestart, code, utf, cd, NULL))