summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2023-09-01 16:32:56 -0700
committerArnold D. Robbins <arnold@skeeve.com>2023-09-01 16:32:56 -0700
commit380a63d656d9ae3c8b91fcf63ef7d50a9ce7fe38 (patch)
tree79429a7962fbb80c16f084f5b5f3005ef15d9d18
parent1ee4860c1a99bd2bbf4fcfebce64ed62dad324a5 (diff)
parent2b09956d8f7e7bb7787e89bfd1de4104d2de7ac8 (diff)
downloadgawk-380a63d656d9ae3c8b91fcf63ef7d50a9ce7fe38.tar.gz
Merge branch 'master' into porting
-rw-r--r--ChangeLog13
-rw-r--r--builtin.c8
-rwxr-xr-xdoc/it/ChangeLog4
-rwxr-xr-xdoc/it/texinfo.tex489
-rw-r--r--node.c7
-rw-r--r--pc/ChangeLog4
-rw-r--r--pc/Makefile.tst11
-rw-r--r--test/ChangeLog6
-rw-r--r--test/Makefile.am7
-rw-r--r--test/Makefile.in13
-rw-r--r--test/Maketests6
-rwxr-xr-xtest/mtchi18n2.awk14
-rwxr-xr-xtest/mtchi18n2.ok4
13 files changed, 396 insertions, 190 deletions
diff --git a/ChangeLog b/ChangeLog
index 2fb55e1..b484d17 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2023-09-01 Miguel Pineiro Jr <mpj@pineiro.cc>
+
+ Fix the handling of zero-length matches in multibyte locales.
+ Thanks to Ed Morton <mortoneccc@comcast.net> for the report.
+
+ * builtin.c (do_match): Translate rstart (byte idx to char idx)
+ even when rlength is zero. For this we tweak the conversion of
+ rlength to keep it in bounds when rstart and rlength are both 0.
+ * node.c (str2wstr): Add an entry to the indices array for the
+ terminating null. It facilitates the tweak above and is needed
+ to translate the idx of a zero-width match at the end of the
+ string.
+
2023-08-27 Arnold D. Robbins <arnold@skeeve.com>
* re.c (make_regexp): When do_traditional and looking to see
diff --git a/builtin.c b/builtin.c
index e394cc3..2bc0aaa 100644
--- a/builtin.c
+++ b/builtin.c
@@ -2791,9 +2791,9 @@ do_match(int nargs)
size_t *wc_indices = NULL;
rlength = REEND(rp, t1->stptr) - RESTART(rp, t1->stptr); /* byte length */
- if (rlength > 0 && gawk_mb_cur_max > 1) {
+ if (gawk_mb_cur_max > 1) {
t1 = str2wstr(t1, & wc_indices);
- rlength = wc_indices[rstart + rlength - 1] - wc_indices[rstart] + 1;
+ rlength = wc_indices[rstart + rlength] - wc_indices[rstart];
rstart = wc_indices[rstart];
}
@@ -2816,9 +2816,9 @@ do_match(int nargs)
start = t1->stptr + s;
subpat_start = s;
subpat_len = len = SUBPATEND(rp, t1->stptr, ii) - s;
- if (len > 0 && gawk_mb_cur_max > 1) {
+ if (gawk_mb_cur_max > 1) {
subpat_start = wc_indices[s];
- subpat_len = wc_indices[s + len - 1] - subpat_start + 1;
+ subpat_len = wc_indices[s + len] - subpat_start;
}
it = make_string(start, len);
diff --git a/doc/it/ChangeLog b/doc/it/ChangeLog
index 6115205..9c9743c 100755
--- a/doc/it/ChangeLog
+++ b/doc/it/ChangeLog
@@ -1,3 +1,7 @@
+2023-08-29 Antonio Giovanni Colombo <azc100@gmail.com>
+
+ * texinfo.tex: Updated.
+
2023-06-18 Antonio Giovanni Colombo <azc100@gmail.com>
* gawktexi.in: Updated.
diff --git a/doc/it/texinfo.tex b/doc/it/texinfo.tex
index 633520b..e6be802 100755
--- a/doc/it/texinfo.tex
+++ b/doc/it/texinfo.tex
@@ -3,7 +3,7 @@
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2023-03-27.21}
+\def\texinfoversion{2023-08-13.14}
%
% Copyright 1985, 1986, 1988, 1990-2023 Free Software Foundation, Inc.
%
@@ -293,8 +293,7 @@
% \topmark doesn't work for the very first chapter (after the title
% page or the contents), so we use \firstmark there -- this gets us
% the mark with the chapter defs, unless the user sneaks in, e.g.,
-% @setcolor (or @url, or @link, etc.) between @contents and the very
-% first @chapter.
+% @setcolor (or @url etc.) between @contents and the very first @chapter.
\def\gettopheadingmarks{%
\ifcase0\the\savedtopmark\fi
\ifx\thischapter\empty \ifcase0\firstmark\fi \fi
@@ -445,42 +444,21 @@
}
% First remove any @comment, then any @c comment. Pass the result on to
-% \argcheckspaces.
+% \argremovespace.
\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
-\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
-
-% Each occurrence of `\^^M' or `<space>\^^M' is replaced by a single space.
-%
-% \argremovec might leave us with trailing space, e.g.,
+\def\argremovec#1\c#2\ArgTerm{\argremovespace#1$ $\ArgTerm}
+% \argremovec might leave us with trailing space, though; e.g.,
% @end itemize @c foo
-% This space token undergoes the same procedure and is eventually removed
-% by \finishparsearg.
-%
-\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
-\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
-\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
- \def\temp{#3}%
- \ifx\temp\empty
- % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
- \let\temp\finishparsearg
- \else
- \let\temp\argcheckspaces
- \fi
- % Put the space token in:
- \temp#1 #3\ArgTerm
-}
+% Note that the argument cannot contain the TeX $, as its catcode is
+% changed to \other when Texinfo source is read.
+\def\argremovespace#1 $#2\ArgTerm{\finishparsearg#1$\ArgTerm}
% If a _delimited_ argument is enclosed in braces, they get stripped; so
% to get _exactly_ the rest of the line, we had to prevent such situation.
-% We prepended an \empty token at the very beginning and we expand it now,
-% just before passing the control to \argtorun.
-% (Similarly, we have to think about #3 of \argcheckspacesY above: it is
-% either the null string, or it ends with \^^M---thus there is no danger
-% that a pair of braces would be stripped.
-%
-% But first, we have to remove the trailing space token.
-%
-\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+% We prepended an \empty token at the very beginning and we expand it
+% just before passing the control to \next.
+% (But first, we have to remove the remaining $ or two.)
+\def\finishparsearg#1$#2\ArgTerm{\expandafter\argtorun\expandafter{#1}}
% \parseargdef - define a command taking an argument on the line
@@ -4968,6 +4946,7 @@ $$%
\commondummyword\inforef {}%
\commondummyword\kbd {}%
\commondummyword\key {}%
+ \commondummyword\link {}%
\commondummyword\math {}%
\commondummyword\option {}%
\commondummyword\pxref {}%
@@ -5602,6 +5581,11 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\newdimen\entryrightmargin
\entryrightmargin=0pt
+% amount to indent subsequent lines in an entry when it spans more than
+% one line.
+\newdimen\entrycontskip
+\entrycontskip=1em
+
% for PDF output, whether to make the text of the entry a link to the page
% number. set for @contents and @shortcontents where there is only one
% page number.
@@ -5698,8 +5682,8 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% Determine how far we can stretch into the margin.
% This allows, e.g., "Appendix H GNU Free Documentation License" to
% fit on one line in @letterpaper format.
- \ifdim\entryrightmargin>2.1em
- \dimen@i=2.1em
+ \ifdim\entryrightmargin>1.5em
+ \dimen@i=1.5em
\else
\dimen@i=0em
\fi
@@ -5711,25 +5695,30 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\advance\dimen@ii by 1\dimen@i
\ifdim\wd\boxA > \dimen@ii % If the entry doesn't fit in one line
\ifdim\dimen@ > 0.8\dimen@ii % due to long index text
+ % Undo changes above
+ \advance \parfillskip by 0pt minus -1\dimen@i
+ \advance\dimen@ii by -1\dimen@i
+ %
% Try to split the text roughly evenly. \dimen@ will be the length of
% the first line.
\dimen@ = 0.7\dimen@
\dimen@ii = \hsize
\ifnum\dimen@>\dimen@ii
% If the entry is too long (for example, if it needs more than
- % two lines), use all the space in the first line.
+ % two lines), use the same line length for all lines.
\dimen@ = \dimen@ii
+ \else
+ \advance \dimen@ by 1\rightskip
\fi
\advance\leftskip by 0pt plus 1fill % ragged right
- \advance \dimen@ by 1\rightskip
\parshape = 2 0pt \dimen@ 0em \dimen@ii
% Ideally we'd add a finite glue at the end of the first line only,
% instead of using \parshape with explicit line lengths, but TeX
% doesn't seem to provide a way to do such a thing.
%
% Indent all lines but the first one.
- \advance\leftskip by 1em
- \advance\parindent by -1em
+ \advance\leftskip by \entrycontskip
+ \advance\parindent by -\entrycontskip
\fi\fi
\indent % start paragraph
\unhbox\boxA
@@ -5752,12 +5741,11 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\newskip\thinshrinkable
\skip\thinshrinkable=.15em minus .15em
-% Like plain.tex's \dotfill, except uses up at least 1 em.
+% Like plain.tex's \dotfill, except uses up at least 0.5 em.
% The filll stretch here overpowers both the fil and fill stretch to push
% the page number to the right.
\def\indexdotfill{\cleaders
- \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1filll}
-
+ \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 0.5em plus 1filll}
\def\primary #1{\line{#1\hfil}}
@@ -5810,7 +5798,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% below is chosen so that the gutter has the same value (well, +-<1pt)
% as it did when we hard-coded it.
%
- % We put the result in a separate register, \doublecolumhsize, so we
+ % We put the result in a separate register, \doublecolumnhsize, so we
% can restore it in \pagesofar, after \hsize itself has (potentially)
% been clobbered.
%
@@ -6748,6 +6736,82 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\input \tocreadfilename
}
+% process toc file to find the maximum width of the section numbers for
+% each chapter
+\def\findsecnowidths{%
+ \begingroup
+ \setupdatafile
+ \activecatcodes
+ \secentryfonts
+ % Redefinitions
+ \def\numchapentry##1##2##3##4{%
+ \def\curchapname{secnowidth-##2}%
+ \curchapmax=0pt
+ }%
+ \let\appentry\numchapentry
+ %
+ \def\numsecentry##1##2##3##4{%
+ \def\cursecname{secnowidth-##2}%
+ \cursecmax=0pt
+ %
+ \setbox0=\hbox{##2}%
+ \ifdim\wd0>\curchapmax
+ \curchapmax=\wd0
+ \expandafter\xdef\csname\curchapname\endcsname{\the\wd0}%
+ \fi
+ }%
+ \let\appsecentry\numsecentry
+ %
+ \def\numsubsecentry##1##2##3##4{%
+ \def\curssecname{secnowidth-##2}%
+ \curssecmax=0pt
+ %
+ \setbox0=\hbox{##2}%
+ \ifdim\wd0>\cursecmax
+ \cursecmax=\wd0
+ \expandafter\xdef\csname\cursecname\endcsname{\the\wd0}%
+ \fi
+ }%
+ \let\appsubsecentry\numsubsecentry
+ %
+ \def\numsubsubsecentry##1##2##3##4{%
+ \setbox0=\hbox{##2}%
+ \ifdim\wd0>\curssecmax
+ \curssecmax=\wd0
+ \expandafter\xdef\csname\curssecname\endcsname{\the\wd0}%
+ \fi
+ }%
+ \let\appsubsubsecentry\numsubsubsecentry
+ %
+ % Discard any output by outputting to dummy vbox, in case the toc file
+ % contains macros that we have not redefined above.
+ \setbox\dummybox\vbox\bgroup
+ \input \tocreadfilename\relax
+ \egroup
+ \endgroup
+}
+\newdimen\curchapmax
+\newdimen\cursecmax
+\newdimen\curssecmax
+
+
+% set #1 to the maximum section width for #2
+\def\retrievesecnowidth#1#2{%
+ \expandafter\let\expandafter\savedsecnowidth \csname secnowidth-#2\endcsname
+ \ifx\savedsecnowidth\relax
+ #1=0pt
+ \else
+ #1=\savedsecnowidth
+ \fi
+}
+\newdimen\secnowidthchap
+\secnowidthchap=0pt
+\newdimen\secnowidthsec
+\secnowidthsec=0pt
+\newdimen\secnowidthssec
+\secnowidthssec=0pt
+
+
\newskip\contentsrightmargin \contentsrightmargin=1in
\newcount\savepageno
\newcount\lastnegativepageno \lastnegativepageno = -1
@@ -6793,6 +6857,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\startcontents{\putwordTOC}%
\openin 1 \tocreadfilename\space
\ifeof 1 \else
+ \findsecnowidths
\readtocfile
\fi
\vfill \eject
@@ -6820,6 +6885,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\rm
\hyphenpenalty = 10000
\advance\baselineskip by 1pt % Open it up a little.
+ \extrasecnoskip=0.4pt
\def\numsecentry##1##2##3##4{}
\let\appsecentry = \numsecentry
\let\unnsecentry = \numsecentry
@@ -6855,8 +6921,6 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% This space should be enough, since a single number is .5em, and the
% widest letter (M) is 1em, at least in the Computer Modern fonts.
% But use \hss just in case.
- % (This space doesn't include the extra space that gets added after
- % the label; that gets put in by \shortchapentry above.)
%
% We'd like to right-justify chapter numbers, but that looks strange
% with appendix letters. And right-justifying numbers and
@@ -6866,10 +6930,15 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\hbox to 1em{#1\hss}%
}
-% These macros generate individual entries in the table of contents.
-% The first argument is the chapter or section name.
-% The last argument is the page number.
-% The arguments in between are the chapter number, section number, ...
+% These macros generate individual entries in the table of contents,
+% and are read in from the *.toc file.
+%
+% The arguments are like:
+% \def\numchapentry#1#2#3#4
+% #1 - the chapter or section name.
+% #2 - section number
+% #3 - level of section (e.g "chap", "sec")
+% #4 - page number
% Parts, in the main contents. Replace the part number, which doesn't
% exist, with an empty box. Let's hope all the numbers have the same width.
@@ -6882,7 +6951,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\vskip 0pt plus 5\baselineskip
\penalty-300
\vskip 0pt plus -5\baselineskip
- \dochapentry{\numeralbox\labelspace#1}{}%
+ \dochapentry{#1}{\numeralbox}{}%
}
%
% Parts, in the short toc.
@@ -6893,12 +6962,14 @@ might help (with 'rm \jobname.?? \jobname.??s')%
}
% Chapters, in the main contents.
-\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+\def\numchapentry#1#2#3#4{%
+ \retrievesecnowidth\secnowidthchap{#2}%
+ \dochapentry{#1}{#2}{#4}%
+}
% Chapters, in the short toc.
-% See comments in \dochapentry re vbox and related settings.
\def\shortchapentry#1#2#3#4{%
- \tocentry{\shortchaplabel{#2}\labelspace #1}{#4}%
+ \tocentry{#1}{\shortchaplabel{#2}}{#4}%
}
% Appendices, in the main contents.
@@ -6909,67 +6980,111 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\setbox0 = \hbox{\putwordAppendix{} M}%
\hbox to \wd0{\putwordAppendix{} #1\hss}}
%
-\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\hskip.7em#1}{#4}}
+\def\appentry#1#2#3#4{%
+ \retrievesecnowidth\secnowidthchap{#2}%
+ \dochapentry{\appendixbox{#2}\hskip.7em#1}{}{#4}%
+}
% Unnumbered chapters.
-\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
-\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{#4}}
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{}{#4}}
% Sections.
-\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\def\numsecentry#1#2#3#4{\dosecentry{#1}{#2}{#4}}
+
+\def\numsecentry#1#2#3#4{%
+ \retrievesecnowidth\secnowidthsec{#2}%
+ \dosecentry{#1}{#2}{#4}%
+}
\let\appsecentry=\numsecentry
-\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+\def\unnsecentry#1#2#3#4{%
+ \retrievesecnowidth\secnowidthsec{#2}%
+ \dosecentry{#1}{}{#4}%
+}
% Subsections.
-\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\def\numsubsecentry#1#2#3#4{%
+ \retrievesecnowidth\secnowidthssec{#2}%
+ \dosubsecentry{#1}{#2}{#4}%
+}
\let\appsubsecentry=\numsubsecentry
-\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+\def\unnsubsecentry#1#2#3#4{%
+ \retrievesecnowidth\secnowidthssec{#2}%
+ \dosubsecentry{#1}{}{#4}%
+}
% And subsubsections.
-\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#2}{#4}}
\let\appsubsubsecentry=\numsubsubsecentry
-\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{}{#4}}
% This parameter controls the indentation of the various levels.
% Same as \defaultparindent.
\newdimen\tocindent \tocindent = 15pt
-% Now for the actual typesetting. In all these, #1 is the text and #2 is the
-% page number.
+% Now for the actual typesetting. In all these, #1 is the text, #2 is
+% a section number if present, and #3 is the page number.
%
% If the toc has to be broken over pages, we want it to be at chapters
% if at all possible; hence the \penalty.
-\def\dochapentry#1#2{%
+\def\dochapentry#1#2#3{%
\penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
\begingroup
% Move the page numbers slightly to the right
\advance\entryrightmargin by -0.05em
\chapentryfonts
- \tocentry{#1}{#2}%
+ \extrasecnoskip=0.4em % separate chapter number more
+ \tocentry{#1}{#2}{#3}%
\endgroup
\nobreak\vskip .25\baselineskip plus.1\baselineskip
}
-\def\dosecentry#1#2{\begingroup
+\def\dosecentry#1#2#3{\begingroup
+ \secnowidth=\secnowidthchap
\secentryfonts \leftskip=\tocindent
- \tocentry{#1}{#2}%
+ \tocentry{#1}{#2}{#3}%
\endgroup}
-\def\dosubsecentry#1#2{\begingroup
+\def\dosubsecentry#1#2#3{\begingroup
+ \secnowidth=\secnowidthsec
\subsecentryfonts \leftskip=2\tocindent
- \tocentry{#1}{#2}%
+ \tocentry{#1}{#2}{#3}%
\endgroup}
-\def\dosubsubsecentry#1#2{\begingroup
+\def\dosubsubsecentry#1#2#3{\begingroup
+ \secnowidth=\secnowidthssec
\subsubsecentryfonts \leftskip=3\tocindent
- \tocentry{#1}{#2}%
+ \tocentry{#1}{#2}{#3}%
\endgroup}
-% We use the same \entry macro as for the index entries.
-\let\tocentry = \entry
+% Used for the maximum width of a section number so we can align
+% section titles.
+\newdimen\secnowidth
+\secnowidth=0pt
+\newdimen\extrasecnoskip
+\extrasecnoskip=0pt
-% Space between chapter (or whatever) number and the title.
-\def\labelspace{\hskip1em \relax}
+% \tocentry{TITLE}{SEC NO}{PAGE}
+%
+\def\tocentry#1#2#3{%
+ \def\secno{#2}%
+ \ifx\empty\secno
+ \entry{#1}{#3}%
+ \else
+ \ifdim 0pt=\secnowidth
+ \setbox0=\hbox{#2\hskip\labelspace\hskip\extrasecnoskip}%
+ \else
+ \advance\secnowidth by \labelspace
+ \advance\secnowidth by \extrasecnoskip
+ \setbox0=\hbox to \secnowidth{%
+ #2\hskip\labelspace\hskip\extrasecnoskip\hfill}%
+ \fi
+ \entrycontskip=\wd0
+ \entry{\box0 #1}{#3}%
+ \fi
+}
+\newdimen\labelspace
+\labelspace=0.6em
\def\chapentryfonts{\secfonts \rm}
\def\secentryfonts{\textfonts}
@@ -7620,9 +7735,13 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\def\deflineheader#1 #2 #3\endheader{%
\printdefname{#1}{}{#2}\magicamp\defunargs{#3\unskip}%
}
+
\def\deftypeline{%
\doingtypefntrue
- \parseargusing\activeparens{\printdefunline\deflineheader}%
+ \parseargusing\activeparens{\printdefunline\deftypelineheader}%
+}
+\def\deftypelineheader#1 #2 #3 #4\endheader{%
+ \printdefname{#1}{#2}{#3}\magicamp\defunargs{#4\unskip}%
}
% \makedefun{deffoo} (\deffooheader parameters) { (\deffooheader expansion) }
@@ -7814,6 +7933,8 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\tolerance=10000 \hbadness=10000
\exdentamount=\defbodyindent
{%
+ \def\^^M{}% for line continuation
+ %
% defun fonts. We use typewriter by default (used to be bold) because:
% . we're printing identifiers, they should be in tt in principle.
% . in languages with many accents, such as Czech or French, it's
@@ -7846,6 +7967,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% Print arguments. Use slanted for @def*, typewriter for @deftype*.
\def\defunargs#1{%
\bgroup
+ \def\^^M{}% for line continuation
\df \ifdoingtypefn \tt \else \sl \fi
\ifflagclear{txicodevaristt}{}%
{\def\var##1{{\setregularquotes \ttsl ##1}}}%
@@ -8207,7 +8329,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% Read recursive and nonrecursive macro bodies. (They're different since
% rec and nonrec macros end differently.)
%
-% We are in \macrobodyctxt, and the \xdef causes backslashshes in the macro
+% We are in \macrobodyctxt, and the \xdef causes backslashes in the macro
% body to be transformed.
% Set \macrobody to the body of the macro, and call \macrodef.
%
@@ -8754,6 +8876,11 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\fi
}
+% @nodedescription, @nodedescriptionblock - do nothing for TeX
+\parseargdef\nodedescription{}
+\def\nodedescriptionblock{\doignore{nodedescriptionblock}}
+
+
% @anchor{NAME} -- define xref target at arbitrary point.
%
\newcount\savesfregister
@@ -8835,109 +8962,11 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
\unsepspaces
%
- % Get args without leading/trailing spaces.
- \def\printedrefname{\ignorespaces #3}%
- \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}%
- %
+ \getprintedrefname{#1}{#3}{#5}%
\def\infofilename{\ignorespaces #4}%
\setbox\infofilenamebox = \hbox{\infofilename\unskip}%
%
- \def\printedmanual{\ignorespaces #5}%
- \setbox\printedmanualbox = \hbox{\printedmanual\unskip}%
- %
- % If the printed reference name (arg #3) was not explicitly given in
- % the @xref, figure out what we want to use.
- \ifdim \wd\printedrefnamebox = 0pt
- % No printed node name was explicitly given.
- \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax
- % Not auto section-title: use node name inside the square brackets.
- \def\printedrefname{\ignorespaces #1}%
- \else
- % Auto section-title: use chapter/section title inside
- % the square brackets if we have it.
- \ifdim \wd\printedmanualbox > 0pt
- % It is in another manual, so we don't have it; use node name.
- \def\printedrefname{\ignorespaces #1}%
- \else
- \ifhavexrefs
- % We (should) know the real title if we have the xref values.
- \def\printedrefname{\refx{#1-title}}%
- \else
- % Otherwise just copy the Info node name.
- \def\printedrefname{\ignorespaces #1}%
- \fi%
- \fi
- \fi
- \fi
- %
- % Make link in pdf output.
- \ifpdf
- % For pdfTeX and LuaTeX
- {\indexnofonts
- \makevalueexpandable
- \turnoffactive
- % This expands tokens, so do it after making catcode changes, so _
- % etc. don't get their TeX definitions. This ignores all spaces in
- % #4, including (wrongly) those in the middle of the filename.
- \getfilename{#4}%
- %
- % This (wrongly) does not take account of leading or trailing
- % spaces in #1, which should be ignored.
- \setpdfdestname{#1}%
- %
- \ifx\pdfdestname\empty
- \def\pdfdestname{Top}% no empty targets
- \fi
- %
- \leavevmode
- \startlink attr{/Border [0 0 0]}%
- \ifnum\filenamelength>0
- goto file{\the\filename.pdf} name{\pdfdestname}%
- \else
- goto name{\pdfmkpgn{\pdfdestname}}%
- \fi
- }%
- \setcolor{\linkcolor}%
- \else
- \ifx\XeTeXrevision\thisisundefined
- \else
- % For XeTeX
- {\indexnofonts
- \makevalueexpandable
- \turnoffactive
- % This expands tokens, so do it after making catcode changes, so _
- % etc. don't get their TeX definitions. This ignores all spaces in
- % #4, including (wrongly) those in the middle of the filename.
- \getfilename{#4}%
- %
- % This (wrongly) does not take account of leading or trailing
- % spaces in #1, which should be ignored.
- \setpdfdestname{#1}%
- %
- \ifx\pdfdestname\empty
- \def\pdfdestname{Top}% no empty targets
- \fi
- %
- \leavevmode
- \ifnum\filenamelength>0
- % With default settings,
- % XeTeX (xdvipdfmx) replaces link destination names with integers.
- % In this case, the replaced destination names of
- % remote PDFs are no longer known. In order to avoid a replacement,
- % you can use xdvipdfmx's command line option `-C 0x0010'.
- % If you use XeTeX 0.99996+ (TeX Live 2016+),
- % this command line option is no longer necessary
- % because we can use the `dvipdfmx:config' special.
- \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A
- << /S /GoToR /F (\the\filename.pdf) /D (\pdfdestname) >> >>}%
- \else
- \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A
- << /S /GoTo /D (\pdfdestname) >> >>}%
- \fi
- }%
- \setcolor{\linkcolor}%
- \fi
- \fi
+ \startxreflink{#1}{#4}%
{%
% Have to otherify everything special to allow the \csname to
% include an _ in the xref name, etc.
@@ -9018,6 +9047,93 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\endlink
\endgroup}
+% \getprintedrefname{NODE}{LABEL}{MANUAL}
+% - set \printedrefname and \printedmanual
+%
+\def\getprintedrefname#1#2#3{%
+ % Get args without leading/trailing spaces.
+ \def\printedrefname{\ignorespaces #2}%
+ \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}%
+ %
+ \def\printedmanual{\ignorespaces #3}%
+ \setbox\printedmanualbox = \hbox{\printedmanual\unskip}%
+ %
+ % If the printed reference name (arg #2) was not explicitly given in
+ % the @xref, figure out what we want to use.
+ \ifdim \wd\printedrefnamebox = 0pt
+ % No printed node name was explicitly given.
+ \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax
+ % Not auto section-title: use node name inside the square brackets.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ % Auto section-title: use chapter/section title inside
+ % the square brackets if we have it.
+ \ifdim \wd\printedmanualbox > 0pt
+ % It is in another manual, so we don't have it; use node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ \ifhavexrefs
+ % We (should) know the real title if we have the xref values.
+ \def\printedrefname{\refx{#1-title}}%
+ \else
+ % Otherwise just copy the Info node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \fi%
+ \fi
+ \fi
+ \fi
+}
+
+% \startxreflink{NODE}{FILE} - start link in pdf output.
+\def\startxreflink#1#2{%
+ \ifpdforxetex
+ % For pdfTeX and LuaTeX
+ {\indexnofonts
+ \makevalueexpandable
+ \turnoffactive
+ % This expands tokens, so do it after making catcode changes, so _
+ % etc. don't get their TeX definitions. This ignores all spaces in
+ % #2, including (wrongly) those in the middle of the filename.
+ \getfilename{#2}%
+ %
+ % This (wrongly) does not take account of leading or trailing
+ % spaces in #1, which should be ignored.
+ \setpdfdestname{#1}%
+ %
+ \ifx\pdfdestname\empty
+ \def\pdfdestname{Top}% no empty targets
+ \fi
+ %
+ \leavevmode
+ \ifpdf
+ \startlink attr{/Border [0 0 0]}%
+ \ifnum\filenamelength>0
+ goto file{\the\filename.pdf} name{\pdfdestname}%
+ \else
+ goto name{\pdfmkpgn{\pdfdestname}}%
+ \fi
+ \else % XeTeX
+ \ifnum\filenamelength>0
+ % With default settings,
+ % XeTeX (xdvipdfmx) replaces link destination names with integers.
+ % In this case, the replaced destination names of
+ % remote PDFs are no longer known. In order to avoid a replacement,
+ % you can use xdvipdfmx's command line option `-C 0x0010'.
+ % If you use XeTeX 0.99996+ (TeX Live 2016+),
+ % this command line option is no longer necessary
+ % because we can use the `dvipdfmx:config' special.
+ \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A
+ << /S /GoToR /F (\the\filename.pdf) /D (\pdfdestname) >> >>}%
+ \else
+ \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A
+ << /S /GoTo /D (\pdfdestname) >> >>}%
+ \fi
+ \fi
+ }%
+ \setcolor{\linkcolor}%
+ \fi
+}
+
% can be overridden in translation files
\def\putpageref#1{%
\space\putwordpage\tie\refx{#1-pg}}
@@ -9055,6 +9171,21 @@ might help (with 'rm \jobname.?? \jobname.??s')%
%
\def\xrefprintnodename#1{[#1]}
+% @link{NODENAME, LABEL, MANUAL} - create a "plain" link, with no
+% page number. Not useful if printed on paper.
+%
+\def\link#1{\linkX[#1,,,]}
+\def\linkX[#1,#2,#3,#4]{%
+ \begingroup
+ \unsepspaces
+ \getprintedrefname{#1}{#2}{#3}%
+ \startxreflink{#1}{#3}%
+ \printedrefname
+ \endlink
+ \endgroup
+}
+
+
% Things referred to by \setref.
%
\def\Ynothing{}
diff --git a/node.c b/node.c
index 5de4e08..bc4e777 100644
--- a/node.c
+++ b/node.c
@@ -851,7 +851,7 @@ str2wstr(NODE *n, size_t **ptr)
* Create the array.
*/
if (ptr != NULL) {
- ezalloc(*ptr, size_t *, sizeof(size_t) * n->stlen, "str2wstr");
+ ezalloc(*ptr, size_t *, sizeof(size_t) * (n->stlen + 1), "str2wstr");
}
sp = n->stptr;
@@ -923,6 +923,11 @@ str2wstr(NODE *n, size_t **ptr)
}
}
+ /* Needed for zero-length matches at the end of a string */
+ assert(sp - n->stptr == n->stlen);
+ if (ptr != NULL)
+ (*ptr)[sp - n->stptr] = i;
+
*wsp = L'\0';
n->wstlen = wsp - n->wstptr;
n->flags |= WSTRCUR;
diff --git a/pc/ChangeLog b/pc/ChangeLog
index da989e6..4e9904d 100644
--- a/pc/ChangeLog
+++ b/pc/ChangeLog
@@ -1,3 +1,7 @@
+2023-09-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.tst: Regenerated.
+
2023-08-20 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.tst: Regenerated.
diff --git a/pc/Makefile.tst b/pc/Makefile.tst
index 4f356ac..79fa1a6 100644
--- a/pc/Makefile.tst
+++ b/pc/Makefile.tst
@@ -235,7 +235,7 @@ LOCALE_CHARSET_TESTS = \
asort asorti backbigs1 backsmalls1 backsmalls2 \
fmttest fnarydel fnparydl jarebug lc_num1 mbfw1 \
mbprintf1 mbprintf2 mbprintf3 mbprintf4 mbprintf5 \
- mtchi18n nlstringtest rebt8b2 rtlenmb sort1 sprintfc
+ mtchi18n mtchi18n2 nlstringtest rebt8b2 rtlenmb sort1 sprintfc
SHLIB_TESTS = \
apiterm \
@@ -315,7 +315,8 @@ NEED_LOCALE_C = \
NEED_LOCALE_EN = \
backbigs1 backsmalls1 backsmalls2 commas concat4 dfamb1 ignrcas2 lc_num1 \
- mbfw1 mbprintf1 mbprintf3 mbprintf4 mbstr1 mbstr2 posix_compare \
+ mbfw1 mbprintf1 mbprintf3 mbprintf4 mbstr1 mbstr2 \
+ mtchi18n2 posix_compare \
printhuge reint2 rri1 subamp subi18n wideidx wideidx2 \
widesub widesub2 widesub3 widesub4 unicode1
@@ -3735,6 +3736,12 @@ mtchi18n:
AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+mtchi18n2:
+ @echo $@
+ @-[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; export GAWKLOCALE; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
rebt8b2:
@echo $@ $(ZOS_FAIL)
@-AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/ChangeLog b/test/ChangeLog
index be048db..0d30699 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,9 @@
+2023-09-01 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (EXTRA_DIST): New test, mtchi18n2.
+ * mtchi18n2.sh, mtchi18n2.ok: New files.
+ Thanks to Miguel Pineiro Jr <mpj@pineiro.cc> for the tests.
+
2023-08-20 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.am (EXTRA_DIST): New test, cmdlinefsbacknl2.
diff --git a/test/Makefile.am b/test/Makefile.am
index d1e8eeb..4876ce5 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -833,6 +833,8 @@ EXTRA_DIST = \
mtchi18n.awk \
mtchi18n.in \
mtchi18n.ok \
+ mtchi18n2.awk \
+ mtchi18n2.ok \
nasty.awk \
nasty.ok \
nasty2.awk \
@@ -1576,7 +1578,7 @@ LOCALE_CHARSET_TESTS = \
asort asorti backbigs1 backsmalls1 backsmalls2 \
fmttest fnarydel fnparydl jarebug lc_num1 mbfw1 \
mbprintf1 mbprintf2 mbprintf3 mbprintf4 mbprintf5 \
- mtchi18n nlstringtest rebt8b2 rtlenmb sort1 sprintfc
+ mtchi18n mtchi18n2 nlstringtest rebt8b2 rtlenmb sort1 sprintfc
SHLIB_TESTS = \
apiterm \
@@ -1651,7 +1653,8 @@ NEED_LOCALE_C = \
NEED_LOCALE_EN = \
backbigs1 backsmalls1 backsmalls2 commas concat4 dfamb1 ignrcas2 lc_num1 \
- mbfw1 mbprintf1 mbprintf3 mbprintf4 mbstr1 mbstr2 posix_compare \
+ mbfw1 mbprintf1 mbprintf3 mbprintf4 mbstr1 mbstr2 \
+ mtchi18n2 posix_compare \
printhuge reint2 rri1 subamp subi18n wideidx wideidx2 \
widesub widesub2 widesub3 widesub4 unicode1
diff --git a/test/Makefile.in b/test/Makefile.in
index 7669b39..ed83c6e 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -1097,6 +1097,8 @@ EXTRA_DIST = \
mtchi18n.awk \
mtchi18n.in \
mtchi18n.ok \
+ mtchi18n2.awk \
+ mtchi18n2.ok \
nasty.awk \
nasty.ok \
nasty2.awk \
@@ -1836,7 +1838,7 @@ LOCALE_CHARSET_TESTS = \
asort asorti backbigs1 backsmalls1 backsmalls2 \
fmttest fnarydel fnparydl jarebug lc_num1 mbfw1 \
mbprintf1 mbprintf2 mbprintf3 mbprintf4 mbprintf5 \
- mtchi18n nlstringtest rebt8b2 rtlenmb sort1 sprintfc
+ mtchi18n mtchi18n2 nlstringtest rebt8b2 rtlenmb sort1 sprintfc
SHLIB_TESTS = \
apiterm \
@@ -1916,7 +1918,8 @@ NEED_LOCALE_C = \
NEED_LOCALE_EN = \
backbigs1 backsmalls1 backsmalls2 commas concat4 dfamb1 ignrcas2 lc_num1 \
- mbfw1 mbprintf1 mbprintf3 mbprintf4 mbstr1 mbstr2 posix_compare \
+ mbfw1 mbprintf1 mbprintf3 mbprintf4 mbstr1 mbstr2 \
+ mtchi18n2 posix_compare \
printhuge reint2 rri1 subamp subi18n wideidx wideidx2 \
widesub widesub2 widesub3 widesub4 unicode1
@@ -5509,6 +5512,12 @@ mtchi18n:
AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+mtchi18n2:
+ @echo $@
+ @-[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; export GAWKLOCALE; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
rebt8b2:
@echo $@ $(ZOS_FAIL)
@-AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/Maketests b/test/Maketests
index b86f2af..84d1881 100644
--- a/test/Maketests
+++ b/test/Maketests
@@ -2407,6 +2407,12 @@ mtchi18n:
AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+mtchi18n2:
+ @echo $@
+ @-[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; export GAWKLOCALE; \
+ AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
rebt8b2:
@echo $@ $(ZOS_FAIL)
@-AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/mtchi18n2.awk b/test/mtchi18n2.awk
new file mode 100755
index 0000000..7043386
--- /dev/null
+++ b/test/mtchi18n2.awk
@@ -0,0 +1,14 @@
+BEGIN {
+ match("\342\200\257", /^/, m)
+ print RSTART, RLENGTH
+
+ #match("\342\200\257", /^(a?)\u202F(b?)$/, m)
+ match("\342\200\257", /^(a?)\342\200\257(b?)$/, m)
+ print RSTART, RLENGTH, m[1,"start"], m[1,"length"], m[2, "start"], m[2, "length"]
+
+ match("\342\200\257", /$/, m)
+ print RSTART, RLENGTH
+
+ match("\342\200\257ac", /a(b?)c/, m)
+ print RSTART, RLENGTH, m[1,"start"], m[1,"length"]
+}
diff --git a/test/mtchi18n2.ok b/test/mtchi18n2.ok
new file mode 100755
index 0000000..1064864
--- /dev/null
+++ b/test/mtchi18n2.ok
@@ -0,0 +1,4 @@
+1 0
+1 1 1 0 2 0
+2 0
+2 2 3 0