aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2008-04-12 20:45:58 +0000
committerChristian Grothoff <christian@grothoff.org>2008-04-12 20:45:58 +0000
commit5e9c5b7621d550d92f5565622ad0bf147d4d8a3f (patch)
tree39a50077b389cfea554cdc8c9ce94adaa8c05f96
parenta7cd9f029a61823c9285318a1dfd283ffac1912b (diff)
downloadlibmicrohttpd-5e9c5b7621d550d92f5565622ad0bf147d4d8a3f.tar.gz
libmicrohttpd-5e9c5b7621d550d92f5565622ad0bf147d4d8a3f.zip
moving stuff around
-rw-r--r--configure.ac11
-rw-r--r--doc/texinfo.tex2008
-rw-r--r--src/Makefile.am10
-rw-r--r--src/daemon/Makefile.am130
-rw-r--r--src/examples/Makefile.am18
-rw-r--r--src/examples/fileserver_example.c (renamed from src/daemon/fileserver_example.c)0
-rw-r--r--src/examples/minimal_example.c (renamed from src/daemon/minimal_example.c)0
-rw-r--r--src/testcurl/Makefile.am126
-rw-r--r--src/testcurl/daemontest.c (renamed from src/daemon/daemontest.c)0
-rw-r--r--src/testcurl/daemontest_get.c (renamed from src/daemon/daemontest_get.c)0
-rw-r--r--src/testcurl/daemontest_get_chunked.c (renamed from src/daemon/daemontest_get_chunked.c)0
-rw-r--r--src/testcurl/daemontest_large_put.c (renamed from src/daemon/daemontest_large_put.c)0
-rw-r--r--src/testcurl/daemontest_long_header.c (renamed from src/daemon/daemontest_long_header.c)0
-rw-r--r--src/testcurl/daemontest_put.c (renamed from src/daemon/daemontest_put.c)0
-rw-r--r--src/testcurl/daemontest_put_chunked.c (renamed from src/daemon/daemontest_put_chunked.c)0
-rw-r--r--src/testzzuf/Makefile.am125
-rw-r--r--src/testzzuf/daemontest.c163
-rw-r--r--src/testzzuf/daemontest_get.c330
-rw-r--r--src/testzzuf/daemontest_get_chunked.c364
-rw-r--r--src/testzzuf/daemontest_large_put.c404
-rw-r--r--src/testzzuf/daemontest_long_header.c240
-rw-r--r--src/testzzuf/daemontest_put.c375
-rw-r--r--src/testzzuf/daemontest_put_chunked.c383
23 files changed, 4293 insertions, 394 deletions
diff --git a/configure.ac b/configure.ac
index 975bb519..0c4040fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -134,6 +134,12 @@ then
134 AC_DEFINE([HAVE_MESSAGES],[1],[Include error messages]) 134 AC_DEFINE([HAVE_MESSAGES],[1],[Include error messages])
135fi 135fi
136 136
137# optional: have zzuf, socat?
138AC_CHECK_PROG([HAVE_ZZUF],[zzuf], 1, 0)
139AC_CHECK_PROG([HAVE_SOCAT],[socat], 1, 0)
140
141AM_CONDITIONAL(HAVE_ZZUF, test 0 != $HAVE_ZZUF)
142AM_CONDITIONAL(HAVE_SOCAT, test 0 != $HAVE_SOCAT)
137 143
138AC_SUBST(CPPFLAGS) 144AC_SUBST(CPPFLAGS)
139AC_SUBST(LIBS) 145AC_SUBST(LIBS)
@@ -147,7 +153,10 @@ doc/Makefile
147m4/Makefile 153m4/Makefile
148src/Makefile 154src/Makefile
149src/include/Makefile 155src/include/Makefile
150src/daemon/Makefile]) 156src/daemon/Makefile
157src/examples/Makefile
158src/testcurl/Makefile
159src/testzzuf/Makefile])
151AC_OUTPUT 160AC_OUTPUT
152 161
153if test "$curl" != 1 162if test "$curl" != 1
diff --git a/doc/texinfo.tex b/doc/texinfo.tex
index 80836223..d2b264dd 100644
--- a/doc/texinfo.tex
+++ b/doc/texinfo.tex
@@ -3,16 +3,16 @@
3% Load plain if necessary, i.e., if running under initex. 3% Load plain if necessary, i.e., if running under initex.
4\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi 4\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
5% 5%
6\def\texinfoversion{2006-10-04.17} 6\def\texinfoversion{2007-12-02.17}
7% 7%
8% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 8% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 2007,
9% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free 9% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
10% Software Foundation, Inc. 10% 2007 Free Software Foundation, Inc.
11% 11%
12% This texinfo.tex file is free software; you can redistribute it and/or 12% This texinfo.tex file is free software: you can redistribute it and/or
13% modify it under the terms of the GNU General Public License as 13% modify it under the terms of the GNU General Public License as
14% published by the Free Software Foundation; either version 2, or (at 14% published by the Free Software Foundation, either version 3 of the
15% your option) any later version. 15% License, or (at your option) any later version.
16% 16%
17% This texinfo.tex file is distributed in the hope that it will be 17% This texinfo.tex file is distributed in the hope that it will be
18% useful, but WITHOUT ANY WARRANTY; without even the implied warranty 18% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
@@ -20,9 +20,7 @@
20% General Public License for more details. 20% General Public License for more details.
21% 21%
22% You should have received a copy of the GNU General Public License 22% You should have received a copy of the GNU General Public License
23% along with this texinfo.tex file; see the file COPYING. If not, write 23% along with this program. If not, see <http://www.gnu.org/licenses/>.
24% to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25% Boston, MA 02110-1301, USA.
26% 24%
27% As a special exception, when this file is read by TeX when processing 25% As a special exception, when this file is read by TeX when processing
28% a Texinfo source document, you may use the result without 26% a Texinfo source document, you may use the result without
@@ -67,7 +65,7 @@
67\everyjob{\message{[Texinfo version \texinfoversion]}% 65\everyjob{\message{[Texinfo version \texinfoversion]}%
68 \catcode`+=\active \catcode`\_=\active} 66 \catcode`+=\active \catcode`\_=\active}
69 67
70\message{Basics,} 68
71\chardef\other=12 69\chardef\other=12
72 70
73% We never want plain's \outer definition of \+ in Texinfo. 71% We never want plain's \outer definition of \+ in Texinfo.
@@ -279,6 +277,50 @@
279\newdimen\cornerthick \cornerthick=.3pt 277\newdimen\cornerthick \cornerthick=.3pt
280\newdimen\topandbottommargin \topandbottommargin=.75in 278\newdimen\topandbottommargin \topandbottommargin=.75in
281 279
280% Output a mark which sets \thischapter, \thissection and \thiscolor.
281% We dump everything together because we only have one kind of mark.
282% This works because we only use \botmark / \topmark, not \firstmark.
283%
284% A mark contains a subexpression of the \ifcase ... \fi construct.
285% \get*marks macros below extract the needed part using \ifcase.
286%
287% Another complication is to let the user choose whether \thischapter
288% (\thissection) refers to the chapter (section) in effect at the top
289% of a page, or that at the bottom of a page. The solution is
290% described on page 260 of The TeXbook. It involves outputting two
291% marks for the sectioning macros, one before the section break, and
292% one after. I won't pretend I can describe this better than DEK...
293\def\domark{%
294 \toks0=\expandafter{\lastchapterdefs}%
295 \toks2=\expandafter{\lastsectiondefs}%
296 \toks4=\expandafter{\prevchapterdefs}%
297 \toks6=\expandafter{\prevsectiondefs}%
298 \toks8=\expandafter{\lastcolordefs}%
299 \mark{%
300 \the\toks0 \the\toks2
301 \noexpand\or \the\toks4 \the\toks6
302 \noexpand\else \the\toks8
303 }%
304}
305% \topmark doesn't work for the very first chapter (after the title
306% page or the contents), so we use \firstmark there -- this gets us
307% the mark with the chapter defs, unless the user sneaks in, e.g.,
308% @setcolor (or @url, or @link, etc.) between @contents and the very
309% first @chapter.
310\def\gettopheadingmarks{%
311 \ifcase0\topmark\fi
312 \ifx\thischapter\empty \ifcase0\firstmark\fi \fi
313}
314\def\getbottomheadingmarks{\ifcase1\botmark\fi}
315\def\getcolormarks{\ifcase2\topmark\fi}
316
317% Avoid "undefined control sequence" errors.
318\def\lastchapterdefs{}
319\def\lastsectiondefs{}
320\def\prevchapterdefs{}
321\def\prevsectiondefs{}
322\def\lastcolordefs{}
323
282% Main output routine. 324% Main output routine.
283\chardef\PAGE = 255 325\chardef\PAGE = 255
284\output = {\onepageout{\pagecontents\PAGE}} 326\output = {\onepageout{\pagecontents\PAGE}}
@@ -296,7 +338,9 @@
296 % 338 %
297 % Do this outside of the \shipout so @code etc. will be expanded in 339 % Do this outside of the \shipout so @code etc. will be expanded in
298 % the headline as they should be, not taken literally (outputting ''code). 340 % the headline as they should be, not taken literally (outputting ''code).
341 \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
299 \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% 342 \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
343 \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
300 \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% 344 \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
301 % 345 %
302 {% 346 {%
@@ -375,7 +419,7 @@
375% marginal hacks, juha@viisa.uucp (Juha Takala) 419% marginal hacks, juha@viisa.uucp (Juha Takala)
376\ifvoid\margin\else % marginal info is present 420\ifvoid\margin\else % marginal info is present
377 \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi 421 \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
378\dimen@=\dp#1 \unvbox#1 422\dimen@=\dp#1\relax \unvbox#1\relax
379\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi 423\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
380\ifr@ggedbottom \kern-\dimen@ \vfil \fi} 424\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
381} 425}
@@ -1225,8 +1269,9 @@ where each line of input produces a line of output.}
1225 1269
1226% To handle parens, we must adopt a different approach, since parens are 1270% To handle parens, we must adopt a different approach, since parens are
1227% not active characters. hyperref.dtx (which has the same problem as 1271% not active characters. hyperref.dtx (which has the same problem as
1228% us) handles it with this amazing macro to replace tokens. I've 1272% us) handles it with this amazing macro to replace tokens, with minor
1229% tinkered with it a little for texinfo, but it's definitely from there. 1273% changes for Texinfo. It is included here under the GPL by permission
1274% from the author, Heiko Oberdiek.
1230% 1275%
1231% #1 is the tokens to replace. 1276% #1 is the tokens to replace.
1232% #2 is the replacement. 1277% #2 is the replacement.
@@ -1255,13 +1300,83 @@ where each line of input produces a line of output.}
1255 \HyPsdSubst{)}{\realbackslash)}{#1}% 1300 \HyPsdSubst{)}{\realbackslash)}{#1}%
1256} 1301}
1257 1302
1303\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
1304with PDF output, and none of those formats could be found. (.eps cannot
1305be supported due to the design of the PDF format; use regular TeX (DVI
1306output) for that.)}
1307
1258\ifpdf 1308\ifpdf
1259 \input pdfcolor 1309 %
1260 \pdfcatalog{/PageMode /UseOutlines}% 1310 % Color manipulation macros based on pdfcolor.tex.
1311 \def\cmykDarkRed{0.28 1 1 0.35}
1312 \def\cmykBlack{0 0 0 1}
1313 %
1314 \def\pdfsetcolor#1{\pdfliteral{#1 k}}
1315 % Set color, and create a mark which defines \thiscolor accordingly,
1316 % so that \makeheadline knows which color to restore.
1317 \def\setcolor#1{%
1318 \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}%
1319 \domark
1320 \pdfsetcolor{#1}%
1321 }
1322 %
1323 \def\maincolor{\cmykBlack}
1324 \pdfsetcolor{\maincolor}
1325 \edef\thiscolor{\maincolor}
1326 \def\lastcolordefs{}
1327 %
1328 \def\makefootline{%
1329 \baselineskip24pt
1330 \line{\pdfsetcolor{\maincolor}\the\footline}%
1331 }
1332 %
1333 \def\makeheadline{%
1334 \vbox to 0pt{%
1335 \vskip-22.5pt
1336 \line{%
1337 \vbox to8.5pt{}%
1338 % Extract \thiscolor definition from the marks.
1339 \getcolormarks
1340 % Typeset the headline with \maincolor, then restore the color.
1341 \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}%
1342 }%
1343 \vss
1344 }%
1345 \nointerlineskip
1346 }
1347 %
1348 %
1349 \pdfcatalog{/PageMode /UseOutlines}
1350 %
1261 % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). 1351 % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
1262 \def\dopdfimage#1#2#3{% 1352 \def\dopdfimage#1#2#3{%
1263 \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% 1353 \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
1264 \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% 1354 \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
1355 %
1356 % pdftex (and the PDF format) support .png, .jpg, .pdf (among
1357 % others). Let's try in that order.
1358 \let\pdfimgext=\empty
1359 \begingroup
1360 \openin 1 #1.png \ifeof 1
1361 \openin 1 #1.jpg \ifeof 1
1362 \openin 1 #1.jpeg \ifeof 1
1363 \openin 1 #1.JPG \ifeof 1
1364 \openin 1 #1.pdf \ifeof 1
1365 \errhelp = \nopdfimagehelp
1366 \errmessage{Could not find image file #1 for pdf}%
1367 \else \gdef\pdfimgext{pdf}%
1368 \fi
1369 \else \gdef\pdfimgext{JPG}%
1370 \fi
1371 \else \gdef\pdfimgext{jpeg}%
1372 \fi
1373 \else \gdef\pdfimgext{jpg}%
1374 \fi
1375 \else \gdef\pdfimgext{png}%
1376 \fi
1377 \closein 1
1378 \endgroup
1379 %
1265 % without \immediate, pdftex seg faults when the same image is 1380 % without \immediate, pdftex seg faults when the same image is
1266 % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) 1381 % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.)
1267 \ifnum\pdftexversion < 14 1382 \ifnum\pdftexversion < 14
@@ -1272,28 +1387,35 @@ where each line of input produces a line of output.}
1272 \ifdim \wd0 >0pt width \imagewidth \fi 1387 \ifdim \wd0 >0pt width \imagewidth \fi
1273 \ifdim \wd2 >0pt height \imageheight \fi 1388 \ifdim \wd2 >0pt height \imageheight \fi
1274 \ifnum\pdftexversion<13 1389 \ifnum\pdftexversion<13
1275 #1.pdf% 1390 #1.\pdfimgext
1276 \else 1391 \else
1277 {#1.pdf}% 1392 {#1.\pdfimgext}%
1278 \fi 1393 \fi
1279 \ifnum\pdftexversion < 14 \else 1394 \ifnum\pdftexversion < 14 \else
1280 \pdfrefximage \pdflastximage 1395 \pdfrefximage \pdflastximage
1281 \fi} 1396 \fi}
1397 %
1282 \def\pdfmkdest#1{{% 1398 \def\pdfmkdest#1{{%
1283 % We have to set dummies so commands such as @code, and characters 1399 % We have to set dummies so commands such as @code, and characters
1284 % such as \, aren't expanded when present in a section title. 1400 % such as \, aren't expanded when present in a section title.
1285 \atdummies 1401 \indexnofonts
1402 \turnoffactive
1286 \activebackslashdouble 1403 \activebackslashdouble
1404 \makevalueexpandable
1287 \def\pdfdestname{#1}% 1405 \def\pdfdestname{#1}%
1288 \backslashparens\pdfdestname 1406 \backslashparens\pdfdestname
1289 \pdfdest name{\pdfdestname} xyz% 1407 \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
1290 }}% 1408 }}
1291 % 1409 %
1292 % used to mark target names; must be expandable. 1410 % used to mark target names; must be expandable.
1293 \def\pdfmkpgn#1{#1}% 1411 \def\pdfmkpgn#1{#1}
1412 %
1413 % by default, use a color that is dark enough to print on paper as
1414 % nearly black, but still distinguishable for online viewing.
1415 \def\urlcolor{\cmykDarkRed}
1416 \def\linkcolor{\cmykDarkRed}
1417 \def\endlink{\setcolor{\maincolor}\pdfendlink}
1294 % 1418 %
1295 \let\linkcolor = \Blue % was Cyan, but that seems light?
1296 \def\endlink{\Black\pdfendlink}
1297 % Adding outlines to PDF; macros for calculating structure of outlines 1419 % Adding outlines to PDF; macros for calculating structure of outlines
1298 % come from Petr Olsak 1420 % come from Petr Olsak
1299 \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% 1421 \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
@@ -1395,7 +1517,7 @@ where each line of input produces a line of output.}
1395 \indexnofonts 1517 \indexnofonts
1396 \setupdatafile 1518 \setupdatafile
1397 \catcode`\\=\active \otherbackslash 1519 \catcode`\\=\active \otherbackslash
1398 \input \jobname.toc 1520 \input \tocreadfilename
1399 \endgroup 1521 \endgroup
1400 } 1522 }
1401 % 1523 %
@@ -1425,7 +1547,7 @@ where each line of input produces a line of output.}
1425 \def\@{@}% 1547 \def\@{@}%
1426 \let\/=\empty 1548 \let\/=\empty
1427 \makevalueexpandable 1549 \makevalueexpandable
1428 \leavevmode\Red 1550 \leavevmode\setcolor{\urlcolor}%
1429 \startlink attr{/Border [0 0 0]}% 1551 \startlink attr{/Border [0 0 0]}%
1430 user{/Subtype /Link /A << /S /URI /URI (#1) >>}% 1552 user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
1431 \endgroup} 1553 \endgroup}
@@ -1452,13 +1574,14 @@ where each line of input produces a line of output.}
1452 {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} 1574 {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
1453 \def\pdflink#1{% 1575 \def\pdflink#1{%
1454 \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} 1576 \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
1455 \linkcolor #1\endlink} 1577 \setcolor{\linkcolor}#1\endlink}
1456 \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} 1578 \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
1457\else 1579\else
1458 \let\pdfmkdest = \gobble 1580 \let\pdfmkdest = \gobble
1459 \let\pdfurl = \gobble 1581 \let\pdfurl = \gobble
1460 \let\endlink = \relax 1582 \let\endlink = \relax
1461 \let\linkcolor = \relax 1583 \let\setcolor = \gobble
1584 \let\pdfsetcolor = \gobble
1462 \let\pdfmakeoutlines = \relax 1585 \let\pdfmakeoutlines = \relax
1463\fi % \ifx\pdfoutput 1586\fi % \ifx\pdfoutput
1464 1587
@@ -1505,8 +1628,12 @@ where each line of input produces a line of output.}
1505\def\strutheightpercent{.70833} 1628\def\strutheightpercent{.70833}
1506\def\strutdepthpercent {.29167} 1629\def\strutdepthpercent {.29167}
1507% 1630%
1631% can get a sort of poor man's double spacing by redefining this.
1632\def\baselinefactor{1}
1633%
1508\def\setleading#1{% 1634\def\setleading#1{%
1509 \normalbaselineskip = #1\relax 1635 \dimen0 = #1\relax
1636 \normalbaselineskip = \baselinefactor\dimen0
1510 \normallineskip = \lineskipfactor\normalbaselineskip 1637 \normallineskip = \lineskipfactor\normalbaselineskip
1511 \normalbaselines 1638 \normalbaselines
1512 \setbox\strutbox =\hbox{% 1639 \setbox\strutbox =\hbox{%
@@ -1515,12 +1642,279 @@ where each line of input produces a line of output.}
1515 }% 1642 }%
1516} 1643}
1517 1644
1645% PDF CMaps. See also LaTeX's t1.cmap.
1646%
1647% do nothing with this by default.
1648\expandafter\let\csname cmapOT1\endcsname\gobble
1649\expandafter\let\csname cmapOT1IT\endcsname\gobble
1650\expandafter\let\csname cmapOT1TT\endcsname\gobble
1651
1652% if we are producing pdf, and we have \pdffontattr, then define cmaps.
1653% (\pdffontattr was introduced many years ago, but people still run
1654% older pdftex's; it's easy to conditionalize, so we do.)
1655\ifpdf \ifx\pdffontattr\undefined \else
1656 \begingroup
1657 \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
1658 \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
1659%%DocumentNeededResources: ProcSet (CIDInit)
1660%%IncludeResource: ProcSet (CIDInit)
1661%%BeginResource: CMap (TeX-OT1-0)
1662%%Title: (TeX-OT1-0 TeX OT1 0)
1663%%Version: 1.000
1664%%EndComments
1665/CIDInit /ProcSet findresource begin
166612 dict begin
1667begincmap
1668/CIDSystemInfo
1669<< /Registry (TeX)
1670/Ordering (OT1)
1671/Supplement 0
1672>> def
1673/CMapName /TeX-OT1-0 def
1674/CMapType 2 def
16751 begincodespacerange
1676<00> <7F>
1677endcodespacerange
16788 beginbfrange
1679<00> <01> <0393>
1680<09> <0A> <03A8>
1681<23> <26> <0023>
1682<28> <3B> <0028>
1683<3F> <5B> <003F>
1684<5D> <5E> <005D>
1685<61> <7A> <0061>
1686<7B> <7C> <2013>
1687endbfrange
168840 beginbfchar
1689<02> <0398>
1690<03> <039B>
1691<04> <039E>
1692<05> <03A0>
1693<06> <03A3>
1694<07> <03D2>
1695<08> <03A6>
1696<0B> <00660066>
1697<0C> <00660069>
1698<0D> <0066006C>
1699<0E> <006600660069>
1700<0F> <00660066006C>
1701<10> <0131>
1702<11> <0237>
1703<12> <0060>
1704<13> <00B4>
1705<14> <02C7>
1706<15> <02D8>
1707<16> <00AF>
1708<17> <02DA>
1709<18> <00B8>
1710<19> <00DF>
1711<1A> <00E6>
1712<1B> <0153>
1713<1C> <00F8>
1714<1D> <00C6>
1715<1E> <0152>
1716<1F> <00D8>
1717<21> <0021>
1718<22> <201D>
1719<27> <2019>
1720<3C> <00A1>
1721<3D> <003D>
1722<3E> <00BF>
1723<5C> <201C>
1724<5F> <02D9>
1725<60> <2018>
1726<7D> <02DD>
1727<7E> <007E>
1728<7F> <00A8>
1729endbfchar
1730endcmap
1731CMapName currentdict /CMap defineresource pop
1732end
1733end
1734%%EndResource
1735%%EOF
1736 }\endgroup
1737 \expandafter\edef\csname cmapOT1\endcsname#1{%
1738 \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
1739 }%
1740%
1741% \cmapOT1IT
1742 \begingroup
1743 \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
1744 \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
1745%%DocumentNeededResources: ProcSet (CIDInit)
1746%%IncludeResource: ProcSet (CIDInit)
1747%%BeginResource: CMap (TeX-OT1IT-0)
1748%%Title: (TeX-OT1IT-0 TeX OT1IT 0)
1749%%Version: 1.000
1750%%EndComments
1751/CIDInit /ProcSet findresource begin
175212 dict begin
1753begincmap
1754/CIDSystemInfo
1755<< /Registry (TeX)
1756/Ordering (OT1IT)
1757/Supplement 0
1758>> def
1759/CMapName /TeX-OT1IT-0 def
1760/CMapType 2 def
17611 begincodespacerange
1762<00> <7F>
1763endcodespacerange
17648 beginbfrange
1765<00> <01> <0393>
1766<09> <0A> <03A8>
1767<25> <26> <0025>
1768<28> <3B> <0028>
1769<3F> <5B> <003F>
1770<5D> <5E> <005D>
1771<61> <7A> <0061>
1772<7B> <7C> <2013>
1773endbfrange
177442 beginbfchar
1775<02> <0398>
1776<03> <039B>
1777<04> <039E>
1778<05> <03A0>
1779<06> <03A3>
1780<07> <03D2>
1781<08> <03A6>
1782<0B> <00660066>
1783<0C> <00660069>
1784<0D> <0066006C>
1785<0E> <006600660069>
1786<0F> <00660066006C>
1787<10> <0131>
1788<11> <0237>
1789<12> <0060>
1790<13> <00B4>
1791<14> <02C7>
1792<15> <02D8>
1793<16> <00AF>
1794<17> <02DA>
1795<18> <00B8>
1796<19> <00DF>
1797<1A> <00E6>
1798<1B> <0153>
1799<1C> <00F8>
1800<1D> <00C6>
1801<1E> <0152>
1802<1F> <00D8>
1803<21> <0021>
1804<22> <201D>
1805<23> <0023>
1806<24> <00A3>
1807<27> <2019>
1808<3C> <00A1>
1809<3D> <003D>
1810<3E> <00BF>
1811<5C> <201C>
1812<5F> <02D9>
1813<60> <2018>
1814<7D> <02DD>
1815<7E> <007E>
1816<7F> <00A8>
1817endbfchar
1818endcmap
1819CMapName currentdict /CMap defineresource pop
1820end
1821end
1822%%EndResource
1823%%EOF
1824 }\endgroup
1825 \expandafter\edef\csname cmapOT1IT\endcsname#1{%
1826 \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
1827 }%
1828%
1829% \cmapOT1TT
1830 \begingroup
1831 \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
1832 \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
1833%%DocumentNeededResources: ProcSet (CIDInit)
1834%%IncludeResource: ProcSet (CIDInit)
1835%%BeginResource: CMap (TeX-OT1TT-0)
1836%%Title: (TeX-OT1TT-0 TeX OT1TT 0)
1837%%Version: 1.000
1838%%EndComments
1839/CIDInit /ProcSet findresource begin
184012 dict begin
1841begincmap
1842/CIDSystemInfo
1843<< /Registry (TeX)
1844/Ordering (OT1TT)
1845/Supplement 0
1846>> def
1847/CMapName /TeX-OT1TT-0 def
1848/CMapType 2 def
18491 begincodespacerange
1850<00> <7F>
1851endcodespacerange
18525 beginbfrange
1853<00> <01> <0393>
1854<09> <0A> <03A8>
1855<21> <26> <0021>
1856<28> <5F> <0028>
1857<61> <7E> <0061>
1858endbfrange
185932 beginbfchar
1860<02> <0398>
1861<03> <039B>
1862<04> <039E>
1863<05> <03A0>
1864<06> <03A3>
1865<07> <03D2>
1866<08> <03A6>
1867<0B> <2191>
1868<0C> <2193>
1869<0D> <0027>
1870<0E> <00A1>
1871<0F> <00BF>
1872<10> <0131>
1873<11> <0237>
1874<12> <0060>
1875<13> <00B4>
1876<14> <02C7>
1877<15> <02D8>
1878<16> <00AF>
1879<17> <02DA>
1880<18> <00B8>
1881<19> <00DF>
1882<1A> <00E6>
1883<1B> <0153>
1884<1C> <00F8>
1885<1D> <00C6>
1886<1E> <0152>
1887<1F> <00D8>
1888<20> <2423>
1889<27> <2019>
1890<60> <2018>
1891<7F> <00A8>
1892endbfchar
1893endcmap
1894CMapName currentdict /CMap defineresource pop
1895end
1896end
1897%%EndResource
1898%%EOF
1899 }\endgroup
1900 \expandafter\edef\csname cmapOT1TT\endcsname#1{%
1901 \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
1902 }%
1903\fi\fi
1904
1518 1905
1519% Set the font macro #1 to the font named #2, adding on the 1906% Set the font macro #1 to the font named #2, adding on the
1520% specified font prefix (normally `cm'). 1907% specified font prefix (normally `cm').
1521% #3 is the font's design size, #4 is a scale factor 1908% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
1522\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} 1909% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass
1523 1910% empty to omit).
1911\def\setfont#1#2#3#4#5{%
1912 \font#1=\fontprefix#2#3 scaled #4
1913 \csname cmap#5\endcsname#1%
1914}
1915% This is what gets called when #5 of \setfont is empty.
1916\let\cmap\gobble
1917% emacs-page end of cmaps
1524 1918
1525% Use cm as the default font prefix. 1919% Use cm as the default font prefix.
1526% To specify the font prefix, you must define \fontprefix 1920% To specify the font prefix, you must define \fontprefix
@@ -1548,119 +1942,127 @@ where each line of input produces a line of output.}
1548% Definitions for a main text size of 11pt. This is the default in 1942% Definitions for a main text size of 11pt. This is the default in
1549% Texinfo. 1943% Texinfo.
1550% 1944%
1551\def\definetextfontsizexi{ 1945\def\definetextfontsizexi{%
1552% Text fonts (11.2pt, magstep1). 1946% Text fonts (11.2pt, magstep1).
1553\def\textnominalsize{11pt} 1947\def\textnominalsize{11pt}
1554\edef\mainmagstep{\magstephalf} 1948\edef\mainmagstep{\magstephalf}
1555\setfont\textrm\rmshape{10}{\mainmagstep} 1949\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
1556\setfont\texttt\ttshape{10}{\mainmagstep} 1950\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
1557\setfont\textbf\bfshape{10}{\mainmagstep} 1951\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
1558\setfont\textit\itshape{10}{\mainmagstep} 1952\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
1559\setfont\textsl\slshape{10}{\mainmagstep} 1953\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
1560\setfont\textsf\sfshape{10}{\mainmagstep} 1954\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
1561\setfont\textsc\scshape{10}{\mainmagstep} 1955\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
1562\setfont\textttsl\ttslshape{10}{\mainmagstep} 1956\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
1563\font\texti=cmmi10 scaled \mainmagstep 1957\font\texti=cmmi10 scaled \mainmagstep
1564\font\textsy=cmsy10 scaled \mainmagstep 1958\font\textsy=cmsy10 scaled \mainmagstep
1959\def\textecsize{1095}
1565 1960
1566% A few fonts for @defun names and args. 1961% A few fonts for @defun names and args.
1567\setfont\defbf\bfshape{10}{\magstep1} 1962\setfont\defbf\bfshape{10}{\magstep1}{OT1}
1568\setfont\deftt\ttshape{10}{\magstep1} 1963\setfont\deftt\ttshape{10}{\magstep1}{OT1TT}
1569\setfont\defttsl\ttslshape{10}{\magstep1} 1964\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT}
1570\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} 1965\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
1571 1966
1572% Fonts for indices, footnotes, small examples (9pt). 1967% Fonts for indices, footnotes, small examples (9pt).
1573\def\smallnominalsize{9pt} 1968\def\smallnominalsize{9pt}
1574\setfont\smallrm\rmshape{9}{1000} 1969\setfont\smallrm\rmshape{9}{1000}{OT1}
1575\setfont\smalltt\ttshape{9}{1000} 1970\setfont\smalltt\ttshape{9}{1000}{OT1TT}
1576\setfont\smallbf\bfshape{10}{900} 1971\setfont\smallbf\bfshape{10}{900}{OT1}
1577\setfont\smallit\itshape{9}{1000} 1972\setfont\smallit\itshape{9}{1000}{OT1IT}
1578\setfont\smallsl\slshape{9}{1000} 1973\setfont\smallsl\slshape{9}{1000}{OT1}
1579\setfont\smallsf\sfshape{9}{1000} 1974\setfont\smallsf\sfshape{9}{1000}{OT1}
1580\setfont\smallsc\scshape{10}{900} 1975\setfont\smallsc\scshape{10}{900}{OT1}
1581\setfont\smallttsl\ttslshape{10}{900} 1976\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
1582\font\smalli=cmmi9 1977\font\smalli=cmmi9
1583\font\smallsy=cmsy9 1978\font\smallsy=cmsy9
1979\def\smallecsize{0900}
1584 1980
1585% Fonts for small examples (8pt). 1981% Fonts for small examples (8pt).
1586\def\smallernominalsize{8pt} 1982\def\smallernominalsize{8pt}
1587\setfont\smallerrm\rmshape{8}{1000} 1983\setfont\smallerrm\rmshape{8}{1000}{OT1}
1588\setfont\smallertt\ttshape{8}{1000} 1984\setfont\smallertt\ttshape{8}{1000}{OT1TT}
1589\setfont\smallerbf\bfshape{10}{800} 1985\setfont\smallerbf\bfshape{10}{800}{OT1}
1590\setfont\smallerit\itshape{8}{1000} 1986\setfont\smallerit\itshape{8}{1000}{OT1IT}
1591\setfont\smallersl\slshape{8}{1000} 1987\setfont\smallersl\slshape{8}{1000}{OT1}
1592\setfont\smallersf\sfshape{8}{1000} 1988\setfont\smallersf\sfshape{8}{1000}{OT1}
1593\setfont\smallersc\scshape{10}{800} 1989\setfont\smallersc\scshape{10}{800}{OT1}
1594\setfont\smallerttsl\ttslshape{10}{800} 1990\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
1595\font\smalleri=cmmi8 1991\font\smalleri=cmmi8
1596\font\smallersy=cmsy8 1992\font\smallersy=cmsy8
1993\def\smallerecsize{0800}
1597 1994
1598% Fonts for title page (20.4pt): 1995% Fonts for title page (20.4pt):
1599\def\titlenominalsize{20pt} 1996\def\titlenominalsize{20pt}
1600\setfont\titlerm\rmbshape{12}{\magstep3} 1997\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
1601\setfont\titleit\itbshape{10}{\magstep4} 1998\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
1602\setfont\titlesl\slbshape{10}{\magstep4} 1999\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
1603\setfont\titlett\ttbshape{12}{\magstep3} 2000\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
1604\setfont\titlettsl\ttslshape{10}{\magstep4} 2001\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
1605\setfont\titlesf\sfbshape{17}{\magstep1} 2002\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
1606\let\titlebf=\titlerm 2003\let\titlebf=\titlerm
1607\setfont\titlesc\scbshape{10}{\magstep4} 2004\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
1608\font\titlei=cmmi12 scaled \magstep3 2005\font\titlei=cmmi12 scaled \magstep3
1609\font\titlesy=cmsy10 scaled \magstep4 2006\font\titlesy=cmsy10 scaled \magstep4
1610\def\authorrm{\secrm} 2007\def\authorrm{\secrm}
1611\def\authortt{\sectt} 2008\def\authortt{\sectt}
2009\def\titleecsize{2074}
1612 2010
1613% Chapter (and unnumbered) fonts (17.28pt). 2011% Chapter (and unnumbered) fonts (17.28pt).
1614\def\chapnominalsize{17pt} 2012\def\chapnominalsize{17pt}
1615\setfont\chaprm\rmbshape{12}{\magstep2} 2013\setfont\chaprm\rmbshape{12}{\magstep2}{OT1}
1616\setfont\chapit\itbshape{10}{\magstep3} 2014\setfont\chapit\itbshape{10}{\magstep3}{OT1IT}
1617\setfont\chapsl\slbshape{10}{\magstep3} 2015\setfont\chapsl\slbshape{10}{\magstep3}{OT1}
1618\setfont\chaptt\ttbshape{12}{\magstep2} 2016\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT}
1619\setfont\chapttsl\ttslshape{10}{\magstep3} 2017\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT}
1620\setfont\chapsf\sfbshape{17}{1000} 2018\setfont\chapsf\sfbshape{17}{1000}{OT1}
1621\let\chapbf=\chaprm 2019\let\chapbf=\chaprm
1622\setfont\chapsc\scbshape{10}{\magstep3} 2020\setfont\chapsc\scbshape{10}{\magstep3}{OT1}
1623\font\chapi=cmmi12 scaled \magstep2 2021\font\chapi=cmmi12 scaled \magstep2
1624\font\chapsy=cmsy10 scaled \magstep3 2022\font\chapsy=cmsy10 scaled \magstep3
2023\def\chapecsize{1728}
1625 2024
1626% Section fonts (14.4pt). 2025% Section fonts (14.4pt).
1627\def\secnominalsize{14pt} 2026\def\secnominalsize{14pt}
1628\setfont\secrm\rmbshape{12}{\magstep1} 2027\setfont\secrm\rmbshape{12}{\magstep1}{OT1}
1629\setfont\secit\itbshape{10}{\magstep2} 2028\setfont\secit\itbshape{10}{\magstep2}{OT1IT}
1630\setfont\secsl\slbshape{10}{\magstep2} 2029\setfont\secsl\slbshape{10}{\magstep2}{OT1}
1631\setfont\sectt\ttbshape{12}{\magstep1} 2030\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT}
1632\setfont\secttsl\ttslshape{10}{\magstep2} 2031\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT}
1633\setfont\secsf\sfbshape{12}{\magstep1} 2032\setfont\secsf\sfbshape{12}{\magstep1}{OT1}
1634\let\secbf\secrm 2033\let\secbf\secrm
1635\setfont\secsc\scbshape{10}{\magstep2} 2034\setfont\secsc\scbshape{10}{\magstep2}{OT1}
1636\font\seci=cmmi12 scaled \magstep1 2035\font\seci=cmmi12 scaled \magstep1
1637\font\secsy=cmsy10 scaled \magstep2 2036\font\secsy=cmsy10 scaled \magstep2
2037\def\sececsize{1440}
1638 2038
1639% Subsection fonts (13.15pt). 2039% Subsection fonts (13.15pt).
1640\def\ssecnominalsize{13pt} 2040\def\ssecnominalsize{13pt}
1641\setfont\ssecrm\rmbshape{12}{\magstephalf} 2041\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1}
1642\setfont\ssecit\itbshape{10}{1315} 2042\setfont\ssecit\itbshape{10}{1315}{OT1IT}
1643\setfont\ssecsl\slbshape{10}{1315} 2043\setfont\ssecsl\slbshape{10}{1315}{OT1}
1644\setfont\ssectt\ttbshape{12}{\magstephalf} 2044\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT}
1645\setfont\ssecttsl\ttslshape{10}{1315} 2045\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT}
1646\setfont\ssecsf\sfbshape{12}{\magstephalf} 2046\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1}
1647\let\ssecbf\ssecrm 2047\let\ssecbf\ssecrm
1648\setfont\ssecsc\scbshape{10}{1315} 2048\setfont\ssecsc\scbshape{10}{1315}{OT1}
1649\font\sseci=cmmi12 scaled \magstephalf 2049\font\sseci=cmmi12 scaled \magstephalf
1650\font\ssecsy=cmsy10 scaled 1315 2050\font\ssecsy=cmsy10 scaled 1315
2051\def\ssececsize{1200}
1651 2052
1652% Reduced fonts for @acro in text (10pt). 2053% Reduced fonts for @acro in text (10pt).
1653\def\reducednominalsize{10pt} 2054\def\reducednominalsize{10pt}
1654\setfont\reducedrm\rmshape{10}{1000} 2055\setfont\reducedrm\rmshape{10}{1000}{OT1}
1655\setfont\reducedtt\ttshape{10}{1000} 2056\setfont\reducedtt\ttshape{10}{1000}{OT1TT}
1656\setfont\reducedbf\bfshape{10}{1000} 2057\setfont\reducedbf\bfshape{10}{1000}{OT1}
1657\setfont\reducedit\itshape{10}{1000} 2058\setfont\reducedit\itshape{10}{1000}{OT1IT}
1658\setfont\reducedsl\slshape{10}{1000} 2059\setfont\reducedsl\slshape{10}{1000}{OT1}
1659\setfont\reducedsf\sfshape{10}{1000} 2060\setfont\reducedsf\sfshape{10}{1000}{OT1}
1660\setfont\reducedsc\scshape{10}{1000} 2061\setfont\reducedsc\scshape{10}{1000}{OT1}
1661\setfont\reducedttsl\ttslshape{10}{1000} 2062\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT}
1662\font\reducedi=cmmi10 2063\font\reducedi=cmmi10
1663\font\reducedsy=cmsy10 2064\font\reducedsy=cmsy10
2065\def\reducedecsize{1000}
1664 2066
1665% reset the current fonts 2067% reset the current fonts
1666\textfonts 2068\textfonts
@@ -1677,115 +2079,123 @@ where each line of input produces a line of output.}
1677% Text fonts (10pt). 2079% Text fonts (10pt).
1678\def\textnominalsize{10pt} 2080\def\textnominalsize{10pt}
1679\edef\mainmagstep{1000} 2081\edef\mainmagstep{1000}
1680\setfont\textrm\rmshape{10}{\mainmagstep} 2082\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
1681\setfont\texttt\ttshape{10}{\mainmagstep} 2083\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
1682\setfont\textbf\bfshape{10}{\mainmagstep} 2084\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
1683\setfont\textit\itshape{10}{\mainmagstep} 2085\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
1684\setfont\textsl\slshape{10}{\mainmagstep} 2086\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
1685\setfont\textsf\sfshape{10}{\mainmagstep} 2087\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
1686\setfont\textsc\scshape{10}{\mainmagstep} 2088\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
1687\setfont\textttsl\ttslshape{10}{\mainmagstep} 2089\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
1688\font\texti=cmmi10 scaled \mainmagstep 2090\font\texti=cmmi10 scaled \mainmagstep
1689\font\textsy=cmsy10 scaled \mainmagstep 2091\font\textsy=cmsy10 scaled \mainmagstep
2092\def\textecsize{1000}
1690 2093
1691% A few fonts for @defun names and args. 2094% A few fonts for @defun names and args.
1692\setfont\defbf\bfshape{10}{\magstephalf} 2095\setfont\defbf\bfshape{10}{\magstephalf}{OT1}
1693\setfont\deftt\ttshape{10}{\magstephalf} 2096\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT}
1694\setfont\defttsl\ttslshape{10}{\magstephalf} 2097\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT}
1695\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} 2098\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
1696 2099
1697% Fonts for indices, footnotes, small examples (9pt). 2100% Fonts for indices, footnotes, small examples (9pt).
1698\def\smallnominalsize{9pt} 2101\def\smallnominalsize{9pt}
1699\setfont\smallrm\rmshape{9}{1000} 2102\setfont\smallrm\rmshape{9}{1000}{OT1}
1700\setfont\smalltt\ttshape{9}{1000} 2103\setfont\smalltt\ttshape{9}{1000}{OT1TT}
1701\setfont\smallbf\bfshape{10}{900} 2104\setfont\smallbf\bfshape{10}{900}{OT1}
1702\setfont\smallit\itshape{9}{1000} 2105\setfont\smallit\itshape{9}{1000}{OT1IT}
1703\setfont\smallsl\slshape{9}{1000} 2106\setfont\smallsl\slshape{9}{1000}{OT1}
1704\setfont\smallsf\sfshape{9}{1000} 2107\setfont\smallsf\sfshape{9}{1000}{OT1}
1705\setfont\smallsc\scshape{10}{900} 2108\setfont\smallsc\scshape{10}{900}{OT1}
1706\setfont\smallttsl\ttslshape{10}{900} 2109\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
1707\font\smalli=cmmi9 2110\font\smalli=cmmi9
1708\font\smallsy=cmsy9 2111\font\smallsy=cmsy9
2112\def\smallecsize{0900}
1709 2113
1710% Fonts for small examples (8pt). 2114% Fonts for small examples (8pt).
1711\def\smallernominalsize{8pt} 2115\def\smallernominalsize{8pt}
1712\setfont\smallerrm\rmshape{8}{1000} 2116\setfont\smallerrm\rmshape{8}{1000}{OT1}
1713\setfont\smallertt\ttshape{8}{1000} 2117\setfont\smallertt\ttshape{8}{1000}{OT1TT}
1714\setfont\smallerbf\bfshape{10}{800} 2118\setfont\smallerbf\bfshape{10}{800}{OT1}
1715\setfont\smallerit\itshape{8}{1000} 2119\setfont\smallerit\itshape{8}{1000}{OT1IT}
1716\setfont\smallersl\slshape{8}{1000} 2120\setfont\smallersl\slshape{8}{1000}{OT1}
1717\setfont\smallersf\sfshape{8}{1000} 2121\setfont\smallersf\sfshape{8}{1000}{OT1}
1718\setfont\smallersc\scshape{10}{800} 2122\setfont\smallersc\scshape{10}{800}{OT1}
1719\setfont\smallerttsl\ttslshape{10}{800} 2123\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
1720\font\smalleri=cmmi8 2124\font\smalleri=cmmi8
1721\font\smallersy=cmsy8 2125\font\smallersy=cmsy8
2126\def\smallerecsize{0800}
1722 2127
1723% Fonts for title page (20.4pt): 2128% Fonts for title page (20.4pt):
1724\def\titlenominalsize{20pt} 2129\def\titlenominalsize{20pt}
1725\setfont\titlerm\rmbshape{12}{\magstep3} 2130\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
1726\setfont\titleit\itbshape{10}{\magstep4} 2131\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
1727\setfont\titlesl\slbshape{10}{\magstep4} 2132\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
1728\setfont\titlett\ttbshape{12}{\magstep3} 2133\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
1729\setfont\titlettsl\ttslshape{10}{\magstep4} 2134\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
1730\setfont\titlesf\sfbshape{17}{\magstep1} 2135\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
1731\let\titlebf=\titlerm 2136\let\titlebf=\titlerm
1732\setfont\titlesc\scbshape{10}{\magstep4} 2137\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
1733\font\titlei=cmmi12 scaled \magstep3 2138\font\titlei=cmmi12 scaled \magstep3
1734\font\titlesy=cmsy10 scaled \magstep4 2139\font\titlesy=cmsy10 scaled \magstep4
1735\def\authorrm{\secrm} 2140\def\authorrm{\secrm}
1736\def\authortt{\sectt} 2141\def\authortt{\sectt}
2142\def\titleecsize{2074}
1737 2143
1738% Chapter fonts (14.4pt). 2144% Chapter fonts (14.4pt).
1739\def\chapnominalsize{14pt} 2145\def\chapnominalsize{14pt}
1740\setfont\chaprm\rmbshape{12}{\magstep1} 2146\setfont\chaprm\rmbshape{12}{\magstep1}{OT1}
1741\setfont\chapit\itbshape{10}{\magstep2} 2147\setfont\chapit\itbshape{10}{\magstep2}{OT1IT}
1742\setfont\chapsl\slbshape{10}{\magstep2} 2148\setfont\chapsl\slbshape{10}{\magstep2}{OT1}
1743\setfont\chaptt\ttbshape{12}{\magstep1} 2149\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT}
1744\setfont\chapttsl\ttslshape{10}{\magstep2} 2150\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT}
1745\setfont\chapsf\sfbshape{12}{\magstep1} 2151\setfont\chapsf\sfbshape{12}{\magstep1}{OT1}
1746\let\chapbf\chaprm 2152\let\chapbf\chaprm
1747\setfont\chapsc\scbshape{10}{\magstep2} 2153\setfont\chapsc\scbshape{10}{\magstep2}{OT1}
1748\font\chapi=cmmi12 scaled \magstep1 2154\font\chapi=cmmi12 scaled \magstep1
1749\font\chapsy=cmsy10 scaled \magstep2 2155\font\chapsy=cmsy10 scaled \magstep2
2156\def\chapecsize{1440}
1750 2157
1751% Section fonts (12pt). 2158% Section fonts (12pt).
1752\def\secnominalsize{12pt} 2159\def\secnominalsize{12pt}
1753\setfont\secrm\rmbshape{12}{1000} 2160\setfont\secrm\rmbshape{12}{1000}{OT1}
1754\setfont\secit\itbshape{10}{\magstep1} 2161\setfont\secit\itbshape{10}{\magstep1}{OT1IT}
1755\setfont\secsl\slbshape{10}{\magstep1} 2162\setfont\secsl\slbshape{10}{\magstep1}{OT1}
1756\setfont\sectt\ttbshape{12}{1000} 2163\setfont\sectt\ttbshape{12}{1000}{OT1TT}
1757\setfont\secttsl\ttslshape{10}{\magstep1} 2164\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT}
1758\setfont\secsf\sfbshape{12}{1000} 2165\setfont\secsf\sfbshape{12}{1000}{OT1}
1759\let\secbf\secrm 2166\let\secbf\secrm
1760\setfont\secsc\scbshape{10}{\magstep1} 2167\setfont\secsc\scbshape{10}{\magstep1}{OT1}
1761\font\seci=cmmi12 2168\font\seci=cmmi12
1762\font\secsy=cmsy10 scaled \magstep1 2169\font\secsy=cmsy10 scaled \magstep1
2170\def\sececsize{1200}
1763 2171
1764% Subsection fonts (10pt). 2172% Subsection fonts (10pt).
1765\def\ssecnominalsize{10pt} 2173\def\ssecnominalsize{10pt}
1766\setfont\ssecrm\rmbshape{10}{1000} 2174\setfont\ssecrm\rmbshape{10}{1000}{OT1}
1767\setfont\ssecit\itbshape{10}{1000} 2175\setfont\ssecit\itbshape{10}{1000}{OT1IT}
1768\setfont\ssecsl\slbshape{10}{1000} 2176\setfont\ssecsl\slbshape{10}{1000}{OT1}
1769\setfont\ssectt\ttbshape{10}{1000} 2177\setfont\ssectt\ttbshape{10}{1000}{OT1TT}
1770\setfont\ssecttsl\ttslshape{10}{1000} 2178\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT}
1771\setfont\ssecsf\sfbshape{10}{1000} 2179\setfont\ssecsf\sfbshape{10}{1000}{OT1}
1772\let\ssecbf\ssecrm 2180\let\ssecbf\ssecrm
1773\setfont\ssecsc\scbshape{10}{1000} 2181\setfont\ssecsc\scbshape{10}{1000}{OT1}
1774\font\sseci=cmmi10 2182\font\sseci=cmmi10
1775\font\ssecsy=cmsy10 2183\font\ssecsy=cmsy10
2184\def\ssececsize{1000}
1776 2185
1777% Reduced fonts for @acro in text (9pt). 2186% Reduced fonts for @acro in text (9pt).
1778\def\reducednominalsize{9pt} 2187\def\reducednominalsize{9pt}
1779\setfont\reducedrm\rmshape{9}{1000} 2188\setfont\reducedrm\rmshape{9}{1000}{OT1}
1780\setfont\reducedtt\ttshape{9}{1000} 2189\setfont\reducedtt\ttshape{9}{1000}{OT1TT}
1781\setfont\reducedbf\bfshape{10}{900} 2190\setfont\reducedbf\bfshape{10}{900}{OT1}
1782\setfont\reducedit\itshape{9}{1000} 2191\setfont\reducedit\itshape{9}{1000}{OT1IT}
1783\setfont\reducedsl\slshape{9}{1000} 2192\setfont\reducedsl\slshape{9}{1000}{OT1}
1784\setfont\reducedsf\sfshape{9}{1000} 2193\setfont\reducedsf\sfshape{9}{1000}{OT1}
1785\setfont\reducedsc\scshape{10}{900} 2194\setfont\reducedsc\scshape{10}{900}{OT1}
1786\setfont\reducedttsl\ttslshape{10}{900} 2195\setfont\reducedttsl\ttslshape{10}{900}{OT1TT}
1787\font\reducedi=cmmi9 2196\font\reducedi=cmmi9
1788\font\reducedsy=cmsy9 2197\font\reducedsy=cmsy9
2198\def\reducedecsize{0900}
1789 2199
1790% reduce space between paragraphs 2200% reduce space between paragraphs
1791\divide\parskip by 2 2201\divide\parskip by 2
@@ -1941,10 +2351,10 @@ where each line of input produces a line of output.}
1941\newcount\fontdepth \fontdepth=0 2351\newcount\fontdepth \fontdepth=0
1942 2352
1943% Fonts for short table of contents. 2353% Fonts for short table of contents.
1944\setfont\shortcontrm\rmshape{12}{1000} 2354\setfont\shortcontrm\rmshape{12}{1000}{OT1}
1945\setfont\shortcontbf\bfshape{10}{\magstep1} % no cmb12 2355\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12
1946\setfont\shortcontsl\slshape{12}{1000} 2356\setfont\shortcontsl\slshape{12}{1000}{OT1}
1947\setfont\shortconttt\ttshape{12}{1000} 2357\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
1948 2358
1949%% Add scribe-like font environments, plus @l for inline lisp (usually sans 2359%% Add scribe-like font environments, plus @l for inline lisp (usually sans
1950%% serif) and @ii for TeX italic 2360%% serif) and @ii for TeX italic
@@ -2007,7 +2417,7 @@ where each line of input produces a line of output.}
2007 \null 2417 \null
2008} 2418}
2009\def\samp#1{`\tclose{#1}'\null} 2419\def\samp#1{`\tclose{#1}'\null}
2010\setfont\keyrm\rmshape{8}{1000} 2420\setfont\keyrm\rmshape{8}{1000}{OT1}
2011\font\keysy=cmsy9 2421\font\keysy=cmsy9
2012\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% 2422\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
2013 \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% 2423 \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
@@ -2015,6 +2425,7 @@ where each line of input produces a line of output.}
2015 \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% 2425 \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
2016 \kern-0.4pt\hrule}% 2426 \kern-0.4pt\hrule}%
2017 \kern-.06em\raise0.4pt\hbox{\angleright}}}} 2427 \kern-.06em\raise0.4pt\hbox{\angleright}}}}
2428\def\key #1{{\nohyphenation \uppercase{#1}}\null}
2018% The old definition, with no lozenge: 2429% The old definition, with no lozenge:
2019%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} 2430%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
2020\def\ctrl #1{{\tt \rawbackslash \hat}#1} 2431\def\ctrl #1{{\tt \rawbackslash \hat}#1}
@@ -2299,6 +2710,35 @@ where each line of input produces a line of output.}
2299 \thiseurofont 2710 \thiseurofont
2300} 2711}
2301 2712
2713% Hacks for glyphs from the EC fonts similar to \euro. We don't
2714% use \let for the aliases, because sometimes we redefine the original
2715% macro, and the alias should reflect the redefinition.
2716\def\guillemetleft{{\ecfont \char"13}}
2717\def\guillemotleft{\guillemetleft}
2718\def\guillemetright{{\ecfont \char"14}}
2719\def\guillemotright{\guillemetright}
2720\def\guilsinglleft{{\ecfont \char"0E}}
2721\def\guilsinglright{{\ecfont \char"0F}}
2722\def\quotedblbase{{\ecfont \char"12}}
2723\def\quotesinglbase{{\ecfont \char"0D}}
2724%
2725\def\ecfont{%
2726 % We can't distinguish serif/sanserif and italic/slanted, but this
2727 % is used for crude hacks anyway (like adding French and German
2728 % quotes to documents typeset with CM, where we lose kerning), so
2729 % hopefully nobody will notice/care.
2730 \edef\ecsize{\csname\curfontsize ecsize\endcsname}%
2731 \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
2732 \ifx\curfontstyle\bfstylename
2733 % bold:
2734 \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
2735 \else
2736 % regular:
2737 \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
2738 \fi
2739 \thisecfont
2740}
2741
2302% @registeredsymbol - R in a circle. The font for the R should really 2742% @registeredsymbol - R in a circle. The font for the R should really
2303% be smaller yet, but lllsize is the best we can do for now. 2743% be smaller yet, but lllsize is the best we can do for now.
2304% Adapted from the plain.tex definition of \copyright. 2744% Adapted from the plain.tex definition of \copyright.
@@ -2321,6 +2761,12 @@ where each line of input produces a line of output.}
2321\def\Orb{\mathhexbox20D} 2761\def\Orb{\mathhexbox20D}
2322\fi 2762\fi
2323 2763
2764% Quotes.
2765\chardef\quotedblleft="5C
2766\chardef\quotedblright=`\"
2767\chardef\quoteleft=`\`
2768\chardef\quoteright=`\'
2769
2324 2770
2325\message{page headings,} 2771\message{page headings,}
2326 2772
@@ -2490,6 +2936,33 @@ where each line of input produces a line of output.}
2490 2936
2491\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}} 2937\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
2492 2938
2939% @evenheadingmarks top \thischapter <- chapter at the top of a page
2940% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page
2941%
2942% The same set of arguments for:
2943%
2944% @oddheadingmarks
2945% @evenfootingmarks
2946% @oddfootingmarks
2947% @everyheadingmarks
2948% @everyfootingmarks
2949
2950\def\evenheadingmarks{\headingmarks{even}{heading}}
2951\def\oddheadingmarks{\headingmarks{odd}{heading}}
2952\def\evenfootingmarks{\headingmarks{even}{footing}}
2953\def\oddfootingmarks{\headingmarks{odd}{footing}}
2954\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1}
2955 \headingmarks{odd}{heading}{#1} }
2956\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1}
2957 \headingmarks{odd}{footing}{#1} }
2958% #1 = even/odd, #2 = heading/footing, #3 = top/bottom.
2959\def\headingmarks#1#2#3 {%
2960 \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname
2961 \global\expandafter\let\csname get#1#2marks\endcsname \temp
2962}
2963
2964\everyheadingmarks bottom
2965\everyfootingmarks bottom
2493 2966
2494% @headings double turns headings on for double-sided printing. 2967% @headings double turns headings on for double-sided printing.
2495% @headings single turns headings on for single-sided printing. 2968% @headings single turns headings on for single-sided printing.
@@ -3530,11 +4003,21 @@ where each line of input produces a line of output.}
3530 \definedummyword\equiv 4003 \definedummyword\equiv
3531 \definedummyword\error 4004 \definedummyword\error
3532 \definedummyword\euro 4005 \definedummyword\euro
4006 \definedummyword\guillemetleft
4007 \definedummyword\guillemetright
4008 \definedummyword\guilsinglleft
4009 \definedummyword\guilsinglright
3533 \definedummyword\expansion 4010 \definedummyword\expansion
3534 \definedummyword\minus 4011 \definedummyword\minus
3535 \definedummyword\pounds 4012 \definedummyword\pounds
3536 \definedummyword\point 4013 \definedummyword\point
3537 \definedummyword\print 4014 \definedummyword\print
4015 \definedummyword\quotedblbase
4016 \definedummyword\quotedblleft
4017 \definedummyword\quotedblright
4018 \definedummyword\quoteleft
4019 \definedummyword\quoteright
4020 \definedummyword\quotesinglbase
3538 \definedummyword\result 4021 \definedummyword\result
3539 \definedummyword\textdegree 4022 \definedummyword\textdegree
3540 % 4023 %
@@ -3664,11 +4147,21 @@ where each line of input produces a line of output.}
3664 \def\equiv{==}% 4147 \def\equiv{==}%
3665 \def\error{error}% 4148 \def\error{error}%
3666 \def\euro{euro}% 4149 \def\euro{euro}%
4150 \def\guillemetleft{<<}%
4151 \def\guillemetright{>>}%
4152 \def\guilsinglleft{<}%
4153 \def\guilsinglright{>}%
3667 \def\expansion{==>}% 4154 \def\expansion{==>}%
3668 \def\minus{-}% 4155 \def\minus{-}%
3669 \def\pounds{pounds}% 4156 \def\pounds{pounds}%
3670 \def\point{.}% 4157 \def\point{.}%
3671 \def\print{-|}% 4158 \def\print{-|}%
4159 \def\quotedblbase{"}%
4160 \def\quotedblleft{"}%
4161 \def\quotedblright{"}%
4162 \def\quoteleft{`}%
4163 \def\quoteright{'}%
4164 \def\quotesinglbase{,}%
3672 \def\result{=>}% 4165 \def\result{=>}%
3673 \def\textdegree{degrees}% 4166 \def\textdegree{degrees}%
3674 % 4167 %
@@ -3710,11 +4203,7 @@ where each line of input produces a line of output.}
3710 % 4203 %
3711 \edef\writeto{\csname#1indfile\endcsname}% 4204 \edef\writeto{\csname#1indfile\endcsname}%
3712 % 4205 %
3713 \ifvmode 4206 \safewhatsit\dosubindwrite
3714 \dosubindsanitize
3715 \else
3716 \dosubindwrite
3717 \fi
3718 }% 4207 }%
3719 \fi 4208 \fi
3720} 4209}
@@ -3751,13 +4240,13 @@ where each line of input produces a line of output.}
3751 \temp 4240 \temp
3752} 4241}
3753 4242
3754% Take care of unwanted page breaks: 4243% Take care of unwanted page breaks/skips around a whatsit:
3755% 4244%
3756% If a skip is the last thing on the list now, preserve it 4245% If a skip is the last thing on the list now, preserve it
3757% by backing up by \lastskip, doing the \write, then inserting 4246% by backing up by \lastskip, doing the \write, then inserting
3758% the skip again. Otherwise, the whatsit generated by the 4247% the skip again. Otherwise, the whatsit generated by the
3759% \write will make \lastskip zero. The result is that sequences 4248% \write or \pdfdest will make \lastskip zero. The result is that
3760% like this: 4249% sequences like this:
3761% @end defun 4250% @end defun
3762% @tindex whatever 4251% @tindex whatever
3763% @defun ... 4252% @defun ...
@@ -3781,25 +4270,31 @@ where each line of input produces a line of output.}
3781% 4270%
3782\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname} 4271\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
3783% 4272%
4273\newskip\whatsitskip
4274\newcount\whatsitpenalty
4275%
3784% ..., ready, GO: 4276% ..., ready, GO:
3785% 4277%
3786\def\dosubindsanitize{% 4278\def\safewhatsit#1{%
4279\ifhmode
4280 #1%
4281\else
3787 % \lastskip and \lastpenalty cannot both be nonzero simultaneously. 4282 % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
3788 \skip0 = \lastskip 4283 \whatsitskip = \lastskip
3789 \edef\lastskipmacro{\the\lastskip}% 4284 \edef\lastskipmacro{\the\lastskip}%
3790 \count255 = \lastpenalty 4285 \whatsitpenalty = \lastpenalty
3791 % 4286 %
3792 % If \lastskip is nonzero, that means the last item was a 4287 % If \lastskip is nonzero, that means the last item was a
3793 % skip. And since a skip is discardable, that means this 4288 % skip. And since a skip is discardable, that means this
3794 % -\skip0 glue we're inserting is preceded by a 4289 % -\whatsitskip glue we're inserting is preceded by a
3795 % non-discardable item, therefore it is not a potential 4290 % non-discardable item, therefore it is not a potential
3796 % breakpoint, therefore no \nobreak needed. 4291 % breakpoint, therefore no \nobreak needed.
3797 \ifx\lastskipmacro\zeroskipmacro 4292 \ifx\lastskipmacro\zeroskipmacro
3798 \else 4293 \else
3799 \vskip-\skip0 4294 \vskip-\whatsitskip
3800 \fi 4295 \fi
3801 % 4296 %
3802 \dosubindwrite 4297 #1%
3803 % 4298 %
3804 \ifx\lastskipmacro\zeroskipmacro 4299 \ifx\lastskipmacro\zeroskipmacro
3805 % If \lastskip was zero, perhaps the last item was a penalty, and 4300 % If \lastskip was zero, perhaps the last item was a penalty, and
@@ -3813,13 +4308,14 @@ where each line of input produces a line of output.}
3813 % Description. 4308 % Description.
3814 % would allow a break between the index-whatever whatsit 4309 % would allow a break between the index-whatever whatsit
3815 % and the "Description." paragraph. 4310 % and the "Description." paragraph.
3816 \ifnum\count255>9999 \penalty\count255 \fi 4311 \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi
3817 \else 4312 \else
3818 % On the other hand, if we had a nonzero \lastskip, 4313 % On the other hand, if we had a nonzero \lastskip,
3819 % this make-up glue would be preceded by a non-discardable item 4314 % this make-up glue would be preceded by a non-discardable item
3820 % (the whatsit from the \write), so we must insert a \nobreak. 4315 % (the whatsit from the \write), so we must insert a \nobreak.
3821 \nobreak\vskip\skip0 4316 \nobreak\vskip\whatsitskip
3822 \fi 4317 \fi
4318\fi
3823} 4319}
3824 4320
3825% The index entry written in the file actually looks like 4321% The index entry written in the file actually looks like
@@ -3862,6 +4358,7 @@ where each line of input produces a line of output.}
3862 % 4358 %
3863 \smallfonts \rm 4359 \smallfonts \rm
3864 \tolerance = 9500 4360 \tolerance = 9500
4361 \plainfrenchspacing
3865 \everypar = {}% don't want the \kern\-parindent from indentation suppression. 4362 \everypar = {}% don't want the \kern\-parindent from indentation suppression.
3866 % 4363 %
3867 % See if the index file exists and is nonempty. 4364 % See if the index file exists and is nonempty.
@@ -3991,11 +4488,8 @@ where each line of input produces a line of output.}
3991 % The following is kludged to not output a line of dots in the index if 4488 % The following is kludged to not output a line of dots in the index if
3992 % there are no page numbers. The next person who breaks this will be 4489 % there are no page numbers. The next person who breaks this will be
3993 % cursed by a Unix daemon. 4490 % cursed by a Unix daemon.
3994 \def\tempa{{\rm }}% 4491 \setbox\boxA = \hbox{#1}%
3995 \def\tempb{#1}% 4492 \ifdim\wd\boxA = 0pt
3996 \edef\tempc{\tempa}%
3997 \edef\tempd{\tempb}%
3998 \ifx\tempc\tempd
3999 \ % 4493 \ %
4000 \else 4494 \else
4001 % 4495 %
@@ -4131,6 +4625,34 @@ where each line of input produces a line of output.}
4131% 4625%
4132% All done with double columns. 4626% All done with double columns.
4133\def\enddoublecolumns{% 4627\def\enddoublecolumns{%
4628 % The following penalty ensures that the page builder is exercised
4629 % _before_ we change the output routine. This is necessary in the
4630 % following situation:
4631 %
4632 % The last section of the index consists only of a single entry.
4633 % Before this section, \pagetotal is less than \pagegoal, so no
4634 % break occurs before the last section starts. However, the last
4635 % section, consisting of \initial and the single \entry, does not
4636 % fit on the page and has to be broken off. Without the following
4637 % penalty the page builder will not be exercised until \eject
4638 % below, and by that time we'll already have changed the output
4639 % routine to the \balancecolumns version, so the next-to-last
4640 % double-column page will be processed with \balancecolumns, which
4641 % is wrong: The two columns will go to the main vertical list, with
4642 % the broken-off section in the recent contributions. As soon as
4643 % the output routine finishes, TeX starts reconsidering the page
4644 % break. The two columns and the broken-off section both fit on the
4645 % page, because the two columns now take up only half of the page
4646 % goal. When TeX sees \eject from below which follows the final
4647 % section, it invokes the new output routine that we've set after
4648 % \balancecolumns below; \onepageout will try to fit the two columns
4649 % and the final section into the vbox of \pageheight (see
4650 % \pagebody), causing an overfull box.
4651 %
4652 % Note that glue won't work here, because glue does not exercise the
4653 % page builder, unlike penalties (see The TeXbook, pp. 280-281).
4654 \penalty0
4655 %
4134 \output = {% 4656 \output = {%
4135 % Split the last of the double-column material. Leave it on the 4657 % Split the last of the double-column material. Leave it on the
4136 % current page, no automatic page break. 4658 % current page, no automatic page break.
@@ -4240,11 +4762,15 @@ where each line of input produces a line of output.}
4240 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi 4762 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
4241 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} 4763 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
4242 4764
4243% Each @chapter defines this as the name of the chapter. 4765% Each @chapter defines these (using marks) as the number+name, number
4244% page headings and footings can use it. @section does likewise. 4766% and name of the chapter. Page headings and footings can use
4245% However, they are not reliable, because we don't use marks. 4767% these. @section does likewise.
4246\def\thischapter{} 4768\def\thischapter{}
4769\def\thischapternum{}
4770\def\thischaptername{}
4247\def\thissection{} 4771\def\thissection{}
4772\def\thissectionnum{}
4773\def\thissectionname{}
4248 4774
4249\newcount\absseclevel % used to calculate proper heading level 4775\newcount\absseclevel % used to calculate proper heading level
4250\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count 4776\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
@@ -4545,7 +5071,20 @@ where each line of input produces a line of output.}
4545 5071
4546\def\chapbreak{\dobreak \chapheadingskip {-4000}} 5072\def\chapbreak{\dobreak \chapheadingskip {-4000}}
4547\def\chappager{\par\vfill\supereject} 5073\def\chappager{\par\vfill\supereject}
4548\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} 5074% Because \domark is called before \chapoddpage, the filler page will
5075% get the headings for the next chapter, which is wrong. But we don't
5076% care -- we just disable all headings on the filler page.
5077\def\chapoddpage{%
5078 \chappager
5079 \ifodd\pageno \else
5080 \begingroup
5081 \evenheadline={\hfil}\evenfootline={\hfil}%
5082 \oddheadline={\hfil}\oddfootline={\hfil}%
5083 \hbox to 0pt{}%
5084 \chappager
5085 \endgroup
5086 \fi
5087}
4549 5088
4550\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} 5089\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
4551 5090
@@ -4579,45 +5118,72 @@ where each line of input produces a line of output.}
4579\def\Yappendixkeyword{Yappendix} 5118\def\Yappendixkeyword{Yappendix}
4580% 5119%
4581\def\chapmacro#1#2#3{% 5120\def\chapmacro#1#2#3{%
5121 % Insert the first mark before the heading break (see notes for \domark).
5122 \let\prevchapterdefs=\lastchapterdefs
5123 \let\prevsectiondefs=\lastsectiondefs
5124 \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}%
5125 \gdef\thissection{}}%
5126 %
5127 \def\temptype{#2}%
5128 \ifx\temptype\Ynothingkeyword
5129 \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
5130 \gdef\thischapter{\thischaptername}}%
5131 \else\ifx\temptype\Yomitfromtockeyword
5132 \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
5133 \gdef\thischapter{}}%
5134 \else\ifx\temptype\Yappendixkeyword
5135 \toks0={#1}%
5136 \xdef\lastchapterdefs{%
5137 \gdef\noexpand\thischaptername{\the\toks0}%
5138 \gdef\noexpand\thischapternum{\appendixletter}%
5139 \gdef\noexpand\thischapter{\putwordAppendix{} \noexpand\thischapternum:
5140 \noexpand\thischaptername}%
5141 }%
5142 \else
5143 \toks0={#1}%
5144 \xdef\lastchapterdefs{%
5145 \gdef\noexpand\thischaptername{\the\toks0}%
5146 \gdef\noexpand\thischapternum{\the\chapno}%
5147 \gdef\noexpand\thischapter{\putwordChapter{} \noexpand\thischapternum:
5148 \noexpand\thischaptername}%
5149 }%
5150 \fi\fi\fi
5151 %
5152 % Output the mark. Pass it through \safewhatsit, to take care of
5153 % the preceding space.
5154 \safewhatsit\domark
5155 %
5156 % Insert the chapter heading break.
4582 \pchapsepmacro 5157 \pchapsepmacro
5158 %
5159 % Now the second mark, after the heading break. No break points
5160 % between here and the heading.
5161 \let\prevchapterdefs=\lastchapterdefs
5162 \let\prevsectiondefs=\lastsectiondefs
5163 \domark
5164 %
4583 {% 5165 {%
4584 \chapfonts \rm 5166 \chapfonts \rm
4585 % 5167 %
4586 % Have to define \thissection before calling \donoderef, because the 5168 % Have to define \lastsection before calling \donoderef, because the
4587 % xref code eventually uses it. On the other hand, it has to be called 5169 % xref code eventually uses it. On the other hand, it has to be called
4588 % after \pchapsepmacro, or the headline will change too soon. 5170 % after \pchapsepmacro, or the headline will change too soon.
4589 \gdef\thissection{#1}% 5171 \gdef\lastsection{#1}%
4590 \gdef\thischaptername{#1}%
4591 % 5172 %
4592 % Only insert the separating space if we have a chapter/appendix 5173 % Only insert the separating space if we have a chapter/appendix
4593 % number, and don't print the unnumbered ``number''. 5174 % number, and don't print the unnumbered ``number''.
4594 \def\temptype{#2}%
4595 \ifx\temptype\Ynothingkeyword 5175 \ifx\temptype\Ynothingkeyword
4596 \setbox0 = \hbox{}% 5176 \setbox0 = \hbox{}%
4597 \def\toctype{unnchap}% 5177 \def\toctype{unnchap}%
4598 \gdef\thischapternum{}%
4599 \gdef\thischapter{#1}%
4600 \else\ifx\temptype\Yomitfromtockeyword 5178 \else\ifx\temptype\Yomitfromtockeyword
4601 \setbox0 = \hbox{}% contents like unnumbered, but no toc entry 5179 \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
4602 \def\toctype{omit}% 5180 \def\toctype{omit}%
4603 \gdef\thischapternum{}%
4604 \gdef\thischapter{}%
4605 \else\ifx\temptype\Yappendixkeyword 5181 \else\ifx\temptype\Yappendixkeyword
4606 \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% 5182 \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
4607 \def\toctype{app}% 5183 \def\toctype{app}%
4608 \xdef\thischapternum{\appendixletter}%
4609 % We don't substitute the actual chapter name into \thischapter
4610 % because we don't want its macros evaluated now. And we don't
4611 % use \thissection because that changes with each section.
4612 %
4613 \xdef\thischapter{\putwordAppendix{} \appendixletter:
4614 \noexpand\thischaptername}%
4615 \else 5184 \else
4616 \setbox0 = \hbox{#3\enspace}% 5185 \setbox0 = \hbox{#3\enspace}%
4617 \def\toctype{numchap}% 5186 \def\toctype{numchap}%
4618 \xdef\thischapternum{\the\chapno}%
4619 \xdef\thischapter{\putwordChapter{} \the\chapno:
4620 \noexpand\thischaptername}%
4621 \fi\fi\fi 5187 \fi\fi\fi
4622 % 5188 %
4623 % Write the toc entry for this chapter. Must come before the 5189 % Write the toc entry for this chapter. Must come before the
@@ -4633,6 +5199,7 @@ where each line of input produces a line of output.}
4633 \donoderef{#2}% 5199 \donoderef{#2}%
4634 % 5200 %
4635 % Typeset the actual heading. 5201 % Typeset the actual heading.
5202 \nobreak % Avoid page breaks at the interline glue.
4636 \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright 5203 \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
4637 \hangindent=\wd0 \centerparametersmaybe 5204 \hangindent=\wd0 \centerparametersmaybe
4638 \unhbox0 #1\par}% 5205 \unhbox0 #1\par}%
@@ -4695,36 +5262,78 @@ where each line of input produces a line of output.}
4695% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the 5262% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
4696% section number. 5263% section number.
4697% 5264%
5265\def\seckeyword{sec}
5266%
4698\def\sectionheading#1#2#3#4{% 5267\def\sectionheading#1#2#3#4{%
4699 {% 5268 {%
4700 % Switch to the right set of fonts. 5269 % Switch to the right set of fonts.
4701 \csname #2fonts\endcsname \rm 5270 \csname #2fonts\endcsname \rm
4702 % 5271 %
5272 \def\sectionlevel{#2}%
5273 \def\temptype{#3}%
5274 %
5275 % Insert first mark before the heading break (see notes for \domark).
5276 \let\prevsectiondefs=\lastsectiondefs
5277 \ifx\temptype\Ynothingkeyword
5278 \ifx\sectionlevel\seckeyword
5279 \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}%
5280 \gdef\thissection{\thissectionname}}%
5281 \fi
5282 \else\ifx\temptype\Yomitfromtockeyword
5283 % Don't redefine \thissection.
5284 \else\ifx\temptype\Yappendixkeyword
5285 \ifx\sectionlevel\seckeyword
5286 \toks0={#1}%
5287 \xdef\lastsectiondefs{%
5288 \gdef\noexpand\thissectionname{\the\toks0}%
5289 \gdef\noexpand\thissectionnum{#4}%
5290 \gdef\noexpand\thissection{\putwordSection{} \noexpand\thissectionnum:
5291 \noexpand\thissectionname}%
5292 }%
5293 \fi
5294 \else
5295 \ifx\sectionlevel\seckeyword
5296 \toks0={#1}%
5297 \xdef\lastsectiondefs{%
5298 \gdef\noexpand\thissectionname{\the\toks0}%
5299 \gdef\noexpand\thissectionnum{#4}%
5300 \gdef\noexpand\thissection{\putwordSection{} \noexpand\thissectionnum:
5301 \noexpand\thissectionname}%
5302 }%
5303 \fi
5304 \fi\fi\fi
5305 %
5306 % Output the mark. Pass it through \safewhatsit, to take care of
5307 % the preceding space.
5308 \safewhatsit\domark
5309 %
4703 % Insert space above the heading. 5310 % Insert space above the heading.
4704 \csname #2headingbreak\endcsname 5311 \csname #2headingbreak\endcsname
4705 % 5312 %
4706 % Only insert the space after the number if we have a section number. 5313 % Now the second mark, after the heading break. No break points
4707 \def\sectionlevel{#2}% 5314 % between here and the heading.
4708 \def\temptype{#3}% 5315 \let\prevsectiondefs=\lastsectiondefs
5316 \domark
4709 % 5317 %
5318 % Only insert the space after the number if we have a section number.
4710 \ifx\temptype\Ynothingkeyword 5319 \ifx\temptype\Ynothingkeyword
4711 \setbox0 = \hbox{}% 5320 \setbox0 = \hbox{}%
4712 \def\toctype{unn}% 5321 \def\toctype{unn}%
4713 \gdef\thissection{#1}% 5322 \gdef\lastsection{#1}%
4714 \else\ifx\temptype\Yomitfromtockeyword 5323 \else\ifx\temptype\Yomitfromtockeyword
4715 % for @headings -- no section number, don't include in toc, 5324 % for @headings -- no section number, don't include in toc,
4716 % and don't redefine \thissection. 5325 % and don't redefine \lastsection.
4717 \setbox0 = \hbox{}% 5326 \setbox0 = \hbox{}%
4718 \def\toctype{omit}% 5327 \def\toctype{omit}%
4719 \let\sectionlevel=\empty 5328 \let\sectionlevel=\empty
4720 \else\ifx\temptype\Yappendixkeyword 5329 \else\ifx\temptype\Yappendixkeyword
4721 \setbox0 = \hbox{#4\enspace}% 5330 \setbox0 = \hbox{#4\enspace}%
4722 \def\toctype{app}% 5331 \def\toctype{app}%
4723 \gdef\thissection{#1}% 5332 \gdef\lastsection{#1}%
4724 \else 5333 \else
4725 \setbox0 = \hbox{#4\enspace}% 5334 \setbox0 = \hbox{#4\enspace}%
4726 \def\toctype{num}% 5335 \def\toctype{num}%
4727 \gdef\thissection{#1}% 5336 \gdef\lastsection{#1}%
4728 \fi\fi\fi 5337 \fi\fi\fi
4729 % 5338 %
4730 % Write the toc entry (before \donoderef). See comments in \chapmacro. 5339 % Write the toc entry (before \donoderef). See comments in \chapmacro.
@@ -4839,7 +5448,7 @@ where each line of input produces a line of output.}
4839\def\readtocfile{% 5448\def\readtocfile{%
4840 \setupdatafile 5449 \setupdatafile
4841 \activecatcodes 5450 \activecatcodes
4842 \input \jobname.toc 5451 \input \tocreadfilename
4843} 5452}
4844 5453
4845\newskip\contentsrightmargin \contentsrightmargin=1in 5454\newskip\contentsrightmargin \contentsrightmargin=1in
@@ -4858,7 +5467,6 @@ where each line of input produces a line of output.}
4858 % 5467 %
4859 % Don't need to put `Contents' or `Short Contents' in the headline. 5468 % Don't need to put `Contents' or `Short Contents' in the headline.
4860 % It is abundantly clear what they are. 5469 % It is abundantly clear what they are.
4861 \def\thischapter{}%
4862 \chapmacro{#1}{Yomitfromtoc}{}% 5470 \chapmacro{#1}{Yomitfromtoc}{}%
4863 % 5471 %
4864 \savepageno = \pageno 5472 \savepageno = \pageno
@@ -4870,11 +5478,16 @@ where each line of input produces a line of output.}
4870 \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi 5478 \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
4871} 5479}
4872 5480
5481% redefined for the two-volume lispref. We always output on
5482% \jobname.toc even if this is redefined.
5483%
5484\def\tocreadfilename{\jobname.toc}
4873 5485
4874% Normal (long) toc. 5486% Normal (long) toc.
5487%
4875\def\contents{% 5488\def\contents{%
4876 \startcontents{\putwordTOC}% 5489 \startcontents{\putwordTOC}%
4877 \openin 1 \jobname.toc 5490 \openin 1 \tocreadfilename\space
4878 \ifeof 1 \else 5491 \ifeof 1 \else
4879 \readtocfile 5492 \readtocfile
4880 \fi 5493 \fi
@@ -4912,7 +5525,7 @@ where each line of input produces a line of output.}
4912 \let\numsubsubsecentry = \numsecentry 5525 \let\numsubsubsecentry = \numsecentry
4913 \let\appsubsubsecentry = \numsecentry 5526 \let\appsubsubsecentry = \numsecentry
4914 \let\unnsubsubsecentry = \numsecentry 5527 \let\unnsubsubsecentry = \numsecentry
4915 \openin 1 \jobname.toc 5528 \openin 1 \tocreadfilename\space
4916 \ifeof 1 \else 5529 \ifeof 1 \else
4917 \readtocfile 5530 \readtocfile
4918 \fi 5531 \fi
@@ -5247,12 +5860,18 @@ where each line of input produces a line of output.}
5247\let\SETdispenvsize\relax 5860\let\SETdispenvsize\relax
5248\def\setnormaldispenv{% 5861\def\setnormaldispenv{%
5249 \ifx\SETdispenvsize\smallword 5862 \ifx\SETdispenvsize\smallword
5863 % end paragraph for sake of leading, in case document has no blank
5864 % line. This is redundant with what happens in \aboveenvbreak, but
5865 % we need to do it before changing the fonts, and it's inconvenient
5866 % to change the fonts afterward.
5867 \ifnum \lastpenalty=10000 \else \endgraf \fi
5250 \smallexamplefonts \rm 5868 \smallexamplefonts \rm
5251 \fi 5869 \fi
5252} 5870}
5253\def\setsmalldispenv{% 5871\def\setsmalldispenv{%
5254 \ifx\SETdispenvsize\nosmallword 5872 \ifx\SETdispenvsize\nosmallword
5255 \else 5873 \else
5874 \ifnum \lastpenalty=10000 \else \endgraf \fi
5256 \smallexamplefonts \rm 5875 \smallexamplefonts \rm
5257 \fi 5876 \fi
5258} 5877}
@@ -5419,11 +6038,11 @@ where each line of input produces a line of output.}
5419% regular 0x27. 6038% regular 0x27.
5420% 6039%
5421\def\codequoteright{% 6040\def\codequoteright{%
5422 \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax 6041 \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
5423 '% 6042 \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
5424 \else 6043 '%
5425 \char'15 6044 \else \char'15 \fi
5426 \fi 6045 \else \char'15 \fi
5427} 6046}
5428% 6047%
5429% and a similar option for the left quote char vs. a grave accent. 6048% and a similar option for the left quote char vs. a grave accent.
@@ -5431,11 +6050,11 @@ where each line of input produces a line of output.}
5431% the code environments to do likewise. 6050% the code environments to do likewise.
5432% 6051%
5433\def\codequoteleft{% 6052\def\codequoteleft{%
5434 \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax 6053 \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
5435 `% 6054 \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
5436 \else 6055 `%
5437 \char'22 6056 \else \char'22 \fi
5438 \fi 6057 \else \char'22 \fi
5439} 6058}
5440% 6059%
5441\begingroup 6060\begingroup
@@ -5553,27 +6172,35 @@ where each line of input produces a line of output.}
5553 \endgroup 6172 \endgroup
5554} 6173}
5555 6174
6175
5556\message{defuns,} 6176\message{defuns,}
5557% @defun etc. 6177% @defun etc.
5558 6178
5559\newskip\defbodyindent \defbodyindent=.4in 6179\newskip\defbodyindent \defbodyindent=.4in
5560\newskip\defargsindent \defargsindent=50pt 6180\newskip\defargsindent \defargsindent=50pt
5561\newskip\deflastargmargin \deflastargmargin=18pt 6181\newskip\deflastargmargin \deflastargmargin=18pt
6182\newcount\defunpenalty
5562 6183
5563% Start the processing of @deffn: 6184% Start the processing of @deffn:
5564\def\startdefun{% 6185\def\startdefun{%
5565 \ifnum\lastpenalty<10000 6186 \ifnum\lastpenalty<10000
5566 \medbreak 6187 \medbreak
6188 \defunpenalty=10003 % Will keep this @deffn together with the
6189 % following @def command, see below.
5567 \else 6190 \else
5568 % If there are two @def commands in a row, we'll have a \nobreak, 6191 % If there are two @def commands in a row, we'll have a \nobreak,
5569 % which is there to keep the function description together with its 6192 % which is there to keep the function description together with its
5570 % header. But if there's nothing but headers, we need to allow a 6193 % header. But if there's nothing but headers, we need to allow a
5571 % break somewhere. Check specifically for penalty 10002, inserted 6194 % break somewhere. Check specifically for penalty 10002, inserted
5572 % by \defargscommonending, instead of 10000, since the sectioning 6195 % by \printdefunline, instead of 10000, since the sectioning
5573 % commands also insert a nobreak penalty, and we don't want to allow 6196 % commands also insert a nobreak penalty, and we don't want to allow
5574 % a break between a section heading and a defun. 6197 % a break between a section heading and a defun.
5575 % 6198 %
5576 \ifnum\lastpenalty=10002 \penalty2000 \fi 6199 % As a minor refinement, we avoid "club" headers by signalling
6200 % with penalty of 10003 after the very first @deffn in the
6201 % sequence (see above), and penalty of 10002 after any following
6202 % @def command.
6203 \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi
5577 % 6204 %
5578 % Similarly, after a section heading, do not allow a break. 6205 % Similarly, after a section heading, do not allow a break.
5579 % But do insert the glue. 6206 % But do insert the glue.
@@ -5591,7 +6218,7 @@ where each line of input produces a line of output.}
5591 % 6218 %
5592 % As above, allow line break if we have multiple x headers in a row. 6219 % As above, allow line break if we have multiple x headers in a row.
5593 % It's not a great place, though. 6220 % It's not a great place, though.
5594 \ifnum\lastpenalty=10002 \penalty3000 \fi 6221 \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi
5595 % 6222 %
5596 % And now, it's time to reuse the body of the original defun: 6223 % And now, it's time to reuse the body of the original defun:
5597 \expandafter\gobbledefun#1% 6224 \expandafter\gobbledefun#1%
@@ -5609,7 +6236,7 @@ where each line of input produces a line of output.}
5609 \advance\rightskip by 0pt plus 1fil 6236 \advance\rightskip by 0pt plus 1fil
5610 \endgraf 6237 \endgraf
5611 \nobreak\vskip -\parskip 6238 \nobreak\vskip -\parskip
5612 \penalty 10002 % signal to \startdefun and \dodefunx 6239 \penalty\defunpenalty % signal to \startdefun and \dodefunx
5613 % Some of the @defun-type tags do not enable magic parentheses, 6240 % Some of the @defun-type tags do not enable magic parentheses,
5614 % rendering the following check redundant. But we don't optimize. 6241 % rendering the following check redundant. But we don't optimize.
5615 \checkparencounts 6242 \checkparencounts
@@ -5878,12 +6505,14 @@ where each line of input produces a line of output.}
5878 \ifnum\parencount=0 \else \badparencount \fi 6505 \ifnum\parencount=0 \else \badparencount \fi
5879 \ifnum\brackcount=0 \else \badbrackcount \fi 6506 \ifnum\brackcount=0 \else \badbrackcount \fi
5880} 6507}
6508% these should not use \errmessage; the glibc manual, at least, actually
6509% has such constructs (when documenting function pointers).
5881\def\badparencount{% 6510\def\badparencount{%
5882 \errmessage{Unbalanced parentheses in @def}% 6511 \message{Warning: unbalanced parentheses in @def...}%
5883 \global\parencount=0 6512 \global\parencount=0
5884} 6513}
5885\def\badbrackcount{% 6514\def\badbrackcount{%
5886 \errmessage{Unbalanced square braces in @def}% 6515 \message{Warning: unbalanced square brackets in @def...}%
5887 \global\brackcount=0 6516 \global\brackcount=0
5888} 6517}
5889 6518
@@ -5978,6 +6607,10 @@ where each line of input produces a line of output.}
5978% all characters are catcode 10, 11 or 12, except \ which is active 6607% all characters are catcode 10, 11 or 12, except \ which is active
5979% (as in normal texinfo). It is necessary to change the definition of \. 6608% (as in normal texinfo). It is necessary to change the definition of \.
5980 6609
6610% Non-ASCII encodings make 8-bit characters active, so un-activate
6611% them to avoid their expansion. Must do this non-globally, to
6612% confine the change to the current group.
6613
5981% It's necessary to have hard CRs when the macro is executed. This is 6614% It's necessary to have hard CRs when the macro is executed. This is
5982% done by making ^^M (\endlinechar) catcode 12 when reading the macro 6615% done by making ^^M (\endlinechar) catcode 12 when reading the macro
5983% body, and then making it the \newlinechar in \scanmacro. 6616% body, and then making it the \newlinechar in \scanmacro.
@@ -5992,6 +6625,7 @@ where each line of input produces a line of output.}
5992 \catcode`\_=\other 6625 \catcode`\_=\other
5993 \catcode`\|=\other 6626 \catcode`\|=\other
5994 \catcode`\~=\other 6627 \catcode`\~=\other
6628 \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi
5995} 6629}
5996 6630
5997\def\scanargctxt{% 6631\def\scanargctxt{%
@@ -6209,7 +6843,6 @@ where each line of input produces a line of output.}
6209\message{cross references,} 6843\message{cross references,}
6210 6844
6211\newwrite\auxfile 6845\newwrite\auxfile
6212
6213\newif\ifhavexrefs % True if xref values are known. 6846\newif\ifhavexrefs % True if xref values are known.
6214\newif\ifwarnedxrefs % True if we warned once that they aren't known. 6847\newif\ifwarnedxrefs % True if we warned once that they aren't known.
6215 6848
@@ -6254,7 +6887,7 @@ where each line of input produces a line of output.}
6254 6887
6255% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an 6888% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
6256% anchor), which consists of three parts: 6889% anchor), which consists of three parts:
6257% 1) NAME-title - the current sectioning name taken from \thissection, 6890% 1) NAME-title - the current sectioning name taken from \lastsection,
6258% or the anchor name. 6891% or the anchor name.
6259% 2) NAME-snt - section number and type, passed as the SNT arg, or 6892% 2) NAME-snt - section number and type, passed as the SNT arg, or
6260% empty for anchors. 6893% empty for anchors.
@@ -6273,10 +6906,10 @@ where each line of input produces a line of output.}
6273 \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef 6906 \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
6274 ##1}{##2}}% these are parameters of \writexrdef 6907 ##1}{##2}}% these are parameters of \writexrdef
6275 }% 6908 }%
6276 \toks0 = \expandafter{\thissection}% 6909 \toks0 = \expandafter{\lastsection}%
6277 \immediate \writexrdef{title}{\the\toks0 }% 6910 \immediate \writexrdef{title}{\the\toks0 }%
6278 \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. 6911 \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
6279 \writexrdef{pg}{\folio}% will be written later, during \shipout 6912 \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, during \shipout
6280 }% 6913 }%
6281 \fi 6914 \fi
6282} 6915}
@@ -6322,7 +6955,8 @@ where each line of input produces a line of output.}
6322 \ifpdf 6955 \ifpdf
6323 \leavevmode 6956 \leavevmode
6324 \getfilename{#4}% 6957 \getfilename{#4}%
6325 {\turnoffactive 6958 {\indexnofonts
6959 \turnoffactive
6326 % See comments at \activebackslashdouble. 6960 % See comments at \activebackslashdouble.
6327 {\activebackslashdouble \xdef\pdfxrefdest{#1}% 6961 {\activebackslashdouble \xdef\pdfxrefdest{#1}%
6328 \backslashparens\pdfxrefdest}% 6962 \backslashparens\pdfxrefdest}%
@@ -6335,7 +6969,7 @@ where each line of input produces a line of output.}
6335 goto name{\pdfmkpgn{\pdfxrefdest}}% 6969 goto name{\pdfmkpgn{\pdfxrefdest}}%
6336 \fi 6970 \fi
6337 }% 6971 }%
6338 \linkcolor 6972 \setcolor{\linkcolor}%
6339 \fi 6973 \fi
6340 % 6974 %
6341 % Float references are printed completely differently: "Figure 1.2" 6975 % Float references are printed completely differently: "Figure 1.2"
@@ -6373,7 +7007,7 @@ where each line of input produces a line of output.}
6373 % is a loss. Therefore, we give the text of the node name again, so it 7007 % is a loss. Therefore, we give the text of the node name again, so it
6374 % is as if TeX is seeing it for the first time. 7008 % is as if TeX is seeing it for the first time.
6375 \ifdim \wd1 > 0pt 7009 \ifdim \wd1 > 0pt
6376 \putwordsection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}% 7010 \putwordSection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
6377 \else 7011 \else
6378 % _ (for example) has to be the character _ for the purposes of the 7012 % _ (for example) has to be the character _ for the purposes of the
6379 % control sequence corresponding to the node, but it has to expand 7013 % control sequence corresponding to the node, but it has to expand
@@ -6469,10 +7103,18 @@ where each line of input produces a line of output.}
6469% collisions). But if this is a float type, we have more work to do. 7103% collisions). But if this is a float type, we have more work to do.
6470% 7104%
6471\def\xrdef#1#2{% 7105\def\xrdef#1#2{%
6472 \expandafter\gdef\csname XR#1\endcsname{#2}% remember this xref value. 7106 {% The node name might contain 8-bit characters, which in our current
7107 % implementation are changed to commands like @'e. Don't let these
7108 % mess up the control sequence name.
7109 \indexnofonts
7110 \turnoffactive
7111 \xdef\safexrefname{#1}%
7112 }%
7113 %
7114 \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref
6473 % 7115 %
6474 % Was that xref control sequence that we just defined for a float? 7116 % Was that xref control sequence that we just defined for a float?
6475 \expandafter\iffloat\csname XR#1\endcsname 7117 \expandafter\iffloat\csname XR\safexrefname\endcsname
6476 % it was a float, and we have the (safe) float type in \iffloattype. 7118 % it was a float, and we have the (safe) float type in \iffloattype.
6477 \expandafter\let\expandafter\floatlist 7119 \expandafter\let\expandafter\floatlist
6478 \csname floatlist\iffloattype\endcsname 7120 \csname floatlist\iffloattype\endcsname
@@ -6487,7 +7129,8 @@ where each line of input produces a line of output.}
6487 % 7129 %
6488 % Remember this xref in the control sequence \floatlistFLOATTYPE, 7130 % Remember this xref in the control sequence \floatlistFLOATTYPE,
6489 % for later use in \listoffloats. 7131 % for later use in \listoffloats.
6490 \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0{#1}}% 7132 \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
7133 {\safexrefname}}%
6491 \fi 7134 \fi
6492} 7135}
6493 7136
@@ -6591,6 +7234,7 @@ where each line of input produces a line of output.}
6591 \input\jobname.#1 7234 \input\jobname.#1
6592\endgroup} 7235\endgroup}
6593 7236
7237
6594\message{insertions,} 7238\message{insertions,}
6595% including footnotes. 7239% including footnotes.
6596 7240
@@ -6863,13 +7507,13 @@ where each line of input produces a line of output.}
6863 \global\advance\floatno by 1 7507 \global\advance\floatno by 1
6864 % 7508 %
6865 {% 7509 {%
6866 % This magic value for \thissection is output by \setref as the 7510 % This magic value for \lastsection is output by \setref as the
6867 % XREFLABEL-title value. \xrefX uses it to distinguish float 7511 % XREFLABEL-title value. \xrefX uses it to distinguish float
6868 % labels (which have a completely different output format) from 7512 % labels (which have a completely different output format) from
6869 % node and anchor labels. And \xrdef uses it to construct the 7513 % node and anchor labels. And \xrdef uses it to construct the
6870 % lists of floats. 7514 % lists of floats.
6871 % 7515 %
6872 \edef\thissection{\floatmagic=\safefloattype}% 7516 \edef\lastsection{\floatmagic=\safefloattype}%
6873 \setref{\floatlabel}{Yfloat}% 7517 \setref{\floatlabel}{Yfloat}%
6874 }% 7518 }%
6875 \fi 7519 \fi
@@ -7004,7 +7648,7 @@ where each line of input produces a line of output.}
7004 7648
7005% #1 is the control sequence we are passed; we expand into a conditional 7649% #1 is the control sequence we are passed; we expand into a conditional
7006% which is true if #1 represents a float ref. That is, the magic 7650% which is true if #1 represents a float ref. That is, the magic
7007% \thissection value which we \setref above. 7651% \lastsection value which we \setref above.
7008% 7652%
7009\def\iffloat#1{\expandafter\doiffloat#1==\finish} 7653\def\iffloat#1{\expandafter\doiffloat#1==\finish}
7010% 7654%
@@ -7065,39 +7709,871 @@ where each line of input produces a line of output.}
7065 \writeentry 7709 \writeentry
7066}} 7710}}
7067 7711
7712
7068\message{localization,} 7713\message{localization,}
7069% and i18n.
7070 7714
7071% @documentlanguage is usually given very early, just after 7715% @documentlanguage is usually given very early, just after
7072% @setfilename. If done too late, it may not override everything 7716% @setfilename. If done too late, it may not override everything
7073% properly. Single argument is the language abbreviation. 7717% properly. Single argument is the language (de) or locale (de_DE)
7074% It would be nice if we could set up a hyphenation file here. 7718% abbreviation. It would be nice if we could set up a hyphenation file.
7075% 7719%
7076\parseargdef\documentlanguage{% 7720{
7721 \catcode`\_ = \active
7722 \globaldefs=1
7723\parseargdef\documentlanguage{\begingroup
7724 \let_=\normalunderscore % normal _ character for filenames
7077 \tex % read txi-??.tex file in plain TeX. 7725 \tex % read txi-??.tex file in plain TeX.
7078 % Read the file if it exists. 7726 % Read the file by the name they passed if it exists.
7079 \openin 1 txi-#1.tex 7727 \openin 1 txi-#1.tex
7080 \ifeof 1 7728 \ifeof 1
7081 \errhelp = \nolanghelp 7729 \documentlanguagetrywithoutunderscore{#1_\finish}%
7082 \errmessage{Cannot read language file txi-#1.tex}%
7083 \else 7730 \else
7084 \input txi-#1.tex 7731 \input txi-#1.tex
7085 \fi 7732 \fi
7086 \closein 1 7733 \closein 1
7087 \endgroup 7734 \endgroup
7735\endgroup}
7736}
7737%
7738% If they passed de_DE, and txi-de_DE.tex doesn't exist,
7739% try txi-de.tex.
7740%
7741\def\documentlanguagetrywithoutunderscore#1_#2\finish{%
7742 \openin 1 txi-#1.tex
7743 \ifeof 1
7744 \errhelp = \nolanghelp
7745 \errmessage{Cannot read language file txi-#1.tex}%
7746 \else
7747 \input txi-#1.tex
7748 \fi
7749 \closein 1
7088} 7750}
7751%
7089\newhelp\nolanghelp{The given language definition file cannot be found or 7752\newhelp\nolanghelp{The given language definition file cannot be found or
7090is empty. Maybe you need to install it? In the current directory 7753is empty. Maybe you need to install it? In the current directory
7091should work if nowhere else does.} 7754should work if nowhere else does.}
7092 7755
7756% Set the catcode of characters 128 through 255 to the specified number.
7757%
7758\def\setnonasciicharscatcode#1{%
7759 \count255=128
7760 \loop\ifnum\count255<256
7761 \global\catcode\count255=#1\relax
7762 \advance\count255 by 1
7763 \repeat
7764}
7093 7765
7094% @documentencoding should change something in TeX eventually, most 7766\def\setnonasciicharscatcodenonglobal#1{%
7095% likely, but for now just recognize it. 7767 \count255=128
7096\let\documentencoding = \comment 7768 \loop\ifnum\count255<256
7769 \catcode\count255=#1\relax
7770 \advance\count255 by 1
7771 \repeat
7772}
7097 7773
7774% @documentencoding sets the definition of non-ASCII characters
7775% according to the specified encoding.
7776%
7777\parseargdef\documentencoding{%
7778 % Encoding being declared for the document.
7779 \def\declaredencoding{\csname #1.enc\endcsname}%
7780 %
7781 % Supported encodings: names converted to tokens in order to be able
7782 % to compare them with \ifx.
7783 \def\ascii{\csname US-ASCII.enc\endcsname}%
7784 \def\latnine{\csname ISO-8859-15.enc\endcsname}%
7785 \def\latone{\csname ISO-8859-1.enc\endcsname}%
7786 \def\lattwo{\csname ISO-8859-2.enc\endcsname}%
7787 \def\utfeight{\csname UTF-8.enc\endcsname}%
7788 %
7789 \ifx \declaredencoding \ascii
7790 \asciichardefs
7791 %
7792 \else \ifx \declaredencoding \lattwo
7793 \setnonasciicharscatcode\active
7794 \lattwochardefs
7795 %
7796 \else \ifx \declaredencoding \latone
7797 \setnonasciicharscatcode\active
7798 \latonechardefs
7799 %
7800 \else \ifx \declaredencoding \latnine
7801 \setnonasciicharscatcode\active
7802 \latninechardefs
7803 %
7804 \else \ifx \declaredencoding \utfeight
7805 \setnonasciicharscatcode\active
7806 \utfeightchardefs
7807 %
7808 \else
7809 \message{Unknown document encoding #1, ignoring.}%
7810 %
7811 \fi % utfeight
7812 \fi % latnine
7813 \fi % latone
7814 \fi % lattwo
7815 \fi % ascii
7816}
7817
7818% A message to be logged when using a character that isn't available
7819% the default font encoding (OT1).
7820%
7821\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
7822
7823% Take account of \c (plain) vs. \, (Texinfo) difference.
7824\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi}
7825
7826% First, make active non-ASCII characters in order for them to be
7827% correctly categorized when TeX reads the replacement text of
7828% macros containing the character definitions.
7829\setnonasciicharscatcode\active
7830%
7831% Latin1 (ISO-8859-1) character definitions.
7832\def\latonechardefs{%
7833 \gdef^^a0{~}
7834 \gdef^^a1{\exclamdown}
7835 \gdef^^a2{\missingcharmsg{CENT SIGN}}
7836 \gdef^^a3{{\pounds}}
7837 \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
7838 \gdef^^a5{\missingcharmsg{YEN SIGN}}
7839 \gdef^^a6{\missingcharmsg{BROKEN BAR}}
7840 \gdef^^a7{\S}
7841 \gdef^^a8{\"{}}
7842 \gdef^^a9{\copyright}
7843 \gdef^^aa{\ordf}
7844 \gdef^^ab{\missingcharmsg{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}}
7845 \gdef^^ac{$\lnot$}
7846 \gdef^^ad{\-}
7847 \gdef^^ae{\registeredsymbol}
7848 \gdef^^af{\={}}
7849 %
7850 \gdef^^b0{\textdegree}
7851 \gdef^^b1{$\pm$}
7852 \gdef^^b2{$^2$}
7853 \gdef^^b3{$^3$}
7854 \gdef^^b4{\'{}}
7855 \gdef^^b5{$\mu$}
7856 \gdef^^b6{\P}
7857 %
7858 \gdef^^b7{$^.$}
7859 \gdef^^b8{\cedilla\ }
7860 \gdef^^b9{$^1$}
7861 \gdef^^ba{\ordm}
7862 %
7863 \gdef^^bb{\missingcharmsg{RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK}}
7864 \gdef^^bc{$1\over4$}
7865 \gdef^^bd{$1\over2$}
7866 \gdef^^be{$3\over4$}
7867 \gdef^^bf{\questiondown}
7868 %
7869 \gdef^^c0{\`A}
7870 \gdef^^c1{\'A}
7871 \gdef^^c2{\^A}
7872 \gdef^^c3{\~A}
7873 \gdef^^c4{\"A}
7874 \gdef^^c5{\ringaccent A}
7875 \gdef^^c6{\AE}
7876 \gdef^^c7{\cedilla C}
7877 \gdef^^c8{\`E}
7878 \gdef^^c9{\'E}
7879 \gdef^^ca{\^E}
7880 \gdef^^cb{\"E}
7881 \gdef^^cc{\`I}
7882 \gdef^^cd{\'I}
7883 \gdef^^ce{\^I}
7884 \gdef^^cf{\"I}
7885 %
7886 \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER ETH}}
7887 \gdef^^d1{\~N}
7888 \gdef^^d2{\`O}
7889 \gdef^^d3{\'O}
7890 \gdef^^d4{\^O}
7891 \gdef^^d5{\~O}
7892 \gdef^^d6{\"O}
7893 \gdef^^d7{$\times$}
7894 \gdef^^d8{\O}
7895 \gdef^^d9{\`U}
7896 \gdef^^da{\'U}
7897 \gdef^^db{\^U}
7898 \gdef^^dc{\"U}
7899 \gdef^^dd{\'Y}
7900 \gdef^^de{\missingcharmsg{LATIN CAPITAL LETTER THORN}}
7901 \gdef^^df{\ss}
7902 %
7903 \gdef^^e0{\`a}
7904 \gdef^^e1{\'a}
7905 \gdef^^e2{\^a}
7906 \gdef^^e3{\~a}
7907 \gdef^^e4{\"a}
7908 \gdef^^e5{\ringaccent a}
7909 \gdef^^e6{\ae}
7910 \gdef^^e7{\cedilla c}
7911 \gdef^^e8{\`e}
7912 \gdef^^e9{\'e}
7913 \gdef^^ea{\^e}
7914 \gdef^^eb{\"e}
7915 \gdef^^ec{\`{\dotless i}}
7916 \gdef^^ed{\'{\dotless i}}
7917 \gdef^^ee{\^{\dotless i}}
7918 \gdef^^ef{\"{\dotless i}}
7919 %
7920 \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER ETH}}
7921 \gdef^^f1{\~n}
7922 \gdef^^f2{\`o}
7923 \gdef^^f3{\'o}
7924 \gdef^^f4{\^o}
7925 \gdef^^f5{\~o}
7926 \gdef^^f6{\"o}
7927 \gdef^^f7{$\div$}
7928 \gdef^^f8{\o}
7929 \gdef^^f9{\`u}
7930 \gdef^^fa{\'u}
7931 \gdef^^fb{\^u}
7932 \gdef^^fc{\"u}
7933 \gdef^^fd{\'y}
7934 \gdef^^fe{\missingcharmsg{LATIN SMALL LETTER THORN}}
7935 \gdef^^ff{\"y}
7936}
7937
7938% Latin9 (ISO-8859-15) encoding character definitions.
7939\def\latninechardefs{%
7940 % Encoding is almost identical to Latin1.
7941 \latonechardefs
7942 %
7943 \gdef^^a4{\euro}
7944 \gdef^^a6{\v S}
7945 \gdef^^a8{\v s}
7946 \gdef^^b4{\v Z}
7947 \gdef^^b8{\v z}
7948 \gdef^^bc{\OE}
7949 \gdef^^bd{\oe}
7950 \gdef^^be{\"Y}
7951}
7952
7953% Latin2 (ISO-8859-2) character definitions.
7954\def\lattwochardefs{%
7955 \gdef^^a0{~}
7956 \gdef^^a1{\missingcharmsg{LATIN CAPITAL LETTER A WITH OGONEK}}
7957 \gdef^^a2{\u{}}
7958 \gdef^^a3{\L}
7959 \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
7960 \gdef^^a5{\v L}
7961 \gdef^^a6{\'S}
7962 \gdef^^a7{\S}
7963 \gdef^^a8{\"{}}
7964 \gdef^^a9{\v S}
7965 \gdef^^aa{\cedilla S}
7966 \gdef^^ab{\v T}
7967 \gdef^^ac{\'Z}
7968 \gdef^^ad{\-}
7969 \gdef^^ae{\v Z}
7970 \gdef^^af{\dotaccent Z}
7971 %
7972 \gdef^^b0{\textdegree}
7973 \gdef^^b1{\missingcharmsg{LATIN SMALL LETTER A WITH OGONEK}}
7974 \gdef^^b2{\missingcharmsg{OGONEK}}
7975 \gdef^^b3{\l}
7976 \gdef^^b4{\'{}}
7977 \gdef^^b5{\v l}
7978 \gdef^^b6{\'s}
7979 \gdef^^b7{\v{}}
7980 \gdef^^b8{\cedilla\ }
7981 \gdef^^b9{\v s}
7982 \gdef^^ba{\cedilla s}
7983 \gdef^^bb{\v t}
7984 \gdef^^bc{\'z}
7985 \gdef^^bd{\H{}}
7986 \gdef^^be{\v z}
7987 \gdef^^bf{\dotaccent z}
7988 %
7989 \gdef^^c0{\'R}
7990 \gdef^^c1{\'A}
7991 \gdef^^c2{\^A}
7992 \gdef^^c3{\u A}
7993 \gdef^^c4{\"A}
7994 \gdef^^c5{\'L}
7995 \gdef^^c6{\'C}
7996 \gdef^^c7{\cedilla C}
7997 \gdef^^c8{\v C}
7998 \gdef^^c9{\'E}
7999 \gdef^^ca{\missingcharmsg{LATIN CAPITAL LETTER E WITH OGONEK}}
8000 \gdef^^cb{\"E}
8001 \gdef^^cc{\v E}
8002 \gdef^^cd{\'I}
8003 \gdef^^ce{\^I}
8004 \gdef^^cf{\v D}
8005 %
8006 \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER D WITH STROKE}}
8007 \gdef^^d1{\'N}
8008 \gdef^^d2{\v N}
8009 \gdef^^d3{\'O}
8010 \gdef^^d4{\^O}
8011 \gdef^^d5{\H O}
8012 \gdef^^d6{\"O}
8013 \gdef^^d7{$\times$}
8014 \gdef^^d8{\v R}
8015 \gdef^^d9{\ringaccent U}
8016 \gdef^^da{\'U}
8017 \gdef^^db{\H U}
8018 \gdef^^dc{\"U}
8019 \gdef^^dd{\'Y}
8020 \gdef^^de{\cedilla T}
8021 \gdef^^df{\ss}
8022 %
8023 \gdef^^e0{\'r}
8024 \gdef^^e1{\'a}
8025 \gdef^^e2{\^a}
8026 \gdef^^e3{\u a}
8027 \gdef^^e4{\"a}
8028 \gdef^^e5{\'l}
8029 \gdef^^e6{\'c}
8030 \gdef^^e7{\cedilla c}
8031 \gdef^^e8{\v c}
8032 \gdef^^e9{\'e}
8033 \gdef^^ea{\missingcharmsg{LATIN SMALL LETTER E WITH OGONEK}}
8034 \gdef^^eb{\"e}
8035 \gdef^^ec{\v e}
8036 \gdef^^ed{\'\i}
8037 \gdef^^ee{\^\i}
8038 \gdef^^ef{\v d}
8039 %
8040 \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER D WITH STROKE}}
8041 \gdef^^f1{\'n}
8042 \gdef^^f2{\v n}
8043 \gdef^^f3{\'o}
8044 \gdef^^f4{\^o}
8045 \gdef^^f5{\H o}
8046 \gdef^^f6{\"o}
8047 \gdef^^f7{$\div$}
8048 \gdef^^f8{\v r}
8049 \gdef^^f9{\ringaccent u}
8050 \gdef^^fa{\'u}
8051 \gdef^^fb{\H u}
8052 \gdef^^fc{\"u}
8053 \gdef^^fd{\'y}
8054 \gdef^^fe{\cedilla t}
8055 \gdef^^ff{\dotaccent{}}
8056}
8057
8058% UTF-8 character definitions.
8059%
8060% This code to support UTF-8 is based on LaTeX's utf8.def, with some
8061% changes for Texinfo conventions. It is included here under the GPL by
8062% permission from Frank Mittelbach and the LaTeX team.
8063%
8064\newcount\countUTFx
8065\newcount\countUTFy
8066\newcount\countUTFz
7098 8067
7099% Page size parameters. 8068\gdef\UTFviiiTwoOctets#1#2{\expandafter
8069 \UTFviiiDefined\csname u8:#1\string #2\endcsname}
8070%
8071\gdef\UTFviiiThreeOctets#1#2#3{\expandafter
8072 \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
7100% 8073%
8074\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter
8075 \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
8076
8077\gdef\UTFviiiDefined#1{%
8078 \ifx #1\relax
8079 \message{\linenumber Unicode char \string #1 not defined for Texinfo}%
8080 \else
8081 \expandafter #1%
8082 \fi
8083}
8084
8085\begingroup
8086 \catcode`\~13
8087 \catcode`\"12
8088
8089 \def\UTFviiiLoop{%
8090 \global\catcode\countUTFx\active
8091 \uccode`\~\countUTFx
8092 \uppercase\expandafter{\UTFviiiTmp}%
8093 \advance\countUTFx by 1
8094 \ifnum\countUTFx < \countUTFy
8095 \expandafter\UTFviiiLoop
8096 \fi}
8097
8098 \countUTFx = "C2
8099 \countUTFy = "E0
8100 \def\UTFviiiTmp{%
8101 \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
8102 \UTFviiiLoop
8103
8104 \countUTFx = "E0
8105 \countUTFy = "F0
8106 \def\UTFviiiTmp{%
8107 \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
8108 \UTFviiiLoop
8109
8110 \countUTFx = "F0
8111 \countUTFy = "F4
8112 \def\UTFviiiTmp{%
8113 \xdef~{\noexpand\UTFviiiFourOctets\string~}}
8114 \UTFviiiLoop
8115\endgroup
8116
8117\begingroup
8118 \catcode`\"=12
8119 \catcode`\<=12
8120 \catcode`\.=12
8121 \catcode`\,=12
8122 \catcode`\;=12
8123 \catcode`\!=12
8124 \catcode`\~=13
8125
8126 \gdef\DeclareUnicodeCharacter#1#2{%
8127 \countUTFz = "#1\relax
8128 \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
8129 \begingroup
8130 \parseXMLCharref
8131 \def\UTFviiiTwoOctets##1##2{%
8132 \csname u8:##1\string ##2\endcsname}%
8133 \def\UTFviiiThreeOctets##1##2##3{%
8134 \csname u8:##1\string ##2\string ##3\endcsname}%
8135 \def\UTFviiiFourOctets##1##2##3##4{%
8136 \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
8137 \expandafter\expandafter\expandafter\expandafter
8138 \expandafter\expandafter\expandafter
8139 \gdef\UTFviiiTmp{#2}%
8140 \endgroup}
8141
8142 \gdef\parseXMLCharref{%
8143 \ifnum\countUTFz < "A0\relax
8144 \errhelp = \EMsimple
8145 \errmessage{Cannot define Unicode char value < 00A0}%
8146 \else\ifnum\countUTFz < "800\relax
8147 \parseUTFviiiA,%
8148 \parseUTFviiiB C\UTFviiiTwoOctets.,%
8149 \else\ifnum\countUTFz < "10000\relax
8150 \parseUTFviiiA;%
8151 \parseUTFviiiA,%
8152 \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
8153 \else
8154 \parseUTFviiiA;%
8155 \parseUTFviiiA,%
8156 \parseUTFviiiA!%
8157 \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
8158 \fi\fi\fi
8159 }
8160
8161 \gdef\parseUTFviiiA#1{%
8162 \countUTFx = \countUTFz
8163 \divide\countUTFz by 64
8164 \countUTFy = \countUTFz
8165 \multiply\countUTFz by 64
8166 \advance\countUTFx by -\countUTFz
8167 \advance\countUTFx by 128
8168 \uccode `#1\countUTFx
8169 \countUTFz = \countUTFy}
8170
8171 \gdef\parseUTFviiiB#1#2#3#4{%
8172 \advance\countUTFz by "#10\relax
8173 \uccode `#3\countUTFz
8174 \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
8175\endgroup
8176
8177\def\utfeightchardefs{%
8178 \DeclareUnicodeCharacter{00A0}{\tie}
8179 \DeclareUnicodeCharacter{00A1}{\exclamdown}
8180 \DeclareUnicodeCharacter{00A3}{\pounds}
8181 \DeclareUnicodeCharacter{00A8}{\"{ }}
8182 \DeclareUnicodeCharacter{00A9}{\copyright}
8183 \DeclareUnicodeCharacter{00AA}{\ordf}
8184 \DeclareUnicodeCharacter{00AB}{\guillemetleft}
8185 \DeclareUnicodeCharacter{00AD}{\-}
8186 \DeclareUnicodeCharacter{00AE}{\registeredsymbol}
8187 \DeclareUnicodeCharacter{00AF}{\={ }}
8188
8189 \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}
8190 \DeclareUnicodeCharacter{00B4}{\'{ }}
8191 \DeclareUnicodeCharacter{00B8}{\cedilla{ }}
8192 \DeclareUnicodeCharacter{00BA}{\ordm}
8193 \DeclareUnicodeCharacter{00BB}{\guillemetright}
8194 \DeclareUnicodeCharacter{00BF}{\questiondown}
8195
8196 \DeclareUnicodeCharacter{00C0}{\`A}
8197 \DeclareUnicodeCharacter{00C1}{\'A}
8198 \DeclareUnicodeCharacter{00C2}{\^A}
8199 \DeclareUnicodeCharacter{00C3}{\~A}
8200 \DeclareUnicodeCharacter{00C4}{\"A}
8201 \DeclareUnicodeCharacter{00C5}{\AA}
8202 \DeclareUnicodeCharacter{00C6}{\AE}
8203 \DeclareUnicodeCharacter{00C7}{\cedilla{C}}
8204 \DeclareUnicodeCharacter{00C8}{\`E}
8205 \DeclareUnicodeCharacter{00C9}{\'E}
8206 \DeclareUnicodeCharacter{00CA}{\^E}
8207 \DeclareUnicodeCharacter{00CB}{\"E}
8208 \DeclareUnicodeCharacter{00CC}{\`I}
8209 \DeclareUnicodeCharacter{00CD}{\'I}
8210 \DeclareUnicodeCharacter{00CE}{\^I}
8211 \DeclareUnicodeCharacter{00CF}{\"I}
8212
8213 \DeclareUnicodeCharacter{00D1}{\~N}
8214 \DeclareUnicodeCharacter{00D2}{\`O}
8215 \DeclareUnicodeCharacter{00D3}{\'O}
8216 \DeclareUnicodeCharacter{00D4}{\^O}
8217 \DeclareUnicodeCharacter{00D5}{\~O}
8218 \DeclareUnicodeCharacter{00D6}{\"O}
8219 \DeclareUnicodeCharacter{00D8}{\O}
8220 \DeclareUnicodeCharacter{00D9}{\`U}
8221 \DeclareUnicodeCharacter{00DA}{\'U}
8222 \DeclareUnicodeCharacter{00DB}{\^U}
8223 \DeclareUnicodeCharacter{00DC}{\"U}
8224 \DeclareUnicodeCharacter{00DD}{\'Y}
8225 \DeclareUnicodeCharacter{00DF}{\ss}
8226
8227 \DeclareUnicodeCharacter{00E0}{\`a}
8228 \DeclareUnicodeCharacter{00E1}{\'a}
8229 \DeclareUnicodeCharacter{00E2}{\^a}
8230 \DeclareUnicodeCharacter{00E3}{\~a}
8231 \DeclareUnicodeCharacter{00E4}{\"a}
8232 \DeclareUnicodeCharacter{00E5}{\aa}
8233 \DeclareUnicodeCharacter{00E6}{\ae}
8234 \DeclareUnicodeCharacter{00E7}{\cedilla{c}}
8235 \DeclareUnicodeCharacter{00E8}{\`e}
8236 \DeclareUnicodeCharacter{00E9}{\'e}
8237 \DeclareUnicodeCharacter{00EA}{\^e}
8238 \DeclareUnicodeCharacter{00EB}{\"e}
8239 \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}
8240 \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}
8241 \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
8242 \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
8243
8244 \DeclareUnicodeCharacter{00F1}{\~n}
8245 \DeclareUnicodeCharacter{00F2}{\`o}
8246 \DeclareUnicodeCharacter{00F3}{\'o}
8247 \DeclareUnicodeCharacter{00F4}{\^o}
8248 \DeclareUnicodeCharacter{00F5}{\~o}
8249 \DeclareUnicodeCharacter{00F6}{\"o}
8250 \DeclareUnicodeCharacter{00F8}{\o}
8251 \DeclareUnicodeCharacter{00F9}{\`u}
8252 \DeclareUnicodeCharacter{00FA}{\'u}
8253 \DeclareUnicodeCharacter{00FB}{\^u}
8254 \DeclareUnicodeCharacter{00FC}{\"u}
8255 \DeclareUnicodeCharacter{00FD}{\'y}
8256 \DeclareUnicodeCharacter{00FF}{\"y}
8257
8258 \DeclareUnicodeCharacter{0100}{\=A}
8259 \DeclareUnicodeCharacter{0101}{\=a}
8260 \DeclareUnicodeCharacter{0102}{\u{A}}
8261 \DeclareUnicodeCharacter{0103}{\u{a}}
8262 \DeclareUnicodeCharacter{0106}{\'C}
8263 \DeclareUnicodeCharacter{0107}{\'c}
8264 \DeclareUnicodeCharacter{0108}{\^C}
8265 \DeclareUnicodeCharacter{0109}{\^c}
8266 \DeclareUnicodeCharacter{010A}{\dotaccent{C}}
8267 \DeclareUnicodeCharacter{010B}{\dotaccent{c}}
8268 \DeclareUnicodeCharacter{010C}{\v{C}}
8269 \DeclareUnicodeCharacter{010D}{\v{c}}
8270 \DeclareUnicodeCharacter{010E}{\v{D}}
8271
8272 \DeclareUnicodeCharacter{0112}{\=E}
8273 \DeclareUnicodeCharacter{0113}{\=e}
8274 \DeclareUnicodeCharacter{0114}{\u{E}}
8275 \DeclareUnicodeCharacter{0115}{\u{e}}
8276 \DeclareUnicodeCharacter{0116}{\dotaccent{E}}
8277 \DeclareUnicodeCharacter{0117}{\dotaccent{e}}
8278 \DeclareUnicodeCharacter{011A}{\v{E}}
8279 \DeclareUnicodeCharacter{011B}{\v{e}}
8280 \DeclareUnicodeCharacter{011C}{\^G}
8281 \DeclareUnicodeCharacter{011D}{\^g}
8282 \DeclareUnicodeCharacter{011E}{\u{G}}
8283 \DeclareUnicodeCharacter{011F}{\u{g}}
8284
8285 \DeclareUnicodeCharacter{0120}{\dotaccent{G}}
8286 \DeclareUnicodeCharacter{0121}{\dotaccent{g}}
8287 \DeclareUnicodeCharacter{0124}{\^H}
8288 \DeclareUnicodeCharacter{0125}{\^h}
8289 \DeclareUnicodeCharacter{0128}{\~I}
8290 \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}
8291 \DeclareUnicodeCharacter{012A}{\=I}
8292 \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}
8293 \DeclareUnicodeCharacter{012C}{\u{I}}
8294 \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}
8295
8296 \DeclareUnicodeCharacter{0130}{\dotaccent{I}}
8297 \DeclareUnicodeCharacter{0131}{\dotless{i}}
8298 \DeclareUnicodeCharacter{0132}{IJ}
8299 \DeclareUnicodeCharacter{0133}{ij}
8300 \DeclareUnicodeCharacter{0134}{\^J}
8301 \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}
8302 \DeclareUnicodeCharacter{0139}{\'L}
8303 \DeclareUnicodeCharacter{013A}{\'l}
8304
8305 \DeclareUnicodeCharacter{0141}{\L}
8306 \DeclareUnicodeCharacter{0142}{\l}
8307 \DeclareUnicodeCharacter{0143}{\'N}
8308 \DeclareUnicodeCharacter{0144}{\'n}
8309 \DeclareUnicodeCharacter{0147}{\v{N}}
8310 \DeclareUnicodeCharacter{0148}{\v{n}}
8311 \DeclareUnicodeCharacter{014C}{\=O}
8312 \DeclareUnicodeCharacter{014D}{\=o}
8313 \DeclareUnicodeCharacter{014E}{\u{O}}
8314 \DeclareUnicodeCharacter{014F}{\u{o}}
8315
8316 \DeclareUnicodeCharacter{0150}{\H{O}}
8317 \DeclareUnicodeCharacter{0151}{\H{o}}
8318 \DeclareUnicodeCharacter{0152}{\OE}
8319 \DeclareUnicodeCharacter{0153}{\oe}
8320 \DeclareUnicodeCharacter{0154}{\'R}
8321 \DeclareUnicodeCharacter{0155}{\'r}
8322 \DeclareUnicodeCharacter{0158}{\v{R}}
8323 \DeclareUnicodeCharacter{0159}{\v{r}}
8324 \DeclareUnicodeCharacter{015A}{\'S}
8325 \DeclareUnicodeCharacter{015B}{\'s}
8326 \DeclareUnicodeCharacter{015C}{\^S}
8327 \DeclareUnicodeCharacter{015D}{\^s}
8328 \DeclareUnicodeCharacter{015E}{\cedilla{S}}
8329 \DeclareUnicodeCharacter{015F}{\cedilla{s}}
8330
8331 \DeclareUnicodeCharacter{0160}{\v{S}}
8332 \DeclareUnicodeCharacter{0161}{\v{s}}
8333 \DeclareUnicodeCharacter{0162}{\cedilla{t}}
8334 \DeclareUnicodeCharacter{0163}{\cedilla{T}}
8335 \DeclareUnicodeCharacter{0164}{\v{T}}
8336
8337 \DeclareUnicodeCharacter{0168}{\~U}
8338 \DeclareUnicodeCharacter{0169}{\~u}
8339 \DeclareUnicodeCharacter{016A}{\=U}
8340 \DeclareUnicodeCharacter{016B}{\=u}
8341 \DeclareUnicodeCharacter{016C}{\u{U}}
8342 \DeclareUnicodeCharacter{016D}{\u{u}}
8343 \DeclareUnicodeCharacter{016E}{\ringaccent{U}}
8344 \DeclareUnicodeCharacter{016F}{\ringaccent{u}}
8345
8346 \DeclareUnicodeCharacter{0170}{\H{U}}
8347 \DeclareUnicodeCharacter{0171}{\H{u}}
8348 \DeclareUnicodeCharacter{0174}{\^W}
8349 \DeclareUnicodeCharacter{0175}{\^w}
8350 \DeclareUnicodeCharacter{0176}{\^Y}
8351 \DeclareUnicodeCharacter{0177}{\^y}
8352 \DeclareUnicodeCharacter{0178}{\"Y}
8353 \DeclareUnicodeCharacter{0179}{\'Z}
8354 \DeclareUnicodeCharacter{017A}{\'z}
8355 \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}
8356 \DeclareUnicodeCharacter{017C}{\dotaccent{z}}
8357 \DeclareUnicodeCharacter{017D}{\v{Z}}
8358 \DeclareUnicodeCharacter{017E}{\v{z}}
8359
8360 \DeclareUnicodeCharacter{01C4}{D\v{Z}}
8361 \DeclareUnicodeCharacter{01C5}{D\v{z}}
8362 \DeclareUnicodeCharacter{01C6}{d\v{z}}
8363 \DeclareUnicodeCharacter{01C7}{LJ}
8364 \DeclareUnicodeCharacter{01C8}{Lj}
8365 \DeclareUnicodeCharacter{01C9}{lj}
8366 \DeclareUnicodeCharacter{01CA}{NJ}
8367 \DeclareUnicodeCharacter{01CB}{Nj}
8368 \DeclareUnicodeCharacter{01CC}{nj}
8369 \DeclareUnicodeCharacter{01CD}{\v{A}}
8370 \DeclareUnicodeCharacter{01CE}{\v{a}}
8371 \DeclareUnicodeCharacter{01CF}{\v{I}}
8372
8373 \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}
8374 \DeclareUnicodeCharacter{01D1}{\v{O}}
8375 \DeclareUnicodeCharacter{01D2}{\v{o}}
8376 \DeclareUnicodeCharacter{01D3}{\v{U}}
8377 \DeclareUnicodeCharacter{01D4}{\v{u}}
8378
8379 \DeclareUnicodeCharacter{01E2}{\={\AE}}
8380 \DeclareUnicodeCharacter{01E3}{\={\ae}}
8381 \DeclareUnicodeCharacter{01E6}{\v{G}}
8382 \DeclareUnicodeCharacter{01E7}{\v{g}}
8383 \DeclareUnicodeCharacter{01E8}{\v{K}}
8384 \DeclareUnicodeCharacter{01E9}{\v{k}}
8385
8386 \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}
8387 \DeclareUnicodeCharacter{01F1}{DZ}
8388 \DeclareUnicodeCharacter{01F2}{Dz}
8389 \DeclareUnicodeCharacter{01F3}{dz}
8390 \DeclareUnicodeCharacter{01F4}{\'G}
8391 \DeclareUnicodeCharacter{01F5}{\'g}
8392 \DeclareUnicodeCharacter{01F8}{\`N}
8393 \DeclareUnicodeCharacter{01F9}{\`n}
8394 \DeclareUnicodeCharacter{01FC}{\'{\AE}}
8395 \DeclareUnicodeCharacter{01FD}{\'{\ae}}
8396 \DeclareUnicodeCharacter{01FE}{\'{\O}}
8397 \DeclareUnicodeCharacter{01FF}{\'{\o}}
8398
8399 \DeclareUnicodeCharacter{021E}{\v{H}}
8400 \DeclareUnicodeCharacter{021F}{\v{h}}
8401
8402 \DeclareUnicodeCharacter{0226}{\dotaccent{A}}
8403 \DeclareUnicodeCharacter{0227}{\dotaccent{a}}
8404 \DeclareUnicodeCharacter{0228}{\cedilla{E}}
8405 \DeclareUnicodeCharacter{0229}{\cedilla{e}}
8406 \DeclareUnicodeCharacter{022E}{\dotaccent{O}}
8407 \DeclareUnicodeCharacter{022F}{\dotaccent{o}}
8408
8409 \DeclareUnicodeCharacter{0232}{\=Y}
8410 \DeclareUnicodeCharacter{0233}{\=y}
8411 \DeclareUnicodeCharacter{0237}{\dotless{j}}
8412
8413 \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
8414 \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
8415 \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
8416 \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}
8417 \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}
8418 \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}
8419 \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}
8420 \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}
8421 \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}
8422 \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}
8423 \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}
8424 \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}
8425
8426 \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}
8427 \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}
8428
8429 \DeclareUnicodeCharacter{1E20}{\=G}
8430 \DeclareUnicodeCharacter{1E21}{\=g}
8431 \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}
8432 \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}
8433 \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}
8434 \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}
8435 \DeclareUnicodeCharacter{1E26}{\"H}
8436 \DeclareUnicodeCharacter{1E27}{\"h}
8437
8438 \DeclareUnicodeCharacter{1E30}{\'K}
8439 \DeclareUnicodeCharacter{1E31}{\'k}
8440 \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}
8441 \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}
8442 \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}
8443 \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}
8444 \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}
8445 \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}
8446 \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}
8447 \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}
8448 \DeclareUnicodeCharacter{1E3E}{\'M}
8449 \DeclareUnicodeCharacter{1E3F}{\'m}
8450
8451 \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}
8452 \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}
8453 \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}
8454 \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}
8455 \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}
8456 \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}
8457 \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}
8458 \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}
8459 \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}
8460 \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}
8461
8462 \DeclareUnicodeCharacter{1E54}{\'P}
8463 \DeclareUnicodeCharacter{1E55}{\'p}
8464 \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}
8465 \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}
8466 \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}
8467 \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}
8468 \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}
8469 \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}
8470 \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}
8471 \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}
8472
8473 \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}
8474 \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}
8475 \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}
8476 \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}
8477 \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}
8478 \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}
8479 \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}
8480 \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}
8481 \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}
8482 \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}
8483
8484 \DeclareUnicodeCharacter{1E7C}{\~V}
8485 \DeclareUnicodeCharacter{1E7D}{\~v}
8486 \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}
8487 \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}
8488
8489 \DeclareUnicodeCharacter{1E80}{\`W}
8490 \DeclareUnicodeCharacter{1E81}{\`w}
8491 \DeclareUnicodeCharacter{1E82}{\'W}
8492 \DeclareUnicodeCharacter{1E83}{\'w}
8493 \DeclareUnicodeCharacter{1E84}{\"W}
8494 \DeclareUnicodeCharacter{1E85}{\"w}
8495 \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}
8496 \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}
8497 \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}
8498 \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}
8499 \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}
8500 \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}
8501 \DeclareUnicodeCharacter{1E8C}{\"X}
8502 \DeclareUnicodeCharacter{1E8D}{\"x}
8503 \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}
8504 \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}
8505
8506 \DeclareUnicodeCharacter{1E90}{\^Z}
8507 \DeclareUnicodeCharacter{1E91}{\^z}
8508 \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}
8509 \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}
8510 \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}
8511 \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}
8512 \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}
8513 \DeclareUnicodeCharacter{1E97}{\"t}
8514 \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}
8515 \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}
8516
8517 \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}
8518 \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}
8519
8520 \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}
8521 \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}
8522 \DeclareUnicodeCharacter{1EBC}{\~E}
8523 \DeclareUnicodeCharacter{1EBD}{\~e}
8524
8525 \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}
8526 \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}
8527 \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}
8528 \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}
8529
8530 \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}
8531 \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}
8532
8533 \DeclareUnicodeCharacter{1EF2}{\`Y}
8534 \DeclareUnicodeCharacter{1EF3}{\`y}
8535 \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}
8536
8537 \DeclareUnicodeCharacter{1EF8}{\~Y}
8538 \DeclareUnicodeCharacter{1EF9}{\~y}
8539
8540 \DeclareUnicodeCharacter{2013}{--}
8541 \DeclareUnicodeCharacter{2014}{---}
8542 \DeclareUnicodeCharacter{2018}{\quoteleft}
8543 \DeclareUnicodeCharacter{2019}{\quoteright}
8544 \DeclareUnicodeCharacter{201A}{\quotesinglbase}
8545 \DeclareUnicodeCharacter{201C}{\quotedblleft}
8546 \DeclareUnicodeCharacter{201D}{\quotedblright}
8547 \DeclareUnicodeCharacter{201E}{\quotedblbase}
8548 \DeclareUnicodeCharacter{2022}{\bullet}
8549 \DeclareUnicodeCharacter{2026}{\dots}
8550 \DeclareUnicodeCharacter{2039}{\guilsinglleft}
8551 \DeclareUnicodeCharacter{203A}{\guilsinglright}
8552 \DeclareUnicodeCharacter{20AC}{\euro}
8553
8554 \DeclareUnicodeCharacter{2192}{\expansion}
8555 \DeclareUnicodeCharacter{21D2}{\result}
8556
8557 \DeclareUnicodeCharacter{2212}{\minus}
8558 \DeclareUnicodeCharacter{2217}{\point}
8559 \DeclareUnicodeCharacter{2261}{\equiv}
8560}% end of \utfeightchardefs
8561
8562
8563% US-ASCII character definitions.
8564\def\asciichardefs{% nothing need be done
8565 \relax
8566}
8567
8568% Make non-ASCII characters printable again for compatibility with
8569% existing Texinfo documents that may use them, even without declaring a
8570% document encoding.
8571%
8572\setnonasciicharscatcode \other
8573
8574
8575\message{formatting,}
8576
7101\newdimen\defaultparindent \defaultparindent = 15pt 8577\newdimen\defaultparindent \defaultparindent = 15pt
7102 8578
7103\chapheadingskip = 15pt plus 4pt minus 2pt 8579\chapheadingskip = 15pt plus 4pt minus 2pt
@@ -7110,7 +8586,7 @@ should work if nowhere else does.}
7110% Don't be so finicky about underfull hboxes, either. 8586% Don't be so finicky about underfull hboxes, either.
7111\hbadness = 2000 8587\hbadness = 2000
7112 8588
7113% Following George Bush, just get rid of widows and orphans. 8589% Following George Bush, get rid of widows and orphans.
7114\widowpenalty=10000 8590\widowpenalty=10000
7115\clubpenalty=10000 8591\clubpenalty=10000
7116 8592
@@ -7157,6 +8633,10 @@ should work if nowhere else does.}
7157 \ifpdf 8633 \ifpdf
7158 \pdfpageheight #7\relax 8634 \pdfpageheight #7\relax
7159 \pdfpagewidth #8\relax 8635 \pdfpagewidth #8\relax
8636 % if we don't reset these, they will remain at "1 true in" of
8637 % whatever layout pdftex was dumped with.
8638 \pdfhorigin = 1 true in
8639 \pdfvorigin = 1 true in
7160 \fi 8640 \fi
7161 % 8641 %
7162 \setleading{\textleading} 8642 \setleading{\textleading}
@@ -7171,7 +8651,7 @@ should work if nowhere else does.}
7171 \textleading = 13.2pt 8651 \textleading = 13.2pt
7172 % 8652 %
7173 % If page is nothing but text, make it come out even. 8653 % If page is nothing but text, make it come out even.
7174 \internalpagesizes{46\baselineskip}{6in}% 8654 \internalpagesizes{607.2pt}{6in}% that's 46 lines
7175 {\voffset}{.25in}% 8655 {\voffset}{.25in}%
7176 {\bindingoffset}{36pt}% 8656 {\bindingoffset}{36pt}%
7177 {11in}{8.5in}% 8657 {11in}{8.5in}%
@@ -7183,7 +8663,7 @@ should work if nowhere else does.}
7183 \textleading = 12pt 8663 \textleading = 12pt
7184 % 8664 %
7185 \internalpagesizes{7.5in}{5in}% 8665 \internalpagesizes{7.5in}{5in}%
7186 {\voffset}{.25in}% 8666 {-.2in}{0in}%
7187 {\bindingoffset}{16pt}% 8667 {\bindingoffset}{16pt}%
7188 {9.25in}{7in}% 8668 {9.25in}{7in}%
7189 % 8669 %
@@ -7227,7 +8707,7 @@ should work if nowhere else does.}
7227 % \global\normaloffset = -6mm 8707 % \global\normaloffset = -6mm
7228 % \global\bindingoffset = 10mm 8708 % \global\bindingoffset = 10mm
7229 % @end tex 8709 % @end tex
7230 \internalpagesizes{51\baselineskip}{160mm} 8710 \internalpagesizes{673.2pt}{160mm}% that's 51 lines
7231 {\voffset}{\hoffset}% 8711 {\voffset}{\hoffset}%
7232 {\bindingoffset}{44pt}% 8712 {\bindingoffset}{44pt}%
7233 {297mm}{210mm}% 8713 {297mm}{210mm}%
@@ -7292,7 +8772,7 @@ should work if nowhere else does.}
7292 \parskip = 3pt plus 2pt minus 1pt 8772 \parskip = 3pt plus 2pt minus 1pt
7293 \setleading{\textleading}% 8773 \setleading{\textleading}%
7294 % 8774 %
7295 \dimen0 = #1 8775 \dimen0 = #1\relax
7296 \advance\dimen0 by \voffset 8776 \advance\dimen0 by \voffset
7297 % 8777 %
7298 \dimen2 = \hsize 8778 \dimen2 = \hsize
diff --git a/src/Makefile.am b/src/Makefile.am
index 401b0ad1..4868557b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1 +1,9 @@
1SUBDIRS = include daemon . 1if HAVE_CURL
2curltests = testcurl
3if HAVE_ZZUF
4if HAVE_SOCAT
5zzuftests = testzzuf
6endif
7endif
8endif
9SUBDIRS = include daemon examples $(curltests) $(zzuftests) .
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
index b2f58c94..b10226fd 100644
--- a/src/daemon/Makefile.am
+++ b/src/daemon/Makefile.am
@@ -23,42 +23,9 @@ libmicrohttpd_la_SOURCES = \
23 postprocessor.c \ 23 postprocessor.c \
24 response.c response.h 24 response.c response.h
25 25
26# example programs
27
28noinst_PROGRAMS = minimal_example fileserver_example
29
30minimal_example_SOURCES = \
31 minimal_example.c
32minimal_example_LDADD = \
33 $(top_builddir)/src/daemon/libmicrohttpd.la
34
35fileserver_example_SOURCES = \
36 fileserver_example.c
37fileserver_example_LDADD = \
38 $(top_builddir)/src/daemon/libmicrohttpd.la
39
40
41# No curl, no testcases
42if HAVE_CURL
43
44check_PROGRAMS = \ 26check_PROGRAMS = \
45 postprocessor_test \ 27 postprocessor_test
46 daemontest \ 28 daemontest
47 daemontest_get \
48 daemontest_post \
49 daemontest_postform \
50 daemontest_post_loop \
51 daemontest_put \
52 daemontest_large_put \
53 daemontest_get11 \
54 daemontest_post11 \
55 daemontest_postform11 \
56 daemontest_post_loop11 \
57 daemontest_put11 \
58 daemontest_large_put11 \
59 daemontest_long_header \
60 daemontest_get_chunked \
61 daemontest_put_chunked
62 29
63TESTS = $(check_PROGRAMS) 30TESTS = $(check_PROGRAMS)
64 31
@@ -71,96 +38,3 @@ postprocessor_test_SOURCES = \
71 postprocessor_test.c 38 postprocessor_test.c
72postprocessor_test_LDADD = \ 39postprocessor_test_LDADD = \
73 $(top_builddir)/src/daemon/libmicrohttpd.la 40 $(top_builddir)/src/daemon/libmicrohttpd.la
74
75daemontest_get_SOURCES = \
76 daemontest_get.c
77daemontest_get_LDADD = \
78 $(top_builddir)/src/daemon/libmicrohttpd.la \
79 @LIBCURL@
80
81daemontest_get_chunked_SOURCES = \
82 daemontest_get_chunked.c
83daemontest_get_chunked_LDADD = \
84 $(top_builddir)/src/daemon/libmicrohttpd.la \
85 @LIBCURL@
86
87daemontest_post_SOURCES = \
88 daemontest_post.c
89daemontest_post_LDADD = \
90 $(top_builddir)/src/daemon/libmicrohttpd.la \
91 @LIBCURL@
92
93daemontest_postform_SOURCES = \
94 daemontest_postform.c
95daemontest_postform_LDADD = \
96 $(top_builddir)/src/daemon/libmicrohttpd.la \
97 @LIBCURL@
98
99daemontest_post_loop_SOURCES = \
100 daemontest_post_loop.c
101daemontest_post_loop_LDADD = \
102 $(top_builddir)/src/daemon/libmicrohttpd.la \
103 @LIBCURL@
104
105daemontest_put_SOURCES = \
106 daemontest_put.c
107daemontest_put_LDADD = \
108 $(top_builddir)/src/daemon/libmicrohttpd.la \
109 @LIBCURL@
110
111daemontest_put_chunked_SOURCES = \
112 daemontest_put_chunked.c
113daemontest_put_chunked_LDADD = \
114 $(top_builddir)/src/daemon/libmicrohttpd.la \
115 @LIBCURL@
116
117daemontest_get11_SOURCES = \
118 daemontest_get.c
119daemontest_get11_LDADD = \
120 $(top_builddir)/src/daemon/libmicrohttpd.la \
121 @LIBCURL@
122
123daemontest_post11_SOURCES = \
124 daemontest_post.c
125daemontest_post11_LDADD = \
126 $(top_builddir)/src/daemon/libmicrohttpd.la \
127 @LIBCURL@
128
129daemontest_postform11_SOURCES = \
130 daemontest_postform.c
131daemontest_postform11_LDADD = \
132 $(top_builddir)/src/daemon/libmicrohttpd.la \
133 @LIBCURL@
134
135daemontest_post_loop11_SOURCES = \
136 daemontest_post_loop.c
137daemontest_post_loop11_LDADD = \
138 $(top_builddir)/src/daemon/libmicrohttpd.la \
139 @LIBCURL@
140
141daemontest_put11_SOURCES = \
142 daemontest_put.c
143daemontest_put11_LDADD = \
144 $(top_builddir)/src/daemon/libmicrohttpd.la \
145 @LIBCURL@
146
147
148daemontest_large_put_SOURCES = \
149 daemontest_large_put.c
150daemontest_large_put_LDADD = \
151 $(top_builddir)/src/daemon/libmicrohttpd.la \
152 @LIBCURL@
153
154daemontest_large_put11_SOURCES = \
155 daemontest_large_put.c
156daemontest_large_put11_LDADD = \
157 $(top_builddir)/src/daemon/libmicrohttpd.la \
158 @LIBCURL@
159
160daemontest_long_header_SOURCES = \
161 daemontest_long_header.c
162daemontest_long_header_LDADD = \
163 $(top_builddir)/src/daemon/libmicrohttpd.la \
164 @LIBCURL@
165
166endif
diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am
new file mode 100644
index 00000000..fd515a56
--- /dev/null
+++ b/src/examples/Makefile.am
@@ -0,0 +1,18 @@
1SUBDIRS = .
2
3INCLUDES = -I$(top_srcdir)/src/include
4
5# example programs
6
7noinst_PROGRAMS = minimal_example fileserver_example
8
9minimal_example_SOURCES = \
10 minimal_example.c
11minimal_example_LDADD = \
12 $(top_builddir)/src/daemon/libmicrohttpd.la
13
14fileserver_example_SOURCES = \
15 fileserver_example.c
16fileserver_example_LDADD = \
17 $(top_builddir)/src/daemon/libmicrohttpd.la
18
diff --git a/src/daemon/fileserver_example.c b/src/examples/fileserver_example.c
index 866c2463..866c2463 100644
--- a/src/daemon/fileserver_example.c
+++ b/src/examples/fileserver_example.c
diff --git a/src/daemon/minimal_example.c b/src/examples/minimal_example.c
index 647a4776..647a4776 100644
--- a/src/daemon/minimal_example.c
+++ b/src/examples/minimal_example.c
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
new file mode 100644
index 00000000..d220ef08
--- /dev/null
+++ b/src/testcurl/Makefile.am
@@ -0,0 +1,126 @@
1SUBDIRS = .
2
3INCLUDES = -I$(top_srcdir)/src/include
4
5check_PROGRAMS = \
6 postprocessor_test \
7 daemontest \
8 daemontest_get \
9 daemontest_post \
10 daemontest_postform \
11 daemontest_post_loop \
12 daemontest_put \
13 daemontest_large_put \
14 daemontest_get11 \
15 daemontest_post11 \
16 daemontest_postform11 \
17 daemontest_post_loop11 \
18 daemontest_put11 \
19 daemontest_large_put11 \
20 daemontest_long_header \
21 daemontest_get_chunked \
22 daemontest_put_chunked
23
24TESTS = $(check_PROGRAMS)
25
26daemontest_SOURCES = \
27 daemontest.c
28daemontest_LDADD = \
29 $(top_builddir)/src/daemon/libmicrohttpd.la
30
31postprocessor_test_SOURCES = \
32 postprocessor_test.c
33postprocessor_test_LDADD = \
34 $(top_builddir)/src/daemon/libmicrohttpd.la
35
36daemontest_get_SOURCES = \
37 daemontest_get.c
38daemontest_get_LDADD = \
39 $(top_builddir)/src/daemon/libmicrohttpd.la \
40 @LIBCURL@
41
42daemontest_get_chunked_SOURCES = \
43 daemontest_get_chunked.c
44daemontest_get_chunked_LDADD = \
45 $(top_builddir)/src/daemon/libmicrohttpd.la \
46 @LIBCURL@
47
48daemontest_post_SOURCES = \
49 daemontest_post.c
50daemontest_post_LDADD = \
51 $(top_builddir)/src/daemon/libmicrohttpd.la \
52 @LIBCURL@
53
54daemontest_postform_SOURCES = \
55 daemontest_postform.c
56daemontest_postform_LDADD = \
57 $(top_builddir)/src/daemon/libmicrohttpd.la \
58 @LIBCURL@
59
60daemontest_post_loop_SOURCES = \
61 daemontest_post_loop.c
62daemontest_post_loop_LDADD = \
63 $(top_builddir)/src/daemon/libmicrohttpd.la \
64 @LIBCURL@
65
66daemontest_put_SOURCES = \
67 daemontest_put.c
68daemontest_put_LDADD = \
69 $(top_builddir)/src/daemon/libmicrohttpd.la \
70 @LIBCURL@
71
72daemontest_put_chunked_SOURCES = \
73 daemontest_put_chunked.c
74daemontest_put_chunked_LDADD = \
75 $(top_builddir)/src/daemon/libmicrohttpd.la \
76 @LIBCURL@
77
78daemontest_get11_SOURCES = \
79 daemontest_get.c
80daemontest_get11_LDADD = \
81 $(top_builddir)/src/daemon/libmicrohttpd.la \
82 @LIBCURL@
83
84daemontest_post11_SOURCES = \
85 daemontest_post.c
86daemontest_post11_LDADD = \
87 $(top_builddir)/src/daemon/libmicrohttpd.la \
88 @LIBCURL@
89
90daemontest_postform11_SOURCES = \
91 daemontest_postform.c
92daemontest_postform11_LDADD = \
93 $(top_builddir)/src/daemon/libmicrohttpd.la \
94 @LIBCURL@
95
96daemontest_post_loop11_SOURCES = \
97 daemontest_post_loop.c
98daemontest_post_loop11_LDADD = \
99 $(top_builddir)/src/daemon/libmicrohttpd.la \
100 @LIBCURL@
101
102daemontest_put11_SOURCES = \
103 daemontest_put.c
104daemontest_put11_LDADD = \
105 $(top_builddir)/src/daemon/libmicrohttpd.la \
106 @LIBCURL@
107
108
109daemontest_large_put_SOURCES = \
110 daemontest_large_put.c
111daemontest_large_put_LDADD = \
112 $(top_builddir)/src/daemon/libmicrohttpd.la \
113 @LIBCURL@
114
115daemontest_large_put11_SOURCES = \
116 daemontest_large_put.c
117daemontest_large_put11_LDADD = \
118 $(top_builddir)/src/daemon/libmicrohttpd.la \
119 @LIBCURL@
120
121daemontest_long_header_SOURCES = \
122 daemontest_long_header.c
123daemontest_long_header_LDADD = \
124 $(top_builddir)/src/daemon/libmicrohttpd.la \
125 @LIBCURL@
126
diff --git a/src/daemon/daemontest.c b/src/testcurl/daemontest.c
index 8048b438..8048b438 100644
--- a/src/daemon/daemontest.c
+++ b/src/testcurl/daemontest.c
diff --git a/src/daemon/daemontest_get.c b/src/testcurl/daemontest_get.c
index 2d5729c1..2d5729c1 100644
--- a/src/daemon/daemontest_get.c
+++ b/src/testcurl/daemontest_get.c
diff --git a/src/daemon/daemontest_get_chunked.c b/src/testcurl/daemontest_get_chunked.c
index 4b2739cf..4b2739cf 100644
--- a/src/daemon/daemontest_get_chunked.c
+++ b/src/testcurl/daemontest_get_chunked.c
diff --git a/src/daemon/daemontest_large_put.c b/src/testcurl/daemontest_large_put.c
index b0c7bf37..b0c7bf37 100644
--- a/src/daemon/daemontest_large_put.c
+++ b/src/testcurl/daemontest_large_put.c
diff --git a/src/daemon/daemontest_long_header.c b/src/testcurl/daemontest_long_header.c
index 385b9776..385b9776 100644
--- a/src/daemon/daemontest_long_header.c
+++ b/src/testcurl/daemontest_long_header.c
diff --git a/src/daemon/daemontest_put.c b/src/testcurl/daemontest_put.c
index e1f89402..e1f89402 100644
--- a/src/daemon/daemontest_put.c
+++ b/src/testcurl/daemontest_put.c
diff --git a/src/daemon/daemontest_put_chunked.c b/src/testcurl/daemontest_put_chunked.c
index 0cc3eb8f..0cc3eb8f 100644
--- a/src/daemon/daemontest_put_chunked.c
+++ b/src/testcurl/daemontest_put_chunked.c
diff --git a/src/testzzuf/Makefile.am b/src/testzzuf/Makefile.am
new file mode 100644
index 00000000..b48b75be
--- /dev/null
+++ b/src/testzzuf/Makefile.am
@@ -0,0 +1,125 @@
1SUBDIRS = .
2
3INCLUDES = -I$(top_srcdir)/src/include
4
5check_PROGRAMS = \
6 postprocessor_test \
7 daemontest \
8 daemontest_get \
9 daemontest_post \
10 daemontest_postform \
11 daemontest_post_loop \
12 daemontest_put \
13 daemontest_large_put \
14 daemontest_get11 \
15 daemontest_post11 \
16 daemontest_postform11 \
17 daemontest_post_loop11 \
18 daemontest_put11 \
19 daemontest_large_put11 \
20 daemontest_long_header \
21 daemontest_get_chunked \
22 daemontest_put_chunked
23
24TESTS = $(check_PROGRAMS)
25
26daemontest_SOURCES = \
27 daemontest.c
28daemontest_LDADD = \
29 $(top_builddir)/src/daemon/libmicrohttpd.la
30
31postprocessor_test_SOURCES = \
32 postprocessor_test.c
33postprocessor_test_LDADD = \
34 $(top_builddir)/src/daemon/libmicrohttpd.la
35
36daemontest_get_SOURCES = \
37 daemontest_get.c
38daemontest_get_LDADD = \
39 $(top_builddir)/src/daemon/libmicrohttpd.la \
40 @LIBCURL@
41
42daemontest_get_chunked_SOURCES = \
43 daemontest_get_chunked.c
44daemontest_get_chunked_LDADD = \
45 $(top_builddir)/src/daemon/libmicrohttpd.la \
46 @LIBCURL@
47
48daemontest_post_SOURCES = \
49 daemontest_post.c
50daemontest_post_LDADD = \
51 $(top_builddir)/src/daemon/libmicrohttpd.la \
52 @LIBCURL@
53
54daemontest_postform_SOURCES = \
55 daemontest_postform.c
56daemontest_postform_LDADD = \
57 $(top_builddir)/src/daemon/libmicrohttpd.la \
58 @LIBCURL@
59
60daemontest_post_loop_SOURCES = \
61 daemontest_post_loop.c
62daemontest_post_loop_LDADD = \
63 $(top_builddir)/src/daemon/libmicrohttpd.la \
64 @LIBCURL@
65
66daemontest_put_SOURCES = \
67 daemontest_put.c
68daemontest_put_LDADD = \
69 $(top_builddir)/src/daemon/libmicrohttpd.la \
70 @LIBCURL@
71
72daemontest_put_chunked_SOURCES = \
73 daemontest_put_chunked.c
74daemontest_put_chunked_LDADD = \
75 $(top_builddir)/src/daemon/libmicrohttpd.la \
76 @LIBCURL@
77
78daemontest_get11_SOURCES = \
79 daemontest_get.c
80daemontest_get11_LDADD = \
81 $(top_builddir)/src/daemon/libmicrohttpd.la \
82 @LIBCURL@
83
84daemontest_post11_SOURCES = \
85 daemontest_post.c
86daemontest_post11_LDADD = \
87 $(top_builddir)/src/daemon/libmicrohttpd.la \
88 @LIBCURL@
89
90daemontest_postform11_SOURCES = \
91 daemontest_postform.c
92daemontest_postform11_LDADD = \
93 $(top_builddir)/src/daemon/libmicrohttpd.la \
94 @LIBCURL@
95
96daemontest_post_loop11_SOURCES = \
97 daemontest_post_loop.c
98daemontest_post_loop11_LDADD = \
99 $(top_builddir)/src/daemon/libmicrohttpd.la \
100 @LIBCURL@
101
102daemontest_put11_SOURCES = \
103 daemontest_put.c
104daemontest_put11_LDADD = \
105 $(top_builddir)/src/daemon/libmicrohttpd.la \
106 @LIBCURL@
107
108
109daemontest_large_put_SOURCES = \
110 daemontest_large_put.c
111daemontest_large_put_LDADD = \
112 $(top_builddir)/src/daemon/libmicrohttpd.la \
113 @LIBCURL@
114
115daemontest_large_put11_SOURCES = \
116 daemontest_large_put.c
117daemontest_large_put11_LDADD = \
118 $(top_builddir)/src/daemon/libmicrohttpd.la \
119 @LIBCURL@
120
121daemontest_long_header_SOURCES = \
122 daemontest_long_header.c
123daemontest_long_header_LDADD = \
124 $(top_builddir)/src/daemon/libmicrohttpd.la \
125 @LIBCURL@
diff --git a/src/testzzuf/daemontest.c b/src/testzzuf/daemontest.c
new file mode 100644
index 00000000..8048b438
--- /dev/null
+++ b/src/testzzuf/daemontest.c
@@ -0,0 +1,163 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2007 Christian Grothoff
4
5 libmicrohttpd is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libmicrohttpd is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libmicrohttpd; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file daemontest.c
23 * @brief Testcase for libmicrohttpd starts and stops
24 * @author Christian Grothoff
25 */
26
27#include "config.h"
28#include "microhttpd.h"
29#include <stdlib.h>
30#include <string.h>
31#include <stdio.h>
32
33#ifndef WINDOWS
34#include <unistd.h>
35#endif
36
37
38static int
39testStartError ()
40{
41 struct MHD_Daemon *d;
42
43 d = MHD_start_daemon (MHD_USE_DEBUG, 0, NULL, NULL, NULL, NULL);
44 if (d != NULL)
45 return 1;
46 return 0;
47}
48
49static int
50apc_nothing (void *cls, const struct sockaddr *addr, socklen_t addrlen)
51{
52 return MHD_NO;
53}
54
55static int
56apc_all (void *cls, const struct sockaddr *addr, socklen_t addrlen)
57{
58 return MHD_YES;
59}
60
61static int
62ahc_nothing (void *cls,
63 struct MHD_Connection *connection,
64 const char *url,
65 const char *method,
66 const char *version,
67 const char *upload_data, unsigned int *upload_data_size,
68 void **unused)
69{
70 return MHD_NO;
71}
72
73static int
74testStartStop ()
75{
76 struct MHD_Daemon *d;
77
78 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
79 1080,
80 &apc_nothing,
81 NULL, &ahc_nothing, NULL, MHD_OPTION_END);
82 if (d == NULL)
83 return 2;
84 MHD_stop_daemon (d);
85 return 0;
86}
87
88static int
89testExternalRun ()
90{
91 struct MHD_Daemon *d;
92 fd_set rs;
93 int maxfd;
94 int i;
95
96 d = MHD_start_daemon (MHD_USE_DEBUG,
97 1081,
98 &apc_all, NULL, &ahc_nothing, NULL, MHD_OPTION_END);
99
100 if (d == NULL)
101 return 4;
102 i = 0;
103 while (i < 15)
104 {
105 maxfd = 0;
106 FD_ZERO (&rs);
107 MHD_get_fdset (d, &rs, &rs, &rs, &maxfd);
108 if (MHD_run (d) == MHD_NO)
109 {
110 MHD_stop_daemon (d);
111 return 8;
112 }
113 i++;
114 }
115 MHD_stop_daemon (d);
116 return 0;
117}
118
119static int
120testThread ()
121{
122 struct MHD_Daemon *d;
123 d = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SELECT_INTERNALLY,
124 1082,
125 &apc_all, NULL, &ahc_nothing, NULL, MHD_OPTION_END);
126
127 if (d == NULL)
128 return 16;
129 if (MHD_run (d) != MHD_NO)
130 return 32;
131 MHD_stop_daemon (d);
132 return 0;
133}
134
135static int
136testMultithread ()
137{
138 struct MHD_Daemon *d;
139 d = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_THREAD_PER_CONNECTION,
140 1083,
141 &apc_all, NULL, &ahc_nothing, NULL, MHD_OPTION_END);
142
143 if (d == NULL)
144 return 64;
145 if (MHD_run (d) != MHD_NO)
146 return 128;
147 MHD_stop_daemon (d);
148 return 0;
149}
150
151int
152main (int argc, char *const *argv)
153{
154 unsigned int errorCount = 0;
155 errorCount += testStartError ();
156 errorCount += testStartStop ();
157 errorCount += testExternalRun ();
158 errorCount += testThread ();
159 errorCount += testMultithread ();
160 if (errorCount != 0)
161 fprintf (stderr, "Error (code: %u)\n", errorCount);
162 return errorCount != 0; /* 0 == pass */
163}
diff --git a/src/testzzuf/daemontest_get.c b/src/testzzuf/daemontest_get.c
new file mode 100644
index 00000000..2d5729c1
--- /dev/null
+++ b/src/testzzuf/daemontest_get.c
@@ -0,0 +1,330 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2007 Christian Grothoff
4
5 libmicrohttpd is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libmicrohttpd is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libmicrohttpd; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file daemontest_get.c
23 * @brief Testcase for libmicrohttpd GET operations
24 * TODO: test parsing of query
25 * @author Christian Grothoff
26 */
27
28#include "config.h"
29#include <curl/curl.h>
30#include <microhttpd.h>
31#include <stdlib.h>
32#include <string.h>
33#include <time.h>
34
35#ifndef WINDOWS
36#include <unistd.h>
37#endif
38
39static int oneone;
40
41struct CBC
42{
43 char *buf;
44 size_t pos;
45 size_t size;
46};
47
48static size_t
49copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
50{
51 struct CBC *cbc = ctx;
52
53 if (cbc->pos + size * nmemb > cbc->size)
54 return 0; /* overflow */
55 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
56 cbc->pos += size * nmemb;
57 return size * nmemb;
58}
59
60static int
61ahc_echo (void *cls,
62 struct MHD_Connection *connection,
63 const char *url,
64 const char *method,
65 const char *version,
66 const char *upload_data, unsigned int *upload_data_size,
67 void **unused)
68{
69 static int ptr;
70 const char *me = cls;
71 struct MHD_Response *response;
72 int ret;
73
74 if (0 != strcmp (me, method))
75 return MHD_NO; /* unexpected method */
76 if (&ptr != *unused)
77 {
78 *unused = &ptr;
79 return MHD_YES;
80 }
81 *unused = NULL;
82 response = MHD_create_response_from_data (strlen (url),
83 (void *) url, MHD_NO, MHD_YES);
84 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
85 MHD_destroy_response (response);
86 if (ret == MHD_NO)
87 abort ();
88 return ret;
89}
90
91
92static int
93testInternalGet ()
94{
95 struct MHD_Daemon *d;
96 CURL *c;
97 char buf[2048];
98 struct CBC cbc;
99 CURLcode errornum;
100
101 cbc.buf = buf;
102 cbc.size = 2048;
103 cbc.pos = 0;
104 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
105 11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
106 if (d == NULL)
107 return 1;
108 c = curl_easy_init ();
109 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11080/hello_world");
110 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
111 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
112 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
113 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
114 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
115 if (oneone)
116 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
117 else
118 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
119 // NOTE: use of CONNECTTIMEOUT without also
120 // setting NOSIGNAL results in really weird
121 // crashes on my system!
122 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
123 if (CURLE_OK != (errornum = curl_easy_perform (c)))
124 {
125 fprintf (stderr,
126 "curl_easy_perform failed: `%s'\n",
127 curl_easy_strerror (errornum));
128 curl_easy_cleanup (c);
129 MHD_stop_daemon (d);
130 return 2;
131 }
132 curl_easy_cleanup (c);
133 MHD_stop_daemon (d);
134 if (cbc.pos != strlen ("/hello_world"))
135 return 4;
136 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
137 return 8;
138 return 0;
139}
140
141static int
142testMultithreadedGet ()
143{
144 struct MHD_Daemon *d;
145 CURL *c;
146 char buf[2048];
147 struct CBC cbc;
148 CURLcode errornum;
149
150 cbc.buf = buf;
151 cbc.size = 2048;
152 cbc.pos = 0;
153 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
154 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
155 if (d == NULL)
156 return 16;
157 c = curl_easy_init ();
158 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
159 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
160 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
161 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
162 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
163 if (oneone)
164 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
165 else
166 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
167 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
168 // NOTE: use of CONNECTTIMEOUT without also
169 // setting NOSIGNAL results in really weird
170 // crashes on my system!
171 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
172 if (CURLE_OK != (errornum = curl_easy_perform (c)))
173 {
174 fprintf (stderr,
175 "curl_easy_perform failed: `%s'\n",
176 curl_easy_strerror (errornum));
177 curl_easy_cleanup (c);
178 MHD_stop_daemon (d);
179 return 32;
180 }
181 curl_easy_cleanup (c);
182 MHD_stop_daemon (d);
183 if (cbc.pos != strlen ("/hello_world"))
184 return 64;
185 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
186 return 128;
187 return 0;
188}
189
190
191static int
192testExternalGet ()
193{
194 struct MHD_Daemon *d;
195 CURL *c;
196 char buf[2048];
197 struct CBC cbc;
198 CURLM *multi;
199 CURLMcode mret;
200 fd_set rs;
201 fd_set ws;
202 fd_set es;
203 int max;
204 int running;
205 struct CURLMsg *msg;
206 time_t start;
207 struct timeval tv;
208
209 multi = NULL;
210 cbc.buf = buf;
211 cbc.size = 2048;
212 cbc.pos = 0;
213 d = MHD_start_daemon (MHD_USE_DEBUG,
214 1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
215 if (d == NULL)
216 return 256;
217 c = curl_easy_init ();
218 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1082/hello_world");
219 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
220 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
221 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
222 if (oneone)
223 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
224 else
225 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
226 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
227 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
228 // NOTE: use of CONNECTTIMEOUT without also
229 // setting NOSIGNAL results in really weird
230 // crashes on my system!
231 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
232
233
234 multi = curl_multi_init ();
235 if (multi == NULL)
236 {
237 curl_easy_cleanup (c);
238 MHD_stop_daemon (d);
239 return 512;
240 }
241 mret = curl_multi_add_handle (multi, c);
242 if (mret != CURLM_OK)
243 {
244 curl_multi_cleanup (multi);
245 curl_easy_cleanup (c);
246 MHD_stop_daemon (d);
247 return 1024;
248 }
249 start = time (NULL);
250 while ((time (NULL) - start < 5) && (multi != NULL))
251 {
252 max = 0;
253 FD_ZERO (&rs);
254 FD_ZERO (&ws);
255 FD_ZERO (&es);
256 curl_multi_perform (multi, &running);
257 mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
258 if (mret != CURLM_OK)
259 {
260 curl_multi_remove_handle (multi, c);
261 curl_multi_cleanup (multi);
262 curl_easy_cleanup (c);
263 MHD_stop_daemon (d);
264 return 2048;
265 }
266 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
267 {
268 curl_multi_remove_handle (multi, c);
269 curl_multi_cleanup (multi);
270 curl_easy_cleanup (c);
271 MHD_stop_daemon (d);
272 return 4096;
273 }
274 tv.tv_sec = 0;
275 tv.tv_usec = 1000;
276 select (max + 1, &rs, &ws, &es, &tv);
277 curl_multi_perform (multi, &running);
278 if (running == 0)
279 {
280 msg = curl_multi_info_read (multi, &running);
281 if (msg == NULL)
282 break;
283 if (msg->msg == CURLMSG_DONE)
284 {
285 if (msg->data.result != CURLE_OK)
286 printf ("%s failed at %s:%d: `%s'\n",
287 "curl_multi_perform",
288 __FILE__,
289 __LINE__, curl_easy_strerror (msg->data.result));
290 curl_multi_remove_handle (multi, c);
291 curl_multi_cleanup (multi);
292 curl_easy_cleanup (c);
293 c = NULL;
294 multi = NULL;
295 }
296 }
297 MHD_run (d);
298 }
299 if (multi != NULL)
300 {
301 curl_multi_remove_handle (multi, c);
302 curl_easy_cleanup (c);
303 curl_multi_cleanup (multi);
304 }
305 MHD_stop_daemon (d);
306 if (cbc.pos != strlen ("/hello_world"))
307 return 8192;
308 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
309 return 16384;
310 return 0;
311}
312
313
314
315int
316main (int argc, char *const *argv)
317{
318 unsigned int errorCount = 0;
319
320 oneone = NULL != strstr (argv[0], "11");
321 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
322 return 2;
323 errorCount += testInternalGet ();
324 errorCount += testMultithreadedGet ();
325 errorCount += testExternalGet ();
326 if (errorCount != 0)
327 fprintf (stderr, "Error (code: %u)\n", errorCount);
328 curl_global_cleanup ();
329 return errorCount != 0; /* 0 == pass */
330}
diff --git a/src/testzzuf/daemontest_get_chunked.c b/src/testzzuf/daemontest_get_chunked.c
new file mode 100644
index 00000000..4b2739cf
--- /dev/null
+++ b/src/testzzuf/daemontest_get_chunked.c
@@ -0,0 +1,364 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2007 Christian Grothoff
4
5 libmicrohttpd is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libmicrohttpd is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libmicrohttpd; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file daemontest_get_chunked.c
23 * @brief Testcase for libmicrohttpd GET operations with chunked content encoding
24 * TODO:
25 * - how to test that chunking was actually used?
26 * - use CURLOPT_HEADERFUNCTION to validate
27 * footer was sent
28 * @author Christian Grothoff
29 */
30
31#include "config.h"
32#include <curl/curl.h>
33#include <microhttpd.h>
34#include <stdlib.h>
35#include <string.h>
36#include <time.h>
37
38#ifndef WINDOWS
39#include <unistd.h>
40#endif
41
42struct CBC
43{
44 char *buf;
45 size_t pos;
46 size_t size;
47};
48
49static size_t
50copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
51{
52 struct CBC *cbc = ctx;
53
54 if (cbc->pos + size * nmemb > cbc->size)
55 return 0; /* overflow */
56 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
57 cbc->pos += size * nmemb;
58 return size * nmemb;
59}
60
61/**
62 * MHD content reader callback that returns
63 * data in chunks.
64 */
65static int
66crc (void *cls, size_t pos, char *buf, int max)
67{
68 struct MHD_Response **responseptr = cls;
69
70 if (pos == 128 * 10)
71 {
72 MHD_add_response_header (*responseptr, "Footer", "working");
73 return -1; /* end of stream */
74 }
75 if (max < 128)
76 abort (); /* should not happen in this testcase... */
77 memset (buf, 'A' + (pos / 128), 128);
78 return 128;
79}
80
81/**
82 * Dummy function that does nothing.
83 */
84static void
85crcf (void *ptr)
86{
87 free (ptr);
88}
89
90static int
91ahc_echo (void *cls,
92 struct MHD_Connection *connection,
93 const char *url,
94 const char *method,
95 const char *version,
96 const char *upload_data, unsigned int *upload_data_size, void **ptr)
97{
98 static int aptr;
99 const char *me = cls;
100 struct MHD_Response *response;
101 struct MHD_Response **responseptr;
102 int ret;
103
104 if (0 != strcmp (me, method))
105 return MHD_NO; /* unexpected method */
106 if (&aptr != *ptr)
107 {
108 /* do never respond on first call */
109 *ptr = &aptr;
110 return MHD_YES;
111 }
112 responseptr = malloc (sizeof (struct MHD_Response *));
113 response = MHD_create_response_from_callback (-1,
114 1024,
115 &crc, responseptr, &crcf);
116 *responseptr = response;
117 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
118 MHD_destroy_response (response);
119 return ret;
120}
121
122static int
123validate (struct CBC cbc, int ebase)
124{
125 int i;
126 char buf[128];
127
128 if (cbc.pos != 128 * 10)
129 return ebase;
130
131 for (i = 0; i < 10; i++)
132 {
133 memset (buf, 'A' + i, 128);
134 if (0 != memcmp (buf, &cbc.buf[i * 128], 128))
135 {
136 fprintf (stderr,
137 "Got `%.*s'\nWant `%.*s'\n",
138 128, buf, 128, &cbc.buf[i * 128]);
139 return ebase * 2;
140 }
141 }
142 return 0;
143}
144
145static int
146testInternalGet ()
147{
148 struct MHD_Daemon *d;
149 CURL *c;
150 char buf[2048];
151 struct CBC cbc;
152 CURLcode errornum;
153
154 cbc.buf = buf;
155 cbc.size = 2048;
156 cbc.pos = 0;
157 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
158 1080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
159 if (d == NULL)
160 return 1;
161 c = curl_easy_init ();
162 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1080/hello_world");
163 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
164 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
165 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
166 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
167 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
168 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
169 // NOTE: use of CONNECTTIMEOUT without also
170 // setting NOSIGNAL results in really weird
171 // crashes on my system!
172 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
173 if (CURLE_OK != (errornum = curl_easy_perform (c)))
174 {
175 fprintf (stderr,
176 "curl_easy_perform failed: `%s'\n",
177 curl_easy_strerror (errornum));
178 curl_easy_cleanup (c);
179 MHD_stop_daemon (d);
180 return 2;
181 }
182 curl_easy_cleanup (c);
183 MHD_stop_daemon (d);
184 return validate (cbc, 4);
185}
186
187static int
188testMultithreadedGet ()
189{
190 struct MHD_Daemon *d;
191 CURL *c;
192 char buf[2048];
193 struct CBC cbc;
194 CURLcode errornum;
195
196 cbc.buf = buf;
197 cbc.size = 2048;
198 cbc.pos = 0;
199 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
200 1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
201 if (d == NULL)
202 return 16;
203 c = curl_easy_init ();
204 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
205 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
206 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
207 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
208 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
209 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
210 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
211 // NOTE: use of CONNECTTIMEOUT without also
212 // setting NOSIGNAL results in really weird
213 // crashes on my system!
214 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
215 if (CURLE_OK != (errornum = curl_easy_perform (c)))
216 {
217 fprintf (stderr,
218 "curl_easy_perform failed: `%s'\n",
219 curl_easy_strerror (errornum));
220 curl_easy_cleanup (c);
221 MHD_stop_daemon (d);
222 return 32;
223 }
224 curl_easy_cleanup (c);
225 MHD_stop_daemon (d);
226 return validate (cbc, 64);
227}
228
229
230static int
231testExternalGet ()
232{
233 struct MHD_Daemon *d;
234 CURL *c;
235 char buf[2048];
236 struct CBC cbc;
237 CURLM *multi;
238 CURLMcode mret;
239 fd_set rs;
240 fd_set ws;
241 fd_set es;
242 int max;
243 int running;
244 struct CURLMsg *msg;
245 time_t start;
246 struct timeval tv;
247
248 multi = NULL;
249 cbc.buf = buf;
250 cbc.size = 2048;
251 cbc.pos = 0;
252 d = MHD_start_daemon (MHD_USE_DEBUG,
253 1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
254 if (d == NULL)
255 return 256;
256 c = curl_easy_init ();
257 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1082/hello_world");
258 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
259 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
260 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
261 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
262 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
263 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 5L);
264 // NOTE: use of CONNECTTIMEOUT without also
265 // setting NOSIGNAL results in really weird
266 // crashes on my system!
267 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
268
269
270 multi = curl_multi_init ();
271 if (multi == NULL)
272 {
273 curl_easy_cleanup (c);
274 MHD_stop_daemon (d);
275 return 512;
276 }
277 mret = curl_multi_add_handle (multi, c);
278 if (mret != CURLM_OK)
279 {
280 curl_multi_cleanup (multi);
281 curl_easy_cleanup (c);
282 MHD_stop_daemon (d);
283 return 1024;
284 }
285 start = time (NULL);
286 while ((time (NULL) - start < 5) && (multi != NULL))
287 {
288 max = 0;
289 FD_ZERO (&rs);
290 FD_ZERO (&ws);
291 FD_ZERO (&es);
292 curl_multi_perform (multi, &running);
293 mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
294 if (mret != CURLM_OK)
295 {
296 curl_multi_remove_handle (multi, c);
297 curl_multi_cleanup (multi);
298 curl_easy_cleanup (c);
299 MHD_stop_daemon (d);
300 return 2048;
301 }
302 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
303 {
304 curl_multi_remove_handle (multi, c);
305 curl_multi_cleanup (multi);
306 curl_easy_cleanup (c);
307 MHD_stop_daemon (d);
308 return 4096;
309 }
310 tv.tv_sec = 0;
311 tv.tv_usec = 1000;
312 select (max + 1, &rs, &ws, &es, &tv);
313 curl_multi_perform (multi, &running);
314 if (running == 0)
315 {
316 msg = curl_multi_info_read (multi, &running);
317 if (msg == NULL)
318 break;
319 if (msg->msg == CURLMSG_DONE)
320 {
321 if (msg->data.result != CURLE_OK)
322 printf ("%s failed at %s:%d: `%s'\n",
323 "curl_multi_perform",
324 __FILE__,
325 __LINE__, curl_easy_strerror (msg->data.result));
326 curl_multi_remove_handle (multi, c);
327 curl_multi_cleanup (multi);
328 curl_easy_cleanup (c);
329 c = NULL;
330 multi = NULL;
331 }
332 }
333 MHD_run (d);
334 }
335 if (multi != NULL)
336 {
337 curl_multi_remove_handle (multi, c);
338 curl_easy_cleanup (c);
339 curl_multi_cleanup (multi);
340 }
341 MHD_stop_daemon (d);
342 return validate (cbc, 8192);
343}
344
345
346
347int
348main (int argc, char *const *argv)
349{
350 unsigned int errorCount = 0;
351
352 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
353 return 2;
354 errorCount += testInternalGet ();
355 if (0)
356 {
357 errorCount += testMultithreadedGet ();
358 errorCount += testExternalGet ();
359 }
360 if (errorCount != 0)
361 fprintf (stderr, "Error (code: %u)\n", errorCount);
362 curl_global_cleanup ();
363 return errorCount != 0; /* 0 == pass */
364}
diff --git a/src/testzzuf/daemontest_large_put.c b/src/testzzuf/daemontest_large_put.c
new file mode 100644
index 00000000..b0c7bf37
--- /dev/null
+++ b/src/testzzuf/daemontest_large_put.c
@@ -0,0 +1,404 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2007 Christian Grothoff
4
5 libmicrohttpd is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libmicrohttpd is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libmicrohttpd; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file daemontest_put.c
23 * @brief Testcase for libmicrohttpd PUT operations
24 * @author Christian Grothoff
25 */
26
27#include "config.h"
28#include <curl/curl.h>
29#include <microhttpd.h>
30#include <stdlib.h>
31#include <string.h>
32#include <time.h>
33
34#ifndef WINDOWS
35#include <unistd.h>
36#endif
37
38static int oneone;
39
40/**
41 * Do not make this much larger since we will hit the
42 * MHD default buffer limit and the test code is not
43 * written for incremental upload processing...
44 */
45#define PUT_SIZE (512 * 1024)
46
47static char *put_buffer;
48
49struct CBC
50{
51 char *buf;
52 size_t pos;
53 size_t size;
54};
55
56static size_t
57putBuffer (void *stream, size_t size, size_t nmemb, void *ptr)
58{
59 unsigned int *pos = ptr;
60 unsigned int wrt;
61
62 wrt = size * nmemb;
63 if (wrt > PUT_SIZE - (*pos))
64 wrt = PUT_SIZE - (*pos);
65 memcpy (stream, &put_buffer[*pos], wrt);
66 (*pos) += wrt;
67 return wrt;
68}
69
70static size_t
71copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
72{
73 struct CBC *cbc = ctx;
74
75 if (cbc->pos + size * nmemb > cbc->size)
76 return 0; /* overflow */
77 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
78 cbc->pos += size * nmemb;
79 return size * nmemb;
80}
81
82static int
83ahc_echo (void *cls,
84 struct MHD_Connection *connection,
85 const char *url,
86 const char *method,
87 const char *version,
88 const char *upload_data, unsigned int *upload_data_size,
89 void **unused)
90{
91 int *done = cls;
92 struct MHD_Response *response;
93 int ret;
94
95 if (0 != strcmp ("PUT", method))
96 return MHD_NO; /* unexpected method */
97 if ((*done) == 0)
98 {
99 if (*upload_data_size != PUT_SIZE)
100 {
101#if 0
102 fprintf (stderr,
103 "Waiting for more data (%u/%u)...\n",
104 *upload_data_size, PUT_SIZE);
105#endif
106 return MHD_YES; /* not yet ready */
107 }
108 if (0 == memcmp (upload_data, put_buffer, PUT_SIZE))
109 {
110 *upload_data_size = 0;
111 }
112 else
113 {
114 printf ("Invalid upload data!\n");
115 return MHD_NO;
116 }
117 *done = 1;
118 return MHD_YES;
119 }
120 response = MHD_create_response_from_data (strlen (url),
121 (void *) url, MHD_NO, MHD_YES);
122 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
123 MHD_destroy_response (response);
124 return ret;
125}
126
127
128static int
129testInternalPut ()
130{
131 struct MHD_Daemon *d;
132 CURL *c;
133 struct CBC cbc;
134 unsigned int pos = 0;
135 int done_flag = 0;
136 CURLcode errornum;
137 char buf[2048];
138
139 cbc.buf = buf;
140 cbc.size = 2048;
141 cbc.pos = 0;
142 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
143 1080,
144 NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
145 if (d == NULL)
146 return 1;
147 c = curl_easy_init ();
148 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1080/hello_world");
149 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
150 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
151 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
152 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
153 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
154 curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
155 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
156 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
157 if (oneone)
158 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
159 else
160 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
161 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
162 // NOTE: use of CONNECTTIMEOUT without also
163 // setting NOSIGNAL results in really weird
164 // crashes on my system!
165 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
166 if (CURLE_OK != (errornum = curl_easy_perform (c)))
167 {
168 fprintf (stderr,
169 "curl_easy_perform failed: `%s'\n",
170 curl_easy_strerror (errornum));
171 curl_easy_cleanup (c);
172 MHD_stop_daemon (d);
173 return 2;
174 }
175 curl_easy_cleanup (c);
176 MHD_stop_daemon (d);
177 if (cbc.pos != strlen ("/hello_world"))
178 return 4;
179 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
180 return 8;
181 return 0;
182}
183
184static int
185testMultithreadedPut ()
186{
187 struct MHD_Daemon *d;
188 CURL *c;
189 struct CBC cbc;
190 unsigned int pos = 0;
191 int done_flag = 0;
192 CURLcode errornum;
193 char buf[2048];
194
195 cbc.buf = buf;
196 cbc.size = 2048;
197 cbc.pos = 0;
198 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
199 1081,
200 NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
201 if (d == NULL)
202 {
203 free (cbc.buf);
204 return 16;
205 }
206 c = curl_easy_init ();
207 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
208 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
209 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
210 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
211 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
212 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
213 curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
214 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
215 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
216 if (oneone)
217 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
218 else
219 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
220 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
221 // NOTE: use of CONNECTTIMEOUT without also
222 // setting NOSIGNAL results in really weird
223 // crashes on my system!
224 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
225 if (CURLE_OK != (errornum = curl_easy_perform (c)))
226 {
227 fprintf (stderr,
228 "curl_easy_perform failed: `%s'\n",
229 curl_easy_strerror (errornum));
230 curl_easy_cleanup (c);
231 MHD_stop_daemon (d);
232 return 32;
233 }
234 curl_easy_cleanup (c);
235 MHD_stop_daemon (d);
236 if (cbc.pos != strlen ("/hello_world"))
237 {
238 fprintf (stderr, "Got invalid response `%.*s'\n", cbc.pos, cbc.buf);
239 return 64;
240 }
241 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
242 return 128;
243 return 0;
244}
245
246
247static int
248testExternalPut ()
249{
250 struct MHD_Daemon *d;
251 CURL *c;
252 struct CBC cbc;
253 CURLM *multi;
254 CURLMcode mret;
255 fd_set rs;
256 fd_set ws;
257 fd_set es;
258 int max;
259 int running;
260 struct CURLMsg *msg;
261 time_t start;
262 struct timeval tv;
263 unsigned int pos = 0;
264 int done_flag = 0;
265 char buf[2048];
266
267 cbc.buf = buf;
268 cbc.size = 2048;
269 cbc.pos = 0;
270 multi = NULL;
271 d = MHD_start_daemon (MHD_USE_DEBUG,
272 1082,
273 NULL, NULL, &ahc_echo, &done_flag,
274 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
275 PUT_SIZE * 4, MHD_OPTION_END);
276 if (d == NULL)
277 return 256;
278 c = curl_easy_init ();
279 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1082/hello_world");
280 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
281 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
282 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
283 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
284 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
285 curl_easy_setopt (c, CURLOPT_INFILESIZE, (long) PUT_SIZE);
286 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
287 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
288 if (oneone)
289 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
290 else
291 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
292 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
293 // NOTE: use of CONNECTTIMEOUT without also
294 // setting NOSIGNAL results in really weird
295 // crashes on my system!
296 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
297
298
299 multi = curl_multi_init ();
300 if (multi == NULL)
301 {
302 curl_easy_cleanup (c);
303 MHD_stop_daemon (d);
304 return 512;
305 }
306 mret = curl_multi_add_handle (multi, c);
307 if (mret != CURLM_OK)
308 {
309 curl_multi_cleanup (multi);
310 curl_easy_cleanup (c);
311 MHD_stop_daemon (d);
312 return 1024;
313 }
314 start = time (NULL);
315 while ((time (NULL) - start < 5) && (multi != NULL))
316 {
317 max = 0;
318 FD_ZERO (&rs);
319 FD_ZERO (&ws);
320 FD_ZERO (&es);
321 curl_multi_perform (multi, &running);
322 mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
323 if (mret != CURLM_OK)
324 {
325 curl_multi_remove_handle (multi, c);
326 curl_multi_cleanup (multi);
327 curl_easy_cleanup (c);
328 MHD_stop_daemon (d);
329 return 2048;
330 }
331 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
332 {
333 curl_multi_remove_handle (multi, c);
334 curl_multi_cleanup (multi);
335 curl_easy_cleanup (c);
336 MHD_stop_daemon (d);
337 return 4096;
338 }
339 tv.tv_sec = 0;
340 tv.tv_usec = 1000;
341 select (max + 1, &rs, &ws, &es, &tv);
342 curl_multi_perform (multi, &running);
343 if (running == 0)
344 {
345 msg = curl_multi_info_read (multi, &running);
346 if (msg == NULL)
347 break;
348 if (msg->msg == CURLMSG_DONE)
349 {
350 if (msg->data.result != CURLE_OK)
351 printf ("%s failed at %s:%d: `%s'\n",
352 "curl_multi_perform",
353 __FILE__,
354 __LINE__, curl_easy_strerror (msg->data.result));
355 curl_multi_remove_handle (multi, c);
356 curl_multi_cleanup (multi);
357 curl_easy_cleanup (c);
358 c = NULL;
359 multi = NULL;
360 }
361 }
362 MHD_run (d);
363 }
364 if (multi != NULL)
365 {
366 curl_multi_remove_handle (multi, c);
367 curl_easy_cleanup (c);
368 curl_multi_cleanup (multi);
369 }
370 MHD_stop_daemon (d);
371 if (cbc.pos != strlen ("/hello_world"))
372 {
373 fprintf (stderr, "Got invalid response `%.*s'\n", cbc.pos, cbc.buf);
374 return 8192;
375 }
376 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
377 return 16384;
378 return 0;
379}
380
381
382
383int
384main (int argc, char *const *argv)
385{
386 unsigned int errorCount = 0;
387
388 oneone = NULL != strstr (argv[0], "11");
389 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
390 return 2;
391 put_buffer = malloc (PUT_SIZE);
392 memset (put_buffer, 1, PUT_SIZE);
393 if (0)
394 {
395 errorCount += testInternalPut ();
396 errorCount += testMultithreadedPut ();
397 }
398 errorCount += testExternalPut ();
399 free (put_buffer);
400 if (errorCount != 0)
401 fprintf (stderr, "Error (code: %u)\n", errorCount);
402 curl_global_cleanup ();
403 return errorCount != 0; /* 0 == pass */
404}
diff --git a/src/testzzuf/daemontest_long_header.c b/src/testzzuf/daemontest_long_header.c
new file mode 100644
index 00000000..385b9776
--- /dev/null
+++ b/src/testzzuf/daemontest_long_header.c
@@ -0,0 +1,240 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2007 Christian Grothoff
4
5 libmicrohttpd is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libmicrohttpd is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libmicrohttpd; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file daemontest_long_header.c
23 * @brief Testcase for libmicrohttpd handling of very long headers
24 * @author Christian Grothoff
25 */
26
27#include "config.h"
28#include <curl/curl.h>
29#include <microhttpd.h>
30#include <stdlib.h>
31#include <string.h>
32#include <time.h>
33
34#ifndef WINDOWS
35#include <unistd.h>
36#endif
37
38/**
39 * We will set the memory available per connection to
40 * half of this value, so the actual value does not have
41 * to be big at all...
42 */
43#define VERY_LONG (1024*10)
44
45static int oneone;
46
47static int
48apc_all (void *cls, const struct sockaddr *addr, socklen_t addrlen)
49{
50 return MHD_YES;
51}
52
53struct CBC
54{
55 char *buf;
56 size_t pos;
57 size_t size;
58};
59
60static size_t
61copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
62{
63 return size * nmemb;
64}
65
66static int
67ahc_echo (void *cls,
68 struct MHD_Connection *connection,
69 const char *url,
70 const char *method,
71 const char *version,
72 const char *upload_data, unsigned int *upload_data_size,
73 void **unused)
74{
75 const char *me = cls;
76 struct MHD_Response *response;
77 int ret;
78
79 if (0 != strcmp (me, method))
80 return MHD_NO; /* unexpected method */
81 response = MHD_create_response_from_data (strlen (url),
82 (void *) url, MHD_NO, MHD_YES);
83 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
84 MHD_destroy_response (response);
85 return ret;
86}
87
88
89static int
90testLongUrlGet ()
91{
92 struct MHD_Daemon *d;
93 CURL *c;
94 char buf[2048];
95 struct CBC cbc;
96 char *url;
97 long code;
98
99 cbc.buf = buf;
100 cbc.size = 2048;
101 cbc.pos = 0;
102 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */ ,
103 1080,
104 &apc_all,
105 NULL,
106 &ahc_echo,
107 "GET",
108 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
109 VERY_LONG / 2, MHD_OPTION_END);
110 if (d == NULL)
111 return 1;
112 c = curl_easy_init ();
113 url = malloc (VERY_LONG);
114 memset (url, 'a', VERY_LONG);
115 url[VERY_LONG - 1] = '\0';
116 memcpy (url, "http://localhost:1080/", strlen ("http://localhost:1080/"));
117 curl_easy_setopt (c, CURLOPT_URL, url);
118 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
119 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
120 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
121 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
122 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
123 if (oneone)
124 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
125 else
126 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
127 // NOTE: use of CONNECTTIMEOUT without also
128 // setting NOSIGNAL results in really weird
129 // crashes on my system!
130 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
131 if (CURLE_OK == curl_easy_perform (c))
132 {
133 curl_easy_cleanup (c);
134 MHD_stop_daemon (d);
135 free (url);
136 return 2;
137 }
138 if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code))
139 {
140 curl_easy_cleanup (c);
141 MHD_stop_daemon (d);
142 free (url);
143 return 4;
144 }
145 curl_easy_cleanup (c);
146 MHD_stop_daemon (d);
147 free (url);
148 if (code != MHD_HTTP_REQUEST_URI_TOO_LONG)
149 return 8;
150 return 0;
151}
152
153
154static int
155testLongHeaderGet ()
156{
157 struct MHD_Daemon *d;
158 CURL *c;
159 char buf[2048];
160 struct CBC cbc;
161 char *url;
162 long code;
163 struct curl_slist *header = NULL;
164
165 cbc.buf = buf;
166 cbc.size = 2048;
167 cbc.pos = 0;
168 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */ ,
169 1080,
170 &apc_all,
171 NULL,
172 &ahc_echo,
173 "GET",
174 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
175 VERY_LONG / 2, MHD_OPTION_END);
176 if (d == NULL)
177 return 16;
178 c = curl_easy_init ();
179 url = malloc (VERY_LONG);
180 memset (url, 'a', VERY_LONG);
181 url[VERY_LONG - 1] = '\0';
182 url[VERY_LONG / 2] = ':';
183 url[VERY_LONG / 2 + 1] = ':';
184 header = curl_slist_append (header, url);
185
186 curl_easy_setopt (c, CURLOPT_HTTPHEADER, header);
187 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1080/hello_world");
188 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
189 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
190 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
191 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
192 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
193 if (oneone)
194 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
195 else
196 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
197 // NOTE: use of CONNECTTIMEOUT without also
198 // setting NOSIGNAL results in really weird
199 // crashes on my system!
200 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
201 if (CURLE_OK == curl_easy_perform (c))
202 {
203 curl_easy_cleanup (c);
204 MHD_stop_daemon (d);
205 curl_slist_free_all (header);
206 free (url);
207 return 32;
208 }
209 if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code))
210 {
211 curl_slist_free_all (header);
212 curl_easy_cleanup (c);
213 MHD_stop_daemon (d);
214 free (url);
215 return 64;
216 }
217 curl_slist_free_all (header);
218 curl_easy_cleanup (c);
219 MHD_stop_daemon (d);
220 free (url);
221 if (code != MHD_HTTP_REQUEST_ENTITY_TOO_LARGE)
222 return 128;
223 return 0;
224}
225
226int
227main (int argc, char *const *argv)
228{
229 unsigned int errorCount = 0;
230
231 oneone = NULL != strstr (argv[0], "11");
232 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
233 return 2;
234 errorCount += testLongUrlGet ();
235 errorCount += testLongHeaderGet ();
236 if (errorCount != 0)
237 fprintf (stderr, "Error (code: %u)\n", errorCount);
238 curl_global_cleanup ();
239 return errorCount != 0; /* 0 == pass */
240}
diff --git a/src/testzzuf/daemontest_put.c b/src/testzzuf/daemontest_put.c
new file mode 100644
index 00000000..e1f89402
--- /dev/null
+++ b/src/testzzuf/daemontest_put.c
@@ -0,0 +1,375 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2007 Christian Grothoff
4
5 libmicrohttpd is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libmicrohttpd is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libmicrohttpd; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file daemontest_put.c
23 * @brief Testcase for libmicrohttpd PUT operations
24 * @author Christian Grothoff
25 */
26
27#include "config.h"
28#include <curl/curl.h>
29#include <microhttpd.h>
30#include <stdlib.h>
31#include <string.h>
32#include <time.h>
33
34#ifndef WINDOWS
35#include <unistd.h>
36#endif
37
38static int oneone;
39
40struct CBC
41{
42 char *buf;
43 size_t pos;
44 size_t size;
45};
46
47static size_t
48putBuffer (void *stream, size_t size, size_t nmemb, void *ptr)
49{
50 unsigned int *pos = ptr;
51 unsigned int wrt;
52
53 wrt = size * nmemb;
54 if (wrt > 8 - (*pos))
55 wrt = 8 - (*pos);
56 memcpy (stream, &("Hello123"[*pos]), wrt);
57 (*pos) += wrt;
58 return wrt;
59}
60
61static size_t
62copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
63{
64 struct CBC *cbc = ctx;
65
66 if (cbc->pos + size * nmemb > cbc->size)
67 return 0; /* overflow */
68 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
69 cbc->pos += size * nmemb;
70 return size * nmemb;
71}
72
73static int
74ahc_echo (void *cls,
75 struct MHD_Connection *connection,
76 const char *url,
77 const char *method,
78 const char *version,
79 const char *upload_data, unsigned int *upload_data_size,
80 void **unused)
81{
82 int *done = cls;
83 struct MHD_Response *response;
84 int ret;
85
86 if (0 != strcmp ("PUT", method))
87 return MHD_NO; /* unexpected method */
88 if ((*done) == 0)
89 {
90 if (*upload_data_size != 8)
91 return MHD_YES; /* not yet ready */
92 if (0 == memcmp (upload_data, "Hello123", 8))
93 {
94 *upload_data_size = 0;
95 }
96 else
97 {
98 printf ("Invalid upload data `%8s'!\n", upload_data);
99 return MHD_NO;
100 }
101 *done = 1;
102 return MHD_YES;
103 }
104 response = MHD_create_response_from_data (strlen (url),
105 (void *) url, MHD_NO, MHD_YES);
106 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
107 MHD_destroy_response (response);
108 return ret;
109}
110
111
112static int
113testInternalPut ()
114{
115 struct MHD_Daemon *d;
116 CURL *c;
117 char buf[2048];
118 struct CBC cbc;
119 unsigned int pos = 0;
120 int done_flag = 0;
121 CURLcode errornum;
122
123 cbc.buf = buf;
124 cbc.size = 2048;
125 cbc.pos = 0;
126 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
127 1080,
128 NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
129 if (d == NULL)
130 return 1;
131 c = curl_easy_init ();
132 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1080/hello_world");
133 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
134 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
135 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
136 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
137 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
138 curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
139 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
140 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
141 if (oneone)
142 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
143 else
144 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
145 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
146 // NOTE: use of CONNECTTIMEOUT without also
147 // setting NOSIGNAL results in really weird
148 // crashes on my system!
149 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
150 if (CURLE_OK != (errornum = curl_easy_perform (c)))
151 {
152 fprintf (stderr,
153 "curl_easy_perform failed: `%s'\n",
154 curl_easy_strerror (errornum));
155 curl_easy_cleanup (c);
156 MHD_stop_daemon (d);
157 return 2;
158 }
159 curl_easy_cleanup (c);
160 MHD_stop_daemon (d);
161 if (cbc.pos != strlen ("/hello_world"))
162 return 4;
163 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
164 return 8;
165 return 0;
166}
167
168static int
169testMultithreadedPut ()
170{
171 struct MHD_Daemon *d;
172 CURL *c;
173 char buf[2048];
174 struct CBC cbc;
175 unsigned int pos = 0;
176 int done_flag = 0;
177 CURLcode errornum;
178
179 cbc.buf = buf;
180 cbc.size = 2048;
181 cbc.pos = 0;
182 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
183 1081,
184 NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
185 if (d == NULL)
186 return 16;
187 c = curl_easy_init ();
188 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world");
189 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
190 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
191 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
192 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
193 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
194 curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
195 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
196 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
197 if (oneone)
198 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
199 else
200 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
201 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
202 // NOTE: use of CONNECTTIMEOUT without also
203 // setting NOSIGNAL results in really weird
204 // crashes on my system!
205 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
206 if (CURLE_OK != (errornum = curl_easy_perform (c)))
207 {
208 fprintf (stderr,
209 "curl_easy_perform failed: `%s'\n",
210 curl_easy_strerror (errornum));
211 curl_easy_cleanup (c);
212 MHD_stop_daemon (d);
213 return 32;
214 }
215 curl_easy_cleanup (c);
216 MHD_stop_daemon (d);
217 if (cbc.pos != strlen ("/hello_world"))
218 return 64;
219 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
220 return 128;
221
222 return 0;
223}
224
225
226static int
227testExternalPut ()
228{
229 struct MHD_Daemon *d;
230 CURL *c;
231 char buf[2048];
232 struct CBC cbc;
233 CURLM *multi;
234 CURLMcode mret;
235 fd_set rs;
236 fd_set ws;
237 fd_set es;
238 int max;
239 int running;
240 struct CURLMsg *msg;
241 time_t start;
242 struct timeval tv;
243 unsigned int pos = 0;
244 int done_flag = 0;
245
246 multi = NULL;
247 cbc.buf = buf;
248 cbc.size = 2048;
249 cbc.pos = 0;
250 d = MHD_start_daemon (MHD_USE_DEBUG,
251 1082,
252 NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
253 if (d == NULL)
254 return 256;
255 c = curl_easy_init ();
256 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1082/hello_world");
257 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
258 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
259 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
260 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
261 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
262 curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
263 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
264 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
265 if (oneone)
266 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
267 else
268 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
269 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
270 // NOTE: use of CONNECTTIMEOUT without also
271 // setting NOSIGNAL results in really weird
272 // crashes on my system!
273 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
274
275
276 multi = curl_multi_init ();
277 if (multi == NULL)
278 {
279 curl_easy_cleanup (c);
280 MHD_stop_daemon (d);
281 return 512;
282 }
283 mret = curl_multi_add_handle (multi, c);
284 if (mret != CURLM_OK)
285 {
286 curl_multi_cleanup (multi);
287 curl_easy_cleanup (c);
288 MHD_stop_daemon (d);
289 return 1024;
290 }
291 start = time (NULL);
292 while ((time (NULL) - start < 5) && (multi != NULL))
293 {
294 max = 0;
295 FD_ZERO (&rs);
296 FD_ZERO (&ws);
297 FD_ZERO (&es);
298 curl_multi_perform (multi, &running);
299 mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
300 if (mret != CURLM_OK)
301 {
302 curl_multi_remove_handle (multi, c);
303 curl_multi_cleanup (multi);
304 curl_easy_cleanup (c);
305 MHD_stop_daemon (d);
306 return 2048;
307 }
308 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
309 {
310 curl_multi_remove_handle (multi, c);
311 curl_multi_cleanup (multi);
312 curl_easy_cleanup (c);
313 MHD_stop_daemon (d);
314 return 4096;
315 }
316 tv.tv_sec = 0;
317 tv.tv_usec = 1000;
318 select (max + 1, &rs, &ws, &es, &tv);
319 curl_multi_perform (multi, &running);
320 if (running == 0)
321 {
322 msg = curl_multi_info_read (multi, &running);
323 if (msg == NULL)
324 break;
325 if (msg->msg == CURLMSG_DONE)
326 {
327 if (msg->data.result != CURLE_OK)
328 printf ("%s failed at %s:%d: `%s'\n",
329 "curl_multi_perform",
330 __FILE__,
331 __LINE__, curl_easy_strerror (msg->data.result));
332 curl_multi_remove_handle (multi, c);
333 curl_multi_cleanup (multi);
334 curl_easy_cleanup (c);
335 c = NULL;
336 multi = NULL;
337 }
338 }
339 MHD_run (d);
340 }
341 if (multi != NULL)
342 {
343 curl_multi_remove_handle (multi, c);
344 curl_easy_cleanup (c);
345 curl_multi_cleanup (multi);
346 }
347 MHD_stop_daemon (d);
348 if (cbc.pos != strlen ("/hello_world"))
349 return 8192;
350 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
351 return 16384;
352 return 0;
353}
354
355
356
357int
358main (int argc, char *const *argv)
359{
360 unsigned int errorCount = 0;
361
362 oneone = NULL != strstr (argv[0], "11");
363 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
364 return 2;
365 errorCount += testInternalPut ();
366 if (0)
367 {
368 errorCount += testMultithreadedPut ();
369 errorCount += testExternalPut ();
370 }
371 if (errorCount != 0)
372 fprintf (stderr, "Error (code: %u)\n", errorCount);
373 curl_global_cleanup ();
374 return errorCount != 0; /* 0 == pass */
375}
diff --git a/src/testzzuf/daemontest_put_chunked.c b/src/testzzuf/daemontest_put_chunked.c
new file mode 100644
index 00000000..0cc3eb8f
--- /dev/null
+++ b/src/testzzuf/daemontest_put_chunked.c
@@ -0,0 +1,383 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2007 Christian Grothoff
4
5 libmicrohttpd is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libmicrohttpd is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libmicrohttpd; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file daemontest_put_chunked.c
23 * @brief Testcase for libmicrohttpd PUT operations with chunked encoding
24 * for the upload data
25 * @author Christian Grothoff
26 */
27
28#include "config.h"
29#include <curl/curl.h>
30#include <microhttpd.h>
31#include <stdlib.h>
32#include <string.h>
33#include <time.h>
34
35#ifndef WINDOWS
36#include <unistd.h>
37#endif
38
39struct CBC
40{
41 char *buf;
42 size_t pos;
43 size_t size;
44};
45
46static size_t
47putBuffer (void *stream, size_t size, size_t nmemb, void *ptr)
48{
49 unsigned int *pos = ptr;
50 unsigned int wrt;
51
52 wrt = size * nmemb;
53 if (wrt > 8 - (*pos))
54 wrt = 8 - (*pos);
55 if (wrt > 4)
56 wrt = 4; /* only send half at first => force multiple chunks! */
57 memcpy (stream, &("Hello123"[*pos]), wrt);
58 (*pos) += wrt;
59 return wrt;
60}
61
62static size_t
63copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
64{
65 struct CBC *cbc = ctx;
66
67 if (cbc->pos + size * nmemb > cbc->size)
68 return 0; /* overflow */
69 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
70 cbc->pos += size * nmemb;
71 return size * nmemb;
72}
73
74static int
75ahc_echo (void *cls,
76 struct MHD_Connection *connection,
77 const char *url,
78 const char *method,
79 const char *version,
80 const char *upload_data, unsigned int *upload_data_size,
81 void **unused)
82{
83 int *done = cls;
84 struct MHD_Response *response;
85 int ret;
86 int have;
87
88 if (0 != strcmp ("PUT", method))
89 return MHD_NO; /* unexpected method */
90 if ((*done) < 8)
91 {
92 have = *upload_data_size;
93 if (have + *done > 8)
94 {
95 printf ("Invalid upload data `%8s'!\n", upload_data);
96 return MHD_NO;
97 }
98 if (0 == memcmp (upload_data, &"Hello123"[*done], have))
99 {
100 *done += have;
101 *upload_data_size = 0;
102 }
103 else
104 {
105 printf ("Invalid upload data `%8s'!\n", upload_data);
106 return MHD_NO;
107 }
108#if 0
109 fprintf (stderr, "Not ready for response: %u/%u\n", *done, 8);
110#endif
111 return MHD_YES;
112 }
113 response = MHD_create_response_from_data (strlen (url),
114 (void *) url, MHD_NO, MHD_YES);
115 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
116 MHD_destroy_response (response);
117 return ret;
118}
119
120
121static int
122testInternalPut ()
123{
124 struct MHD_Daemon *d;
125 CURL *c;
126 char buf[2048];
127 struct CBC cbc;
128 unsigned int pos = 0;
129 int done_flag = 0;
130 CURLcode errornum;
131
132 cbc.buf = buf;
133 cbc.size = 2048;
134 cbc.pos = 0;
135 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
136 11080,
137 NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
138 if (d == NULL)
139 return 1;
140 c = curl_easy_init ();
141 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11080/hello_world");
142 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
143 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
144 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
145 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
146 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
147 /*
148 // by not giving the file size, we force chunking!
149 curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
150 */
151 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
152 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
153 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
154 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
155 // NOTE: use of CONNECTTIMEOUT without also
156 // setting NOSIGNAL results in really weird
157 // crashes on my system!
158 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
159 if (CURLE_OK != (errornum = curl_easy_perform (c)))
160 {
161 fprintf (stderr,
162 "curl_easy_perform failed: `%s'\n",
163 curl_easy_strerror (errornum));
164 curl_easy_cleanup (c);
165 MHD_stop_daemon (d);
166 return 2;
167 }
168 curl_easy_cleanup (c);
169 MHD_stop_daemon (d);
170 if (cbc.pos != strlen ("/hello_world"))
171 return 4;
172 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
173 return 8;
174 return 0;
175}
176
177static int
178testMultithreadedPut ()
179{
180 struct MHD_Daemon *d;
181 CURL *c;
182 char buf[2048];
183 struct CBC cbc;
184 unsigned int pos = 0;
185 int done_flag = 0;
186 CURLcode errornum;
187
188 cbc.buf = buf;
189 cbc.size = 2048;
190 cbc.pos = 0;
191 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
192 11081,
193 NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
194 if (d == NULL)
195 return 16;
196 c = curl_easy_init ();
197 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11081/hello_world");
198 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
199 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
200 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
201 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
202 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
203 /*
204 // by not giving the file size, we force chunking!
205 curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
206 */
207 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
208 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
209 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
210 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
211 // NOTE: use of CONNECTTIMEOUT without also
212 // setting NOSIGNAL results in really weird
213 // crashes on my system!
214 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
215 if (CURLE_OK != (errornum = curl_easy_perform (c)))
216 {
217 fprintf (stderr,
218 "curl_easy_perform failed: `%s'\n",
219 curl_easy_strerror (errornum));
220 curl_easy_cleanup (c);
221 MHD_stop_daemon (d);
222 return 32;
223 }
224 curl_easy_cleanup (c);
225 MHD_stop_daemon (d);
226 if (cbc.pos != strlen ("/hello_world"))
227 return 64;
228 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
229 return 128;
230
231 return 0;
232}
233
234
235static int
236testExternalPut ()
237{
238 struct MHD_Daemon *d;
239 CURL *c;
240 char buf[2048];
241 struct CBC cbc;
242 CURLM *multi;
243 CURLMcode mret;
244 fd_set rs;
245 fd_set ws;
246 fd_set es;
247 int max;
248 int running;
249 struct CURLMsg *msg;
250 time_t start;
251 struct timeval tv;
252 unsigned int pos = 0;
253 int done_flag = 0;
254
255 multi = NULL;
256 cbc.buf = buf;
257 cbc.size = 2048;
258 cbc.pos = 0;
259 d = MHD_start_daemon (MHD_USE_DEBUG,
260 11082,
261 NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
262 if (d == NULL)
263 return 256;
264 c = curl_easy_init ();
265 curl_easy_setopt (c, CURLOPT_URL, "http://localhost:11082/hello_world");
266 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
267 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
268 curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
269 curl_easy_setopt (c, CURLOPT_READDATA, &pos);
270 curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
271 /*
272 // by not giving the file size, we force chunking!
273 curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
274 */
275 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
276 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
277 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
278 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
279 // NOTE: use of CONNECTTIMEOUT without also
280 // setting NOSIGNAL results in really weird
281 // crashes on my system!
282 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
283
284
285 multi = curl_multi_init ();
286 if (multi == NULL)
287 {
288 curl_easy_cleanup (c);
289 MHD_stop_daemon (d);
290 return 512;
291 }
292 mret = curl_multi_add_handle (multi, c);
293 if (mret != CURLM_OK)
294 {
295 curl_multi_cleanup (multi);
296 curl_easy_cleanup (c);
297 MHD_stop_daemon (d);
298 return 1024;
299 }
300 start = time (NULL);
301 while ((time (NULL) - start < 5) && (multi != NULL))
302 {
303 max = 0;
304 FD_ZERO (&rs);
305 FD_ZERO (&ws);
306 FD_ZERO (&es);
307 curl_multi_perform (multi, &running);
308 mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
309 if (mret != CURLM_OK)
310 {
311 curl_multi_remove_handle (multi, c);
312 curl_multi_cleanup (multi);
313 curl_easy_cleanup (c);
314 MHD_stop_daemon (d);
315 return 2048;
316 }
317 if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
318 {
319 curl_multi_remove_handle (multi, c);
320 curl_multi_cleanup (multi);
321 curl_easy_cleanup (c);
322 MHD_stop_daemon (d);
323 return 4096;
324 }
325 tv.tv_sec = 0;
326 tv.tv_usec = 1000;
327 select (max + 1, &rs, &ws, &es, &tv);
328 curl_multi_perform (multi, &running);
329 if (running == 0)
330 {
331 msg = curl_multi_info_read (multi, &running);
332 if (msg == NULL)
333 break;
334 if (msg->msg == CURLMSG_DONE)
335 {
336 if (msg->data.result != CURLE_OK)
337 printf ("%s failed at %s:%d: `%s'\n",
338 "curl_multi_perform",
339 __FILE__,
340 __LINE__, curl_easy_strerror (msg->data.result));
341 curl_multi_remove_handle (multi, c);
342 curl_multi_cleanup (multi);
343 curl_easy_cleanup (c);
344 c = NULL;
345 multi = NULL;
346 }
347 }
348 MHD_run (d);
349 }
350 if (multi != NULL)
351 {
352 curl_multi_remove_handle (multi, c);
353 curl_easy_cleanup (c);
354 curl_multi_cleanup (multi);
355 }
356 MHD_stop_daemon (d);
357 if (cbc.pos != strlen ("/hello_world"))
358 return 8192;
359 if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
360 return 16384;
361 return 0;
362}
363
364
365
366int
367main (int argc, char *const *argv)
368{
369 unsigned int errorCount = 0;
370
371 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
372 return 2;
373 errorCount += testInternalPut ();
374 if (0)
375 {
376 errorCount += testMultithreadedPut ();
377 errorCount += testExternalPut ();
378 }
379 if (errorCount != 0)
380 fprintf (stderr, "Error (code: %u)\n", errorCount);
381 curl_global_cleanup ();
382 return errorCount != 0; /* 0 == pass */
383}