w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

regexec.c
Go to the documentation of this file.
1 /* Extended regular expression matching and search library.
2  Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3  This file is part of the GNU C Library.
4  Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
5 
6  The GNU C Library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  The GNU C Library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with the GNU C Library; if not, write to the Free
18  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19  02111-1307 USA. */
20 
22  int n) internal_function;
26  int str_idx, int from, int to)
28 static int search_cur_bkref_entry (const re_match_context_t *mctx, int str_idx)
31  int str_idx) internal_function;
33  int node, int str_idx)
35 static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
36  re_dfastate_t **limited_sts, int last_node,
37  int last_str_idx)
39 static reg_errcode_t re_search_internal (const regex_t *preg,
40  const char *string, int length,
41  int start, int range, int stop,
42  size_t nmatch, regmatch_t pmatch[],
43  int eflags) internal_function;
44 static int re_search_2_stub (struct re_pattern_buffer *bufp,
45  const char *string1, int length1,
46  const char *string2, int length2,
47  int start, int range, struct re_registers *regs,
48  int stop, int ret_len) internal_function;
49 static int re_search_stub (struct re_pattern_buffer *bufp,
50  const char *string, int length, int start,
51  int range, int stop, struct re_registers *regs,
52  int ret_len) internal_function;
53 static unsigned re_copy_regs (struct re_registers *regs, regmatch_t *pmatch,
54  int nregs, int regs_allocated) internal_function;
57 static int check_matching (re_match_context_t *mctx, int fl_longest_match,
58  int *p_match_first) internal_function;
59 static int check_halt_state_context (const re_match_context_t *mctx,
60  const re_dfastate_t *state, int idx)
62 static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
63  regmatch_t *prev_idx_match, int cur_node,
64  int cur_idx, int nmatch) internal_function;
66  int str_idx, int dest_node, int nregs,
68  re_node_set *eps_via_nodes)
70 static reg_errcode_t set_regs (const regex_t *preg,
71  const re_match_context_t *mctx,
72  size_t nmatch, regmatch_t *pmatch,
73  int fl_backtrack) internal_function;
76 
77 #ifdef RE_ENABLE_I18N
78 static int sift_states_iter_mb (const re_match_context_t *mctx,
79  re_sift_context_t *sctx,
80  int node_idx, int str_idx, int max_str_idx)
82 #endif /* RE_ENABLE_I18N */
84  re_sift_context_t *sctx)
87  re_sift_context_t *sctx, int str_idx,
88  re_node_set *cur_dest)
91  re_sift_context_t *sctx,
92  int str_idx,
93  re_node_set *dest_nodes)
96  re_node_set *dest_nodes,
97  const re_node_set *candidates)
99 static int check_dst_limits (const re_match_context_t *mctx,
101  int dst_node, int dst_idx, int src_node,
102  int src_idx) internal_function;
103 static int check_dst_limits_calc_pos_1 (const re_match_context_t *mctx,
104  int boundaries, int subexp_idx,
105  int from_node, int bkref_idx)
107 static int check_dst_limits_calc_pos (const re_match_context_t *mctx,
108  int limit, int subexp_idx,
109  int node, int str_idx,
110  int bkref_idx) internal_function;
111 static reg_errcode_t check_subexp_limits (const re_dfa_t *dfa,
112  re_node_set *dest_nodes,
113  const re_node_set *candidates,
115  struct re_backref_cache_entry *bkref_ents,
116  int str_idx) internal_function;
118  re_sift_context_t *sctx,
119  int str_idx, const re_node_set *candidates)
121 static reg_errcode_t merge_state_array (const re_dfa_t *dfa,
122  re_dfastate_t **dst,
123  re_dfastate_t **src, int num)
128  re_match_context_t *mctx,
131  re_match_context_t *mctx,
132  re_dfastate_t *next_state)
135  re_node_set *cur_nodes,
136  int str_idx) internal_function;
137 #if 0
138 static re_dfastate_t *transit_state_sb (reg_errcode_t *err,
139  re_match_context_t *mctx,
140  re_dfastate_t *pstate)
142 #endif
143 #ifdef RE_ENABLE_I18N
144 static reg_errcode_t transit_state_mb (re_match_context_t *mctx,
145  re_dfastate_t *pstate)
147 #endif /* RE_ENABLE_I18N */
149  const re_node_set *nodes)
152  int bkref_node, int bkref_str_idx)
155  const re_sub_match_top_t *sub_top,
156  re_sub_match_last_t *sub_last,
157  int bkref_node, int bkref_str)
159 static int find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
160  int subexp_idx, int type) internal_function;
162  state_array_t *path, int top_node,
163  int top_str, int last_node, int last_str,
164  int type) internal_function;
166  int str_idx,
167  re_node_set *cur_nodes,
168  re_node_set *next_nodes)
171  re_node_set *cur_nodes,
172  int ex_subexp, int type)
175  re_node_set *dst_nodes,
176  int target, int ex_subexp,
177  int type) internal_function;
179  re_node_set *cur_nodes, int cur_str,
180  int subexp_num, int type)
182 static int build_trtable (const re_dfa_t *dfa,
184 #ifdef RE_ENABLE_I18N
185 static int check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
186  const re_string_t *input, int idx)
188 # ifdef _LIBC
189 static unsigned int find_collation_sequence_value (const unsigned char *mbs,
190  size_t name_len)
192 # endif /* _LIBC */
193 #endif /* RE_ENABLE_I18N */
194 static int group_nodes_into_DFAstates (const re_dfa_t *dfa,
195  const re_dfastate_t *state,
196  re_node_set *states_node,
197  bitset_t *states_ch) internal_function;
198 static int check_node_accept (const re_match_context_t *mctx,
199  const re_token_t *node, int idx)
203 ␌
204 /* Entry point for POSIX code. */
205 
206 /* regexec searches for a given pattern, specified by PREG, in the
207  string STRING.
208 
209  If NMATCH is zero or REG_NOSUB was set in the cflags argument to
210  `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at
211  least NMATCH elements, and we set them to the offsets of the
212  corresponding matched substrings.
213 
214  EFLAGS specifies `execution flags' which affect matching: if
215  REG_NOTBOL is set, then ^ does not match at the beginning of the
216  string; if REG_NOTEOL is set, then $ does not match at the end.
217 
218  We return 0 if we find a match and REG_NOMATCH if not. */
219 
220 int
221 regexec (const regex_t *__restrict preg, const char *__restrict string,
222  size_t nmatch, regmatch_t pmatch[], int eflags)
223 {
225  int start, length;
226 #ifdef _LIBC
227  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
228 #endif
229 
230  if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND))
231  return REG_BADPAT;
232 
233  if (eflags & REG_STARTEND)
234  {
235  start = pmatch[0].rm_so;
236  length = pmatch[0].rm_eo;
237  }
238  else
239  {
240  start = 0;
241  length = strlen (string);
242  }
243 
244  __libc_lock_lock (dfa->lock);
245  if (preg->no_sub)
246  err = re_search_internal (preg, string, length, start, length - start,
247  length, 0, NULL, eflags);
248  else
249  err = re_search_internal (preg, string, length, start, length - start,
250  length, nmatch, pmatch, eflags);
251  __libc_lock_unlock (dfa->lock);
252  return err != REG_NOERROR;
253 }
254 
255 #ifdef _LIBC
256 # include <shlib-compat.h>
257 versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
258 
259 # if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
260 __typeof__ (__regexec) __compat_regexec;
261 
262 int
263 attribute_compat_text_section
264 __compat_regexec (const regex_t *__restrict preg,
265  const char *__restrict string, size_t nmatch,
266  regmatch_t pmatch[], int eflags)
267 {
268  return regexec (preg, string, nmatch, pmatch,
269  eflags & (REG_NOTBOL | REG_NOTEOL));
270 }
271 compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
272 # endif
273 #endif
274 
275 /* Entry points for GNU code. */
276 
277 /* re_match, re_search, re_match_2, re_search_2
278 
279  The former two functions operate on STRING with length LENGTH,
280  while the later two operate on concatenation of STRING1 and STRING2
281  with lengths LENGTH1 and LENGTH2, respectively.
282 
283  re_match() matches the compiled pattern in BUFP against the string,
284  starting at index START.
285 
286  re_search() first tries matching at index START, then it tries to match
287  starting from index START + 1, and so on. The last start position tried
288  is START + RANGE. (Thus RANGE = 0 forces re_search to operate the same
289  way as re_match().)
290 
291  The parameter STOP of re_{match,search}_2 specifies that no match exceeding
292  the first STOP characters of the concatenation of the strings should be
293  concerned.
294 
295  If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match
296  and all groups is stroed in REGS. (For the "_2" variants, the offsets are
297  computed relative to the concatenation, not relative to the individual
298  strings.)
299 
300  On success, re_match* functions return the length of the match, re_search*
301  return the position of the start of the match. Return value -1 means no
302  match was found and -2 indicates an internal error. */
303 
304 int
305 re_match (struct re_pattern_buffer *bufp, const char *string, int length, int start,
306  struct re_registers *regs)
307 {
308  return re_search_stub (bufp, string, length, start, 0, length, regs, 1);
309 }
310 #ifdef _LIBC
311 weak_alias (__re_match, re_match)
312 #endif
313 
314 int
315 re_search (struct re_pattern_buffer *bufp, const char *string, int length, int start,
316  int range, struct re_registers *regs)
317 {
318  return re_search_stub (bufp, string, length, start, range, length, regs, 0);
319 }
320 #ifdef _LIBC
321 weak_alias (__re_search, re_search)
322 #endif
323 
324 int
325 re_match_2 (struct re_pattern_buffer *bufp, const char *string1, int length1,
326  const char *string2, int length2, int start,
327  struct re_registers *regs, int stop)
328 {
329  return re_search_2_stub (bufp, string1, length1, string2, length2,
330  start, 0, regs, stop, 1);
331 }
332 #ifdef _LIBC
333 weak_alias (__re_match_2, re_match_2)
334 #endif
335 
336 int
337 re_search_2 (struct re_pattern_buffer *bufp, const char *string1, int length1,
338  const char *string2, int length2, int start, int range,
339  struct re_registers *regs, int stop)
340 {
341  return re_search_2_stub (bufp, string1, length1, string2, length2,
342  start, range, regs, stop, 0);
343 }
344 #ifdef _LIBC
345 weak_alias (__re_search_2, re_search_2)
346 #endif
347 
348 static int internal_function
349 re_search_2_stub (struct re_pattern_buffer *bufp, const char *string1, int length1,
350  const char *string2, int length2, int start, int range,
351  struct re_registers *regs, int stop, int ret_len)
352 {
353  const char *str;
354  int rval;
355  int len = length1 + length2;
356  char *s = NULL;
357 
358  if (BE (length1 < 0 || length2 < 0 || stop < 0, 0))
359  return -2;
360 
361  /* Concatenate the strings. */
362  if (length2 > 0)
363  if (length1 > 0)
364  {
365  s = re_malloc (char, len);
366 
367  if (BE (s == NULL, 0))
368  return -2;
369 #ifdef _LIBC
370  memcpy (__mempcpy (s, string1, length1), string2, length2);
371 #else
372  memcpy (s, string1, length1);
373  memcpy (s + length1, string2, length2);
374 #endif
375  str = s;
376  }
377  else
378  str = string2;
379  else
380  str = string1;
381 
382  rval = re_search_stub (bufp, str, len, start, range, stop, regs,
383  ret_len);
384  if (s)
385  re_free (s);
386  return rval;
387 }
388 
389 /* The parameters have the same meaning as those of re_search.
390  Additional parameters:
391  If RET_LEN is nonzero the length of the match is returned (re_match style);
392  otherwise the position of the match is returned. */
393 
394 static int internal_function
395 re_search_stub (struct re_pattern_buffer *bufp, const char *string, int length,
396  int start, int range, int stop, struct re_registers *regs, int ret_len)
397 {
400  int nregs, rval;
401  int eflags = 0;
402 #ifdef _LIBC
403  re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
404 #endif
405 
406  /* Check for out-of-range. */
407  if (BE (start < 0 || start > length, 0))
408  return -1;
409  if (BE (start + range > length, 0))
410  range = length - start;
411  else if (BE (start + range < 0, 0))
412  range = -start;
413 
414  __libc_lock_lock (dfa->lock);
415 
416  eflags |= (bufp->not_bol) ? REG_NOTBOL : 0;
417  eflags |= (bufp->not_eol) ? REG_NOTEOL : 0;
418 
419  /* Compile fastmap if we haven't yet. */
420  if (range > 0 && bufp->fastmap != NULL && !bufp->fastmap_accurate)
421  re_compile_fastmap (bufp);
422 
423  if (BE (bufp->no_sub, 0))
424  regs = NULL;
425 
426  /* We need at least 1 register. */
427  if (regs == NULL)
428  nregs = 1;
429  else if (BE (bufp->regs_allocated == REGS_FIXED &&
430  regs->num_regs < bufp->re_nsub + 1, 0))
431  {
432  nregs = regs->num_regs;
433  if (BE (nregs < 1, 0))
434  {
435  /* Nothing can be copied to regs. */
436  regs = NULL;
437  nregs = 1;
438  }
439  }
440  else
441  nregs = bufp->re_nsub + 1;
442  pmatch = re_malloc (regmatch_t, nregs);
443  if (BE (pmatch == NULL, 0))
444  {
445  rval = -2;
446  goto out;
447  }
448 
449  result = re_search_internal (bufp, string, length, start, range, stop,
450  nregs, pmatch, eflags);
451 
452  rval = 0;
453 
454  /* I hope we needn't fill ther regs with -1's when no match was found. */
455  if (result != REG_NOERROR)
456  rval = -1;
457  else if (regs != NULL)
458  {
459  /* If caller wants register contents data back, copy them. */
460  bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs,
461  bufp->regs_allocated);
462  if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0))
463  rval = -2;
464  }
465 
466  if (BE (rval == 0, 1))
467  {
468  if (ret_len)
469  {
470  assert (pmatch[0].rm_so == start);
471  rval = pmatch[0].rm_eo - start;
472  }
473  else
474  rval = pmatch[0].rm_so;
475  }
476  re_free (pmatch);
477  out:
478  __libc_lock_unlock (dfa->lock);
479  return rval;
480 }
481 
482 static unsigned internal_function
483 re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, int nregs, int regs_allocated)
484 {
485  int rval = REGS_REALLOCATE;
486  int i;
487  int need_regs = nregs + 1;
488  /* We need one extra element beyond `num_regs' for the `-1' marker GNU code
489  uses. */
490 
491  /* Have the register data arrays been allocated? */
492  if (regs_allocated == REGS_UNALLOCATED)
493  { /* No. So allocate them with malloc. */
494  regs->start = re_malloc (regoff_t, need_regs);
495  regs->end = re_malloc (regoff_t, need_regs);
496  if (BE (regs->start == NULL, 0) || BE (regs->end == NULL, 0))
497  return REGS_UNALLOCATED;
498  regs->num_regs = need_regs;
499  }
500  else if (regs_allocated == REGS_REALLOCATE)
501  { /* Yes. If we need more elements than were already
502  allocated, reallocate them. If we need fewer, just
503  leave it alone. */
504  if (BE (need_regs > regs->num_regs, 0))
505  {
506  regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);
507  regoff_t *new_end = re_realloc (regs->end, regoff_t, need_regs);
508  if (BE (new_start == NULL, 0) || BE (new_end == NULL, 0))
509  return REGS_UNALLOCATED;
510  regs->start = new_start;
511  regs->end = new_end;
512  regs->num_regs = need_regs;
513  }
514  }
515  else
516  {
517  assert (regs_allocated == REGS_FIXED);
518  /* This function may not be called with REGS_FIXED and nregs too big. */
519  assert (regs->num_regs >= nregs);
520  rval = REGS_FIXED;
521  }
522 
523  /* Copy the regs. */
524  for (i = 0; i < nregs; ++i)
525  {
526  regs->start[i] = pmatch[i].rm_so;
527  regs->end[i] = pmatch[i].rm_eo;
528  }
529  for ( ; i < regs->num_regs; ++i)
530  regs->start[i] = regs->end[i] = -1;
531 
532  return rval;
533 }
534 
535 /* Set REGS to hold NUM_REGS registers, storing them in STARTS and
536  ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use
537  this memory for recording register information. STARTS and ENDS
538  must be allocated using the malloc library routine, and must each
539  be at least NUM_REGS * sizeof (regoff_t) bytes long.
540 
541  If NUM_REGS == 0, then subsequent matches should allocate their own
542  register data.
543 
544  Unless this function is called, the first search or match using
545  PATTERN_BUFFER will allocate its own register data, without
546  freeing the old data. */
547 
548 void
550  unsigned num_regs, regoff_t *starts, regoff_t *ends)
551 {
552  if (num_regs)
553  {
555  regs->num_regs = num_regs;
556  regs->start = starts;
557  regs->end = ends;
558  }
559  else
560  {
562  regs->num_regs = 0;
563  regs->start = regs->end = (regoff_t *) 0;
564  }
565 }
566 #ifdef _LIBC
568 #endif
569 ␌
570 /* Entry points compatible with 4.2 BSD regex library. We don't define
571  them unless specifically requested. */
572 
573 #if defined _REGEX_RE_COMP || defined _LIBC
574 int
575 # ifdef _LIBC
576 weak_function
577 # endif
578 re_exec (s)
579  const char *s;
580 {
581  return 0 == regexec (&re_comp_buf, s, 0, NULL, 0);
582 }
583 #endif /* _REGEX_RE_COMP */
584 ␌
585 /* Internal entry point. */
586 
587 /* Searches for a compiled pattern PREG in the string STRING, whose
588  length is LENGTH. NMATCH, PMATCH, and EFLAGS have the same
589  mingings with regexec. START, and RANGE have the same meanings
590  with re_search.
591  Return REG_NOERROR if we find a match, and REG_NOMATCH if not,
592  otherwise return the error code.
593  Note: We assume front end functions already check ranges.
594  (START + RANGE >= 0 && START + RANGE <= LENGTH) */
595 
597 re_search_internal (const regex_t *preg, const char *string, int length, int start,
598  int range, int stop, size_t nmatch, regmatch_t pmatch[],
599  int eflags)
600 {
602  const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer;
603  int left_lim, right_lim, incr;
604  int fl_longest_match, match_first, match_kind, match_last = -1;
605  int extra_nmatch;
606  int sb, ch;
607 #if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
608  re_match_context_t mctx = { .dfa = dfa };
609 #else
610  re_match_context_t mctx;
611 #endif
612  char *fastmap = (preg->fastmap != NULL && preg->fastmap_accurate
613  && range && !preg->can_be_null) ? preg->fastmap : NULL;
614  RE_TRANSLATE_TYPE t = preg->translate;
615 
616 #if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
617  memset (&mctx, '\0', sizeof (re_match_context_t));
618  mctx.dfa = dfa;
619 #endif
620 
621  extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0;
622  nmatch -= extra_nmatch;
623 
624  /* Check if the DFA haven't been compiled. */
625  if (BE (preg->used == 0 || dfa->init_state == NULL
626  || dfa->init_state_word == NULL || dfa->init_state_nl == NULL
627  || dfa->init_state_begbuf == NULL, 0))
628  return REG_NOMATCH;
629 
630 #ifdef DEBUG
631  /* We assume front-end functions already check them. */
632  assert (start + range >= 0 && start + range <= length);
633 #endif
634 
635  /* If initial states with non-begbuf contexts have no elements,
636  the regex must be anchored. If preg->newline_anchor is set,
637  we'll never use init_state_nl, so do not check it. */
638  if (dfa->init_state->nodes.nelem == 0
639  && dfa->init_state_word->nodes.nelem == 0
640  && (dfa->init_state_nl->nodes.nelem == 0
641  || !preg->newline_anchor))
642  {
643  if (start != 0 && start + range != 0)
644  return REG_NOMATCH;
645  start = range = 0;
646  }
647 
648  /* We must check the longest matching, if nmatch > 0. */
649  fl_longest_match = (nmatch != 0 || dfa->nbackref);
650 
651  err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1,
652  preg->translate, preg->syntax & RE_ICASE, dfa);
653  if (BE (err != REG_NOERROR, 0))
654  goto free_return;
655  mctx.input.stop = stop;
656  mctx.input.raw_stop = stop;
657  mctx.input.newline_anchor = preg->newline_anchor;
658 
659  err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2);
660  if (BE (err != REG_NOERROR, 0))
661  goto free_return;
662 
663  /* We will log all the DFA states through which the dfa pass,
664  if nmatch > 1, or this dfa has "multibyte node", which is a
665  back-reference or a node which can accept multibyte character or
666  multi character collating element. */
667  if (nmatch > 1 || dfa->has_mb_node)
668  {
669  mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1);
670  if (BE (mctx.state_log == NULL, 0))
671  {
672  err = REG_ESPACE;
673  goto free_return;
674  }
675  }
676  else
677  mctx.state_log = NULL;
678 
679  match_first = start;
680  mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
682 
683  /* Check incrementally whether of not the input string match. */
684  incr = (range < 0) ? -1 : 1;
685  left_lim = (range < 0) ? start + range : start;
686  right_lim = (range < 0) ? start : start + range;
687  sb = dfa->mb_cur_max == 1;
688  match_kind =
689  (fastmap
690  ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
691  | (range >= 0 ? 2 : 0)
692  | (t != NULL ? 1 : 0))
693  : 8);
694 
695  for (;; match_first += incr)
696  {
697  err = REG_NOMATCH;
698  if (match_first < left_lim || right_lim < match_first)
699  goto free_return;
700 
701  /* Advance as rapidly as possible through the string, until we
702  find a plausible place to start matching. This may be done
703  with varying efficiency, so there are various possibilities:
704  only the most common of them are specialized, in order to
705  save on code size. We use a switch statement for speed. */
706  switch (match_kind)
707  {
708  case 8:
709  /* No fastmap. */
710  break;
711 
712  case 7:
713  /* Fastmap with single-byte translation, match forward. */
714  while (BE (match_first < right_lim, 1)
715  && !fastmap[t[(unsigned char) string[match_first]]])
716  ++match_first;
717  goto forward_match_found_start_or_reached_end;
718 
719  case 6:
720  /* Fastmap without translation, match forward. */
721  while (BE (match_first < right_lim, 1)
722  && !fastmap[(unsigned char) string[match_first]])
723  ++match_first;
724 
725  forward_match_found_start_or_reached_end:
726  if (BE (match_first == right_lim, 0))
727  {
728  ch = match_first >= length
729  ? 0 : (unsigned char) string[match_first];
730  if (!fastmap[t ? t[ch] : ch])
731  goto free_return;
732  }
733  break;
734 
735  case 4:
736  case 5:
737  /* Fastmap without multi-byte translation, match backwards. */
738  while (match_first >= left_lim)
739  {
740  ch = match_first >= length
741  ? 0 : (unsigned char) string[match_first];
742  if (fastmap[t ? t[ch] : ch])
743  break;
744  --match_first;
745  }
746  if (match_first < left_lim)
747  goto free_return;
748  break;
749 
750  default:
751  /* In this case, we can't determine easily the current byte,
752  since it might be a component byte of a multibyte
753  character. Then we use the constructed buffer instead. */
754  for (;;)
755  {
756  /* If MATCH_FIRST is out of the valid range, reconstruct the
757  buffers. */
758  unsigned int offset = match_first - mctx.input.raw_mbs_idx;
759  if (BE (offset >= (unsigned int) mctx.input.valid_raw_len, 0))
760  {
761  err = re_string_reconstruct (&mctx.input, match_first,
762  eflags);
763  if (BE (err != REG_NOERROR, 0))
764  goto free_return;
765 
766  offset = match_first - mctx.input.raw_mbs_idx;
767  }
768  /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
769  Note that MATCH_FIRST must not be smaller than 0. */
770  ch = (match_first >= length
771  ? 0 : re_string_byte_at (&mctx.input, offset));
772  if (fastmap[ch])
773  break;
774  match_first += incr;
775  if (match_first < left_lim || match_first > right_lim)
776  {
777  err = REG_NOMATCH;
778  goto free_return;
779  }
780  }
781  break;
782  }
783 
784  /* Reconstruct the buffers so that the matcher can assume that
785  the matching starts from the beginning of the buffer. */
786  err = re_string_reconstruct (&mctx.input, match_first, eflags);
787  if (BE (err != REG_NOERROR, 0))
788  goto free_return;
789 
790 #ifdef RE_ENABLE_I18N
791  /* Don't consider this char as a possible match start if it part,
792  yet isn't the head, of a multibyte character. */
793  if (!sb && !re_string_first_byte (&mctx.input, 0))
794  continue;
795 #endif
796 
797  /* It seems to be appropriate one, then use the matcher. */
798  /* We assume that the matching starts from 0. */
799  mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;
800  match_last = check_matching (&mctx, fl_longest_match,
801  range >= 0 ? &match_first : NULL);
802  if (match_last != -1)
803  {
804  if (BE (match_last == -2, 0))
805  {
806  err = REG_ESPACE;
807  goto free_return;
808  }
809  else
810  {
811  mctx.match_last = match_last;
812  if ((!preg->no_sub && nmatch > 1) || dfa->nbackref)
813  {
814  re_dfastate_t *pstate = mctx.state_log[match_last];
815  mctx.last_node = check_halt_state_context (&mctx, pstate,
816  match_last);
817  }
818  if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match)
819  || dfa->nbackref)
820  {
821  err = prune_impossible_nodes (&mctx);
822  if (err == REG_NOERROR)
823  break;
824  if (BE (err != REG_NOMATCH, 0))
825  goto free_return;
826  match_last = -1;
827  }
828  else
829  break; /* We found a match. */
830  }
831  }
832 
833  match_ctx_clean (&mctx);
834  }
835 
836 #ifdef DEBUG
837  assert (match_last != -1);
838  assert (err == REG_NOERROR);
839 #endif
840 
841  /* Set pmatch[] if we need. */
842  if (nmatch > 0)
843  {
844  int reg_idx;
845 
846  /* Initialize registers. */
847  for (reg_idx = 1; reg_idx < nmatch; ++reg_idx)
848  pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1;
849 
850  /* Set the points where matching start/end. */
851  pmatch[0].rm_so = 0;
852  pmatch[0].rm_eo = mctx.match_last;
853 
854  if (!preg->no_sub && nmatch > 1)
855  {
856  err = set_regs (preg, &mctx, nmatch, pmatch,
857  dfa->has_plural_match && dfa->nbackref > 0);
858  if (BE (err != REG_NOERROR, 0))
859  goto free_return;
860  }
861 
862  /* At last, add the offset to the each registers, since we slided
863  the buffers so that we could assume that the matching starts
864  from 0. */
865  for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
866  if (pmatch[reg_idx].rm_so != -1)
867  {
868 #ifdef RE_ENABLE_I18N
869  if (BE (mctx.input.offsets_needed != 0, 0))
870  {
871  pmatch[reg_idx].rm_so =
872  (pmatch[reg_idx].rm_so == mctx.input.valid_len
873  ? mctx.input.valid_raw_len
874  : mctx.input.offsets[pmatch[reg_idx].rm_so]);
875  pmatch[reg_idx].rm_eo =
876  (pmatch[reg_idx].rm_eo == mctx.input.valid_len
877  ? mctx.input.valid_raw_len
878  : mctx.input.offsets[pmatch[reg_idx].rm_eo]);
879  }
880 #else
881  assert (mctx.input.offsets_needed == 0);
882 #endif
883  pmatch[reg_idx].rm_so += match_first;
884  pmatch[reg_idx].rm_eo += match_first;
885  }
886  for (reg_idx = 0; reg_idx < extra_nmatch; ++reg_idx)
887  {
888  pmatch[nmatch + reg_idx].rm_so = -1;
889  pmatch[nmatch + reg_idx].rm_eo = -1;
890  }
891 
892  if (dfa->subexp_map)
893  for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++)
894  if (dfa->subexp_map[reg_idx] != reg_idx)
895  {
896  pmatch[reg_idx + 1].rm_so
897  = pmatch[dfa->subexp_map[reg_idx] + 1].rm_so;
898  pmatch[reg_idx + 1].rm_eo
899  = pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo;
900  }
901  }
902 
903  free_return:
904  re_free (mctx.state_log);
905  if (dfa->nbackref)
906  match_ctx_free (&mctx);
907  re_string_destruct (&mctx.input);
908  return err;
909 }
910 
913 {
914  const re_dfa_t *const dfa = mctx->dfa;
915  int halt_node, match_last;
917  re_dfastate_t **sifted_states;
918  re_dfastate_t **lim_states = NULL;
919  re_sift_context_t sctx;
920 #ifdef DEBUG
921  assert (mctx->state_log != NULL);
922 #endif
923  match_last = mctx->match_last;
924  halt_node = mctx->last_node;
925  sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
926  if (BE (sifted_states == NULL, 0))
927  {
928  ret = REG_ESPACE;
929  goto free_return;
930  }
931  if (dfa->nbackref)
932  {
933  lim_states = re_malloc (re_dfastate_t *, match_last + 1);
934  if (BE (lim_states == NULL, 0))
935  {
936  ret = REG_ESPACE;
937  goto free_return;
938  }
939  while (1)
940  {
941  memset (lim_states, '\0',
942  sizeof (re_dfastate_t *) * (match_last + 1));
943  sift_ctx_init (&sctx, sifted_states, lim_states, halt_node,
944  match_last);
945  ret = sift_states_backward (mctx, &sctx);
946  re_node_set_free (&sctx.limits);
947  if (BE (ret != REG_NOERROR, 0))
948  goto free_return;
949  if (sifted_states[0] != NULL || lim_states[0] != NULL)
950  break;
951  do
952  {
953  --match_last;
954  if (match_last < 0)
955  {
956  ret = REG_NOMATCH;
957  goto free_return;
958  }
959  } while (mctx->state_log[match_last] == NULL
960  || !mctx->state_log[match_last]->halt);
961  halt_node = check_halt_state_context (mctx,
962  mctx->state_log[match_last],
963  match_last);
964  }
965  ret = merge_state_array (dfa, sifted_states, lim_states,
966  match_last + 1);
967  re_free (lim_states);
968  lim_states = NULL;
969  if (BE (ret != REG_NOERROR, 0))
970  goto free_return;
971  }
972  else
973  {
974  sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last);
975  ret = sift_states_backward (mctx, &sctx);
976  re_node_set_free (&sctx.limits);
977  if (BE (ret != REG_NOERROR, 0))
978  goto free_return;
979  }
980  re_free (mctx->state_log);
981  mctx->state_log = sifted_states;
982  sifted_states = NULL;
983  mctx->last_node = halt_node;
984  mctx->match_last = match_last;
985  ret = REG_NOERROR;
986  free_return:
987  re_free (sifted_states);
988  re_free (lim_states);
989  return ret;
990 }
991 
992 /* Acquire an initial state and return it.
993  We must select appropriate initial state depending on the context,
994  since initial states may have constraints like "<", "^", etc.. */
995 
996 static inline re_dfastate_t *
998 acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx,
999  int idx)
1000 {
1001  const re_dfa_t *const dfa = mctx->dfa;
1002  if (dfa->init_state->has_constraint)
1003  {
1004  unsigned int context;
1005  context = re_string_context_at (&mctx->input, idx - 1, mctx->eflags);
1006  if (IS_WORD_CONTEXT (context))
1007  return dfa->init_state_word;
1008  else if (IS_ORDINARY_CONTEXT (context))
1009  return dfa->init_state;
1011  return dfa->init_state_begbuf;
1012  else if (IS_NEWLINE_CONTEXT (context))
1013  return dfa->init_state_nl;
1014  else if (IS_BEGBUF_CONTEXT (context))
1015  {
1016  /* It is relatively rare case, then calculate on demand. */
1017  return re_acquire_state_context (err, dfa,
1018  dfa->init_state->entrance_nodes,
1019  context);
1020  }
1021  else
1022  /* Must not happen? */
1023  return dfa->init_state;
1024  }
1025  else
1026  return dfa->init_state;
1027 }
1028 
1029 /* Check whether the regular expression match input string INPUT or not,
1030  and return the index where the matching end, return -1 if not match,
1031  or return -2 in case of an error.
1032  FL_LONGEST_MATCH means we want the POSIX longest matching.
1033  If P_MATCH_FIRST is not NULL, and the match fails, it is set to the
1034  next place where we may want to try matching.
1035  Note that the matcher assume that the maching starts from the current
1036  index of the buffer. */
1037 
1038 static int
1040 check_matching (re_match_context_t *mctx, int fl_longest_match,
1041  int *p_match_first)
1042 {
1043  const re_dfa_t *const dfa = mctx->dfa;
1045  int match = 0;
1046  int match_last = -1;
1047  int cur_str_idx = re_string_cur_idx (&mctx->input);
1049  int at_init_state = p_match_first != NULL;
1050  int next_start_idx = cur_str_idx;
1051 
1052  err = REG_NOERROR;
1053  cur_state = acquire_init_state_context (&err, mctx, cur_str_idx);
1054  /* An initial state must not be NULL (invalid). */
1055  if (BE (cur_state == NULL, 0))
1056  {
1057  assert (err == REG_ESPACE);
1058  return -2;
1059  }
1060 
1061  if (mctx->state_log != NULL)
1062  {
1063  mctx->state_log[cur_str_idx] = cur_state;
1064 
1065  /* Check OP_OPEN_SUBEXP in the initial state in case that we use them
1066  later. E.g. Processing back references. */
1067  if (BE (dfa->nbackref, 0))
1068  {
1069  at_init_state = 0;
1070  err = check_subexp_matching_top (mctx, &cur_state->nodes, 0);
1071  if (BE (err != REG_NOERROR, 0))
1072  return err;
1073 
1074  if (cur_state->has_backref)
1075  {
1076  err = transit_state_bkref (mctx, &cur_state->nodes);
1077  if (BE (err != REG_NOERROR, 0))
1078  return err;
1079  }
1080  }
1081  }
1082 
1083  /* If the RE accepts NULL string. */
1084  if (BE (cur_state->halt, 0))
1085  {
1086  if (!cur_state->has_constraint
1087  || check_halt_state_context (mctx, cur_state, cur_str_idx))
1088  {
1089  if (!fl_longest_match)
1090  return cur_str_idx;
1091  else
1092  {
1093  match_last = cur_str_idx;
1094  match = 1;
1095  }
1096  }
1097  }
1098 
1099  while (!re_string_eoi (&mctx->input))
1100  {
1101  re_dfastate_t *old_state = cur_state;
1102  int next_char_idx = re_string_cur_idx (&mctx->input) + 1;
1103 
1104  if (BE (next_char_idx >= mctx->input.bufs_len, 0)
1105  || (BE (next_char_idx >= mctx->input.valid_len, 0)
1106  && mctx->input.valid_len < mctx->input.len))
1107  {
1108  err = extend_buffers (mctx);
1109  if (BE (err != REG_NOERROR, 0))
1110  {
1111  assert (err == REG_ESPACE);
1112  return -2;
1113  }
1114  }
1115 
1116  cur_state = transit_state (&err, mctx, cur_state);
1117  if (mctx->state_log != NULL)
1119 
1120  if (cur_state == NULL)
1121  {
1122  /* Reached the invalid state or an error. Try to recover a valid
1123  state using the state log, if available and if we have not
1124  already found a valid (even if not the longest) match. */
1125  if (BE (err != REG_NOERROR, 0))
1126  return -2;
1127 
1128  if (mctx->state_log == NULL
1129  || (match && !fl_longest_match)
1130  || (cur_state = find_recover_state (&err, mctx)) == NULL)
1131  break;
1132  }
1133 
1134  if (BE (at_init_state, 0))
1135  {
1136  if (old_state == cur_state)
1137  next_start_idx = next_char_idx;
1138  else
1139  at_init_state = 0;
1140  }
1141 
1142  if (cur_state->halt)
1143  {
1144  /* Reached a halt state.
1145  Check the halt state can satisfy the current context. */
1146  if (!cur_state->has_constraint
1148  re_string_cur_idx (&mctx->input)))
1149  {
1150  /* We found an appropriate halt state. */
1151  match_last = re_string_cur_idx (&mctx->input);
1152  match = 1;
1153 
1154  /* We found a match, do not modify match_first below. */
1155  p_match_first = NULL;
1156  if (!fl_longest_match)
1157  break;
1158  }
1159  }
1160  }
1161 
1162  if (p_match_first)
1163  *p_match_first += next_start_idx;
1164 
1165  return match_last;
1166 }
1167 
1168 /* Check NODE match the current context. */
1169 
1170 static int
1172 check_halt_node_context (const re_dfa_t *dfa, int node, unsigned int context)
1173 {
1175  unsigned int constraint = dfa->nodes[node].constraint;
1176  if (type != END_OF_RE)
1177  return 0;
1178  if (!constraint)
1179  return 1;
1181  return 0;
1182  return 1;
1183 }
1184 
1185 /* Check the halt state STATE match the current context.
1186  Return 0 if not match, if the node, STATE has, is a halt node and
1187  match the context, return the node. */
1188 
1189 static int
1192  const re_dfastate_t *state, int idx)
1193 {
1194  int i;
1195  unsigned int context;
1196 #ifdef DEBUG
1197  assert (state->halt);
1198 #endif
1199  context = re_string_context_at (&mctx->input, idx, mctx->eflags);
1200  for (i = 0; i < state->nodes.nelem; ++i)
1201  if (check_halt_node_context (mctx->dfa, state->nodes.elems[i], context))
1202  return state->nodes.elems[i];
1203  return 0;
1204 }
1205 
1206 /* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA
1207  corresponding to the DFA).
1208  Return the destination node, and update EPS_VIA_NODES, return -1 in case
1209  of errors. */
1210 
1211 static int
1214  int *pidx, int node, re_node_set *eps_via_nodes,
1215  struct re_fail_stack_t *fs)
1216 {
1217  const re_dfa_t *const dfa = mctx->dfa;
1218  int i, err;
1219  if (IS_EPSILON_NODE (dfa->nodes[node].type))
1220  {
1221  re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes;
1222  re_node_set *edests = &dfa->edests[node];
1223  int dest_node;
1224  err = re_node_set_insert (eps_via_nodes, node);
1225  if (BE (err < 0, 0))
1226  return -2;
1227  /* Pick up a valid destination, or return -1 if none is found. */
1228  for (dest_node = -1, i = 0; i < edests->nelem; ++i)
1229  {
1230  int candidate = edests->elems[i];
1231  if (!re_node_set_contains (cur_nodes, candidate))
1232  continue;
1233  if (dest_node == -1)
1234  dest_node = candidate;
1235 
1236  else
1237  {
1238  /* In order to avoid infinite loop like "(a*)*", return the second
1239  epsilon-transition if the first was already considered. */
1240  if (re_node_set_contains (eps_via_nodes, dest_node))
1241  return candidate;
1242 
1243  /* Otherwise, push the second epsilon-transition on the fail stack. */
1244  else if (fs != NULL
1245  && push_fail_stack (fs, *pidx, candidate, nregs, regs,
1246  eps_via_nodes))
1247  return -2;
1248 
1249  /* We know we are going to exit. */
1250  break;
1251  }
1252  }
1253  return dest_node;
1254  }
1255  else
1256  {
1257  int naccepted = 0;
1259 
1260 #ifdef RE_ENABLE_I18N
1261  if (dfa->nodes[node].accept_mb)
1262  naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx);
1263  else
1264 #endif /* RE_ENABLE_I18N */
1265  if (type == OP_BACK_REF)
1266  {
1267  int subexp_idx = dfa->nodes[node].opr.idx + 1;
1268  naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so;
1269  if (fs != NULL)
1270  {
1271  if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1)
1272  return -1;
1273  else if (naccepted)
1274  {
1275  char *buf = (char *) re_string_get_buffer (&mctx->input);
1276  if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
1277  naccepted) != 0)
1278  return -1;
1279  }
1280  }
1281 
1282  if (naccepted == 0)
1283  {
1284  int dest_node;
1285  err = re_node_set_insert (eps_via_nodes, node);
1286  if (BE (err < 0, 0))
1287  return -2;
1288  dest_node = dfa->edests[node].elems[0];
1289  if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,
1290  dest_node))
1291  return dest_node;
1292  }
1293  }
1294 
1295  if (naccepted != 0
1296  || check_node_accept (mctx, dfa->nodes + node, *pidx))
1297  {
1298  int dest_node = dfa->nexts[node];
1299  *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted;
1300  if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL
1301  || !re_node_set_contains (&mctx->state_log[*pidx]->nodes,
1302  dest_node)))
1303  return -1;
1304  re_node_set_empty (eps_via_nodes);
1305  return dest_node;
1306  }
1307  }
1308  return -1;
1309 }
1310 
1311 static reg_errcode_t
1313 push_fail_stack (struct re_fail_stack_t *fs, int str_idx, int dest_node,
1314  int nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
1315 {
1317  int num = fs->num++;
1318  if (fs->num == fs->alloc)
1319  {
1322  * fs->alloc * 2));
1323  if (new_array == NULL)
1324  return REG_ESPACE;
1325  fs->alloc *= 2;
1326  fs->stack = new_array;
1327  }
1328  fs->stack[num].idx = str_idx;
1329  fs->stack[num].node = dest_node;
1330  fs->stack[num].regs = re_malloc (regmatch_t, nregs);
1331  if (fs->stack[num].regs == NULL)
1332  return REG_ESPACE;
1333  memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
1335  return err;
1336 }
1337 
1338 static int
1340 pop_fail_stack (struct re_fail_stack_t *fs, int *pidx, int nregs,
1342 {
1343  int num = --fs->num;
1344  assert (num >= 0);
1345  *pidx = fs->stack[num].idx;
1346  memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
1348  re_free (fs->stack[num].regs);
1350  return fs->stack[num].node;
1351 }
1352 
1353 /* Set the positions where the subexpressions are starts/ends to registers
1354  PMATCH.
1355  Note: We assume that pmatch[0] is already set, and
1356  pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch. */
1357 
1358 static reg_errcode_t
1360 set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
1361  regmatch_t *pmatch, int fl_backtrack)
1362 {
1363  const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer;
1364  int idx, cur_node;
1366  struct re_fail_stack_t *fs;
1367  struct re_fail_stack_t fs_body = { 0, 2, NULL };
1368  regmatch_t *prev_idx_match;
1369  int prev_idx_match_malloced = 0;
1370 
1371 #ifdef DEBUG
1372  assert (nmatch > 1);
1373  assert (mctx->state_log != NULL);
1374 #endif
1375  if (fl_backtrack)
1376  {
1377  fs = &fs_body;
1378  fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc);
1379  if (fs->stack == NULL)
1380  return REG_ESPACE;
1381  }
1382  else
1383  fs = NULL;
1384 
1385  cur_node = dfa->init_node;
1387 
1388  if (__libc_use_alloca (nmatch * sizeof (regmatch_t)))
1389  prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t));
1390  else
1391  {
1392  prev_idx_match = re_malloc (regmatch_t, nmatch);
1393  if (prev_idx_match == NULL)
1394  {
1396  return REG_ESPACE;
1397  }
1398  prev_idx_match_malloced = 1;
1399  }
1400  memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
1401 
1402  for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)
1403  {
1404  update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch);
1405 
1406  if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
1407  {
1408  int reg_idx;
1409  if (fs)
1410  {
1411  for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
1412  if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1)
1413  break;
1414  if (reg_idx == nmatch)
1415  {
1417  if (prev_idx_match_malloced)
1418  re_free (prev_idx_match);
1419  return free_fail_stack_return (fs);
1420  }
1421  cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
1422  &eps_via_nodes);
1423  }
1424  else
1425  {
1427  if (prev_idx_match_malloced)
1428  re_free (prev_idx_match);
1429  return REG_NOERROR;
1430  }
1431  }
1432 
1433  /* Proceed to next node. */
1434  cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node,
1435  &eps_via_nodes, fs);
1436 
1437  if (BE (cur_node < 0, 0))
1438  {
1439  if (BE (cur_node == -2, 0))
1440  {
1442  if (prev_idx_match_malloced)
1443  re_free (prev_idx_match);
1445  return REG_ESPACE;
1446  }
1447  if (fs)
1448  cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
1449  &eps_via_nodes);
1450  else
1451  {
1453  if (prev_idx_match_malloced)
1454  re_free (prev_idx_match);
1455  return REG_NOMATCH;
1456  }
1457  }
1458  }
1460  if (prev_idx_match_malloced)
1461  re_free (prev_idx_match);
1462  return free_fail_stack_return (fs);
1463 }
1464 
1465 static reg_errcode_t
1468 {
1469  if (fs)
1470  {
1471  int fs_idx;
1472  for (fs_idx = 0; fs_idx < fs->num; ++fs_idx)
1473  {
1474  re_node_set_free (&fs->stack[fs_idx].eps_via_nodes);
1475  re_free (fs->stack[fs_idx].regs);
1476  }
1477  re_free (fs->stack);
1478  }
1479  return REG_NOERROR;
1480 }
1481 
1482 static void
1485  regmatch_t *prev_idx_match, int cur_node, int cur_idx, int nmatch)
1486 {
1487  int type = dfa->nodes[cur_node].type;
1488  if (type == OP_OPEN_SUBEXP)
1489  {
1490  int reg_num = dfa->nodes[cur_node].opr.idx + 1;
1491 
1492  /* We are at the first node of this sub expression. */
1493  if (reg_num < nmatch)
1494  {
1495  pmatch[reg_num].rm_so = cur_idx;
1496  pmatch[reg_num].rm_eo = -1;
1497  }
1498  }
1499  else if (type == OP_CLOSE_SUBEXP)
1500  {
1501  int reg_num = dfa->nodes[cur_node].opr.idx + 1;
1502  if (reg_num < nmatch)
1503  {
1504  /* We are at the last node of this sub expression. */
1505  if (pmatch[reg_num].rm_so < cur_idx)
1506  {
1507  pmatch[reg_num].rm_eo = cur_idx;
1508  /* This is a non-empty match or we are not inside an optional
1509  subexpression. Accept this right away. */
1510  memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
1511  }
1512  else
1513  {
1514  if (dfa->nodes[cur_node].opt_subexp
1515  && prev_idx_match[reg_num].rm_so != -1)
1516  /* We transited through an empty match for an optional
1517  subexpression, like (a?)*, and this is not the subexp's
1518  first match. Copy back the old content of the registers
1519  so that matches of an inner subexpression are undone as
1520  well, like in ((a?))*. */
1521  memcpy (pmatch, prev_idx_match, sizeof (regmatch_t) * nmatch);
1522  else
1523  /* We completed a subexpression, but it may be part of
1524  an optional one, so do not update PREV_IDX_MATCH. */
1525  pmatch[reg_num].rm_eo = cur_idx;
1526  }
1527  }
1528  }
1529 }
1530 
1531 /* This function checks the STATE_LOG from the SCTX->last_str_idx to 0
1532  and sift the nodes in each states according to the following rules.
1533  Updated state_log will be wrote to STATE_LOG.
1534 
1535  Rules: We throw away the Node `a' in the STATE_LOG[STR_IDX] if...
1536  1. When STR_IDX == MATCH_LAST(the last index in the state_log):
1537  If `a' isn't the LAST_NODE and `a' can't epsilon transit to
1538  the LAST_NODE, we throw away the node `a'.
1539  2. When 0 <= STR_IDX < MATCH_LAST and `a' accepts
1540  string `s' and transit to `b':
1541  i. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw
1542  away the node `a'.
1543  ii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is
1544  thrown away, we throw away the node `a'.
1545  3. When 0 <= STR_IDX < MATCH_LAST and 'a' epsilon transit to 'b':
1546  i. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the
1547  node `a'.
1548  ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away,
1549  we throw away the node `a'. */
1550 
1551 #define STATE_NODE_CONTAINS(state,node) \
1552  ((state) != NULL && re_node_set_contains (&(state)->nodes, node))
1553 
1554 static reg_errcode_t
1557 {
1559  int null_cnt = 0;
1560  int str_idx = sctx->last_str_idx;
1561  re_node_set cur_dest;
1562 
1563 #ifdef DEBUG
1564  assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL);
1565 #endif
1566 
1567  /* Build sifted state_log[str_idx]. It has the nodes which can epsilon
1568  transit to the last_node and the last_node itself. */
1569  err = re_node_set_init_1 (&cur_dest, sctx->last_node);
1570  if (BE (err != REG_NOERROR, 0))
1571  return err;
1572  err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
1573  if (BE (err != REG_NOERROR, 0))
1574  goto free_return;
1575 
1576  /* Then check each states in the state_log. */
1577  while (str_idx > 0)
1578  {
1579  /* Update counters. */
1580  null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0;
1581  if (null_cnt > mctx->max_mb_elem_len)
1582  {
1583  memset (sctx->sifted_states, '\0',
1584  sizeof (re_dfastate_t *) * str_idx);
1585  re_node_set_free (&cur_dest);
1586  return REG_NOERROR;
1587  }
1588  re_node_set_empty (&cur_dest);
1589  --str_idx;
1590 
1591  if (mctx->state_log[str_idx])
1592  {
1593  err = build_sifted_states (mctx, sctx, str_idx, &cur_dest);
1594  if (BE (err != REG_NOERROR, 0))
1595  goto free_return;
1596  }
1597 
1598  /* Add all the nodes which satisfy the following conditions:
1599  - It can epsilon transit to a node in CUR_DEST.
1600  - It is in CUR_SRC.
1601  And update state_log. */
1602  err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
1603  if (BE (err != REG_NOERROR, 0))
1604  goto free_return;
1605  }
1606  err = REG_NOERROR;
1607  free_return:
1608  re_node_set_free (&cur_dest);
1609  return err;
1610 }
1611 
1612 static reg_errcode_t
1615  int str_idx, re_node_set *cur_dest)
1616 {
1617  const re_dfa_t *const dfa = mctx->dfa;
1618  const re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes;
1619  int i;
1620 
1621  /* Then build the next sifted state.
1622  We build the next sifted state on `cur_dest', and update
1623  `sifted_states[str_idx]' with `cur_dest'.
1624  Note:
1625  `cur_dest' is the sifted state from `state_log[str_idx + 1]'.
1626  `cur_src' points the node_set of the old `state_log[str_idx]'
1627  (with the epsilon nodes pre-filtered out). */
1628  for (i = 0; i < cur_src->nelem; i++)
1629  {
1630  int prev_node = cur_src->elems[i];
1631  int naccepted = 0;
1632  int ret;
1633 
1634 #ifdef DEBUG
1637 #endif
1638 #ifdef RE_ENABLE_I18N
1639  /* If the node may accept `multi byte'. */
1640  if (dfa->nodes[prev_node].accept_mb)
1641  naccepted = sift_states_iter_mb (mctx, sctx, prev_node,
1642  str_idx, sctx->last_str_idx);
1643 #endif /* RE_ENABLE_I18N */
1644 
1645  /* We don't check backreferences here.
1646  See update_cur_sifted_state(). */
1647  if (!naccepted
1648  && check_node_accept (mctx, dfa->nodes + prev_node, str_idx)
1649  && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1],
1650  dfa->nexts[prev_node]))
1651  naccepted = 1;
1652 
1653  if (naccepted == 0)
1654  continue;
1655 
1656  if (sctx->limits.nelem)
1657  {
1658  int to_idx = str_idx + naccepted;
1659  if (check_dst_limits (mctx, &sctx->limits,
1660  dfa->nexts[prev_node], to_idx,
1661  prev_node, str_idx))
1662  continue;
1663  }
1664  ret = re_node_set_insert (cur_dest, prev_node);
1665  if (BE (ret == -1, 0))
1666  return REG_ESPACE;
1667  }
1668 
1669  return REG_NOERROR;
1670 }
1671 
1672 /* Helper functions. */
1673 
1674 static reg_errcode_t
1676 clean_state_log_if_needed (re_match_context_t *mctx, int next_state_log_idx)
1677 {
1678  int top = mctx->state_log_top;
1679 
1680  if (next_state_log_idx >= mctx->input.bufs_len
1681  || (next_state_log_idx >= mctx->input.valid_len
1682  && mctx->input.valid_len < mctx->input.len))
1683  {
1685  err = extend_buffers (mctx);
1686  if (BE (err != REG_NOERROR, 0))
1687  return err;
1688  }
1689 
1690  if (top < next_state_log_idx)
1691  {
1692  memset (mctx->state_log + top + 1, '\0',
1693  sizeof (re_dfastate_t *) * (next_state_log_idx - top));
1694  mctx->state_log_top = next_state_log_idx;
1695  }
1696  return REG_NOERROR;
1697 }
1698 
1699 static reg_errcode_t
1702  re_dfastate_t **src, int num)
1703 {
1704  int st_idx;
1706  for (st_idx = 0; st_idx < num; ++st_idx)
1707  {
1708  if (dst[st_idx] == NULL)
1709  dst[st_idx] = src[st_idx];
1710  else if (src[st_idx] != NULL)
1711  {
1712  re_node_set merged_set;
1713  err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes,
1714  &src[st_idx]->nodes);
1715  if (BE (err != REG_NOERROR, 0))
1716  return err;
1717  dst[st_idx] = re_acquire_state (&err, dfa, &merged_set);
1718  re_node_set_free (&merged_set);
1719  if (BE (err != REG_NOERROR, 0))
1720  return err;
1721  }
1722  }
1723  return REG_NOERROR;
1724 }
1725 
1726 static reg_errcode_t
1729  re_sift_context_t *sctx, int str_idx,
1730  re_node_set *dest_nodes)
1731 {
1732  const re_dfa_t *const dfa = mctx->dfa;
1734  const re_node_set *candidates;
1735  candidates = ((mctx->state_log[str_idx] == NULL) ? NULL
1736  : &mctx->state_log[str_idx]->nodes);
1737 
1738  if (dest_nodes->nelem == 0)
1739  sctx->sifted_states[str_idx] = NULL;
1740  else
1741  {
1742  if (candidates)
1743  {
1744  /* At first, add the nodes which can epsilon transit to a node in
1745  DEST_NODE. */
1746  err = add_epsilon_src_nodes (dfa, dest_nodes, candidates);
1747  if (BE (err != REG_NOERROR, 0))
1748  return err;
1749 
1750  /* Then, check the limitations in the current sift_context. */
1751  if (sctx->limits.nelem)
1752  {
1753  err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits,
1754  mctx->bkref_ents, str_idx);
1755  if (BE (err != REG_NOERROR, 0))
1756  return err;
1757  }
1758  }
1759 
1760  sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes);
1761  if (BE (err != REG_NOERROR, 0))
1762  return err;
1763  }
1764 
1765  if (candidates && mctx->state_log[str_idx]->has_backref)
1766  {
1767  err = sift_states_bkref (mctx, sctx, str_idx, candidates);
1768  if (BE (err != REG_NOERROR, 0))
1769  return err;
1770  }
1771  return REG_NOERROR;
1772 }
1773 
1774 static reg_errcode_t
1776 add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes,
1777  const re_node_set *candidates)
1778 {
1780  int i;
1781 
1782  re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes);
1783  if (BE (err != REG_NOERROR, 0))
1784  return err;
1785 
1786  if (!state->inveclosure.alloc)
1787  {
1788  err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem);
1789  if (BE (err != REG_NOERROR, 0))
1790  return REG_ESPACE;
1791  for (i = 0; i < dest_nodes->nelem; i++)
1792  re_node_set_merge (&state->inveclosure,
1793  dfa->inveclosures + dest_nodes->elems[i]);
1794  }
1795  return re_node_set_add_intersect (dest_nodes, candidates,
1796  &state->inveclosure);
1797 }
1798 
1799 static reg_errcode_t
1801 sub_epsilon_src_nodes (const re_dfa_t *dfa, int node, re_node_set *dest_nodes,
1802  const re_node_set *candidates)
1803 {
1804  int ecl_idx;
1806  re_node_set *inv_eclosure = dfa->inveclosures + node;
1807  re_node_set except_nodes;
1808  re_node_set_init_empty (&except_nodes);
1809  for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
1810  {
1811  int cur_node = inv_eclosure->elems[ecl_idx];
1812  if (cur_node == node)
1813  continue;
1814  if (IS_EPSILON_NODE (dfa->nodes[cur_node].type))
1815  {
1816  int edst1 = dfa->edests[cur_node].elems[0];
1817  int edst2 = ((dfa->edests[cur_node].nelem > 1)
1818  ? dfa->edests[cur_node].elems[1] : -1);
1819  if ((!re_node_set_contains (inv_eclosure, edst1)
1820  && re_node_set_contains (dest_nodes, edst1))
1821  || (edst2 > 0
1822  && !re_node_set_contains (inv_eclosure, edst2)
1823  && re_node_set_contains (dest_nodes, edst2)))
1824  {
1825  err = re_node_set_add_intersect (&except_nodes, candidates,
1826  dfa->inveclosures + cur_node);
1827  if (BE (err != REG_NOERROR, 0))
1828  {
1829  re_node_set_free (&except_nodes);
1830  return err;
1831  }
1832  }
1833  }
1834  }
1835  for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
1836  {
1837  int cur_node = inv_eclosure->elems[ecl_idx];
1838  if (!re_node_set_contains (&except_nodes, cur_node))
1839  {
1840  int idx = re_node_set_contains (dest_nodes, cur_node) - 1;
1841  re_node_set_remove_at (dest_nodes, idx);
1842  }
1843  }
1844  re_node_set_free (&except_nodes);
1845  return REG_NOERROR;
1846 }
1847 
1848 static int
1851  int dst_node, int dst_idx, int src_node, int src_idx)
1852 {
1853  const re_dfa_t *const dfa = mctx->dfa;
1854  int lim_idx, src_pos, dst_pos;
1855 
1856  int dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx);
1857  int src_bkref_idx = search_cur_bkref_entry (mctx, src_idx);
1858  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
1859  {
1860  int subexp_idx;
1861  struct re_backref_cache_entry *ent;
1862  ent = mctx->bkref_ents + limits->elems[lim_idx];
1863  subexp_idx = dfa->nodes[ent->node].opr.idx;
1864 
1865  dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
1866  subexp_idx, dst_node, dst_idx,
1867  dst_bkref_idx);
1868  src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
1869  subexp_idx, src_node, src_idx,
1870  src_bkref_idx);
1871 
1872  /* In case of:
1873  <src> <dst> ( <subexp> )
1874  ( <subexp> ) <src> <dst>
1875  ( <subexp1> <src> <subexp2> <dst> <subexp3> ) */
1876  if (src_pos == dst_pos)
1877  continue; /* This is unrelated limitation. */
1878  else
1879  return 1;
1880  }
1881  return 0;
1882 }
1883 
1884 static int
1887  int subexp_idx, int from_node, int bkref_idx)
1888 {
1889  const re_dfa_t *const dfa = mctx->dfa;
1890  const re_node_set *eclosures = dfa->eclosures + from_node;
1891  int node_idx;
1892 
1893  /* Else, we are on the boundary: examine the nodes on the epsilon
1894  closure. */
1895  for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx)
1896  {
1897  int node = eclosures->elems[node_idx];
1898  switch (dfa->nodes[node].type)
1899  {
1900  case OP_BACK_REF:
1901  if (bkref_idx != -1)
1902  {
1903  struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx;
1904  do
1905  {
1906  int dst, cpos;
1907 
1908  if (ent->node != node)
1909  continue;
1910 
1911  if (subexp_idx < BITSET_WORD_BITS
1912  && !(ent->eps_reachable_subexps_map
1913  & ((bitset_word_t) 1 << subexp_idx)))
1914  continue;
1915 
1916  /* Recurse trying to reach the OP_OPEN_SUBEXP and
1917  OP_CLOSE_SUBEXP cases below. But, if the
1918  destination node is the same node as the source
1919  node, don't recurse because it would cause an
1920  infinite loop: a regex that exhibits this behavior
1921  is ()\1*\1* */
1922  dst = dfa->edests[node].elems[0];
1923  if (dst == from_node)
1924  {
1925  if (boundaries & 1)
1926  return -1;
1927  else /* if (boundaries & 2) */
1928  return 0;
1929  }
1930 
1931  cpos =
1932  check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
1933  dst, bkref_idx);
1934  if (cpos == -1 /* && (boundaries & 1) */)
1935  return -1;
1936  if (cpos == 0 && (boundaries & 2))
1937  return 0;
1938 
1939  if (subexp_idx < BITSET_WORD_BITS)
1941  &= ~((bitset_word_t) 1 << subexp_idx);
1942  }
1943  while (ent++->more);
1944  }
1945  break;
1946 
1947  case OP_OPEN_SUBEXP:
1948  if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx)
1949  return -1;
1950  break;
1951 
1952  case OP_CLOSE_SUBEXP:
1953  if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx)
1954  return 0;
1955  break;
1956 
1957  default:
1958  break;
1959  }
1960  }
1961 
1962  return (boundaries & 2) ? 1 : 0;
1963 }
1964 
1965 static int
1968  int subexp_idx, int from_node, int str_idx,
1969  int bkref_idx)
1970 {
1971  struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;
1972  int boundaries;
1973 
1974  /* If we are outside the range of the subexpression, return -1 or 1. */
1975  if (str_idx < lim->subexp_from)
1976  return -1;
1977 
1978  if (lim->subexp_to < str_idx)
1979  return 1;
1980 
1981  /* If we are within the subexpression, return 0. */
1982  boundaries = (str_idx == lim->subexp_from);
1983  boundaries |= (str_idx == lim->subexp_to) << 1;
1984  if (boundaries == 0)
1985  return 0;
1986 
1987  /* Else, examine epsilon closure. */
1988  return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
1989  from_node, bkref_idx);
1990 }
1991 
1992 /* Check the limitations of sub expressions LIMITS, and remove the nodes
1993  which are against limitations from DEST_NODES. */
1994 
1995 static reg_errcode_t
1997 check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes,
1998  const re_node_set *candidates, re_node_set *limits,
1999  struct re_backref_cache_entry *bkref_ents, int str_idx)
2000 {
2002  int node_idx, lim_idx;
2003 
2004  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
2005  {
2006  int subexp_idx;
2007  struct re_backref_cache_entry *ent;
2008  ent = bkref_ents + limits->elems[lim_idx];
2009 
2010  if (str_idx <= ent->subexp_from || ent->str_idx < str_idx)
2011  continue; /* This is unrelated limitation. */
2012 
2013  subexp_idx = dfa->nodes[ent->node].opr.idx;
2014  if (ent->subexp_to == str_idx)
2015  {
2016  int ops_node = -1;
2017  int cls_node = -1;
2018  for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
2019  {
2020  int node = dest_nodes->elems[node_idx];
2022  if (type == OP_OPEN_SUBEXP
2023  && subexp_idx == dfa->nodes[node].opr.idx)
2024  ops_node = node;
2025  else if (type == OP_CLOSE_SUBEXP
2026  && subexp_idx == dfa->nodes[node].opr.idx)
2027  cls_node = node;
2028  }
2029 
2030  /* Check the limitation of the open subexpression. */
2031  /* Note that (ent->subexp_to = str_idx != ent->subexp_from). */
2032  if (ops_node >= 0)
2033  {
2034  err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes,
2035  candidates);
2036  if (BE (err != REG_NOERROR, 0))
2037  return err;
2038  }
2039 
2040  /* Check the limitation of the close subexpression. */
2041  if (cls_node >= 0)
2042  for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
2043  {
2044  int node = dest_nodes->elems[node_idx];
2045  if (!re_node_set_contains (dfa->inveclosures + node,
2046  cls_node)
2047  && !re_node_set_contains (dfa->eclosures + node,
2048  cls_node))
2049  {
2050  /* It is against this limitation.
2051  Remove it form the current sifted state. */
2052  err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
2053  candidates);
2054  if (BE (err != REG_NOERROR, 0))
2055  return err;
2056  --node_idx;
2057  }
2058  }
2059  }
2060  else /* (ent->subexp_to != str_idx) */
2061  {
2062  for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
2063  {
2064  int node = dest_nodes->elems[node_idx];
2066  if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP)
2067  {
2068  if (subexp_idx != dfa->nodes[node].opr.idx)
2069  continue;
2070  /* It is against this limitation.
2071  Remove it form the current sifted state. */
2072  err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
2073  candidates);
2074  if (BE (err != REG_NOERROR, 0))
2075  return err;
2076  }
2077  }
2078  }
2079  }
2080  return REG_NOERROR;
2081 }
2082 
2083 static reg_errcode_t
2086  int str_idx, const re_node_set *candidates)
2087 {
2088  const re_dfa_t *const dfa = mctx->dfa;
2090  int node_idx, node;
2091  re_sift_context_t local_sctx;
2092  int first_idx = search_cur_bkref_entry (mctx, str_idx);
2093 
2094  if (first_idx == -1)
2095  return REG_NOERROR;
2096 
2097  local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized. */
2098 
2099  for (node_idx = 0; node_idx < candidates->nelem; ++node_idx)
2100  {
2101  int enabled_idx;
2103  struct re_backref_cache_entry *entry;
2104  node = candidates->elems[node_idx];
2105  type = dfa->nodes[node].type;
2106  /* Avoid infinite loop for the REs like "()\1+". */
2107  if (node == sctx->last_node && str_idx == sctx->last_str_idx)
2108  continue;
2109  if (type != OP_BACK_REF)
2110  continue;
2111 
2112  entry = mctx->bkref_ents + first_idx;
2113  enabled_idx = first_idx;
2114  do
2115  {
2116  int subexp_len;
2117  int to_idx;
2118  int dst_node;
2119  int ret;
2121 
2122  if (entry->node != node)
2123  continue;
2124  subexp_len = entry->subexp_to - entry->subexp_from;
2125  to_idx = str_idx + subexp_len;
2126  dst_node = (subexp_len ? dfa->nexts[node]
2127  : dfa->edests[node].elems[0]);
2128 
2129  if (to_idx > sctx->last_str_idx
2130  || sctx->sifted_states[to_idx] == NULL
2131  || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node)
2132  || check_dst_limits (mctx, &sctx->limits, node,
2133  str_idx, dst_node, to_idx))
2134  continue;
2135 
2136  if (local_sctx.sifted_states == NULL)
2137  {
2138  local_sctx = *sctx;
2139  err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits);
2140  if (BE (err != REG_NOERROR, 0))
2141  goto free_return;
2142  }
2143  local_sctx.last_node = node;
2144  local_sctx.last_str_idx = str_idx;
2145  ret = re_node_set_insert (&local_sctx.limits, enabled_idx);
2146  if (BE (ret < 0, 0))
2147  {
2148  err = REG_ESPACE;
2149  goto free_return;
2150  }
2151  cur_state = local_sctx.sifted_states[str_idx];
2152  err = sift_states_backward (mctx, &local_sctx);
2153  if (BE (err != REG_NOERROR, 0))
2154  goto free_return;
2155  if (sctx->limited_states != NULL)
2156  {
2157  err = merge_state_array (dfa, sctx->limited_states,
2158  local_sctx.sifted_states,
2159  str_idx + 1);
2160  if (BE (err != REG_NOERROR, 0))
2161  goto free_return;
2162  }
2163  local_sctx.sifted_states[str_idx] = cur_state;
2164  re_node_set_remove (&local_sctx.limits, enabled_idx);
2165 
2166  /* mctx->bkref_ents may have changed, reload the pointer. */
2167  entry = mctx->bkref_ents + enabled_idx;
2168  }
2169  while (enabled_idx++, entry++->more);
2170  }
2171  err = REG_NOERROR;
2172  free_return:
2173  if (local_sctx.sifted_states != NULL)
2174  {
2175  re_node_set_free (&local_sctx.limits);
2176  }
2177 
2178  return err;
2179 }
2180 
2181 
2182 #ifdef RE_ENABLE_I18N
2183 static int
2185 sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx,
2186  int node_idx, int str_idx, int max_str_idx)
2187 {
2188  const re_dfa_t *const dfa = mctx->dfa;
2189  int naccepted;
2190  /* Check the node can accept `multi byte'. */
2191  naccepted = check_node_accept_bytes (dfa, node_idx, &mctx->input, str_idx);
2192  if (naccepted > 0 && str_idx + naccepted <= max_str_idx &&
2193  !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted],
2194  dfa->nexts[node_idx]))
2195  /* The node can't accept the `multi byte', or the
2196  destination was already thrown away, then the node
2197  could't accept the current input `multi byte'. */
2198  naccepted = 0;
2199  /* Otherwise, it is sure that the node could accept
2200  `naccepted' bytes input. */
2201  return naccepted;
2202 }
2203 #endif /* RE_ENABLE_I18N */
2204 
2205 ␌
2206 /* Functions for state transition. */
2207 
2208 /* Return the next state to which the current state STATE will transit by
2209  accepting the current input byte, and update STATE_LOG if necessary.
2210  If STATE can accept a multibyte char/collating element/back reference
2211  update the destination of STATE_LOG. */
2212 
2213 static re_dfastate_t *
2217 {
2218  re_dfastate_t **trtable;
2219  unsigned char ch;
2220 
2221 #ifdef RE_ENABLE_I18N
2222  /* If the current state can accept multibyte. */
2223  if (BE (state->accept_mb, 0))
2224  {
2225  *err = transit_state_mb (mctx, state);
2226  if (BE (*err != REG_NOERROR, 0))
2227  return NULL;
2228  }
2229 #endif /* RE_ENABLE_I18N */
2230 
2231  /* Then decide the next state with the single byte. */
2232 #if 0
2233  if (0)
2234  /* don't use transition table */
2235  return transit_state_sb (err, mctx, state);
2236 #endif
2237 
2238  /* Use transition table */
2239  ch = re_string_fetch_byte (&mctx->input);
2240  for (;;)
2241  {
2242  trtable = state->trtable;
2243  if (BE (trtable != NULL, 1))
2244  return trtable[ch];
2245 
2246  trtable = state->word_trtable;
2247  if (BE (trtable != NULL, 1))
2248  {
2249  unsigned int context;
2250  context
2251  = re_string_context_at (&mctx->input,
2252  re_string_cur_idx (&mctx->input) - 1,
2253  mctx->eflags);
2254  if (IS_WORD_CONTEXT (context))
2255  return trtable[ch + SBC_MAX];
2256  else
2257  return trtable[ch];
2258  }
2259 
2260  if (!build_trtable (mctx->dfa, state))
2261  {
2262  *err = REG_ESPACE;
2263  return NULL;
2264  }
2265 
2266  /* Retry, we now have a transition table. */
2267  }
2268 }
2269 
2270 /* Update the state_log if we need */
2271 re_dfastate_t *
2274  re_dfastate_t *next_state)
2275 {
2276  const re_dfa_t *const dfa = mctx->dfa;
2277  int cur_idx = re_string_cur_idx (&mctx->input);
2278 
2279  if (cur_idx > mctx->state_log_top)
2280  {
2281  mctx->state_log[cur_idx] = next_state;
2282  mctx->state_log_top = cur_idx;
2283  }
2284  else if (mctx->state_log[cur_idx] == 0)
2285  {
2286  mctx->state_log[cur_idx] = next_state;
2287  }
2288  else
2289  {
2290  re_dfastate_t *pstate;
2291  unsigned int context;
2292  re_node_set next_nodes, *log_nodes, *table_nodes = NULL;
2293  /* If (state_log[cur_idx] != 0), it implies that cur_idx is
2294  the destination of a multibyte char/collating element/
2295  back reference. Then the next state is the union set of
2296  these destinations and the results of the transition table. */
2297  pstate = mctx->state_log[cur_idx];
2298  log_nodes = pstate->entrance_nodes;
2299  if (next_state != NULL)
2300  {
2301  table_nodes = next_state->entrance_nodes;
2302  *err = re_node_set_init_union (&next_nodes, table_nodes,
2303  log_nodes);
2304  if (BE (*err != REG_NOERROR, 0))
2305  return NULL;
2306  }
2307  else
2308  next_nodes = *log_nodes;
2309  /* Note: We already add the nodes of the initial state,
2310  then we don't need to add them here. */
2311 
2313  re_string_cur_idx (&mctx->input) - 1,
2314  mctx->eflags);
2315  next_state = mctx->state_log[cur_idx]
2316  = re_acquire_state_context (err, dfa, &next_nodes, context);
2317  /* We don't need to check errors here, since the return value of
2318  this function is next_state and ERR is already set. */
2319 
2320  if (table_nodes != NULL)
2321  re_node_set_free (&next_nodes);
2322  }
2323 
2324  if (BE (dfa->nbackref, 0) && next_state != NULL)
2325  {
2326  /* Check OP_OPEN_SUBEXP in the current state in case that we use them
2327  later. We must check them here, since the back references in the
2328  next state might use them. */
2329  *err = check_subexp_matching_top (mctx, &next_state->nodes,
2330  cur_idx);
2331  if (BE (*err != REG_NOERROR, 0))
2332  return NULL;
2333 
2334  /* If the next state has back references. */
2335  if (next_state->has_backref)
2336  {
2337  *err = transit_state_bkref (mctx, &next_state->nodes);
2338  if (BE (*err != REG_NOERROR, 0))
2339  return NULL;
2340  next_state = mctx->state_log[cur_idx];
2341  }
2342  }
2343 
2344  return next_state;
2345 }
2346 
2347 /* Skip bytes in the input that correspond to part of a
2348  multi-byte match, then look in the log for a state
2349  from which to restart matching. */
2350 re_dfastate_t *
2353 {
2355  do
2356  {
2357  int max = mctx->state_log_top;
2358  int cur_str_idx = re_string_cur_idx (&mctx->input);
2359 
2360  do
2361  {
2362  if (++cur_str_idx > max)
2363  return NULL;
2364  re_string_skip_bytes (&mctx->input, 1);
2365  }
2366  while (mctx->state_log[cur_str_idx] == NULL);
2367 
2369  }
2370  while (*err == REG_NOERROR && cur_state == NULL);
2371  return cur_state;
2372 }
2373 
2374 /* Helper functions for transit_state. */
2375 
2376 /* From the node set CUR_NODES, pick up the nodes whose types are
2377  OP_OPEN_SUBEXP and which have corresponding back references in the regular
2378  expression. And register them to use them later for evaluating the
2379  correspoding back references. */
2380 
2381 static reg_errcode_t
2384  int str_idx)
2385 {
2386  const re_dfa_t *const dfa = mctx->dfa;
2387  int node_idx;
2389 
2390  /* TODO: This isn't efficient.
2391  Because there might be more than one nodes whose types are
2392  OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
2393  nodes.
2394  E.g. RE: (a){2} */
2395  for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx)
2396  {
2397  int node = cur_nodes->elems[node_idx];
2398  if (dfa->nodes[node].type == OP_OPEN_SUBEXP
2399  && dfa->nodes[node].opr.idx < BITSET_WORD_BITS
2400  && (dfa->used_bkref_map
2401  & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx)))
2402  {
2403  err = match_ctx_add_subtop (mctx, node, str_idx);
2404  if (BE (err != REG_NOERROR, 0))
2405  return err;
2406  }
2407  }
2408  return REG_NOERROR;
2409 }
2410 
2411 #if 0
2412 /* Return the next state to which the current state STATE will transit by
2413  accepting the current input byte. */
2414 
2415 static re_dfastate_t *
2416 transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx,
2418 {
2419  const re_dfa_t *const dfa = mctx->dfa;
2420  re_node_set next_nodes;
2421  re_dfastate_t *next_state;
2422  int node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input);
2423  unsigned int context;
2424 
2425  *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1);
2426  if (BE (*err != REG_NOERROR, 0))
2427  return NULL;
2428  for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt)
2429  {
2430  int cur_node = state->nodes.elems[node_cnt];
2431  if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx))
2432  {
2433  *err = re_node_set_merge (&next_nodes,
2434  dfa->eclosures + dfa->nexts[cur_node]);
2435  if (BE (*err != REG_NOERROR, 0))
2436  {
2437  re_node_set_free (&next_nodes);
2438  return NULL;
2439  }
2440  }
2441  }
2442  context = re_string_context_at (&mctx->input, cur_str_idx, mctx->eflags);
2443  next_state = re_acquire_state_context (err, dfa, &next_nodes, context);
2444  /* We don't need to check errors here, since the return value of
2445  this function is next_state and ERR is already set. */
2446 
2447  re_node_set_free (&next_nodes);
2448  re_string_skip_bytes (&mctx->input, 1);
2449  return next_state;
2450 }
2451 #endif
2452 
2453 #ifdef RE_ENABLE_I18N
2454 static reg_errcode_t
2456 transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate)
2457 {
2458  const re_dfa_t *const dfa = mctx->dfa;
2460  int i;
2461 
2462  for (i = 0; i < pstate->nodes.nelem; ++i)
2463  {
2464  re_node_set dest_nodes, *new_nodes;
2465  int cur_node_idx = pstate->nodes.elems[i];
2466  int naccepted, dest_idx;
2467  unsigned int context;
2468  re_dfastate_t *dest_state;
2469 
2470  if (!dfa->nodes[cur_node_idx].accept_mb)
2471  continue;
2472 
2473  if (dfa->nodes[cur_node_idx].constraint)
2474  {
2476  re_string_cur_idx (&mctx->input),
2477  mctx->eflags);
2478  if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint,
2479  context))
2480  continue;
2481  }
2482 
2483  /* How many bytes the node can accept? */
2484  naccepted = check_node_accept_bytes (dfa, cur_node_idx, &mctx->input,
2485  re_string_cur_idx (&mctx->input));
2486  if (naccepted == 0)
2487  continue;
2488 
2489  /* The node can accepts `naccepted' bytes. */
2490  dest_idx = re_string_cur_idx (&mctx->input) + naccepted;
2491  mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted
2492  : mctx->max_mb_elem_len);
2493  err = clean_state_log_if_needed (mctx, dest_idx);
2494  if (BE (err != REG_NOERROR, 0))
2495  return err;
2496 #ifdef DEBUG
2497  assert (dfa->nexts[cur_node_idx] != -1);
2498 #endif
2499  new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx];
2500 
2501  dest_state = mctx->state_log[dest_idx];
2502  if (dest_state == NULL)
2503  dest_nodes = *new_nodes;
2504  else
2505  {
2506  err = re_node_set_init_union (&dest_nodes,
2507  dest_state->entrance_nodes, new_nodes);
2508  if (BE (err != REG_NOERROR, 0))
2509  return err;
2510  }
2511  context = re_string_context_at (&mctx->input, dest_idx - 1,
2512  mctx->eflags);
2513  mctx->state_log[dest_idx]
2514  = re_acquire_state_context (&err, dfa, &dest_nodes, context);
2515  if (dest_state != NULL)
2516  re_node_set_free (&dest_nodes);
2517  if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0))
2518  return err;
2519  }
2520  return REG_NOERROR;
2521 }
2522 #endif /* RE_ENABLE_I18N */
2523 
2524 static reg_errcode_t
2527 {
2528  const re_dfa_t *const dfa = mctx->dfa;
2530  int i;
2531  int cur_str_idx = re_string_cur_idx (&mctx->input);
2532 
2533  for (i = 0; i < nodes->nelem; ++i)
2534  {
2535  int dest_str_idx, prev_nelem, bkc_idx;
2536  int node_idx = nodes->elems[i];
2537  unsigned int context;
2538  const re_token_t *node = dfa->nodes + node_idx;
2539  re_node_set *new_dest_nodes;
2540 
2541  /* Check whether `node' is a backreference or not. */
2542  if (node->type != OP_BACK_REF)
2543  continue;
2544 
2545  if (node->constraint)
2546  {
2547  context = re_string_context_at (&mctx->input, cur_str_idx,
2548  mctx->eflags);
2549  if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
2550  continue;
2551  }
2552 
2553  /* `node' is a backreference.
2554  Check the substring which the substring matched. */
2555  bkc_idx = mctx->nbkref_ents;
2556  err = get_subexp (mctx, node_idx, cur_str_idx);
2557  if (BE (err != REG_NOERROR, 0))
2558  goto free_return;
2559 
2560  /* And add the epsilon closures (which is `new_dest_nodes') of
2561  the backreference to appropriate state_log. */
2562 #ifdef DEBUG
2563  assert (dfa->nexts[node_idx] != -1);
2564 #endif
2565  for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx)
2566  {
2567  int subexp_len;
2568  re_dfastate_t *dest_state;
2569  struct re_backref_cache_entry *bkref_ent;
2570  bkref_ent = mctx->bkref_ents + bkc_idx;
2571  if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx)
2572  continue;
2573  subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from;
2574  new_dest_nodes = (subexp_len == 0
2575  ? dfa->eclosures + dfa->edests[node_idx].elems[0]
2576  : dfa->eclosures + dfa->nexts[node_idx]);
2577  dest_str_idx = (cur_str_idx + bkref_ent->subexp_to
2578  - bkref_ent->subexp_from);
2579  context = re_string_context_at (&mctx->input, dest_str_idx - 1,
2580  mctx->eflags);
2581  dest_state = mctx->state_log[dest_str_idx];
2582  prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0
2583  : mctx->state_log[cur_str_idx]->nodes.nelem);
2584  /* Add `new_dest_node' to state_log. */
2585  if (dest_state == NULL)
2586  {
2587  mctx->state_log[dest_str_idx]
2588  = re_acquire_state_context (&err, dfa, new_dest_nodes,
2589  context);
2590  if (BE (mctx->state_log[dest_str_idx] == NULL
2591  && err != REG_NOERROR, 0))
2592  goto free_return;
2593  }
2594  else
2595  {
2596  re_node_set dest_nodes;
2597  err = re_node_set_init_union (&dest_nodes,
2598  dest_state->entrance_nodes,
2599  new_dest_nodes);
2600  if (BE (err != REG_NOERROR, 0))
2601  {
2602  re_node_set_free (&dest_nodes);
2603  goto free_return;
2604  }
2605  mctx->state_log[dest_str_idx]
2606  = re_acquire_state_context (&err, dfa, &dest_nodes, context);
2607  re_node_set_free (&dest_nodes);
2608  if (BE (mctx->state_log[dest_str_idx] == NULL
2609  && err != REG_NOERROR, 0))
2610  goto free_return;
2611  }
2612  /* We need to check recursively if the backreference can epsilon
2613  transit. */
2614  if (subexp_len == 0
2615  && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem)
2616  {
2617  err = check_subexp_matching_top (mctx, new_dest_nodes,
2618  cur_str_idx);
2619  if (BE (err != REG_NOERROR, 0))
2620  goto free_return;
2621  err = transit_state_bkref (mctx, new_dest_nodes);
2622  if (BE (err != REG_NOERROR, 0))
2623  goto free_return;
2624  }
2625  }
2626  }
2627  err = REG_NOERROR;
2628  free_return:
2629  return err;
2630 }
2631 
2632 /* Enumerate all the candidates which the backreference BKREF_NODE can match
2633  at BKREF_STR_IDX, and register them by match_ctx_add_entry().
2634  Note that we might collect inappropriate candidates here.
2635  However, the cost of checking them strictly here is too high, then we
2636  delay these checking for prune_impossible_nodes(). */
2637 
2638 static reg_errcode_t
2640 get_subexp (re_match_context_t *mctx, int bkref_node, int bkref_str_idx)
2641 {
2642  const re_dfa_t *const dfa = mctx->dfa;
2643  int subexp_num, sub_top_idx;
2644  const char *buf = (const char *) re_string_get_buffer (&mctx->input);
2645  /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX. */
2646  int cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx);
2647  if (cache_idx != -1)
2648  {
2649  const struct re_backref_cache_entry *entry
2650  = mctx->bkref_ents + cache_idx;
2651  do
2652  if (entry->node == bkref_node)
2653  return REG_NOERROR; /* We already checked it. */
2654  while (entry++->more);
2655  }
2656 
2657  subexp_num = dfa->nodes[bkref_node].opr.idx;
2658 
2659  /* For each sub expression */
2660  for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx)
2661  {
2663  re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx];
2664  re_sub_match_last_t *sub_last;
2665  int sub_last_idx, sl_str, bkref_str_off;
2666 
2667  if (dfa->nodes[sub_top->node].opr.idx != subexp_num)
2668  continue; /* It isn't related. */
2669 
2670  sl_str = sub_top->str_idx;
2671  bkref_str_off = bkref_str_idx;
2672  /* At first, check the last node of sub expressions we already
2673  evaluated. */
2674  for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx)
2675  {
2676  int sl_str_diff;
2677  sub_last = sub_top->lasts[sub_last_idx];
2678  sl_str_diff = sub_last->str_idx - sl_str;
2679  /* The matched string by the sub expression match with the substring
2680  at the back reference? */
2681  if (sl_str_diff > 0)
2682  {
2683  if (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0))
2684  {
2685  /* Not enough chars for a successful match. */
2686  if (bkref_str_off + sl_str_diff > mctx->input.len)
2687  break;
2688 
2690  bkref_str_off
2691  + sl_str_diff);
2692  if (BE (err != REG_NOERROR, 0))
2693  return err;
2694  buf = (const char *) re_string_get_buffer (&mctx->input);
2695  }
2696  if (memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0)
2697  /* We don't need to search this sub expression any more. */
2698  break;
2699  }
2700  bkref_str_off += sl_str_diff;
2701  sl_str += sl_str_diff;
2702  err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
2703  bkref_str_idx);
2704 
2705  /* Reload buf, since the preceding call might have reallocated
2706  the buffer. */
2707  buf = (const char *) re_string_get_buffer (&mctx->input);
2708 
2709  if (err == REG_NOMATCH)
2710  continue;
2711  if (BE (err != REG_NOERROR, 0))
2712  return err;
2713  }
2714 
2715  if (sub_last_idx < sub_top->nlasts)
2716  continue;
2717  if (sub_last_idx > 0)
2718  ++sl_str;
2719  /* Then, search for the other last nodes of the sub expression. */
2720  for (; sl_str <= bkref_str_idx; ++sl_str)
2721  {
2722  int cls_node, sl_str_off;
2723  const re_node_set *nodes;
2724  sl_str_off = sl_str - sub_top->str_idx;
2725  /* The matched string by the sub expression match with the substring
2726  at the back reference? */
2727  if (sl_str_off > 0)
2728  {
2729  if (BE (bkref_str_off >= mctx->input.valid_len, 0))
2730  {
2731  /* If we are at the end of the input, we cannot match. */
2732  if (bkref_str_off >= mctx->input.len)
2733  break;
2734 
2735  err = extend_buffers (mctx);
2736  if (BE (err != REG_NOERROR, 0))
2737  return err;
2738 
2739  buf = (const char *) re_string_get_buffer (&mctx->input);
2740  }
2741  if (buf [bkref_str_off++] != buf[sl_str - 1])
2742  break; /* We don't need to search this sub expression
2743  any more. */
2744  }
2745  if (mctx->state_log[sl_str] == NULL)
2746  continue;
2747  /* Does this state have a ')' of the sub expression? */
2748  nodes = &mctx->state_log[sl_str]->nodes;
2749  cls_node = find_subexp_node (dfa, nodes, subexp_num,
2750  OP_CLOSE_SUBEXP);
2751  if (cls_node == -1)
2752  continue; /* No. */
2753  if (sub_top->path == NULL)
2754  {
2755  sub_top->path = calloc (sizeof (state_array_t),
2756  sl_str - sub_top->str_idx + 1);
2757  if (sub_top->path == NULL)
2758  return REG_ESPACE;
2759  }
2760  /* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node
2761  in the current context? */
2762  err = check_arrival (mctx, sub_top->path, sub_top->node,
2763  sub_top->str_idx, cls_node, sl_str,
2764  OP_CLOSE_SUBEXP);
2765  if (err == REG_NOMATCH)
2766  continue;
2767  if (BE (err != REG_NOERROR, 0))
2768  return err;
2769  sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str);
2770  if (BE (sub_last == NULL, 0))
2771  return REG_ESPACE;
2772  err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
2773  bkref_str_idx);
2774  if (err == REG_NOMATCH)
2775  continue;
2776  }
2777  }
2778  return REG_NOERROR;
2779 }
2780 
2781 /* Helper functions for get_subexp(). */
2782 
2783 /* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR.
2784  If it can arrive, register the sub expression expressed with SUB_TOP
2785  and SUB_LAST. */
2786 
2787 static reg_errcode_t
2790  re_sub_match_last_t *sub_last, int bkref_node, int bkref_str)
2791 {
2793  int to_idx;
2794  /* Can the subexpression arrive the back reference? */
2795  err = check_arrival (mctx, &sub_last->path, sub_last->node,
2796  sub_last->str_idx, bkref_node, bkref_str,
2797  OP_OPEN_SUBEXP);
2798  if (err != REG_NOERROR)
2799  return err;
2800  err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx,
2801  sub_last->str_idx);
2802  if (BE (err != REG_NOERROR, 0))
2803  return err;
2804  to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx;
2805  return clean_state_log_if_needed (mctx, to_idx);
2806 }
2807 
2808 /* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX.
2809  Search '(' if FL_OPEN, or search ')' otherwise.
2810  TODO: This function isn't efficient...
2811  Because there might be more than one nodes whose types are
2812  OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
2813  nodes.
2814  E.g. RE: (a){2} */
2815 
2816 static int
2818 find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
2819  int subexp_idx, int type)
2820 {
2821  int cls_idx;
2822  for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx)
2823  {
2824  int cls_node = nodes->elems[cls_idx];
2825  const re_token_t *node = dfa->nodes + cls_node;
2826  if (node->type == type
2827  && node->opr.idx == subexp_idx)
2828  return cls_node;
2829  }
2830  return -1;
2831 }
2832 
2833 /* Check whether the node TOP_NODE at TOP_STR can arrive to the node
2834  LAST_NODE at LAST_STR. We record the path onto PATH since it will be
2835  heavily reused.
2836  Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */
2837 
2838 static reg_errcode_t
2841  int top_str, int last_node, int last_str, int type)
2842 {
2843  const re_dfa_t *const dfa = mctx->dfa;
2845  int subexp_num, backup_cur_idx, str_idx, null_cnt;
2847  re_node_set *cur_nodes, next_nodes;
2848  re_dfastate_t **backup_state_log;
2849  unsigned int context;
2850 
2851  subexp_num = dfa->nodes[top_node].opr.idx;
2852  /* Extend the buffer if we need. */
2853  if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0))
2854  {
2856  int old_alloc = path->alloc;
2857  path->alloc += last_str + mctx->max_mb_elem_len + 1;
2858  new_array = re_realloc (path->array, re_dfastate_t *, path->alloc);
2859  if (BE (new_array == NULL, 0))
2860  {
2861  path->alloc = old_alloc;
2862  return REG_ESPACE;
2863  }
2864  path->array = new_array;
2865  memset (new_array + old_alloc, '\0',
2866  sizeof (re_dfastate_t *) * (path->alloc - old_alloc));
2867  }
2868 
2869 #ifdef _MSC_VER
2870  str_idx = path->next_idx ? path->next_idx : top_str;
2871 #else
2872  str_idx = path->next_idx ?: top_str;
2873 #endif
2874 
2875  /* Temporary modify MCTX. */
2876  backup_state_log = mctx->state_log;
2877  backup_cur_idx = mctx->input.cur_idx;
2878  mctx->state_log = path->array;
2879  mctx->input.cur_idx = str_idx;
2880 
2881  /* Setup initial node set. */
2882  context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);
2883  if (str_idx == top_str)
2884  {
2885  err = re_node_set_init_1 (&next_nodes, top_node);
2886  if (BE (err != REG_NOERROR, 0))
2887  return err;
2888  err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
2889  if (BE (err != REG_NOERROR, 0))
2890  {
2891  re_node_set_free (&next_nodes);
2892  return err;
2893  }
2894  }
2895  else
2896  {
2897  cur_state = mctx->state_log[str_idx];
2898  if (cur_state && cur_state->has_backref)
2899  {
2900  err = re_node_set_init_copy (&next_nodes, &cur_state->nodes);
2901  if (BE (err != REG_NOERROR, 0))
2902  return err;
2903  }
2904  else
2905  re_node_set_init_empty (&next_nodes);
2906  }
2907  if (str_idx == top_str || (cur_state && cur_state->has_backref))
2908  {
2909  if (next_nodes.nelem)
2910  {
2911  err = expand_bkref_cache (mctx, &next_nodes, str_idx,
2912  subexp_num, type);
2913  if (BE (err != REG_NOERROR, 0))
2914  {
2915  re_node_set_free (&next_nodes);
2916  return err;
2917  }
2918  }
2919  cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
2920  if (BE (cur_state == NULL && err != REG_NOERROR, 0))
2921  {
2922  re_node_set_free (&next_nodes);
2923  return err;
2924  }
2925  mctx->state_log[str_idx] = cur_state;
2926  }
2927 
2928  for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;)
2929  {
2930  re_node_set_empty (&next_nodes);
2931  if (mctx->state_log[str_idx + 1])
2932  {
2933  err = re_node_set_merge (&next_nodes,
2934  &mctx->state_log[str_idx + 1]->nodes);
2935  if (BE (err != REG_NOERROR, 0))
2936  {
2937  re_node_set_free (&next_nodes);
2938  return err;
2939  }
2940  }
2941  if (cur_state)
2942  {
2944  &cur_state->non_eps_nodes,
2945  &next_nodes);
2946  if (BE (err != REG_NOERROR, 0))
2947  {
2948  re_node_set_free (&next_nodes);
2949  return err;
2950  }
2951  }
2952  ++str_idx;
2953  if (next_nodes.nelem)
2954  {
2955  err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
2956  if (BE (err != REG_NOERROR, 0))
2957  {
2958  re_node_set_free (&next_nodes);
2959  return err;
2960  }
2961  err = expand_bkref_cache (mctx, &next_nodes, str_idx,
2962  subexp_num, type);
2963  if (BE (err != REG_NOERROR, 0))
2964  {
2965  re_node_set_free (&next_nodes);
2966  return err;
2967  }
2968  }
2969  context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);
2970  cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
2971  if (BE (cur_state == NULL && err != REG_NOERROR, 0))
2972  {
2973  re_node_set_free (&next_nodes);
2974  return err;
2975  }
2976  mctx->state_log[str_idx] = cur_state;
2977  null_cnt = cur_state == NULL ? null_cnt + 1 : 0;
2978  }
2979  re_node_set_free (&next_nodes);
2980  cur_nodes = (mctx->state_log[last_str] == NULL ? NULL
2981  : &mctx->state_log[last_str]->nodes);
2982  path->next_idx = str_idx;
2983 
2984  /* Fix MCTX. */
2985  mctx->state_log = backup_state_log;
2986  mctx->input.cur_idx = backup_cur_idx;
2987 
2988  /* Then check the current node set has the node LAST_NODE. */
2989  if (cur_nodes != NULL && re_node_set_contains (cur_nodes, last_node))
2990  return REG_NOERROR;
2991 
2992  return REG_NOMATCH;
2993 }
2994 
2995 /* Helper functions for check_arrival. */
2996 
2997 /* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them
2998  to NEXT_NODES.
2999  TODO: This function is similar to the functions transit_state*(),
3000  however this function has many additional works.
3001  Can't we unify them? */
3002 
3003 static reg_errcode_t
3006  re_node_set *cur_nodes, re_node_set *next_nodes)
3007 {
3008  const re_dfa_t *const dfa = mctx->dfa;
3009  int result;
3010  int cur_idx;
3011 #ifdef RE_ENABLE_I18N
3013 #endif
3014  re_node_set union_set;
3015  re_node_set_init_empty (&union_set);
3016  for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx)
3017  {
3018  int naccepted = 0;
3019  int cur_node = cur_nodes->elems[cur_idx];
3020 #ifdef DEBUG
3021  re_token_type_t type = dfa->nodes[cur_node].type;
3023 #endif
3024 #ifdef RE_ENABLE_I18N
3025  /* If the node may accept `multi byte'. */
3026  if (dfa->nodes[cur_node].accept_mb)
3027  {
3028  naccepted = check_node_accept_bytes (dfa, cur_node, &mctx->input,
3029  str_idx);
3030  if (naccepted > 1)
3031  {
3032  re_dfastate_t *dest_state;
3033  int next_node = dfa->nexts[cur_node];
3034  int next_idx = str_idx + naccepted;
3035  dest_state = mctx->state_log[next_idx];
3036  re_node_set_empty (&union_set);
3037  if (dest_state)
3038  {
3039  err = re_node_set_merge (&union_set, &dest_state->nodes);
3040  if (BE (err != REG_NOERROR, 0))
3041  {
3042  re_node_set_free (&union_set);
3043  return err;
3044  }
3045  }
3046  result = re_node_set_insert (&union_set, next_node);
3047  if (BE (result < 0, 0))
3048  {
3049  re_node_set_free (&union_set);
3050  return REG_ESPACE;
3051  }
3052  mctx->state_log[next_idx] = re_acquire_state (&err, dfa,
3053  &union_set);
3054  if (BE (mctx->state_log[next_idx] == NULL
3055  && err != REG_NOERROR, 0))
3056  {
3057  re_node_set_free (&union_set);
3058  return err;
3059  }
3060  }
3061  }
3062 #endif /* RE_ENABLE_I18N */
3063  if (naccepted
3064  || check_node_accept (mctx, dfa->nodes + cur_node, str_idx))
3065  {
3066  result = re_node_set_insert (next_nodes, dfa->nexts[cur_node]);
3067  if (BE (result < 0, 0))
3068  {
3069  re_node_set_free (&union_set);
3070  return REG_ESPACE;
3071  }
3072  }
3073  }
3074  re_node_set_free (&union_set);
3075  return REG_NOERROR;
3076 }
3077 
3078 /* For all the nodes in CUR_NODES, add the epsilon closures of them to
3079  CUR_NODES, however exclude the nodes which are:
3080  - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN.
3081  - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN.
3082 */
3083 
3084 static reg_errcode_t
3087  int ex_subexp, int type)
3088 {
3090  int idx, outside_node;
3091  re_node_set new_nodes;
3092 #ifdef DEBUG
3093  assert (cur_nodes->nelem);
3094 #endif
3095  err = re_node_set_alloc (&new_nodes, cur_nodes->nelem);
3096  if (BE (err != REG_NOERROR, 0))
3097  return err;
3098  /* Create a new node set NEW_NODES with the nodes which are epsilon
3099  closures of the node in CUR_NODES. */
3100 
3101  for (idx = 0; idx < cur_nodes->nelem; ++idx)
3102  {
3103  int cur_node = cur_nodes->elems[idx];
3104  const re_node_set *eclosure = dfa->eclosures + cur_node;
3105  outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type);
3106  if (outside_node == -1)
3107  {
3108  /* There are no problematic nodes, just merge them. */
3109  err = re_node_set_merge (&new_nodes, eclosure);
3110  if (BE (err != REG_NOERROR, 0))
3111  {
3112  re_node_set_free (&new_nodes);
3113  return err;
3114  }
3115  }
3116  else
3117  {
3118  /* There are problematic nodes, re-calculate incrementally. */
3119  err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node,
3120  ex_subexp, type);
3121  if (BE (err != REG_NOERROR, 0))
3122  {
3123  re_node_set_free (&new_nodes);
3124  return err;
3125  }
3126  }
3127  }
3128  re_node_set_free (cur_nodes);
3129  *cur_nodes = new_nodes;
3130  return REG_NOERROR;
3131 }
3132 
3133 /* Helper function for check_arrival_expand_ecl.
3134  Check incrementally the epsilon closure of TARGET, and if it isn't
3135  problematic append it to DST_NODES. */
3136 
3137 static reg_errcode_t
3140  int target, int ex_subexp, int type)
3141 {
3142  int cur_node;
3143  for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);)
3144  {
3145  int err;
3146 
3147  if (dfa->nodes[cur_node].type == type
3148  && dfa->nodes[cur_node].opr.idx == ex_subexp)
3149  {
3150  if (type == OP_CLOSE_SUBEXP)
3151  {
3152  err = re_node_set_insert (dst_nodes, cur_node);
3153  if (BE (err == -1, 0))
3154  return REG_ESPACE;
3155  }
3156  break;
3157  }
3158  err = re_node_set_insert (dst_nodes, cur_node);
3159  if (BE (err == -1, 0))
3160  return REG_ESPACE;
3161  if (dfa->edests[cur_node].nelem == 0)
3162  break;
3163  if (dfa->edests[cur_node].nelem == 2)
3164  {
3165  err = check_arrival_expand_ecl_sub (dfa, dst_nodes,
3166  dfa->edests[cur_node].elems[1],
3167  ex_subexp, type);
3168  if (BE (err != REG_NOERROR, 0))
3169  return err;
3170  }
3171  cur_node = dfa->edests[cur_node].elems[0];
3172  }
3173  return REG_NOERROR;
3174 }
3175 
3176 
3177 /* For all the back references in the current state, calculate the
3178  destination of the back references by the appropriate entry
3179  in MCTX->BKREF_ENTS. */
3180 
3181 static reg_errcode_t
3184  int cur_str, int subexp_num, int type)
3185 {
3186  const re_dfa_t *const dfa = mctx->dfa;
3188  int cache_idx_start = search_cur_bkref_entry (mctx, cur_str);
3189  struct re_backref_cache_entry *ent;
3190 
3191  if (cache_idx_start == -1)
3192  return REG_NOERROR;
3193 
3194  restart:
3195  ent = mctx->bkref_ents + cache_idx_start;
3196  do
3197  {
3198  int to_idx, next_node;
3199 
3200  /* Is this entry ENT is appropriate? */
3201  if (!re_node_set_contains (cur_nodes, ent->node))
3202  continue; /* No. */
3203 
3204  to_idx = cur_str + ent->subexp_to - ent->subexp_from;
3205  /* Calculate the destination of the back reference, and append it
3206  to MCTX->STATE_LOG. */
3207  if (to_idx == cur_str)
3208  {
3209  /* The backreference did epsilon transit, we must re-check all the
3210  node in the current state. */
3211  re_node_set new_dests;
3212  reg_errcode_t err2, err3;
3213  next_node = dfa->edests[ent->node].elems[0];
3214  if (re_node_set_contains (cur_nodes, next_node))
3215  continue;
3216  err = re_node_set_init_1 (&new_dests, next_node);
3217  err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num, type);
3218  err3 = re_node_set_merge (cur_nodes, &new_dests);
3219  re_node_set_free (&new_dests);
3220  if (BE (err != REG_NOERROR || err2 != REG_NOERROR
3221  || err3 != REG_NOERROR, 0))
3222  {
3223  err = (err != REG_NOERROR ? err
3224  : (err2 != REG_NOERROR ? err2 : err3));
3225  return err;
3226  }
3227  /* TODO: It is still inefficient... */
3228  goto restart;
3229  }
3230  else
3231  {
3232  re_node_set union_set;
3233  next_node = dfa->nexts[ent->node];
3234  if (mctx->state_log[to_idx])
3235  {
3236  int ret;
3237  if (re_node_set_contains (&mctx->state_log[to_idx]->nodes,
3238  next_node))
3239  continue;
3240  err = re_node_set_init_copy (&union_set,
3241  &mctx->state_log[to_idx]->nodes);
3242  ret = re_node_set_insert (&union_set, next_node);
3243  if (BE (err != REG_NOERROR || ret < 0, 0))
3244  {
3245  re_node_set_free (&union_set);
3246  err = err != REG_NOERROR ? err : REG_ESPACE;
3247  return err;
3248  }
3249  }
3250  else
3251  {
3252  err = re_node_set_init_1 (&union_set, next_node);
3253  if (BE (err != REG_NOERROR, 0))
3254  return err;
3255  }
3256  mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set);
3257  re_node_set_free (&union_set);
3258  if (BE (mctx->state_log[to_idx] == NULL
3259  && err != REG_NOERROR, 0))
3260  return err;
3261  }
3262  }
3263  while (ent++->more);
3264  return REG_NOERROR;
3265 }
3266 
3267 /* Build transition table for the state.
3268  Return 1 if succeeded, otherwise return NULL. */
3269 
3270 static int
3273 {
3275  int i, j, ch, need_word_trtable = 0;
3276  bitset_word_t elem, mask;
3277  bool dests_node_malloced = false;
3278  bool dest_states_malloced = false;
3279  int ndests; /* Number of the destination states from `state'. */
3280  re_dfastate_t **trtable;
3281  re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl;
3282  re_node_set follows, *dests_node;
3283  bitset_t *dests_ch;
3284  bitset_t acceptable;
3285 
3286  struct dests_alloc
3287  {
3288  re_node_set dests_node[SBC_MAX];
3289  bitset_t dests_ch[SBC_MAX];
3290  } *dests_alloc;
3291 
3292  /* We build DFA states which corresponds to the destination nodes
3293  from `state'. `dests_node[i]' represents the nodes which i-th
3294  destination state contains, and `dests_ch[i]' represents the
3295  characters which i-th destination state accepts. */
3296  if (__libc_use_alloca (sizeof (struct dests_alloc)))
3297  dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc));
3298  else
3299  {
3300  dests_alloc = re_malloc (struct dests_alloc, 1);
3301  if (BE (dests_alloc == NULL, 0))
3302  return 0;
3303  dests_node_malloced = true;
3304  }
3305  dests_node = dests_alloc->dests_node;
3306  dests_ch = dests_alloc->dests_ch;
3307 
3308  /* Initialize transiton table. */
3309  state->word_trtable = state->trtable = NULL;
3310 
3311  /* At first, group all nodes belonging to `state' into several
3312  destinations. */
3313  ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch);
3314  if (BE (ndests <= 0, 0))
3315  {
3316  if (dests_node_malloced)
3317  free (dests_alloc);
3318  /* Return 0 in case of an error, 1 otherwise. */
3319  if (ndests == 0)
3320  {
3321  state->trtable = (re_dfastate_t **)
3322  calloc (sizeof (re_dfastate_t *), SBC_MAX);
3323  return 1;
3324  }
3325  return 0;
3326  }
3327 
3328  err = re_node_set_alloc (&follows, ndests + 1);
3329  if (BE (err != REG_NOERROR, 0))
3330  goto out_free;
3331 
3332  if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX
3333  + ndests * 3 * sizeof (re_dfastate_t *)))
3334  dest_states = (re_dfastate_t **)
3335  alloca (ndests * 3 * sizeof (re_dfastate_t *));
3336  else
3337  {
3338  dest_states = (re_dfastate_t **)
3339  malloc (ndests * 3 * sizeof (re_dfastate_t *));
3340  if (BE (dest_states == NULL, 0))
3341  {
3342 out_free:
3343  if (dest_states_malloced)
3344  free (dest_states);
3345  re_node_set_free (&follows);
3346  for (i = 0; i < ndests; ++i)
3347  re_node_set_free (dests_node + i);
3348  if (dests_node_malloced)
3349  free (dests_alloc);
3350  return 0;
3351  }
3352  dest_states_malloced = true;
3353  }
3354  dest_states_word = dest_states + ndests;
3355  dest_states_nl = dest_states_word + ndests;
3356  bitset_empty (acceptable);
3357 
3358  /* Then build the states for all destinations. */
3359  for (i = 0; i < ndests; ++i)
3360  {
3361  int next_node;
3362  re_node_set_empty (&follows);
3363  /* Merge the follows of this destination states. */
3364  for (j = 0; j < dests_node[i].nelem; ++j)
3365  {
3366  next_node = dfa->nexts[dests_node[i].elems[j]];
3367  if (next_node != -1)
3368  {
3369  err = re_node_set_merge (&follows, dfa->eclosures + next_node);
3370  if (BE (err != REG_NOERROR, 0))
3371  goto out_free;
3372  }
3373  }
3374  dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0);
3375  if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0))
3376  goto out_free;
3377  /* If the new state has context constraint,
3378  build appropriate states for these contexts. */
3379  if (dest_states[i]->has_constraint)
3380  {
3381  dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows,
3382  CONTEXT_WORD);
3383  if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
3384  goto out_free;
3385 
3386  if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
3387  need_word_trtable = 1;
3388 
3389  dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
3390  CONTEXT_NEWLINE);
3391  if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0))
3392  goto out_free;
3393  }
3394  else
3395  {
3396  dest_states_word[i] = dest_states[i];
3397  dest_states_nl[i] = dest_states[i];
3398  }
3399  bitset_merge (acceptable, dests_ch[i]);
3400  }
3401 
3402  if (!BE (need_word_trtable, 0))
3403  {
3404  /* We don't care about whether the following character is a word
3405  character, or we are in a single-byte character set so we can
3406  discern by looking at the character code: allocate a
3407  256-entry transition table. */
3408  trtable = state->trtable =
3409  (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
3410  if (BE (trtable == NULL, 0))
3411  goto out_free;
3412 
3413  /* For all characters ch...: */
3414  for (i = 0; i < BITSET_WORDS; ++i)
3415  for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
3416  elem;
3417  mask <<= 1, elem >>= 1, ++ch)
3418  if (BE (elem & 1, 0))
3419  {
3420  /* There must be exactly one destination which accepts
3421  character ch. See group_nodes_into_DFAstates. */
3422  for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
3423  ;
3424 
3425  /* j-th destination accepts the word character ch. */
3426  if (dfa->word_char[i] & mask)
3427  trtable[ch] = dest_states_word[j];
3428  else
3429  trtable[ch] = dest_states[j];
3430  }
3431  }
3432  else
3433  {
3434  /* We care about whether the following character is a word
3435  character, and we are in a multi-byte character set: discern
3436  by looking at the character code: build two 256-entry
3437  transition tables, one starting at trtable[0] and one
3438  starting at trtable[SBC_MAX]. */
3439  trtable = state->word_trtable =
3440  (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX);
3441  if (BE (trtable == NULL, 0))
3442  goto out_free;
3443 
3444  /* For all characters ch...: */
3445  for (i = 0; i < BITSET_WORDS; ++i)
3446  for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
3447  elem;
3448  mask <<= 1, elem >>= 1, ++ch)
3449  if (BE (elem & 1, 0))
3450  {
3451  /* There must be exactly one destination which accepts
3452  character ch. See group_nodes_into_DFAstates. */
3453  for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
3454  ;
3455 
3456  /* j-th destination accepts the word character ch. */
3457  trtable[ch] = dest_states[j];
3458  trtable[ch + SBC_MAX] = dest_states_word[j];
3459  }
3460  }
3461 
3462  /* new line */
3463  if (bitset_contain (acceptable, NEWLINE_CHAR))
3464  {
3465  /* The current state accepts newline character. */
3466  for (j = 0; j < ndests; ++j)
3467  if (bitset_contain (dests_ch[j], NEWLINE_CHAR))
3468  {
3469  /* k-th destination accepts newline character. */
3470  trtable[NEWLINE_CHAR] = dest_states_nl[j];
3471  if (need_word_trtable)
3472  trtable[NEWLINE_CHAR + SBC_MAX] = dest_states_nl[j];
3473  /* There must be only one destination which accepts
3474  newline. See group_nodes_into_DFAstates. */
3475  break;
3476  }
3477  }
3478 
3479  if (dest_states_malloced)
3480  free (dest_states);
3481 
3482  re_node_set_free (&follows);
3483  for (i = 0; i < ndests; ++i)
3484  re_node_set_free (dests_node + i);
3485 
3486  if (dests_node_malloced)
3487  free (dests_alloc);
3488 
3489  return 1;
3490 }
3491 
3492 /* Group all nodes belonging to STATE into several destinations.
3493  Then for all destinations, set the nodes belonging to the destination
3494  to DESTS_NODE[i] and set the characters accepted by the destination
3495  to DEST_CH[i]. This function return the number of destinations. */
3496 
3497 static int
3500  re_node_set *dests_node, bitset_t *dests_ch)
3501 {
3503  int result;
3504  int i, j, k;
3505  int ndests; /* Number of the destinations from `state'. */
3506  bitset_t accepts; /* Characters a node can accept. */
3507  const re_node_set *cur_nodes = &state->nodes;
3508  bitset_empty (accepts);
3509  ndests = 0;
3510 
3511  /* For all the nodes belonging to `state', */
3512  for (i = 0; i < cur_nodes->nelem; ++i)
3513  {
3514  re_token_t *node = &dfa->nodes[cur_nodes->elems[i]];
3515  re_token_type_t type = node->type;
3516  unsigned int constraint = node->constraint;
3517 
3518  /* Enumerate all single byte character this node can accept. */
3519  if (type == CHARACTER)
3520  bitset_set (accepts, node->opr.c);
3521  else if (type == SIMPLE_BRACKET)
3522  {
3523  bitset_merge (accepts, node->opr.sbcset);
3524  }
3525  else if (type == OP_PERIOD)
3526  {
3527 #ifdef RE_ENABLE_I18N
3528  if (dfa->mb_cur_max > 1)
3529  bitset_merge (accepts, dfa->sb_char);
3530  else
3531 #endif
3532  bitset_set_all (accepts);
3533  if (!(dfa->syntax & RE_DOT_NEWLINE))
3534  bitset_clear (accepts, '\n');
3535  if (dfa->syntax & RE_DOT_NOT_NULL)
3536  bitset_clear (accepts, '\0');
3537  }
3538 #ifdef RE_ENABLE_I18N
3539  else if (type == OP_UTF8_PERIOD)
3540  {
3541  memset (accepts, '\xff', sizeof (bitset_t) / 2);
3542  if (!(dfa->syntax & RE_DOT_NEWLINE))
3543  bitset_clear (accepts, '\n');
3544  if (dfa->syntax & RE_DOT_NOT_NULL)
3545  bitset_clear (accepts, '\0');
3546  }
3547 #endif
3548  else
3549  continue;
3550 
3551  /* Check the `accepts' and sift the characters which are not
3552  match it the context. */
3553  if (constraint)
3554  {
3556  {
3557  bool accepts_newline = bitset_contain (accepts, NEWLINE_CHAR);
3558  bitset_empty (accepts);
3559  if (accepts_newline)
3560  bitset_set (accepts, NEWLINE_CHAR);
3561  else
3562  continue;
3563  }
3565  {
3566  bitset_empty (accepts);
3567  continue;
3568  }
3569 
3571  {
3572  bitset_word_t any_set = 0;
3573  if (type == CHARACTER && !node->word_char)
3574  {
3575  bitset_empty (accepts);
3576  continue;
3577  }
3578 #ifdef RE_ENABLE_I18N
3579  if (dfa->mb_cur_max > 1)
3580  for (j = 0; j < BITSET_WORDS; ++j)
3581  any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));
3582  else
3583 #endif
3584  for (j = 0; j < BITSET_WORDS; ++j)
3585  any_set |= (accepts[j] &= dfa->word_char[j]);
3586  if (!any_set)
3587  continue;
3588  }
3590  {
3591  bitset_word_t any_set = 0;
3592  if (type == CHARACTER && node->word_char)
3593  {
3594  bitset_empty (accepts);
3595  continue;
3596  }
3597 #ifdef RE_ENABLE_I18N
3598  if (dfa->mb_cur_max > 1)
3599  for (j = 0; j < BITSET_WORDS; ++j)
3600  any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));
3601  else
3602 #endif
3603  for (j = 0; j < BITSET_WORDS; ++j)
3604  any_set |= (accepts[j] &= ~dfa->word_char[j]);
3605  if (!any_set)
3606  continue;
3607  }
3608  }
3609 
3610  /* Then divide `accepts' into DFA states, or create a new
3611  state. Above, we make sure that accepts is not empty. */
3612  for (j = 0; j < ndests; ++j)
3613  {
3614  bitset_t intersec; /* Intersection sets, see below. */
3615  bitset_t remains;
3616  /* Flags, see below. */
3617  bitset_word_t has_intersec, not_subset, not_consumed;
3618 
3619  /* Optimization, skip if this state doesn't accept the character. */
3620  if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c))
3621  continue;
3622 
3623  /* Enumerate the intersection set of this state and `accepts'. */
3624  has_intersec = 0;
3625  for (k = 0; k < BITSET_WORDS; ++k)
3626  has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k];
3627  /* And skip if the intersection set is empty. */
3628  if (!has_intersec)
3629  continue;
3630 
3631  /* Then check if this state is a subset of `accepts'. */
3632  not_subset = not_consumed = 0;
3633  for (k = 0; k < BITSET_WORDS; ++k)
3634  {
3635  not_subset |= remains[k] = ~~accepts[k] & dests_ch[j][k];
3636  not_consumed |= accepts[k] = accepts[k] & ~~dests_ch[j][k];
3637  }
3638 
3639  /* If this state isn't a subset of `accepts', create a
3640  new group state, which has the `remains'. */
3641  if (not_subset)
3642  {
3643  bitset_copy (dests_ch[ndests], remains);
3644  bitset_copy (dests_ch[j], intersec);
3645  err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]);
3646  if (BE (err != REG_NOERROR, 0))
3647  goto error_return;
3648  ++ndests;
3649  }
3650 
3651  /* Put the position in the current group. */
3652  result = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
3653  if (BE (result < 0, 0))
3654  goto error_return;
3655 
3656  /* If all characters are consumed, go to next node. */
3657  if (!not_consumed)
3658  break;
3659  }
3660  /* Some characters remain, create a new group. */
3661  if (j == ndests)
3662  {
3663  bitset_copy (dests_ch[ndests], accepts);
3664  err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]);
3665  if (BE (err != REG_NOERROR, 0))
3666  goto error_return;
3667  ++ndests;
3668  bitset_empty (accepts);
3669  }
3670  }
3671  return ndests;
3672  error_return:
3673  for (j = 0; j < ndests; ++j)
3674  re_node_set_free (dests_node + j);
3675  return -1;
3676 }
3677 
3678 #ifdef RE_ENABLE_I18N
3679 /* Check how many bytes the node `dfa->nodes[node_idx]' accepts.
3680  Return the number of the bytes the node accepts.
3681  STR_IDX is the current index of the input string.
3682 
3683  This function handles the nodes which can accept one character, or
3684  one collating element like '.', '[a-z]', opposite to the other nodes
3685  can only accept one byte. */
3686 
3687 static int
3689 check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
3690  const re_string_t *input, int str_idx)
3691 {
3692  const re_token_t *node = dfa->nodes + node_idx;
3693  int char_len, elem_len;
3694  int i;
3695 
3696  if (BE (node->type == OP_UTF8_PERIOD, 0))
3697  {
3698  unsigned char c = re_string_byte_at (input, str_idx), d;
3699  if (BE (c < 0xc2, 1))
3700  return 0;
3701 
3702  if (str_idx + 2 > input->len)
3703  return 0;
3704 
3705  d = re_string_byte_at (input, str_idx + 1);
3706  if (c < 0xe0)
3707  return (d < 0x80 || d > 0xbf) ? 0 : 2;
3708  else if (c < 0xf0)
3709  {
3710  char_len = 3;
3711  if (c == 0xe0 && d < 0xa0)
3712  return 0;
3713  }
3714  else if (c < 0xf8)
3715  {
3716  char_len = 4;
3717  if (c == 0xf0 && d < 0x90)
3718  return 0;
3719  }
3720  else if (c < 0xfc)
3721  {
3722  char_len = 5;
3723  if (c == 0xf8 && d < 0x88)
3724  return 0;
3725  }
3726  else if (c < 0xfe)
3727  {
3728  char_len = 6;
3729  if (c == 0xfc && d < 0x84)
3730  return 0;
3731  }
3732  else
3733  return 0;
3734 
3735  if (str_idx + char_len > input->len)
3736  return 0;
3737 
3738  for (i = 1; i < char_len; ++i)
3739  {
3740  d = re_string_byte_at (input, str_idx + i);
3741  if (d < 0x80 || d > 0xbf)
3742  return 0;
3743  }
3744  return char_len;
3745  }
3746 
3747  char_len = re_string_char_size_at (input, str_idx);
3748  if (node->type == OP_PERIOD)
3749  {
3750  if (char_len <= 1)
3751  return 0;
3752  /* FIXME: I don't think this if is needed, as both '\n'
3753  and '\0' are char_len == 1. */
3754  /* '.' accepts any one character except the following two cases. */
3755  if ((!(dfa->syntax & RE_DOT_NEWLINE) &&
3756  re_string_byte_at (input, str_idx) == '\n') ||
3757  ((dfa->syntax & RE_DOT_NOT_NULL) &&
3758  re_string_byte_at (input, str_idx) == '\0'))
3759  return 0;
3760  return char_len;
3761  }
3762 
3763  elem_len = re_string_elem_size_at (input, str_idx);
3764  if ((elem_len <= 1 && char_len <= 1) || char_len == 0)
3765  return 0;
3766 
3767  if (node->type == COMPLEX_BRACKET)
3768  {
3769  const re_charset_t *cset = node->opr.mbcset;
3770 # ifdef _LIBC
3771  const unsigned char *pin
3772  = ((const unsigned char *) re_string_get_buffer (input) + str_idx);
3773  int j;
3774  uint32_t nrules;
3775 # endif /* _LIBC */
3776  int match_len = 0;
3777  wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
3778  ? re_string_wchar_at (input, str_idx) : 0);
3779 
3780  /* match with multibyte character? */
3781  for (i = 0; i < cset->nmbchars; ++i)
3782  if (wc == cset->mbchars[i])
3783  {
3784  match_len = char_len;
3785  goto check_node_accept_bytes_match;
3786  }
3787  /* match with character_class? */
3788  for (i = 0; i < cset->nchar_classes; ++i)
3789  {
3790  wctype_t wt = cset->char_classes[i];
3791  if (__iswctype (wc, wt))
3792  {
3793  match_len = char_len;
3794  goto check_node_accept_bytes_match;
3795  }
3796  }
3797 
3798 # ifdef _LIBC
3799  nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
3800  if (nrules != 0)
3801  {
3802  unsigned int in_collseq = 0;
3803  const int32_t *table, *indirect;
3804  const unsigned char *weights, *extra;
3805  const char *collseqwc;
3806  int32_t idx;
3807  /* This #include defines a local function! */
3808 # include <locale/weight.h>
3809 
3810  /* match with collating_symbol? */
3811  if (cset->ncoll_syms)
3812  extra = (const unsigned char *)
3813  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
3814  for (i = 0; i < cset->ncoll_syms; ++i)
3815  {
3816  const unsigned char *coll_sym = extra + cset->coll_syms[i];
3817  /* Compare the length of input collating element and
3818  the length of current collating element. */
3819  if (*coll_sym != elem_len)
3820  continue;
3821  /* Compare each bytes. */
3822  for (j = 0; j < *coll_sym; j++)
3823  if (pin[j] != coll_sym[1 + j])
3824  break;
3825  if (j == *coll_sym)
3826  {
3827  /* Match if every bytes is equal. */
3828  match_len = j;
3829  goto check_node_accept_bytes_match;
3830  }
3831  }
3832 
3833  if (cset->nranges)
3834  {
3835  if (elem_len <= char_len)
3836  {
3837  collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
3838  in_collseq = __collseq_table_lookup (collseqwc, wc);
3839  }
3840  else
3841  in_collseq = find_collation_sequence_value (pin, elem_len);
3842  }
3843  /* match with range expression? */
3844  for (i = 0; i < cset->nranges; ++i)
3845  if (cset->range_starts[i] <= in_collseq
3846  && in_collseq <= cset->range_ends[i])
3847  {
3848  match_len = elem_len;
3849  goto check_node_accept_bytes_match;
3850  }
3851 
3852  /* match with equivalence_class? */
3853  if (cset->nequiv_classes)
3854  {
3855  const unsigned char *cp = pin;
3856  table = (const int32_t *)
3857  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
3858  weights = (const unsigned char *)
3859  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
3860  extra = (const unsigned char *)
3861  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
3862  indirect = (const int32_t *)
3863  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
3864  idx = findidx (&cp);
3865  if (idx > 0)
3866  for (i = 0; i < cset->nequiv_classes; ++i)
3867  {
3868  int32_t equiv_class_idx = cset->equiv_classes[i];
3869  size_t weight_len = weights[idx];
3870  if (weight_len == weights[equiv_class_idx])
3871  {
3872  int cnt = 0;
3873  while (cnt <= weight_len
3874  && (weights[equiv_class_idx + 1 + cnt]
3875  == weights[idx + 1 + cnt]))
3876  ++cnt;
3877  if (cnt > weight_len)
3878  {
3879  match_len = elem_len;
3880  goto check_node_accept_bytes_match;
3881  }
3882  }
3883  }
3884  }
3885  }
3886  else
3887 # endif /* _LIBC */
3888  {
3889  /* match with range expression? */
3890 #if __GNUC__ >= 2
3891  wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
3892 #else
3893  wchar_t cmp_buf[] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
3894  cmp_buf[2] = wc;
3895 #endif
3896  for (i = 0; i < cset->nranges; ++i)
3897  {
3898  cmp_buf[0] = cset->range_starts[i];
3899  cmp_buf[4] = cset->range_ends[i];
3900  if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
3901  && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
3902  {
3903  match_len = char_len;
3904  goto check_node_accept_bytes_match;
3905  }
3906  }
3907  }
3908  check_node_accept_bytes_match:
3909  if (!cset->non_match)
3910  return match_len;
3911  else
3912  {
3913  if (match_len > 0)
3914  return 0;
3915  else
3916  return (elem_len > char_len) ? elem_len : char_len;
3917  }
3918  }
3919  return 0;
3920 }
3921 
3922 # ifdef _LIBC
3923 static unsigned int
3925 find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
3926 {
3927  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
3928  if (nrules == 0)
3929  {
3930  if (mbs_len == 1)
3931  {
3932  /* No valid character. Match it as a single byte character. */
3933  const unsigned char *collseq = (const unsigned char *)
3934  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
3935  return collseq[mbs[0]];
3936  }
3937  return UINT_MAX;
3938  }
3939  else
3940  {
3941  int32_t idx;
3942  const unsigned char *extra = (const unsigned char *)
3943  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
3944  int32_t extrasize = (const unsigned char *)
3945  _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB + 1) - extra;
3946 
3947  for (idx = 0; idx < extrasize;)
3948  {
3949  int mbs_cnt, found = 0;
3950  int32_t elem_mbs_len;
3951  /* Skip the name of collating element name. */
3952  idx = idx + extra[idx] + 1;
3953  elem_mbs_len = extra[idx++];
3954  if (mbs_len == elem_mbs_len)
3955  {
3956  for (mbs_cnt = 0; mbs_cnt < elem_mbs_len; ++mbs_cnt)
3957  if (extra[idx + mbs_cnt] != mbs[mbs_cnt])
3958  break;
3959  if (mbs_cnt == elem_mbs_len)
3960  /* Found the entry. */
3961  found = 1;
3962  }
3963  /* Skip the byte sequence of the collating element. */
3964  idx += elem_mbs_len;
3965  /* Adjust for the alignment. */
3966  idx = (idx + 3) & ~3;
3967  /* Skip the collation sequence value. */
3968  idx += sizeof (uint32_t);
3969  /* Skip the wide char sequence of the collating element. */
3970  idx = idx + sizeof (uint32_t) * (extra[idx] + 1);
3971  /* If we found the entry, return the sequence value. */
3972  if (found)
3973  return *(uint32_t *) (extra + idx);
3974  /* Skip the collation sequence value. */
3975  idx += sizeof (uint32_t);
3976  }
3977  return UINT_MAX;
3978  }
3979 }
3980 # endif /* _LIBC */
3981 #endif /* RE_ENABLE_I18N */
3982 
3983 /* Check whether the node accepts the byte which is IDX-th
3984  byte of the INPUT. */
3985 
3986 static int
3989  int idx)
3990 {
3991  unsigned char ch;
3992  ch = re_string_byte_at (&mctx->input, idx);
3993  switch (node->type)
3994  {
3995  case CHARACTER:
3996  if (node->opr.c != ch)
3997  return 0;
3998  break;
3999 
4000  case SIMPLE_BRACKET:
4001  if (!bitset_contain (node->opr.sbcset, ch))
4002  return 0;
4003  break;
4004 
4005 #ifdef RE_ENABLE_I18N
4006  case OP_UTF8_PERIOD:
4007  if (ch >= 0x80)
4008  return 0;
4009  /* FALLTHROUGH */
4010 #endif
4011  case OP_PERIOD:
4012  if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE))
4013  || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL)))
4014  return 0;
4015  break;
4016 
4017  default:
4018  return 0;
4019  }
4020 
4021  if (node->constraint)
4022  {
4023  /* The node has constraints. Check whether the current context
4024  satisfies the constraints. */
4025  unsigned int context = re_string_context_at (&mctx->input, idx,
4026  mctx->eflags);
4027  if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
4028  return 0;
4029  }
4030 
4031  return 1;
4032 }
4033 
4034 /* Extend the buffers, if the buffers have run out. */
4035 
4036 static reg_errcode_t
4039 {
4041  re_string_t *pstr = &mctx->input;
4042 
4043  /* Double the lengthes of the buffers. */
4044  ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
4045  if (BE (ret != REG_NOERROR, 0))
4046  return ret;
4047 
4048  if (mctx->state_log != NULL)
4049  {
4050  /* And double the length of state_log. */
4051  /* XXX We have no indication of the size of this buffer. If this
4052  allocation fail we have no indication that the state_log array
4053  does not have the right size. */
4055  pstr->bufs_len + 1);
4056  if (BE (new_array == NULL, 0))
4057  return REG_ESPACE;
4058  mctx->state_log = new_array;
4059  }
4060 
4061  /* Then reconstruct the buffers. */
4062  if (pstr->icase)
4063  {
4064 #ifdef RE_ENABLE_I18N
4065  if (pstr->mb_cur_max > 1)
4066  {
4067  ret = build_wcs_upper_buffer (pstr);
4068  if (BE (ret != REG_NOERROR, 0))
4069  return ret;
4070  }
4071  else
4072 #endif /* RE_ENABLE_I18N */
4073  build_upper_buffer (pstr);
4074  }
4075  else
4076  {
4077 #ifdef RE_ENABLE_I18N
4078  if (pstr->mb_cur_max > 1)
4079  build_wcs_buffer (pstr);
4080  else
4081 #endif /* RE_ENABLE_I18N */
4082  {
4083  if (pstr->trans != NULL)
4085  }
4086  }
4087  return REG_NOERROR;
4088 }
4089 
4090 ␌
4091 /* Functions for matching context. */
4092 
4093 /* Initialize MCTX. */
4094 
4095 static reg_errcode_t
4097 match_ctx_init (re_match_context_t *mctx, int eflags, int n)
4098 {
4099  mctx->eflags = eflags;
4100  mctx->match_last = -1;
4101  if (n > 0)
4102  {
4103  mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n);
4104  mctx->sub_tops = re_malloc (re_sub_match_top_t *, n);
4105  if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0))
4106  return REG_ESPACE;
4107  }
4108  /* Already zero-ed by the caller.
4109  else
4110  mctx->bkref_ents = NULL;
4111  mctx->nbkref_ents = 0;
4112  mctx->nsub_tops = 0; */
4113  mctx->abkref_ents = n;
4114  mctx->max_mb_elem_len = 1;
4115  mctx->asub_tops = n;
4116  return REG_NOERROR;
4117 }
4118 
4119 /* Clean the entries which depend on the current input in MCTX.
4120  This function must be invoked when the matcher changes the start index
4121  of the input, or changes the input string. */
4122 
4123 static void
4126 {
4127  int st_idx;
4128  for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx)
4129  {
4130  int sl_idx;
4131  re_sub_match_top_t *top = mctx->sub_tops[st_idx];
4132  for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx)
4133  {
4134  re_sub_match_last_t *last = top->lasts[sl_idx];
4135  re_free (last->path.array);
4136  re_free (last);
4137  }
4138  re_free (top->lasts);
4139  if (top->path)
4140  {
4141  re_free (top->path->array);
4142  re_free (top->path);
4143  }
4144  free (top);
4145  }
4146 
4147  mctx->nsub_tops = 0;
4148  mctx->nbkref_ents = 0;
4149 }
4150 
4151 /* Free all the memory associated with MCTX. */
4152 
4153 static void
4156 {
4157  /* First, free all the memory associated with MCTX->SUB_TOPS. */
4158  match_ctx_clean (mctx);
4159  re_free (mctx->sub_tops);
4160  re_free (mctx->bkref_ents);
4161 }
4162 
4163 /* Add a new backreference entry to MCTX.
4164  Note that we assume that caller never call this function with duplicate
4165  entry, and call with STR_IDX which isn't smaller than any existing entry.
4166 */
4167 
4168 static reg_errcode_t
4170 match_ctx_add_entry (re_match_context_t *mctx, int node, int str_idx, int from,
4171  int to)
4172 {
4173  if (mctx->nbkref_ents >= mctx->abkref_ents)
4174  {
4177  mctx->abkref_ents * 2);
4178  if (BE (new_entry == NULL, 0))
4179  {
4180  re_free (mctx->bkref_ents);
4181  return REG_ESPACE;
4182  }
4183  mctx->bkref_ents = new_entry;
4184  memset (mctx->bkref_ents + mctx->nbkref_ents, '\0',
4185  sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);
4186  mctx->abkref_ents *= 2;
4187  }
4188  if (mctx->nbkref_ents > 0
4189  && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx)
4190  mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1;
4191 
4192  mctx->bkref_ents[mctx->nbkref_ents].node = node;
4193  mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx;
4194  mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from;
4195  mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to;
4196 
4197  /* This is a cache that saves negative results of check_dst_limits_calc_pos.
4198  If bit N is clear, means that this entry won't epsilon-transition to
4199  an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression. If
4200  it is set, check_dst_limits_calc_pos_1 will recurse and try to find one
4201  such node.
4202 
4203  A backreference does not epsilon-transition unless it is empty, so set
4204  to all zeros if FROM != TO. */
4206  = (from == to ? ~0 : 0);
4207 
4208  mctx->bkref_ents[mctx->nbkref_ents++].more = 0;
4209  if (mctx->max_mb_elem_len < to - from)
4210  mctx->max_mb_elem_len = to - from;
4211  return REG_NOERROR;
4212 }
4213 
4214 /* Search for the first entry which has the same str_idx, or -1 if none is
4215  found. Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX. */
4216 
4217 static int
4220 {
4221  int left, right, mid, last;
4222  last = right = mctx->nbkref_ents;
4223  for (left = 0; left < right;)
4224  {
4225  mid = (left + right) / 2;
4226  if (mctx->bkref_ents[mid].str_idx < str_idx)
4227  left = mid + 1;
4228  else
4229  right = mid;
4230  }
4231  if (left < last && mctx->bkref_ents[left].str_idx == str_idx)
4232  return left;
4233  else
4234  return -1;
4235 }
4236 
4237 /* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches
4238  at STR_IDX. */
4239 
4240 static reg_errcode_t
4243 {
4244 #ifdef DEBUG
4245  assert (mctx->sub_tops != NULL);
4246  assert (mctx->asub_tops > 0);
4247 #endif
4248  if (BE (mctx->nsub_tops == mctx->asub_tops, 0))
4249  {
4250  int new_asub_tops = mctx->asub_tops * 2;
4253  new_asub_tops);
4254  if (BE (new_array == NULL, 0))
4255  return REG_ESPACE;
4256  mctx->sub_tops = new_array;
4257  mctx->asub_tops = new_asub_tops;
4258  }
4259  mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t));
4260  if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0))
4261  return REG_ESPACE;
4262  mctx->sub_tops[mctx->nsub_tops]->node = node;
4263  mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx;
4264  return REG_NOERROR;
4265 }
4266 
4267 /* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches
4268  at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP. */
4269 
4270 static re_sub_match_last_t *
4273 {
4275  if (BE (subtop->nlasts == subtop->alasts, 0))
4276  {
4277  int new_alasts = 2 * subtop->alasts + 1;
4280  new_alasts);
4281  if (BE (new_array == NULL, 0))
4282  return NULL;
4283  subtop->lasts = new_array;
4284  subtop->alasts = new_alasts;
4285  }
4286  new_entry = calloc (1, sizeof (re_sub_match_last_t));
4287  if (BE (new_entry != NULL, 1))
4288  {
4289  subtop->lasts[subtop->nlasts] = new_entry;
4290  new_entry->node = node;
4291  new_entry->str_idx = str_idx;
4292  ++subtop->nlasts;
4293  }
4294  return new_entry;
4295 }
4296 
4297 static void
4300  re_dfastate_t **limited_sts, int last_node, int last_str_idx)
4301 {
4302  sctx->sifted_states = sifted_sts;
4303  sctx->limited_states = limited_sts;
4304  sctx->last_node = last_node;
4305  sctx->last_str_idx = last_str_idx;
4306  re_node_set_init_empty (&sctx->limits);
4307 }
return _Result< 0 ? -1 :_Result;} #line 1069 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vsnwprintf_s_l(wchar_t *const _Buffer, size_t const _BufferCount, size_t const _MaxCount, wchar_t const *const _Format, _locale_t const _Locale, va_list _ArgList) { int const _Result=__stdio_common_vsnwprintf_s((*__local_stdio_printf_options()), _Buffer, _BufferCount, _MaxCount, _Format, _Locale, _ArgList);return _Result< 0 ? -1 :_Result;} #line 1091 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vsnwprintf_s(wchar_t *const _Buffer, size_t const _BufferCount, size_t const _MaxCount, wchar_t const *const _Format, va_list _ArgList) { return _vsnwprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format,((void *) 0), _ArgList);} #line 1108 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_snwprintf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _snwprintf(wchar_t *_Buffer, size_t _BufferCount, wchar_t const *_Format,...);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_vsnwprintf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _vsnwprintf(wchar_t *_Buffer, size_t _BufferCount, wchar_t const *_Format, va_list _Args);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_vsnwprintf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _vsnwprintf(wchar_t *_Buffer, size_t _BufferCount, wchar_t const *_Format, va_list _ArgList) { return _vsnwprintf_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);} #line 1133 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vswprintf_c_l(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, _locale_t const _Locale, va_list _ArgList) { int const _Result=__stdio_common_vswprintf((*__local_stdio_printf_options()), _Buffer, _BufferCount, _Format, _Locale, _ArgList);return _Result< 0 ? -1 :_Result;} #line 1163 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vswprintf_c(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, va_list _ArgList) { return _vswprintf_c_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);} #line 1179 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vswprintf_l(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, _locale_t const _Locale, va_list _ArgList) { return _vswprintf_c_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);} #line 1196 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl __vswprintf_l(wchar_t *const _Buffer, wchar_t const *const _Format, _locale_t const _Locale, va_list _ArgList) { return _vswprintf_l(_Buffer,(size_t) -1, _Format, _Locale, _ArgList);} #line 1212 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vswprintf(wchar_t *const _Buffer, wchar_t const *const _Format, va_list _ArgList) { return _vswprintf_l(_Buffer,(size_t) -1, _Format,((void *) 0), _ArgList);} #line 1227 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl vswprintf(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, va_list _ArgList) { return _vswprintf_c_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);} #line 1243 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vswprintf_s_l(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, _locale_t const _Locale, va_list _ArgList) { int const _Result=__stdio_common_vswprintf_s((*__local_stdio_printf_options()), _Buffer, _BufferCount, _Format, _Locale, _ArgList);return _Result< 0 ? -1 :_Result;} #line 1264 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl vswprintf_s(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, va_list _ArgList) { return _vswprintf_s_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);} #line 1281 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" #line 1283 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vswprintf_p_l(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, _locale_t const _Locale, va_list _ArgList) { int const _Result=__stdio_common_vswprintf_p((*__local_stdio_printf_options()), _Buffer, _BufferCount, _Format, _Locale, _ArgList);return _Result< 0 ? -1 :_Result;} #line 1312 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vswprintf_p(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, va_list _ArgList) { return _vswprintf_p_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);} #line 1328 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vscwprintf_l(wchar_t const *const _Format, _locale_t const _Locale, va_list _ArgList) { int const _Result=__stdio_common_vswprintf((*__local_stdio_printf_options())|(1ULL<< 1),((void *) 0), 0, _Format, _Locale, _ArgList);return _Result< 0 ? -1 :_Result;} #line 1347 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vscwprintf(wchar_t const *const _Format, va_list _ArgList) { return _vscwprintf_l(_Format,((void *) 0), _ArgList);} #line 1361 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vscwprintf_p_l(wchar_t const *const _Format, _locale_t const _Locale, va_list _ArgList) { int const _Result=__stdio_common_vswprintf_p((*__local_stdio_printf_options())|(1ULL<< 1),((void *) 0), 0, _Format, _Locale, _ArgList);return _Result< 0 ? -1 :_Result;} #line 1380 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vscwprintf_p(wchar_t const *const _Format, va_list _ArgList) { return _vscwprintf_p_l(_Format,((void *) 0), _ArgList);} #line 1394 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl __swprintf_l(wchar_t *const _Buffer, wchar_t const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=__vswprintf_l(_Buffer, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1414 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _swprintf_l(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vswprintf_c_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1435 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _swprintf(wchar_t *const _Buffer, wchar_t const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=__vswprintf_l(_Buffer, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1454 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl swprintf(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vswprintf_c_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1474 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "__swprintf_l_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl __swprintf_l(wchar_t *_Buffer, wchar_t const *_Format, _locale_t _Locale,...);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_vswprintf_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl __vswprintf_l(wchar_t *_Buffer, wchar_t const *_Format, _locale_t _Locale, va_list _Args);__declspec(deprecated("This function or variable may be unsafe. Consider using " "swprintf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _swprintf(wchar_t *_Buffer, wchar_t const *_Format,...);__declspec(deprecated("This function or variable may be unsafe. Consider using " "vswprintf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _vswprintf(wchar_t *_Buffer, wchar_t const *_Format, va_list _Args);__inline int __cdecl _swprintf_s_l(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vswprintf_s_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1511 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl swprintf_s(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vswprintf_s_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1532 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" #line 1534 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _swprintf_p_l(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vswprintf_p_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1562 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _swprintf_p(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vswprintf_p_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1582 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _swprintf_c_l(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vswprintf_c_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1603 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _swprintf_c(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vswprintf_c_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1623 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_snwprintf_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _snwprintf_l(wchar_t *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnwprintf_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1646 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _snwprintf(wchar_t *_Buffer, size_t _BufferCount, wchar_t const *_Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnwprintf_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1668 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _snwprintf_s_l(wchar_t *const _Buffer, size_t const _BufferCount, size_t const _MaxCount, wchar_t const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnwprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1690 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _snwprintf_s(wchar_t *const _Buffer, size_t const _BufferCount, size_t const _MaxCount, wchar_t const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnwprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1711 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _scwprintf_l(wchar_t const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vscwprintf_l(_Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1737 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _scwprintf(wchar_t const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vscwprintf_l(_Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1755 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _scwprintf_p_l(wchar_t const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vscwprintf_p_l(_Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1774 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _scwprintf_p(wchar_t const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vscwprintf_p_l(_Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1792 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" #pragma warning(push) #pragma warning(disable:4141 6054) #pragma warning(pop) #line 1856 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" int __cdecl __stdio_common_vswscanf(unsigned __int64 _Options, wchar_t const *_Buffer, size_t _BufferCount, wchar_t const *_Format, _locale_t _Locale, va_list _ArgList);__inline int __cdecl _vswscanf_l(wchar_t const *const _Buffer, wchar_t const *const _Format, _locale_t const _Locale, va_list _ArgList) { return __stdio_common_vswscanf((*__local_stdio_scanf_options()), _Buffer,(size_t) -1, _Format, _Locale, _ArgList);} #line 1897 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl vswscanf(wchar_t const *_Buffer, wchar_t const *_Format, va_list _ArgList) { return _vswscanf_l(_Buffer, _Format,((void *) 0), _ArgList);} #line 1912 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vswscanf_s_l(wchar_t const *const _Buffer, wchar_t const *const _Format, _locale_t const _Locale, va_list _ArgList) { return __stdio_common_vswscanf((*__local_stdio_scanf_options())|(1ULL<< 0), _Buffer,(size_t) -1, _Format, _Locale, _ArgList);} #line 1930 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl vswscanf_s(wchar_t const *const _Buffer, wchar_t const *const _Format, va_list _ArgList) { return _vswscanf_s_l(_Buffer, _Format,((void *) 0), _ArgList);} #line 1947 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" #line 1949 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_vsnwscanf_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _vsnwscanf_l(wchar_t const *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, _locale_t const _Locale, va_list _ArgList) { return __stdio_common_vswscanf((*__local_stdio_scanf_options()), _Buffer, _BufferCount, _Format, _Locale, _ArgList);} #line 1976 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _vsnwscanf_s_l(wchar_t const *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, _locale_t const _Locale, va_list _ArgList) { return __stdio_common_vswscanf((*__local_stdio_scanf_options())|(1ULL<< 0), _Buffer, _BufferCount, _Format, _Locale, _ArgList);} #line 1995 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_swscanf_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _swscanf_l(wchar_t const *const _Buffer, wchar_t const *const _Format, _locale_t _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vswscanf_l(_Buffer, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2015 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "swscanf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl swscanf(wchar_t const *const _Buffer, wchar_t const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vswscanf_l(_Buffer, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2034 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _swscanf_s_l(wchar_t const *const _Buffer, wchar_t const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vswscanf_s_l(_Buffer, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2054 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl swscanf_s(wchar_t const *const _Buffer, wchar_t const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vswscanf_s_l(_Buffer, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2075 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" #line 2077 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_snwscanf_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _snwscanf_l(wchar_t const *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnwscanf_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2100 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_snwscanf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _snwscanf(wchar_t const *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnwscanf_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2122 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _snwscanf_s_l(wchar_t const *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnwscanf_s_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2143 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __inline int __cdecl _snwscanf_s(wchar_t const *const _Buffer, size_t const _BufferCount, wchar_t const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnwscanf_s_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2163 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstdio.h" __pragma(pack(pop))#pragma warning(pop) #pragma warning(push)#pragma warning(disable:4324 4514 4574 4710 4793 4820 4995 4996 28719 28726 28727) __pragma(pack(push, 8)) typedef __int64 fpos_t;errno_t __cdecl _get_stream_buffer_pointers(FILE *_Stream, char ***_Base, char ***_Pointer, int **_Count);errno_t __cdecl clearerr_s(FILE *_Stream);errno_t __cdecl fopen_s(FILE **_Stream, char const *_FileName, char const *_Mode);size_t __cdecl fread_s(void *_Buffer, size_t _BufferSize, size_t _ElementSize, size_t _ElementCount, FILE *_Stream);errno_t __cdecl freopen_s(FILE **_Stream, char const *_FileName, char const *_Mode, FILE *_OldStream);char *__cdecl gets_s(char *_Buffer, rsize_t _Size);errno_t __cdecl tmpfile_s(FILE **_Stream);errno_t __cdecl tmpnam_s(char *_Buffer, rsize_t _Size);#line 145 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" void __cdecl clearerr(FILE *_Stream);int __cdecl fclose(FILE *_Stream);int __cdecl _fcloseall(void);FILE *__cdecl _fdopen(int _FileHandle, char const *_Mode);int __cdecl feof(FILE *_Stream);int __cdecl ferror(FILE *_Stream);int __cdecl fflush(FILE *_Stream);int __cdecl fgetc(FILE *_Stream);int __cdecl _fgetchar(void);int __cdecl fgetpos(FILE *_Stream, fpos_t *_Position);char *__cdecl fgets(char *_Buffer, int _MaxCount, FILE *_Stream);int __cdecl _fileno(FILE *_Stream);int __cdecl _flushall(void);__declspec(deprecated("This function or variable may be unsafe. Consider using " "fopen_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) FILE *__cdecl fopen(char const *_FileName, char const *_Mode);int __cdecl fputc(int _Character, FILE *_Stream);int __cdecl _fputchar(int _Character);int __cdecl fputs(char const *_Buffer, FILE *_Stream);size_t __cdecl fread(void *_Buffer, size_t _ElementSize, size_t _ElementCount, FILE *_Stream);__declspec(deprecated("This function or variable may be unsafe. Consider using " "freopen_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) FILE *__cdecl freopen(char const *_FileName, char const *_Mode, FILE *_Stream);FILE *__cdecl _fsopen(char const *_FileName, char const *_Mode, int _ShFlag);int __cdecl fsetpos(FILE *_Stream, fpos_t const *_Position);int __cdecl fseek(FILE *_Stream, long _Offset, int _Origin);int __cdecl _fseeki64(FILE *_Stream, __int64 _Offset, int _Origin);long __cdecl ftell(FILE *_Stream);__int64 __cdecl _ftelli64(FILE *_Stream);size_t __cdecl fwrite(void const *_Buffer, size_t _ElementSize, size_t _ElementCount, FILE *_Stream);int __cdecl getc(FILE *_Stream);int __cdecl getchar(void);int __cdecl _getmaxstdio(void);int __cdecl _getw(FILE *_Stream);void __cdecl perror(char const *_ErrorMessage);int __cdecl _pclose(FILE *_Stream);FILE *__cdecl _popen(char const *_Command, char const *_Mode);#line 344 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" int __cdecl putc(int _Character, FILE *_Stream);int __cdecl putchar(int _Character);int __cdecl puts(char const *_Buffer);int __cdecl _putw(int _Word, FILE *_Stream);int __cdecl remove(char const *_FileName);int __cdecl rename(char const *_OldFileName, char const *_NewFileName);int __cdecl _unlink(char const *_FileName);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_unlink" ". See online help for details.")) int __cdecl unlink(char const *_FileName);#line 391 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" void __cdecl rewind(FILE *_Stream);int __cdecl _rmtmp(void);__declspec(deprecated("This function or variable may be unsafe. Consider using " "setvbuf" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) void __cdecl setbuf(FILE *_Stream, char *_Buffer);int __cdecl _setmaxstdio(int _Maximum);int __cdecl setvbuf(FILE *_Stream, char *_Buffer, int _Mode, size_t _Size);__declspec(allocator) char *__cdecl _tempnam(char const *_DirectoryName, char const *_FilePrefix);__declspec(deprecated("This function or variable may be unsafe. Consider using " "tmpfile_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) FILE *__cdecl tmpfile(void);__declspec(deprecated("This function or variable may be unsafe. Consider using " "tmpnam_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl tmpnam(char *_Buffer);int __cdecl ungetc(int _Character, FILE *_Stream);void __cdecl _lock_file(FILE *_Stream);void __cdecl _unlock_file(FILE *_Stream);int __cdecl _fclose_nolock(FILE *_Stream);int __cdecl _fflush_nolock(FILE *_Stream);int __cdecl _fgetc_nolock(FILE *_Stream);int __cdecl _fputc_nolock(int _Character, FILE *_Stream);size_t __cdecl _fread_nolock(void *_Buffer, size_t _ElementSize, size_t _ElementCount, FILE *_Stream);size_t __cdecl _fread_nolock_s(void *_Buffer, size_t _BufferSize, size_t _ElementSize, size_t _ElementCount, FILE *_Stream);int __cdecl _fseek_nolock(FILE *_Stream, long _Offset, int _Origin);int __cdecl _fseeki64_nolock(FILE *_Stream, __int64 _Offset, int _Origin);long __cdecl _ftell_nolock(FILE *_Stream);__int64 __cdecl _ftelli64_nolock(FILE *_Stream);size_t __cdecl _fwrite_nolock(void const *_Buffer, size_t _ElementSize, size_t _ElementCount, FILE *_Stream);int __cdecl _getc_nolock(FILE *_Stream);int __cdecl _putc_nolock(int _Character, FILE *_Stream);int __cdecl _ungetc_nolock(int _Character, FILE *_Stream);int *__cdecl __p__commode(void);#line 596 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" int __cdecl __stdio_common_vfprintf(unsigned __int64 _Options, FILE *_Stream, char const *_Format, _locale_t _Locale, va_list _ArgList);int __cdecl __stdio_common_vfprintf_s(unsigned __int64 _Options, FILE *_Stream, char const *_Format, _locale_t _Locale, va_list _ArgList);int __cdecl __stdio_common_vfprintf_p(unsigned __int64 _Options, FILE *_Stream, char const *_Format, _locale_t _Locale, va_list _ArgList);__inline int __cdecl _vfprintf_l(FILE *const _Stream, char const *const _Format, _locale_t const _Locale, va_list _ArgList) { return __stdio_common_vfprintf((*__local_stdio_printf_options()), _Stream, _Format, _Locale, _ArgList);} #line 648 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl vfprintf(FILE *const _Stream, char const *const _Format, va_list _ArgList) { return _vfprintf_l(_Stream, _Format,((void *) 0), _ArgList);} #line 662 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vfprintf_s_l(FILE *const _Stream, char const *const _Format, _locale_t const _Locale, va_list _ArgList) { return __stdio_common_vfprintf_s((*__local_stdio_printf_options()), _Stream, _Format, _Locale, _ArgList);} #line 677 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl vfprintf_s(FILE *const _Stream, char const *const _Format, va_list _ArgList) { return _vfprintf_s_l(_Stream, _Format,((void *) 0), _ArgList);} #line 693 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #line 695 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vfprintf_p_l(FILE *const _Stream, char const *const _Format, _locale_t const _Locale, va_list _ArgList) { return __stdio_common_vfprintf_p((*__local_stdio_printf_options()), _Stream, _Format, _Locale, _ArgList);} #line 710 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vfprintf_p(FILE *const _Stream, char const *const _Format, va_list _ArgList) { return _vfprintf_p_l(_Stream, _Format,((void *) 0), _ArgList);} #line 724 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vprintf_l(char const *const _Format, _locale_t const _Locale, va_list _ArgList) { return _vfprintf_l((__acrt_iob_func(1)), _Format, _Locale, _ArgList);} #line 738 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl vprintf(char const *const _Format, va_list _ArgList) { return _vfprintf_l((__acrt_iob_func(1)), _Format,((void *) 0), _ArgList);} #line 751 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vprintf_s_l(char const *const _Format, _locale_t const _Locale, va_list _ArgList) { return _vfprintf_s_l((__acrt_iob_func(1)), _Format, _Locale, _ArgList);} #line 765 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl vprintf_s(char const *const _Format, va_list _ArgList) { return _vfprintf_s_l((__acrt_iob_func(1)), _Format,((void *) 0), _ArgList);} #line 780 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #line 782 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vprintf_p_l(char const *const _Format, _locale_t const _Locale, va_list _ArgList) { return _vfprintf_p_l((__acrt_iob_func(1)), _Format, _Locale, _ArgList);} #line 796 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vprintf_p(char const *const _Format, va_list _ArgList) { return _vfprintf_p_l((__acrt_iob_func(1)), _Format,((void *) 0), _ArgList);} #line 809 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _fprintf_l(FILE *const _Stream, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfprintf_l(_Stream, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 828 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl fprintf(FILE *const _Stream, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfprintf_l(_Stream, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 846 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" int __cdecl _set_printf_count_output(int _Value);int __cdecl _get_printf_count_output(void);__inline int __cdecl _fprintf_s_l(FILE *const _Stream, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfprintf_s_l(_Stream, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 871 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl fprintf_s(FILE *const _Stream, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfprintf_s_l(_Stream, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 891 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #line 893 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _fprintf_p_l(FILE *const _Stream, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfprintf_p_l(_Stream, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 912 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _fprintf_p(FILE *const _Stream, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfprintf_p_l(_Stream, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 930 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _printf_l(char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfprintf_l((__acrt_iob_func(1)), _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 948 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl printf(char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfprintf_l((__acrt_iob_func(1)), _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 965 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _printf_s_l(char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfprintf_s_l((__acrt_iob_func(1)), _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 983 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl printf_s(char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfprintf_s_l((__acrt_iob_func(1)), _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1002 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #line 1004 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _printf_p_l(char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfprintf_p_l((__acrt_iob_func(1)), _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1022 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _printf_p(char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfprintf_p_l((__acrt_iob_func(1)), _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1039 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" int __cdecl __stdio_common_vfscanf(unsigned __int64 _Options, FILE *_Stream, char const *_Format, _locale_t _Locale, va_list _Arglist);__inline int __cdecl _vfscanf_l(FILE *const _Stream, char const *const _Format, _locale_t const _Locale, va_list _ArgList) { return __stdio_common_vfscanf((*__local_stdio_scanf_options()), _Stream, _Format, _Locale, _ArgList);} #line 1070 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl vfscanf(FILE *const _Stream, char const *const _Format, va_list _ArgList) { return _vfscanf_l(_Stream, _Format,((void *) 0), _ArgList);} #line 1084 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vfscanf_s_l(FILE *const _Stream, char const *const _Format, _locale_t const _Locale, va_list _ArgList) { return __stdio_common_vfscanf((*__local_stdio_scanf_options())|(1ULL<< 0), _Stream, _Format, _Locale, _ArgList);} #line 1101 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl vfscanf_s(FILE *const _Stream, char const *const _Format, va_list _ArgList) { return _vfscanf_s_l(_Stream, _Format,((void *) 0), _ArgList);} #line 1118 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #line 1120 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vscanf_l(char const *const _Format, _locale_t const _Locale, va_list _ArgList) { return _vfscanf_l((__acrt_iob_func(0)), _Format, _Locale, _ArgList);} #line 1134 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl vscanf(char const *const _Format, va_list _ArgList) { return _vfscanf_l((__acrt_iob_func(0)), _Format,((void *) 0), _ArgList);} #line 1147 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vscanf_s_l(char const *const _Format, _locale_t const _Locale, va_list _ArgList) { return _vfscanf_s_l((__acrt_iob_func(0)), _Format, _Locale, _ArgList);} #line 1161 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl vscanf_s(char const *const _Format, va_list _ArgList) { return _vfscanf_s_l((__acrt_iob_func(0)), _Format,((void *) 0), _ArgList);} #line 1176 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #line 1178 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_fscanf_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _fscanf_l(FILE *const _Stream, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfscanf_l(_Stream, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1197 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "fscanf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl fscanf(FILE *const _Stream, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfscanf_l(_Stream, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1215 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _fscanf_s_l(FILE *const _Stream, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfscanf_s_l(_Stream, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1234 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl fscanf_s(FILE *const _Stream, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfscanf_s_l(_Stream, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1254 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #line 1256 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_scanf_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _scanf_l(char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfscanf_l((__acrt_iob_func(0)), _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1274 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "scanf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl scanf(char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfscanf_l((__acrt_iob_func(0)), _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1291 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _scanf_s_l(char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfscanf_s_l((__acrt_iob_func(0)), _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1309 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl scanf_s(char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vfscanf_s_l((__acrt_iob_func(0)), _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1328 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #line 1330 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" int __cdecl __stdio_common_vsprintf(unsigned __int64 _Options, char *_Buffer, size_t _BufferCount, char const *_Format, _locale_t _Locale, va_list _ArgList);int __cdecl __stdio_common_vsprintf_s(unsigned __int64 _Options, char *_Buffer, size_t _BufferCount, char const *_Format, _locale_t _Locale, va_list _ArgList);int __cdecl __stdio_common_vsnprintf_s(unsigned __int64 _Options, char *_Buffer, size_t _BufferCount, size_t _MaxCount, char const *_Format, _locale_t _Locale, va_list _ArgList);int __cdecl __stdio_common_vsprintf_p(unsigned __int64 _Options, char *_Buffer, size_t _BufferCount, char const *_Format, _locale_t _Locale, va_list _ArgList);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_vsnprintf_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _vsnprintf_l(char *const _Buffer, size_t const _BufferCount, char const *const _Format, _locale_t const _Locale, va_list _ArgList) { int const _Result=__stdio_common_vsprintf((*__local_stdio_printf_options())|(1ULL<< 0), _Buffer, _BufferCount, _Format, _Locale, _ArgList);return _Result< 0 ? -1 :_Result;} #line 1399 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vsnprintf(char *const _Buffer, size_t const _BufferCount, char const *const _Format, va_list _ArgList) { return _vsnprintf_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);} #line 1415 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl vsnprintf(char *const _Buffer, size_t const _BufferCount, char const *const _Format, va_list _ArgList) { int const _Result=__stdio_common_vsprintf((*__local_stdio_printf_options())|(1ULL<< 1), _Buffer, _BufferCount, _Format,((void *) 0), _ArgList);return _Result< 0 ? -1 :_Result;} #line 1446 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_vsprintf_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _vsprintf_l(char *const _Buffer, char const *const _Format, _locale_t const _Locale, va_list _ArgList) { return _vsnprintf_l(_Buffer,(size_t) -1, _Format, _Locale, _ArgList);} #line 1462 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "vsprintf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl vsprintf(char *const _Buffer, char const *const _Format, va_list _ArgList) { return _vsnprintf_l(_Buffer,(size_t) -1, _Format,((void *) 0), _ArgList);} #line 1477 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vsprintf_s_l(char *const _Buffer, size_t const _BufferCount, char const *const _Format, _locale_t const _Locale, va_list _ArgList) { int const _Result=__stdio_common_vsprintf_s((*__local_stdio_printf_options()), _Buffer, _BufferCount, _Format, _Locale, _ArgList);return _Result< 0 ? -1 :_Result;} #line 1498 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl vsprintf_s(char *const _Buffer, size_t const _BufferCount, char const *const _Format, va_list _ArgList) { return _vsprintf_s_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);} #line 1516 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #line 1526 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vsprintf_p_l(char *const _Buffer, size_t const _BufferCount, char const *const _Format, _locale_t const _Locale, va_list _ArgList) { int const _Result=__stdio_common_vsprintf_p((*__local_stdio_printf_options()), _Buffer, _BufferCount, _Format, _Locale, _ArgList);return _Result< 0 ? -1 :_Result;} #line 1547 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vsprintf_p(char *const _Buffer, size_t const _BufferCount, char const *const _Format, va_list _ArgList) { return _vsprintf_p_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);} #line 1563 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vsnprintf_s_l(char *const _Buffer, size_t const _BufferCount, size_t const _MaxCount, char const *const _Format, _locale_t const _Locale, va_list _ArgList) { int const _Result=__stdio_common_vsnprintf_s((*__local_stdio_printf_options()), _Buffer, _BufferCount, _MaxCount, _Format, _Locale, _ArgList);return _Result< 0 ? -1 :_Result;} #line 1585 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vsnprintf_s(char *const _Buffer, size_t const _BufferCount, size_t const _MaxCount, char const *const _Format, va_list _ArgList) { return _vsnprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format,((void *) 0), _ArgList);} #line 1602 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl vsnprintf_s(char *const _Buffer, size_t const _BufferCount, size_t const _MaxCount, char const *const _Format, va_list _ArgList) { return _vsnprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format,((void *) 0), _ArgList);} #line 1630 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #line 1641 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vscprintf_l(char const *const _Format, _locale_t const _Locale, va_list _ArgList) { int const _Result=__stdio_common_vsprintf((*__local_stdio_printf_options())|(1ULL<< 1),((void *) 0), 0, _Format, _Locale, _ArgList);return _Result< 0 ? -1 :_Result;} #line 1659 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vscprintf(char const *const _Format, va_list _ArgList) { return _vscprintf_l(_Format,((void *) 0), _ArgList);} #line 1672 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vscprintf_p_l(char const *const _Format, _locale_t const _Locale, va_list _ArgList) { int const _Result=__stdio_common_vsprintf_p((*__local_stdio_printf_options())|(1ULL<< 1),((void *) 0), 0, _Format, _Locale, _ArgList);return _Result< 0 ? -1 :_Result;} #line 1690 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vscprintf_p(char const *const _Format, va_list _ArgList) { return _vscprintf_p_l(_Format,((void *) 0), _ArgList);} #line 1703 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vsnprintf_c_l(char *const _Buffer, size_t const _BufferCount, char const *const _Format, _locale_t const _Locale, va_list _ArgList) { int const _Result=__stdio_common_vsprintf((*__local_stdio_printf_options()), _Buffer, _BufferCount, _Format, _Locale, _ArgList);return _Result< 0 ? -1 :_Result;} #line 1723 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vsnprintf_c(char *const _Buffer, size_t const _BufferCount, char const *const _Format, va_list _ArgList) { return _vsnprintf_c_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);} #line 1739 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_sprintf_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _sprintf_l(char *const _Buffer, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsprintf_l(_Buffer, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1761 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl sprintf(char *const _Buffer, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsprintf_l(_Buffer, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1782 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "sprintf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) int __cdecl sprintf(char *_Buffer, char const *_Format,...);__declspec(deprecated("This function or variable may be unsafe. Consider using " "vsprintf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) int __cdecl vsprintf(char *_Buffer, char const *_Format, va_list _Args);__inline int __cdecl _sprintf_s_l(char *const _Buffer, size_t const _BufferCount, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsprintf_s_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1810 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl sprintf_s(char *const _Buffer, size_t const _BufferCount, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsprintf_s_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1832 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #line 1834 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _sprintf_p_l(char *const _Buffer, size_t const _BufferCount, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsprintf_p_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1862 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _sprintf_p(char *const _Buffer, size_t const _BufferCount, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsprintf_p_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1882 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_snprintf_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _snprintf_l(char *const _Buffer, size_t const _BufferCount, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnprintf_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1905 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl snprintf(char *const _Buffer, size_t const _BufferCount, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=vsnprintf(_Buffer, _BufferCount, _Format, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1936 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _snprintf(char *const _Buffer, size_t const _BufferCount, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnprintf(_Buffer, _BufferCount, _Format, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1956 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_snprintf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) int __cdecl _snprintf(char *_Buffer, size_t _BufferCount, char const *_Format,...);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_vsnprintf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) int __cdecl _vsnprintf(char *_Buffer, size_t _BufferCount, char const *_Format, va_list _Args);__inline int __cdecl _snprintf_c_l(char *const _Buffer, size_t const _BufferCount, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnprintf_c_l(_Buffer, _BufferCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 1986 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _snprintf_c(char *const _Buffer, size_t const _BufferCount, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnprintf_c_l(_Buffer, _BufferCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2006 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _snprintf_s_l(char *const _Buffer, size_t const _BufferCount, size_t const _MaxCount, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2028 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _snprintf_s(char *const _Buffer, size_t const _BufferCount, size_t const _MaxCount, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsnprintf_s_l(_Buffer, _BufferCount, _MaxCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2049 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _scprintf_l(char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vscprintf_l(_Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2075 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _scprintf(char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vscprintf_l(_Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2092 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _scprintf_p_l(char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vscprintf_p_l(_Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2110 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _scprintf_p(char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vscprintf_p(_Format, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2127 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" int __cdecl __stdio_common_vsscanf(unsigned __int64 _Options, char const *_Buffer, size_t _BufferCount, char const *_Format, _locale_t _Locale, va_list _ArgList);__inline int __cdecl _vsscanf_l(char const *const _Buffer, char const *const _Format, _locale_t const _Locale, va_list _ArgList) { return __stdio_common_vsscanf((*__local_stdio_scanf_options()), _Buffer,(size_t) -1, _Format, _Locale, _ArgList);} #line 2158 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl vsscanf(char const *const _Buffer, char const *const _Format, va_list _ArgList) { return _vsscanf_l(_Buffer, _Format,((void *) 0), _ArgList);} #line 2172 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _vsscanf_s_l(char const *const _Buffer, char const *const _Format, _locale_t const _Locale, va_list _ArgList) { return __stdio_common_vsscanf((*__local_stdio_scanf_options())|(1ULL<< 0), _Buffer,(size_t) -1, _Format, _Locale, _ArgList);} #line 2189 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #pragma warning(push) #pragma warning(disable:6530) __inline int __cdecl vsscanf_s(char const *const _Buffer, char const *const _Format, va_list _ArgList) { return _vsscanf_s_l(_Buffer, _Format,((void *) 0), _ArgList);} #line 2208 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #pragma warning(pop) #line 2219 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_sscanf_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _sscanf_l(char const *const _Buffer, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsscanf_l(_Buffer, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2238 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "sscanf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl sscanf(char const *const _Buffer, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsscanf_l(_Buffer, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2256 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _sscanf_s_l(char const *const _Buffer, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=_vsscanf_s_l(_Buffer, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2275 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl sscanf_s(char const *const _Buffer, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=vsscanf_s(_Buffer, _Format, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2297 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #line 2299 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #pragma warning(push) #pragma warning(disable:6530) __declspec(deprecated("This function or variable may be unsafe. Consider using " "_snscanf_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _snscanf_l(char const *const _Buffer, size_t const _BufferCount, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=__stdio_common_vsscanf((*__local_stdio_scanf_options()), _Buffer, _BufferCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2326 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "_snscanf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) __inline int __cdecl _snscanf(char const *const _Buffer, size_t const _BufferCount, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=__stdio_common_vsscanf((*__local_stdio_scanf_options()), _Buffer, _BufferCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2349 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _snscanf_s_l(char const *const _Buffer, size_t const _BufferCount, char const *const _Format, _locale_t const _Locale,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Locale))+((sizeof(_Locale)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=__stdio_common_vsscanf((*__local_stdio_scanf_options())|(1ULL<< 0), _Buffer, _BufferCount, _Format, _Locale, _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2374 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" __inline int __cdecl _snscanf_s(char const *const _Buffer, size_t const _BufferCount, char const *const _Format,...) { int _Result;va_list _ArgList;((void)(_ArgList=(va_list)(&(_Format))+((sizeof(_Format)+sizeof(int) - 1) &~(sizeof(int) - 1)))) ;_Result=__stdio_common_vsscanf((*__local_stdio_scanf_options())|(1ULL<< 0), _Buffer, _BufferCount, _Format,((void *) 0), _ArgList);((void)(_ArgList=(va_list) 0)) ;return _Result;} #line 2397 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h" #pragma warning(pop) __declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_tempnam" ". See online help for details.")) char *__cdecl tempnam(char const *_Directory, char const *_FilePrefix);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_fcloseall" ". See online help for details.")) int __cdecl fcloseall(void);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_fdopen" ". See online help for details.")) FILE *__cdecl fdopen(int _FileHandle, char const *_Format);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_fgetchar" ". See online help for details.")) int __cdecl fgetchar(void);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_fileno" ". See online help for details.")) int __cdecl fileno(FILE *_Stream);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_flushall" ". See online help for details.")) int __cdecl flushall(void);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_fputchar" ". See online help for details.")) int __cdecl fputchar(int _Ch);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_getw" ". See online help for details.")) int __cdecl getw(FILE *_Stream);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_putw" ". See online help for details.")) int __cdecl putw(int _Ch, FILE *_Stream);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_rmtmp" ". See online help for details.")) int __cdecl rmtmp(void);#line 2441 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\stdio.h"__pragma(pack(pop))#pragma warning(pop) #pragma once#pragma once#pragma once#pragma once#pragma warning(push)#pragma warning(disable:4324 4514 4574 4710 4793 4820 4995 4996 28719 28726 28727) __pragma(pack(push, 8)) int *__cdecl _errno(void);errno_t __cdecl _set_errno(int _Value);errno_t __cdecl _get_errno(int *_Value);unsigned long *__cdecl __doserrno(void);errno_t __cdecl _set_doserrno(unsigned long _Value);errno_t __cdecl _get_doserrno(unsigned long *_Value);__pragma(pack(pop))#pragma warning(pop) #pragma once#pragma warning(push)#pragma warning(disable:4514 4820) __pragma(pack(push, 8)) void *__cdecl memchr(void const *_Buf, int _Val, size_t _MaxCount);int __cdecl memcmp(void const *_Buf1, void const *_Buf2, size_t _Size);void *__cdecl memcpy(void *_Dst, void const *_Src, size_t _Size);void *__cdecl memmove(void *_Dst, void const *_Src, size_t _Size);void *__cdecl memset(void *_Dst, int _Val, size_t _Size);char *__cdecl strchr(char const *_Str, int _Val);char *__cdecl strrchr(char const *_Str, int _Ch);char *__cdecl strstr(char const *_Str, char const *_SubStr);wchar_t *__cdecl wcschr(wchar_t const *_Str, wchar_t _Ch);wchar_t *__cdecl wcsrchr(wchar_t const *_Str, wchar_t _Ch);wchar_t *__cdecl wcsstr(wchar_t const *_Str, wchar_t const *_SubStr);__pragma(pack(pop))#pragma warning(pop) #pragma warning(push)#pragma warning(disable:4324 4514 4574 4710 4793 4820 4995 4996 28719 28726 28727) __pragma(pack(push, 8)) static __inline errno_t __cdecl memcpy_s(void *const _Destination, rsize_t const _DestinationSize, void const *const _Source, rsize_t const _SourceSize) { if(_SourceSize==0) { return 0;} { int _Expr_val=!!(_Destination !=((void *) 0));if(!(_Expr_val)) {(*_errno())=22;_invalid_parameter_noinfo();return 22;} } ;if(_Source==((void *) 0)||_DestinationSize< _SourceSize) { memset(_Destination, 0, _DestinationSize);{ int _Expr_val=!!(_Source !=((void *) 0));if(!(_Expr_val)) {(*_errno())=22;_invalid_parameter_noinfo();return 22;} } ;{ int _Expr_val=!!(_DestinationSize >=_SourceSize);if(!(_Expr_val)) {(*_errno())=34;_invalid_parameter_noinfo();return 34;} } ;return 22 ;} memcpy(_Destination, _Source, _SourceSize);return 0;} static __inline errno_t __cdecl memmove_s(void *const _Destination, rsize_t const _DestinationSize, void const *const _Source, rsize_t const _SourceSize) { if(_SourceSize==0) { return 0;} { int _Expr_val=!!(_Destination !=((void *) 0));if(!(_Expr_val)) {(*_errno())=22;_invalid_parameter_noinfo();return 22;} } ;{ int _Expr_val=!!(_Source !=((void *) 0));if(!(_Expr_val)) {(*_errno())=22;_invalid_parameter_noinfo();return 22;} } ;{ int _Expr_val=!!(_DestinationSize >=_SourceSize);if(!(_Expr_val)) {(*_errno())=34;_invalid_parameter_noinfo();return 34;} } ;memmove(_Destination, _Source, _SourceSize);return 0;}#pragma warning(pop) __pragma(pack(pop))#pragma warning(push)#pragma warning(disable:4324 4514 4574 4710 4793 4820 4995 4996 28719 28726 28727) __pragma(pack(push, 8)) int __cdecl _memicmp(void const *_Buf1, void const *_Buf2, size_t _Size);int __cdecl _memicmp_l(void const *_Buf1, void const *_Buf2, size_t _Size, _locale_t _Locale);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_memccpy" ". See online help for details.")) void *__cdecl memccpy(void *_Dst, void const *_Src, int _Val, size_t _Size);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_memicmp" ". See online help for details.")) int __cdecl memicmp(void const *_Buf1, void const *_Buf2, size_t _Size);__pragma(pack(pop))#pragma warning(pop) #pragma once#pragma warning(push)#pragma warning(disable:4324 4514 4574 4710 4793 4820 4995 4996 28719 28726 28727) __pragma(pack(push, 8)) errno_t __cdecl wcscat_s(wchar_t *_Destination, rsize_t _SizeInWords, wchar_t const *_Source);errno_t __cdecl wcscpy_s(wchar_t *_Destination, rsize_t _SizeInWords, wchar_t const *_Source);errno_t __cdecl wcsncat_s(wchar_t *_Destination, rsize_t _SizeInWords, wchar_t const *_Source, rsize_t _MaxCount);errno_t __cdecl wcsncpy_s(wchar_t *_Destination, rsize_t _SizeInWords, wchar_t const *_Source, rsize_t _MaxCount);wchar_t *__cdecl wcstok_s(wchar_t *_String, wchar_t const *_Delimiter, wchar_t **_Context);__declspec(allocator) wchar_t *__cdecl _wcsdup(wchar_t const *_String);__declspec(deprecated("This function or variable may be unsafe. Consider using " "wcscat_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) wchar_t *__cdecl wcscat(wchar_t *_Destination, wchar_t const *_Source);int __cdecl wcscmp(wchar_t const *_String1, wchar_t const *_String2);__declspec(deprecated("This function or variable may be unsafe. Consider using " "wcscpy_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) wchar_t *__cdecl wcscpy(wchar_t *_Destination, wchar_t const *_Source);size_t __cdecl wcscspn(wchar_t const *_String, wchar_t const *_Control);size_t __cdecl wcslen(wchar_t const *_String);size_t __cdecl wcsnlen(wchar_t const *_Source, size_t _MaxCount);static __inline size_t __cdecl wcsnlen_s(wchar_t const *_Source, size_t _MaxCount) { return(_Source==0) ? 0 :wcsnlen(_Source, _MaxCount);}__declspec(deprecated("This function or variable may be unsafe. Consider using " "wcsncat_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) wchar_t *__cdecl wcsncat(wchar_t *_Destination, wchar_t const *_Source, size_t _Count);int __cdecl wcsncmp(wchar_t const *_String1, wchar_t const *_String2, size_t _MaxCount);__declspec(deprecated("This function or variable may be unsafe. Consider using " "wcsncpy_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) wchar_t *__cdecl wcsncpy(wchar_t *_Destination, wchar_t const *_Source, size_t _Count);wchar_t *__cdecl wcspbrk(wchar_t const *_String, wchar_t const *_Control);size_t __cdecl wcsspn(wchar_t const *_String, wchar_t const *_Control);__declspec(deprecated("This function or variable may be unsafe. Consider using " "wcstok_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) wchar_t *__cdecl wcstok(wchar_t *_String, wchar_t const *_Delimiter, wchar_t **_Context);#line 237 "C:/Program Files (x86)/Windows Kits/10/include/10.0.19041.0/ucrt\\corecrt_wstring.h" __declspec(deprecated("This function or variable may be unsafe. Consider using " "wcstok_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) static __inline wchar_t *__cdecl _wcstok(wchar_t *const _String, wchar_t const *const _Delimiter) { return wcstok(_String, _Delimiter, 0);} __declspec(deprecated("This function or variable may be unsafe. Consider using " "_wcserror_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) wchar_t *__cdecl _wcserror(int _ErrorNumber);errno_t __cdecl _wcserror_s(wchar_t *_Buffer, size_t _SizeInWords, int _ErrorNumber);__declspec(deprecated("This function or variable may be unsafe. Consider using " "__wcserror_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) wchar_t *__cdecl __wcserror(wchar_t const *_String);errno_t __cdecl __wcserror_s(wchar_t *_Buffer, size_t _SizeInWords, wchar_t const *_ErrorMessage);int __cdecl _wcsicmp(wchar_t const *_String1, wchar_t const *_String2);int __cdecl _wcsicmp_l(wchar_t const *_String1, wchar_t const *_String2, _locale_t _Locale);int __cdecl _wcsnicmp(wchar_t const *_String1, wchar_t const *_String2, size_t _MaxCount);int __cdecl _wcsnicmp_l(wchar_t const *_String1, wchar_t const *_String2, size_t _MaxCount, _locale_t _Locale);errno_t __cdecl _wcsnset_s(wchar_t *_Destination, size_t _SizeInWords, wchar_t _Value, size_t _MaxCount);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_wcsnset_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) wchar_t *__cdecl _wcsnset(wchar_t *_String, wchar_t _Value, size_t _MaxCount);wchar_t *__cdecl _wcsrev(wchar_t *_String);errno_t __cdecl _wcsset_s(wchar_t *_Destination, size_t _SizeInWords, wchar_t _Value);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_wcsset_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) wchar_t *__cdecl _wcsset(wchar_t *_String, wchar_t _Value);errno_t __cdecl _wcslwr_s(wchar_t *_String, size_t _SizeInWords);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_wcslwr_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) wchar_t *__cdecl _wcslwr(wchar_t *_String);errno_t __cdecl _wcslwr_s_l(wchar_t *_String, size_t _SizeInWords, _locale_t _Locale);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_wcslwr_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) wchar_t *__cdecl _wcslwr_l(wchar_t *_String, _locale_t _Locale);errno_t __cdecl _wcsupr_s(wchar_t *_String, size_t _Size);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_wcsupr_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) wchar_t *__cdecl _wcsupr(wchar_t *_String);errno_t __cdecl _wcsupr_s_l(wchar_t *_String, size_t _Size, _locale_t _Locale);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_wcsupr_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) wchar_t *__cdecl _wcsupr_l(wchar_t *_String, _locale_t _Locale);size_t __cdecl wcsxfrm(wchar_t *_Destination, wchar_t const *_Source, size_t _MaxCount);size_t __cdecl _wcsxfrm_l(wchar_t *_Destination, wchar_t const *_Source, size_t _MaxCount, _locale_t _Locale);int __cdecl wcscoll(wchar_t const *_String1, wchar_t const *_String2);int __cdecl _wcscoll_l(wchar_t const *_String1, wchar_t const *_String2, _locale_t _Locale);int __cdecl _wcsicoll(wchar_t const *_String1, wchar_t const *_String2);int __cdecl _wcsicoll_l(wchar_t const *_String1, wchar_t const *_String2, _locale_t _Locale);int __cdecl _wcsncoll(wchar_t const *_String1, wchar_t const *_String2, size_t _MaxCount);int __cdecl _wcsncoll_l(wchar_t const *_String1, wchar_t const *_String2, size_t _MaxCount, _locale_t _Locale);int __cdecl _wcsnicoll(wchar_t const *_String1, wchar_t const *_String2, size_t _MaxCount);int __cdecl _wcsnicoll_l(wchar_t const *_String1, wchar_t const *_String2, size_t _MaxCount, _locale_t _Locale);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_wcsdup" ". See online help for details.")) wchar_t *__cdecl wcsdup(wchar_t const *_String);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_wcsicmp" ". See online help for details.")) int __cdecl wcsicmp(wchar_t const *_String1, wchar_t const *_String2);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_wcsnicmp" ". See online help for details.")) int __cdecl wcsnicmp(wchar_t const *_String1, wchar_t const *_String2, size_t _MaxCount);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_wcsnset" ". See online help for details.")) wchar_t *__cdecl wcsnset(wchar_t *_String, wchar_t _Value, size_t _MaxCount);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_wcsrev" ". See online help for details.")) wchar_t *__cdecl wcsrev(wchar_t *_String);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_wcsset" ". See online help for details.")) wchar_t *__cdecl wcsset(wchar_t *_String, wchar_t _Value);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_wcslwr" ". See online help for details.")) wchar_t *__cdecl wcslwr(wchar_t *_String);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_wcsupr" ". See online help for details.")) wchar_t *__cdecl wcsupr(wchar_t *_String);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_wcsicoll" ". See online help for details.")) int __cdecl wcsicoll(wchar_t const *_String1, wchar_t const *_String2);__pragma(pack(pop))#pragma warning(pop) #pragma warning(push)#pragma warning(disable:4324 4514 4574 4710 4793 4820 4995 4996 28719 28726 28727) __pragma(pack(push, 8)) errno_t __cdecl strcpy_s(char *_Destination, rsize_t _SizeInBytes, char const *_Source);errno_t __cdecl strcat_s(char *_Destination, rsize_t _SizeInBytes, char const *_Source);errno_t __cdecl strerror_s(char *_Buffer, size_t _SizeInBytes, int _ErrorNumber);errno_t __cdecl strncat_s(char *_Destination, rsize_t _SizeInBytes, char const *_Source, rsize_t _MaxCount);errno_t __cdecl strncpy_s(char *_Destination, rsize_t _SizeInBytes, char const *_Source, rsize_t _MaxCount);char *__cdecl strtok_s(char *_String, char const *_Delimiter, char **_Context);void *__cdecl _memccpy(void *_Dst, void const *_Src, int _Val, size_t _MaxCount);__declspec(deprecated("This function or variable may be unsafe. Consider using " "strcat_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl strcat(char *_Destination, char const *_Source);int __cdecl strcmp(char const *_Str1, char const *_Str2);int __cdecl _strcmpi(char const *_String1, char const *_String2);int __cdecl strcoll(char const *_String1, char const *_String2);int __cdecl _strcoll_l(char const *_String1, char const *_String2, _locale_t _Locale);__declspec(deprecated("This function or variable may be unsafe. Consider using " "strcpy_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl strcpy(char *_Destination, char const *_Source);size_t __cdecl strcspn(char const *_Str, char const *_Control);__declspec(allocator) char *__cdecl _strdup(char const *_Source);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_strerror_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl _strerror(char const *_ErrorMessage);errno_t __cdecl _strerror_s(char *_Buffer, size_t _SizeInBytes, char const *_ErrorMessage);__declspec(deprecated("This function or variable may be unsafe. Consider using " "strerror_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl strerror(int _ErrorMessage);int __cdecl _stricmp(char const *_String1, char const *_String2);int __cdecl _stricoll(char const *_String1, char const *_String2);int __cdecl _stricoll_l(char const *_String1, char const *_String2, _locale_t _Locale);int __cdecl _stricmp_l(char const *_String1, char const *_String2, _locale_t _Locale);size_t __cdecl strlen(char const *_Str);errno_t __cdecl _strlwr_s(char *_String, size_t _Size);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_strlwr_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl _strlwr(char *_String);errno_t __cdecl _strlwr_s_l(char *_String, size_t _Size, _locale_t _Locale);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_strlwr_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl _strlwr_l(char *_String, _locale_t _Locale);__declspec(deprecated("This function or variable may be unsafe. Consider using " "strncat_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl strncat(char *_Destination, char const *_Source, size_t _Count);int __cdecl strncmp(char const *_Str1, char const *_Str2, size_t _MaxCount);int __cdecl _strnicmp(char const *_String1, char const *_String2, size_t _MaxCount);int __cdecl _strnicmp_l(char const *_String1, char const *_String2, size_t _MaxCount, _locale_t _Locale);int __cdecl _strnicoll(char const *_String1, char const *_String2, size_t _MaxCount);int __cdecl _strnicoll_l(char const *_String1, char const *_String2, size_t _MaxCount, _locale_t _Locale);int __cdecl _strncoll(char const *_String1, char const *_String2, size_t _MaxCount);int __cdecl _strncoll_l(char const *_String1, char const *_String2, size_t _MaxCount, _locale_t _Locale);size_t __cdecl __strncnt(char const *_String, size_t _Count);__declspec(deprecated("This function or variable may be unsafe. Consider using " "strncpy_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl strncpy(char *_Destination, char const *_Source, size_t _Count);size_t __cdecl strnlen(char const *_String, size_t _MaxCount);static __inline size_t __cdecl strnlen_s(char const *_String, size_t _MaxCount) { return _String==0 ? 0 :strnlen(_String, _MaxCount);} errno_t __cdecl _strnset_s(char *_String, size_t _SizeInBytes, int _Value, size_t _MaxCount);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_strnset_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl _strnset(char *_Destination, int _Value, size_t _Count);char *__cdecl strpbrk(char const *_Str, char const *_Control);char *__cdecl _strrev(char *_Str);errno_t __cdecl _strset_s(char *_Destination, size_t _DestinationSize, int _Value);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_strset_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl _strset(char *_Destination, int _Value);size_t __cdecl strspn(char const *_Str, char const *_Control);__declspec(deprecated("This function or variable may be unsafe. Consider using " "strtok_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl strtok(char *_String, char const *_Delimiter);errno_t __cdecl _strupr_s(char *_String, size_t _Size);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_strupr_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl _strupr(char *_String);errno_t __cdecl _strupr_s_l(char *_String, size_t _Size, _locale_t _Locale);__declspec(deprecated("This function or variable may be unsafe. Consider using " "_strupr_s_l" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. " "See online help for details.")) char *__cdecl _strupr_l(char *_String, _locale_t _Locale);size_t __cdecl strxfrm(char *_Destination, char const *_Source, size_t _MaxCount);size_t __cdecl _strxfrm_l(char *_Destination, char const *_Source, size_t _MaxCount, _locale_t _Locale);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_strdup" ". See online help for details.")) char *__cdecl strdup(char const *_String);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_strcmpi" ". See online help for details.")) int __cdecl strcmpi(char const *_String1, char const *_String2);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_stricmp" ". See online help for details.")) int __cdecl stricmp(char const *_String1, char const *_String2);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_strlwr" ". See online help for details.")) char *__cdecl strlwr(char *_String);__declspec(deprecated("The POSIX name for this item is deprecated. Instead, use the ISO C " "and C++ conformant name: " "_strnicmp" ". See online help for details.")) int __cdecl strnicmp(char const *_String1, char const *_String2, size_t _MaxCount);__declspec