% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2019-09-20.22}
+\def\texinfoversion{2019-09-24.13}
%
% Copyright 1985, 1986, 1988, 1990-2019 Free Software Foundation, Inc.
%
\def\wordbefore{before}
\def\wordnone{none}
-% Allow a ragged right output to aid breaking long URL's. Putting stretch in
-% between characters of the URL doesn't look good.
+% Allow a ragged right output to aid breaking long URL's. There can
+% be a break at the \allowbreak with no extra glue (if the existing stretch in
+% the line is sufficent), a break at the \penalty100 with extra glue added
+% at the end of the line, or no break at all here.
+% Changing the value of the penalty and/or the amount of stretch affects how
+% preferrable one choice is over the other.
\def\urefallowbreak{%
- \hskip 0pt plus 4 em\relax
\allowbreak
+ \hskip 0pt plus 4 em\relax
+ \penalty100
\hskip 0pt plus -4 em\relax
}
#endif
#if OPEN_TRAILING_SLASH_BUG
- /* If the filename ends in a slash and one of O_CREAT, O_WRONLY, O_RDWR
- is specified, then fail.
- Rationale: POSIX <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html>
+ /* Fail if one of O_CREAT, O_WRONLY, O_RDWR is specified and the filename
+ ends in a slash, as POSIX says such a filename must name a directory
+ <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>:
+ "A pathname that contains at least one non-<slash> character and that
+ ends with one or more trailing <slash> characters shall not be resolved
+ successfully unless the last pathname component before the trailing
+ <slash> characters names an existing directory"
If the named file already exists as a directory, then
- if O_CREAT is specified, open() must fail because of the semantics
of O_CREAT,
#if OPEN_TRAILING_SLASH_BUG
/* If the filename ends in a slash and fd does not refer to a directory,
then fail.
+ Rationale: POSIX says such a filename must name a directory
+ <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>:
+ "A pathname that contains at least one non-<slash> character and that
+ ends with one or more trailing <slash> characters shall not be resolved
+ successfully unless the last pathname component before the trailing
+ <slash> characters names an existing directory"
If the named file without the slash is not a directory, open() must fail
with ENOTDIR. */
if (fd >= 0)
break;
case END_OF_RE:
- assert (node->next == NULL);
+ DEBUG_ASSERT (node->next == NULL);
break;
case OP_DUP_ASTERISK:
right = node->right->first->node_idx;
else
right = node->next->node_idx;
- assert (left > -1);
- assert (right > -1);
+ DEBUG_ASSERT (left > -1);
+ DEBUG_ASSERT (right > -1);
err = re_node_set_init_2 (dfa->edests + idx, left, right);
}
break;
break;
default:
- assert (!IS_EPSILON_NODE (node->token.type));
+ DEBUG_ASSERT (!IS_EPSILON_NODE (node->token.type));
dfa->nexts[idx] = node->next->node_idx;
break;
}
{
Idx node_idx;
bool incomplete;
-#ifdef DEBUG
- assert (dfa->nodes_len > 0);
-#endif
+ DEBUG_ASSERT (dfa->nodes_len > 0);
incomplete = false;
/* For each nodes, calculate epsilon closure. */
for (node_idx = 0; ; ++node_idx)
node_idx = 0;
}
-#ifdef DEBUG
- assert (dfa->eclosures[node_idx].nelem != -1);
-#endif
+ DEBUG_ASSERT (dfa->eclosures[node_idx].nelem != -1);
/* If we have already calculated, skip it. */
if (dfa->eclosures[node_idx].nelem != 0)
default:
/* Must not happen? */
-#ifdef DEBUG
- assert (0);
-#endif
+ DEBUG_ASSERT (false);
return NULL;
}
fetch_token (token, regexp, syntax);
goto parse_bracket_exp_free_return;
break;
default:
- assert (0);
+ DEBUG_ASSERT (false);
break;
}
}
Idx alloc = 0;
#endif /* not RE_ENABLE_I18N */
reg_errcode_t ret;
- re_token_t br_token;
bin_tree_t *tree;
sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
#endif
/* Build a tree for simple bracket. */
-#if defined GCC_LINT || defined lint
- memset (&br_token, 0, sizeof br_token);
-#endif
- br_token.type = SIMPLE_BRACKET;
- br_token.opr.sbcset = sbcset;
+ re_token_t br_token = { .type = SIMPLE_BRACKET, .opr.sbcset = sbcset };
tree = create_token_tree (dfa, NULL, NULL, &br_token);
if (__glibc_unlikely (tree == NULL))
goto build_word_op_espace;
create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
re_token_type_t type)
{
- re_token_t t;
-#if defined GCC_LINT || defined lint
- memset (&t, 0, sizeof t);
-#endif
- t.type = type;
+ re_token_t t = { .type = type };
return create_token_tree (dfa, left, right, &t);
}
{
#ifdef _LIBC
unsigned char buf[MB_LEN_MAX];
- assert (MB_LEN_MAX >= pstr->mb_cur_max);
+ DEBUG_ASSERT (MB_LEN_MAX >= pstr->mb_cur_max);
#else
unsigned char buf[64];
#endif
size_t mbclen;
#ifdef _LIBC
char buf[MB_LEN_MAX];
- assert (MB_LEN_MAX >= pstr->mb_cur_max);
+ DEBUG_ASSERT (pstr->mb_cur_max <= MB_LEN_MAX);
#else
char buf[64];
#endif
pstr->valid_len - offset);
pstr->valid_len -= offset;
pstr->valid_raw_len -= offset;
-#if defined DEBUG && DEBUG
- assert (pstr->valid_len > 0);
-#endif
+ DEBUG_ASSERT (pstr->valid_len > 0);
}
}
else
Idx wc_idx = idx;
while(input->wcs[wc_idx] == WEOF)
{
-#if defined DEBUG && DEBUG
- /* It must not happen. */
- assert (wc_idx >= 0);
-#endif
+ DEBUG_ASSERT (wc_idx >= 0);
--wc_idx;
if (wc_idx < 0)
return input->tip_context;
#ifndef _REGEX_INTERNAL_H
#define _REGEX_INTERNAL_H 1
-#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <intprops.h>
+#include <verify.h>
+
+#if defined DEBUG && DEBUG != 0
+# include <assert.h>
+# define DEBUG_ASSERT(x) assert (x)
+#else
+# define DEBUG_ASSERT(x) assume (x)
+#endif
#ifdef _LIBC
# include <libc-lock.h>
# define lock_unlock(lock) __libc_lock_unlock (lock)
#elif defined GNULIB_LOCK && !defined USE_UNLOCKED_IO
# include "glthread/lock.h"
- /* Use gl_lock_define if empty macro arguments are known to work.
- Otherwise, fall back on less-portable substitutes. */
-# if ((defined __GNUC__ && !defined __STRICT_ANSI__) \
- || (defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__))
-# define lock_define(name) gl_lock_define (, name)
-# elif USE_POSIX_THREADS
-# define lock_define(name) pthread_mutex_t name;
-# elif USE_PTH_THREADS
-# define lock_define(name) pth_mutex_t name;
-# elif USE_SOLARIS_THREADS
-# define lock_define(name) mutex_t name;
-# elif USE_WINDOWS_THREADS
-# define lock_define(name) gl_lock_t name;
-# else
-# define lock_define(name)
-# endif
+# define lock_define(name) gl_lock_define (, name)
# define lock_init(lock) glthread_lock_init (&(lock))
# define lock_fini(lock) glthread_lock_destroy (&(lock))
# define lock_lock(lock) glthread_lock_lock (&(lock))
{
/* The string object corresponding to the input string. */
re_string_t input;
-#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
const re_dfa_t *const dfa;
-#else
- const re_dfa_t *dfa;
-#endif
/* EFLAGS of the argument of regexec. */
int eflags;
/* Where the matching ends. */
{
if (ret_len)
{
- assert (pmatch[0].rm_so == start);
+ DEBUG_ASSERT (pmatch[0].rm_so == start);
rval = pmatch[0].rm_eo - start;
}
else
}
else
{
- assert (regs_allocated == REGS_FIXED);
+ DEBUG_ASSERT (regs_allocated == REGS_FIXED);
/* This function may not be called with REGS_FIXED and nregs too big. */
- assert (regs->num_regs >= nregs);
+ DEBUG_ASSERT (nregs <= regs->num_regs);
rval = REGS_FIXED;
}
Idx extra_nmatch;
bool sb;
int ch;
-#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
re_match_context_t mctx = { .dfa = dfa };
-#else
- re_match_context_t mctx;
-#endif
char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate
&& start != last_start && !preg->can_be_null)
? preg->fastmap : NULL);
RE_TRANSLATE_TYPE t = preg->translate;
-#if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
- memset (&mctx, '\0', sizeof (re_match_context_t));
- mctx.dfa = dfa;
-#endif
-
extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0;
nmatch -= extra_nmatch;
|| dfa->init_state_begbuf == NULL))
return REG_NOMATCH;
-#ifdef DEBUG
/* We assume front-end functions already check them. */
- assert (0 <= last_start && last_start <= length);
-#endif
+ DEBUG_ASSERT (0 <= last_start && last_start <= length);
/* If initial states with non-begbuf contexts have no elements,
the regex must be anchored. If preg->newline_anchor is set,
goto free_return;
}
}
- else
- mctx.state_log = NULL;
match_first = start;
mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
match_ctx_clean (&mctx);
}
-#ifdef DEBUG
- assert (match_last != -1);
- assert (err == REG_NOERROR);
-#endif
+ DEBUG_ASSERT (match_last != -1);
+ DEBUG_ASSERT (err == REG_NOERROR);
/* Set pmatch[] if we need. */
if (nmatch > 0)
: mctx.input.offsets[pmatch[reg_idx].rm_eo]);
}
#else
- assert (mctx.input.offsets_needed == 0);
+ DEBUG_ASSERT (mctx.input.offsets_needed == 0);
#endif
pmatch[reg_idx].rm_so += match_first;
pmatch[reg_idx].rm_eo += match_first;
re_dfastate_t **sifted_states;
re_dfastate_t **lim_states = NULL;
re_sift_context_t sctx;
-#ifdef DEBUG
- assert (mctx->state_log != NULL);
-#endif
+ DEBUG_ASSERT (mctx->state_log != NULL);
match_last = mctx->match_last;
halt_node = mctx->last_node;
/* An initial state must not be NULL (invalid). */
if (__glibc_unlikely (cur_state == NULL))
{
- assert (err == REG_ESPACE);
+ DEBUG_ASSERT (err == REG_ESPACE);
return -2;
}
err = extend_buffers (mctx, next_char_idx + 1);
if (__glibc_unlikely (err != REG_NOERROR))
{
- assert (err == REG_ESPACE);
+ DEBUG_ASSERT (err == REG_ESPACE);
return -2;
}
}
{
Idx i;
unsigned int context;
-#ifdef DEBUG
- assert (state->halt);
-#endif
+ DEBUG_ASSERT (state->halt);
context = re_string_context_at (&mctx->input, idx, mctx->eflags);
for (i = 0; i < state->nodes.nelem; ++i)
if (check_halt_node_context (mctx->dfa, state->nodes.elems[i], context))
regmatch_t *regs, re_node_set *eps_via_nodes)
{
Idx num = --fs->num;
- assert (num >= 0);
+ DEBUG_ASSERT (num >= 0);
*pidx = fs->stack[num].idx;
memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
re_node_set_free (eps_via_nodes);
regmatch_t *prev_idx_match;
bool prev_idx_match_malloced = false;
-#ifdef DEBUG
- assert (nmatch > 1);
- assert (mctx->state_log != NULL);
-#endif
+ DEBUG_ASSERT (nmatch > 1);
+ DEBUG_ASSERT (mctx->state_log != NULL);
if (fl_backtrack)
{
fs = &fs_body;
Idx str_idx = sctx->last_str_idx;
re_node_set cur_dest;
-#ifdef DEBUG
- assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL);
-#endif
+ DEBUG_ASSERT (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL);
/* Build sifted state_log[str_idx]. It has the nodes which can epsilon
transit to the last_node and the last_node itself. */
Idx prev_node = cur_src->elems[i];
int naccepted = 0;
bool ok;
+ DEBUG_ASSERT (!IS_EPSILON_NODE (dfa->nodes[prev_node].type));
-#ifdef DEBUG
- re_token_type_t type = dfa->nodes[prev_node].type;
- assert (!IS_EPSILON_NODE (type));
-#endif
#ifdef RE_ENABLE_I18N
/* If the node may accept "multi byte". */
if (dfa->nodes[prev_node].accept_mb)
err = clean_state_log_if_needed (mctx, dest_idx);
if (__glibc_unlikely (err != REG_NOERROR))
return err;
-#ifdef DEBUG
- assert (dfa->nexts[cur_node_idx] != -1);
-#endif
+ DEBUG_ASSERT (dfa->nexts[cur_node_idx] != -1);
new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx];
dest_state = mctx->state_log[dest_idx];
/* And add the epsilon closures (which is 'new_dest_nodes') of
the backreference to appropriate state_log. */
-#ifdef DEBUG
- assert (dfa->nexts[node_idx] != -1);
-#endif
+ DEBUG_ASSERT (dfa->nexts[node_idx] != -1);
for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx)
{
Idx subexp_len;
{
int naccepted = 0;
Idx cur_node = cur_nodes->elems[cur_idx];
-#ifdef DEBUG
- re_token_type_t type = dfa->nodes[cur_node].type;
- assert (!IS_EPSILON_NODE (type));
-#endif
+ DEBUG_ASSERT (!IS_EPSILON_NODE (dfa->nodes[cur_node].type));
+
#ifdef RE_ENABLE_I18N
/* If the node may accept "multi byte". */
if (dfa->nodes[cur_node].accept_mb)
reg_errcode_t err;
Idx idx, outside_node;
re_node_set new_nodes;
-#ifdef DEBUG
- assert (cur_nodes->nelem);
-#endif
+ DEBUG_ASSERT (cur_nodes->nelem);
err = re_node_set_alloc (&new_nodes, cur_nodes->nelem);
if (__glibc_unlikely (err != REG_NOERROR))
return err;
bitset_empty (accepts);
}
}
+ assume (ndests <= SBC_MAX);
return ndests;
error_return:
for (j = 0; j < ndests; ++j)
__attribute_warn_unused_result__
match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx)
{
-#ifdef DEBUG
- assert (mctx->sub_tops != NULL);
- assert (mctx->asub_tops > 0);
-#endif
+ DEBUG_ASSERT (mctx->sub_tops != NULL);
+ DEBUG_ASSERT (mctx->asub_tops > 0);
if (__glibc_unlikely (mctx->nsub_tops == mctx->asub_tops))
{
Idx new_asub_tops = mctx->asub_tops * 2;
the same implementation of stdio extension API, except that some fields
have different naming conventions, or their access requires some casts. */
-/* Glibc 2.28 made _IO_IN_BACKUP private. For now, work around this
- problem by defining it ourselves. FIXME: Do not rely on glibc
+/* Glibc 2.28 made _IO_UNBUFFERED and _IO_IN_BACKUP private. For now, work
+ around this problem by defining them ourselves. FIXME: Do not rely on glibc
internals. */
-#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
-# define _IO_IN_BACKUP 0x100
+#if defined _IO_EOF_SEEN
+# if !defined _IO_UNBUFFERED
+# define _IO_UNBUFFERED 0x2
+# endif
+# if !defined _IO_IN_BACKUP
+# define _IO_IN_BACKUP 0x100
+# endif
#endif
/* BSD stdio derived implementations. */