libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 5a046307a7475f15698afb6450d92ff4e6ffd0ad
parent ad74bf4b442d214e4c3e8ade23d460fcf35c11f1
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sat,  8 Sep 2012 19:15:04 +0000

applyin Karl Berry's suggestions for GNU libextractor also to MHD

Diffstat:
Mdoc/Makefile.am | 12++++++------
Adoc/libmicrohttpd-tutorial.texi | 178+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adoc/libmicrohttpd.texi | 2140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ddoc/microhttpd-tutorial.texi | 174-------------------------------------------------------------------------------
Ddoc/microhttpd.texi | 2189------------------------------------------------------------------------------
Mdoc/texinfo.tex | 2100++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
6 files changed, 3717 insertions(+), 3076 deletions(-)

diff --git a/doc/Makefile.am b/doc/Makefile.am @@ -2,13 +2,13 @@ man_MANS = libmicrohttpd.3 EXTRA_DIST = $(man_MANS) Doxyfile DISTCLEANFILES = \ - microhttpd.cps \ - microhttpd.dvi \ - microhttpd-tutorial.cps \ - microhttpd-tutorial.dvi + libmicrohttpd.cps \ + libmicrohttpd.dvi \ + libmicrohttpd-tutorial.cps \ + libmicrohttpd-tutorial.dvi info_TEXINFOS = \ - microhttpd.texi \ - microhttpd-tutorial.texi + libmicrohttpd.texi \ + libmicrohttpd-tutorial.texi microhttpd_TEXINFOS = \ chapters/basicauthentication.inc \ chapters/bibliography.inc \ diff --git a/doc/libmicrohttpd-tutorial.texi b/doc/libmicrohttpd-tutorial.texi @@ -0,0 +1,178 @@ +\input texinfo @c -*-texinfo-*- +@finalout +@setfilename libmicrohttpd-tutorial.info +@include version.texi +@settitle A tutorial for GNU libmicrohttpd +@c Unify all the indices into concept index. +@syncodeindex fn cp +@syncodeindex vr cp +@syncodeindex ky cp +@syncodeindex pg cp +@syncodeindex tp cp + +@dircategory Software libraries +@direntry +* libmicrohttpdtutorial: (libmicrohttpd). A tutorial for GNU libmicrohttpd. +@end direntry + +@copying +This tutorial documents GNU libmicrohttpd version @value{VERSION}, last +updated @value{UPDATED}. + +Copyright (c) 2008 Sebastian Gerhardt. + +Copyright (c) 2010, 2011, 2012 Christian Grothoff. +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 +or any later version published by the Free Software Foundation; +with no Invariant Sections, no Front-Cover Texts, and no Back-Cover +Texts. A copy of the license is included in the section entitled "GNU +Free Documentation License". +@end quotation +@end copying + +@titlepage +@title A Tutorial for GNU libmicrohttpd +@subtitle Version @value{VERSION} +@subtitle @value{UPDATED} +@author Sebastian Gerhardt (@email{sebgerhardt@@gmx.net}) +@author Christian Grothoff (@email{christian@@grothoff.org}) +@author Matthieu Speder (@email{mspeder@@users.sourceforge.net}) + +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + + + +@contents + +@ifnottex +@node Top +@top A Tutorial for GNU libmicrohttpd +@insertcopying +@end ifnottex + +@menu +* Introduction:: +* Hello browser example:: +* Exploring requests:: +* Response headers:: +* Supporting basic authentication:: +* Processing POST data:: +* Improved processing of POST data:: +* Session management:: +* Adding a layer of security:: +* Bibliography:: +* License text:: +* Example programs:: +@end menu + +@node Introduction +@chapter Introduction +@include chapters/introduction.inc + +@node Hello browser example +@chapter Hello browser example +@include chapters/hellobrowser.inc + +@node Exploring requests +@chapter Exploring requests +@include chapters/exploringrequests.inc + +@node Response headers +@chapter Response headers +@include chapters/responseheaders.inc + +@node Supporting basic authentication +@chapter Supporting basic authentication +@include chapters/basicauthentication.inc + +@node Processing POST data +@chapter Processing POST data +@include chapters/processingpost.inc + +@node Improved processing of POST data +@chapter Improved processing of POST data +@include chapters/largerpost.inc + +@node Session management +@chapter Session management +@include chapters/sessions.inc + +@node Adding a layer of security +@chapter Adding a layer of security +@include chapters/tlsauthentication.inc + +@node Bibliography +@appendix Bibliography +@include chapters/bibliography.inc + +@node License text +@appendix GNU Free Documentation License +@include fdl-1.3.texi + +@node Example programs +@appendix Example programs +@menu +* hellobrowser.c:: +* logging.c:: +* responseheaders.c:: +* basicauthentication.c:: +* simplepost.c:: +* largepost.c:: +* sessions.c:: +* tlsauthentication.c:: +@end menu + +@node hellobrowser.c +@section hellobrowser.c +@smalldisplay +@verbatiminclude examples/hellobrowser.c +@end smalldisplay + +@node logging.c +@section logging.c +@smalldisplay +@verbatiminclude examples/logging.c +@end smalldisplay + +@node responseheaders.c +@section responseheaders.c +@smalldisplay +@verbatiminclude examples/responseheaders.c +@end smalldisplay + +@node basicauthentication.c +@section basicauthentication.c +@smalldisplay +@verbatiminclude examples/basicauthentication.c +@end smalldisplay + +@node simplepost.c +@section simplepost.c +@smalldisplay +@verbatiminclude examples/simplepost.c +@end smalldisplay + +@node largepost.c +@section largepost.c +@smalldisplay +@verbatiminclude examples/largepost.c +@end smalldisplay + +@node sessions.c +@section sessions.c +@smalldisplay +@verbatiminclude examples/sessions.c +@end smalldisplay + +@node tlsauthentication.c +@section tlsauthentication.c +@smalldisplay +@verbatiminclude examples/tlsauthentication.c +@end smalldisplay + +@bye diff --git a/doc/libmicrohttpd.texi b/doc/libmicrohttpd.texi @@ -0,0 +1,2140 @@ +\input texinfo +@setfilename libmicrohttpd.info +@include version.texi +@settitle The GNU libmicrohttpd Reference Manual +@c Unify all the indices into concept index. +@syncodeindex fn cp +@syncodeindex vr cp +@syncodeindex ky cp +@syncodeindex pg cp +@syncodeindex tp cp +@copying +This manual is for GNU libmicrohttpd +(version @value{VERSION}, @value{UPDATED}), a library for embedding +an HTTP(S) server into C applications. + +Copyright @copyright{} 2007--2012 Christian Grothoff + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 +or any later version published by the Free Software Foundation; +with no Invariant Sections, no Front-Cover Texts, and no Back-Cover +Texts. A copy of the license is included in the section entitled "GNU +Free Documentation License". +@end quotation +@end copying + +@dircategory Software libraries +@direntry +* libmicrohttpd: (libmicrohttpd). Embedded HTTP server library. +@end direntry + +@c +@c Titlepage +@c +@titlepage +@title The GNU libmicrohttpd Reference Manual +@subtitle Version @value{VERSION} +@subtitle @value{UPDATED} +@author Marco Maggi (@email{marco.maggi-ipsu@@poste.it}) +@author Christian Grothoff (@email{christian@@grothoff.org}) +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@summarycontents +@contents + +@c ------------------------------------------------------------ +@ifnottex +@node Top +@top The GNU libmicrohttpd Library +@insertcopying +@end ifnottex + +@menu +* microhttpd-intro:: Introduction. +* microhttpd-const:: Constants. +* microhttpd-struct:: Structures type definition. +* microhttpd-cb:: Callback functions definition. +* microhttpd-init:: Starting and stopping the server. +* microhttpd-inspect:: Implementing external @code{select}. +* microhttpd-requests:: Handling requests. +* microhttpd-responses:: Building responses to requests. +* microhttpd-dauth:: Utilizing Authentication. +* microhttpd-post:: Adding a @code{POST} processor. +* microhttpd-info:: Obtaining and modifying status information. + +Appendices + +* GNU-LGPL:: The GNU Lesser General Public License says how you + can copy and share almost all of `libmicrohttpd'. +* GNU GPL with eCos Extension:: The GNU General Public License with eCos extension says how you + can copy and share some parts of `libmicrohttpd'. +* GNU-FDL:: The GNU Free Documentation License says how you + can copy and share the documentation of `libmicrohttpd'. + +Indices + +* Concept Index:: Index of concepts and programs. +* Function and Data Index:: Index of functions, variables and data types. +* Type Index:: Index of data types. +@end menu + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-intro +@chapter Introduction + + +@noindent +All symbols defined in the public API start with @code{MHD_}. MHD +is a small HTTP daemon library. As such, it does not have any API +for logging errors (you can only enable or disable logging to stderr). +Also, it may not support all of the HTTP features directly, where +applicable, portions of HTTP may have to be handled by clients of the +library. + +The library is supposed to handle everything that it must handle +(because the API would not allow clients to do this), such as basic +connection management; however, detailed interpretations of headers --- +such as range requests --- and HTTP methods are left to clients. The +library does understand @code{HEAD} and will only send the headers of +the response and not the body, even if the client supplied a body. The +library also understands headers that control connection management +(specifically, @code{Connection: close} and @code{Expect: 100 continue} +are understood and handled automatically). + +MHD understands @code{POST} data and is able to decode certain +formats (at the moment only @code{application/x-www-form-urlencoded} +and @code{multipart/form-data}) using the post processor API. The +data stream of a POST is also provided directly to the main +application, so unsupported encodings could still be processed, just +not conveniently by MHD. + +The header file defines various constants used by the HTTP protocol. +This does not mean that MHD actually interprets all of these values. +The provided constants are exported as a convenience for users of the +library. MHD does not verify that transmitted HTTP headers are +part of the standard specification; users of the library are free to +define their own extensions of the HTTP standard and use those with +MHD. + +All functions are guaranteed to be completely reentrant and +thread-safe. MHD checks for allocation failures and tries to +recover gracefully (for example, by closing the connection). +Additionally, clients can specify resource limits on the overall +number of connections, number of connections per IP address and memory +used per connection to avoid resource exhaustion. + +@section Scope + +MHD is currently used in a wide range of implementations. +Examples based on reports we've received from developers include: +@itemize +@item Embedded HTTP server on a cortex M3 (128 KB code space) +@item Large-scale multimedia server (reportedly serving at the + simulator limit of 7.5 GB/s) +@item Administrative console (via HTTP/HTTPS) for network appliances +@c If you have other interesting examples, please let us know +@end itemize + + +@section Compiling GNU libmicrohttpd +@cindex compilation +@cindex embedded systems +@cindex portability + +MHD uses the standard GNU system where the usual build process +involves running +@verbatim +$ ./configure +$ make +$ make install +@end verbatim + +MHD supports various options to be given to configure to tailor the +binary to a specific situation. Note that some of these options will +remove portions of the MHD code that are required for +binary-compatibility. They should only be used on embedded systems +with tight resource constraints and no concerns about library +versioning. Standard distributions including MHD are expected to +always ship with all features enabled, otherwise unexpected +incompatibilities can arise! + +Here is a list of MHD-specific options that can be given to configure +(canonical configure options such as ``--prefix'' are also supported, for a +full list of options run ``./configure --help''): + +@table @code +@item ``--disable-curl'' +disable running testcases using libcurl + +@item ``--disable-largefile'' +disable support for 64-bit files + +@item ``--disable-messages'' +disable logging of error messages (smaller binary size, not so much fun for debugging) + +@item ``--disable-https'' +disable HTTPS support, even if GNUtls is found; this option must be used if eCOS license is desired as an option (in all cases the resulting binary falls under a GNU LGPL-only license) + +@item ``--disable-postprocessor'' +do not include the post processor API (results in binary incompatibility) + +@item ``--disable-dauth'' +do not include the authentication APIs (results in binary incompatibility) + +@item ``--enable-coverage'' +set flags for analysis of code-coverage with gcc/gcov (results in slow, large binaries) + +@item ``--with-gcrypt=PATH'' +specifies path to libgcrypt installation + +@item ``--with-gnutls=PATH'' +specifies path to libgnutls installation + + + +@end table + +@section Including the microhttpd.h header +@cindex portability +@cindex microhttpd.h + +Ideally, before including "microhttpd.h" you should add the necessary +includes to define the @code{uint64_t}, @code{size_t}, @code{fd_set}, +@code{socklen_t} and @code{struct sockaddr} data types. Which +specific headers are needed may depend on your platform and your build +system might include some tests to provide you with the necessary +conditional operations. For possible suggestions consult +@code{platform.h} and @code{configure.ac} in the MHD distribution. + +Once you have ensured that you manually (!) included the right headers +for your platform before "microhttpd.h", you should also add a line +with @code{#define MHD_PLATFORM_H} which will prevent the +"microhttpd.h" header from trying (and, depending on your platform, +failing) to include the right headers. + +If you do not define MHD_PLATFORM_H, the "microhttpd.h" header will +automatically include headers needed on GNU/Linux systems (possibly +causing problems when porting to other platforms). + +@section SIGPIPE +@cindex signals +MHD does not install a signal handler for SIGPIPE. On platforms +where this is possible (such as GNU/Linux), it disables SIGPIPE for +its I/O operations (by passing MSG_NOSIGNAL). On other platforms, +SIGPIPE signals may be generated from network operations by +MHD and will cause the process to die unless the developer +explicitly installs a signal handler for SIGPIPE. + +Hence portable code using MHD must install a SIGPIPE handler or +explicitly block the SIGPIPE signal. MHD does not do so in order +to avoid messing with other parts of the application that may +need to handle SIGPIPE in a particular way. You can make your application handle SIGPIPE by calling the following function in @code{main}: + +@verbatim +static void +catcher (int sig) +{ +} + +static void +ignore_sigpipe () +{ + struct sigaction oldsig; + struct sigaction sig; + + sig.sa_handler = &catcher; + sigemptyset (&sig.sa_mask); +#ifdef SA_INTERRUPT + sig.sa_flags = SA_INTERRUPT; /* SunOS */ +#else + sig.sa_flags = SA_RESTART; +#endif + if (0 != sigaction (SIGPIPE, &sig, &oldsig)) + fprintf (stderr, + "Failed to install SIGPIPE handler: %s\n", strerror (errno)); +} +@end verbatim + +@section MHD_LONG_LONG +@cindex long long +@cindex IAR +@cindex ARM +@cindex cortex m3 +@cindex embedded systems + +Some platforms do not support @code{long long}. Hence MHD defines +a macro @code{MHD_LONG_LONG} which will default to @code{long long}. +If your platform does not support @code{long long}, you should +change "platform.h" to define @code{MHD_LONG_LONG} to an appropriate +alternative type and also define @code{MHD_LONG_LONG_PRINTF} to the +corresponding format string for printing such a data type (without +the percent sign). + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-const +@chapter Constants + + +@deftp {Enumeration} MHD_FLAG +Options for the MHD daemon. + +Note that if neither @code{MHD_USE_THREAD_PER_CONNECTION} nor +@code{MHD_USE_SELECT_INTERNALLY} is used, the client wants control over +the process and will call the appropriate microhttpd callbacks. + +Starting the daemon may also fail if a particular option is not +implemented or not supported on the target platform (i.e. no support for +@acronym{SSL}, threads or IPv6). SSL support generally depends on +options given during MHD compilation. Threaded operations +(including @code{MHD_USE_SELECT_INTERNALLY}) are not supported on +Symbian. + +@table @code +@item MHD_NO_FLAG +No options selected. + +@item MHD_USE_DEBUG +@cindex debugging +Run in debug mode. If this flag is used, the library should print error +messages and warnings to stderr. Note that for this +run-time option to have any effect, MHD needs to be +compiled with messages enabled. This is done by default except you ran +configure with the @code{--disable-messages} flag set. + +@item MHD_USE_SSL +Run in https mode (this option may not work with all threading modes yet). + +@item MHD_USE_THREAD_PER_CONNECTION +Run using one thread per connection. + +@item MHD_USE_SELECT_INTERNALLY +Run using an internal thread doing @code{SELECT}. + +@item MHD_USE_IPv6 +@cindex IPv6 +Run using the IPv6 protocol (otherwise, MHD will just support IPv4). + + +@item MHD_USE_PEDANTIC_CHECKS +Be pedantic about the protocol (as opposed to as tolerant as possible). +Specifically, at the moment, this flag causes MHD to reject HTTP +1.1 connections without a @code{Host} header. This is required by the +standard, but of course in violation of the ``be as liberal as possible +in what you accept'' norm. It is recommended to turn this @strong{ON} +if you are testing clients against MHD, and @strong{OFF} in +production. + +@item MHD_USE_POLL +@cindex FD_SETSIZE +@cindex poll +@cindex select +Use poll instead of select. This allows sockets with descriptors +@code{>= FD_SETSIZE}. This option only works in conjunction with +@code{MHD_USE_THREAD_PER_CONNECTION} (at this point). + +@item MHD_SUPPRESS_DATE_NO_CLOCK +@cindex date +@cindex clock +@cindex embedded systems +Suppress (automatically) adding the 'Date:' header to HTTP responses. +This option should ONLY be used on systems that do not have a clock +and that DO provide other mechanisms for cache control. See also +RFC 2616, section 14.18 (exception 3). + + +@item MHD_USE_NO_LISTEN_SOCKET +@cindex listen +@cindex proxy +@cindex embedded systems +Run the HTTP server without any listen socket. This option only makes +sense if @code{MHD_add_connection} is going to be used exclusively to +connect HTTP clients to the HTTP server. This option is incompatible +with using a thread pool; if it is used, +@code{MHD_OPTION_THREAD_POOL_SIZE} is ignored. + +@end table +@end deftp + + +@deftp {Enumeration} MHD_OPTION +MHD options. Passed in the varargs portion of +@code{MHD_start_daemon()}. + +@table @code +@item MHD_OPTION_END +No more options / last option. This is used to terminate the VARARGs +list. + +@item MHD_OPTION_CONNECTION_MEMORY_LIMIT +@cindex memory, limiting memory utilization +Maximum memory size per connection (followed by a @code{size_t}). The +default is 32 kB (32*1024 bytes) as defined by the internal constant +@code{MHD_POOL_SIZE_DEFAULT}. + +@item MHD_OPTION_CONNECTION_LIMIT +@cindex connection, limiting number of connections +Maximum number of concurrent connections to accept (followed by an +@code{unsigned int}). The default is @code{FD_SETSIZE - 4} (the +maximum number of file descriptors supported by @code{select} minus +four for @code{stdin}, @code{stdout}, @code{stderr} and the server +socket). In other words, the default is as large as possible. + +Note that if you set a low connection limit, you can easily get into +trouble with browsers doing request pipelining. For example, if your +connection limit is ``1'', a browser may open a first connection to +access your ``index.html'' file, keep it open but use a second +connection to retrieve CSS files, images and the like. In fact, modern +browsers are typically by default configured for up to 15 parallel +connections to a single server. If this happens, MHD will refuse to +even accept the second connection until the first connection is +closed --- which does not happen until timeout. As a result, the +browser will fail to render the page and seem to hang. If you expect +your server to operate close to the connection limit, you should +first consider using a lower timeout value and also possibly add +a ``Connection: close'' header to your response to ensure that +request pipelining is not used and connections are closed immediately +after the request has completed: +@example +MHD_add_response_header (response, + MHD_HTTP_HEADER_CONNECTION, + "close"); +@end example + +@item MHD_OPTION_CONNECTION_TIMEOUT +@cindex timeout +After how many seconds of inactivity should a connection automatically +be timed out? (followed by an @code{unsigned int}; use zero for no +timeout). The default is zero (no timeout). + +@item MHD_OPTION_NOTIFY_COMPLETED +Register a function that should be called whenever a request has been +completed (this can be used for application-specific clean up). +Requests that have never been presented to the application (via +@code{MHD_AccessHandlerCallback()}) will not result in +notifications. + +This option should be followed by @strong{TWO} pointers. First a +pointer to a function of type @code{MHD_RequestCompletedCallback()} +and second a pointer to a closure to pass to the request completed +callback. The second pointer maybe @code{NULL}. + + +@item MHD_OPTION_PER_IP_CONNECTION_LIMIT +Limit on the number of (concurrent) connections made to the +server from the same IP address. Can be used to prevent one +IP from taking over all of the allowed connections. If the +same IP tries to establish more than the specified number of +connections, they will be immediately rejected. The option +should be followed by an @code{unsigned int}. The default is +zero, which means no limit on the number of connections +from the same IP address. + +@item MHD_OPTION_SOCK_ADDR +@cindex bind, restricting bind +Bind daemon to the supplied socket address. This option should be followed by a +@code{struct sockaddr *}. If @code{MHD_USE_IPv6} is specified, +the @code{struct sockaddr*} should point to a @code{struct sockaddr_in6}, +otherwise to a @code{struct sockaddr_in}. If this option is not specified, +the daemon will listen to incoming connections from anywhere. If you use this +option, the 'port' argument from @code{MHD_start_daemon} is ignored and the port +from the given @code{struct sockaddr *} will be used instead. + +@item MHD_OPTION_URI_LOG_CALLBACK +@cindex debugging +@cindex logging +@cindex query string +Specify a function that should be called before parsing the URI from +the client. The specified callback function can be used for processing +the URI (including the options) before it is parsed. The URI after +parsing will no longer contain the options, which maybe inconvenient for +logging. This option should be followed by two arguments, the first +one must be of the form +@example + void * my_logger(void * cls, const char * uri) +@end example +where the return value will be passed as +@code{*con_cls} in calls to the @code{MHD_AccessHandlerCallback} +when this request is processed later; returning a +value of @code{NULL} has no special significance; (however, +note that if you return non-@code{NULL}, you can no longer +rely on the first call to the access handler having +@code{NULL == *con_cls} on entry) +@code{cls} will be set to the second argument following +MHD_OPTION_URI_LOG_CALLBACK. Finally, @code{uri} will +be the 0-terminated URI of the request. + +@item MHD_OPTION_HTTPS_MEM_KEY +@cindex SSL +@cindex TLS +Memory pointer to the private key to be used by the +HTTPS daemon. This option should be followed by an +"const char*" argument. +This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_CERT'. + +@item MHD_OPTION_HTTPS_MEM_CERT +@cindex SSL +@cindex TLS +Memory pointer to the certificate to be used by the +HTTPS daemon. This option should be followed by an +"const char*" argument. +This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_KEY'. + +@item MHD_OPTION_HTTPS_MEM_TRUST +@cindex SSL +@cindex TLS +Memory pointer to the CA certificate to be used by the +HTTPS daemon to authenticate and trust clients certificates. +This option should be followed by an "const char*" argument. +The presence of this option activates the request of certificate +to the client. The request to the client is marked optional, and +it is the responsibility of the server to check the presence +of the certificate if needed. +Note that most browsers will only present a client certificate +only if they have one matching the specified CA, not sending +any certificate otherwise. + +@item MHD_OPTION_HTTPS_CRED_TYPE +@cindex SSL +@cindex TLS +Daemon credentials type. Either certificate or anonymous, +this option should be followed by one of the values listed in +"enum gnutls_credentials_type_t". + +@item MHD_OPTION_HTTPS_PRIORITIES +@cindex SSL +@cindex TLS +@cindex cipher +SSL/TLS protocol version and ciphers. +This option must be followed by an "const char *" argument +specifying the SSL/TLS protocol versions and ciphers that +are acceptable for the application. The string is passed +unchanged to gnutls_priority_init. If this option is not +specified, ``NORMAL'' is used. + +@item MHD_OPTION_DIGEST_AUTH_RANDOM +@cindex digest auth +@cindex random +Digest Authentication nonce's seed. + +This option should be followed by two arguments. First an integer of +type "size_t" which specifies the size of the buffer pointed to by the +second argument in bytes. Note that the application must ensure that +the buffer of the second argument remains allocated and unmodified +while the daemon is running. For security, you SHOULD provide a fresh +random nonce when using MHD with Digest Authentication. + +@item MHD_OPTION_NONCE_NC_SIZE +@cindex digest auth +@cindex replay attack + +Size of an array of nonce and nonce counter map. This option must be +followed by an "unsigned int" argument that have the size (number of +elements) of a map of a nonce and a nonce-counter. If this option +is not specified, a default value of 4 will be used (which might be +too small for servers handling many requests). If you do not use +digest authentication at all, you can specify a value of zero to +save some memory. + +You should calculate the value of NC_SIZE based on the number of +connections per second multiplied by your expected session duration +plus a factor of about two for hash table collisions. For example, if +you expect 100 digest-authenticated connections per second and the +average user to stay on your site for 5 minutes, then you likely need +a value of about 60000. On the other hand, if you can only expect +only 10 digest-authenticated connections per second, tolerate browsers +getting a fresh nonce for each request and expect a HTTP request +latency of 250 ms, then a value of about 5 should be fine. + + +@item MHD_OPTION_LISTEN_SOCKET +@cindex systemd +Listen socket to use. Pass a listen socket for MHD to use +(systemd-style). If this option is used, MHD will not open its own +listen socket(s). The argument passed must be of type "int" and refer +to an existing socket that has been bound to a port and is listening. + +@item MHD_OPTION_EXTERNAL_LOGGER +@cindex logging +Use the given function for logging error messages. +This option must be followed by two arguments; the +first must be a pointer to a function +of type 'void fun(void * arg, const char * fmt, va_list ap)' +and the second a pointer of type 'void*' which will +be passed as the "arg" argument to "fun". + +Note that MHD will not generate any log messages without +the MHD_USE_DEBUG flag set and if MHD was compiled +with the "--disable-messages" flag. + +@item MHD_OPTION_THREAD_POOL_SIZE +@cindex performance +Number (unsigned int) of threads in thread pool. Enable +thread pooling by setting this value to to something +greater than 1. Currently, thread model must be +MHD_USE_SELECT_INTERNALLY if thread pooling is enabled +(MHD_start_daemon returns @code{NULL} for an unsupported thread +model). + +@item MHD_OPTION_ARRAY +@cindex options +@cindex foreign-function interface +This option can be used for initializing MHD using options from an +array. A common use for this is writing an FFI for MHD. The actual +options given are in an array of 'struct MHD_OptionItem', so this +option requires a single argument of type 'struct MHD_OptionItem'. +The array must be terminated with an entry @code{MHD_OPTION_END}. + +An example for code using MHD_OPTION_ARRAY is: +@example +struct MHD_OptionItem ops[] = @{ + @{ MHD_OPTION_CONNECTION_LIMIT, 100, NULL @}, + @{ MHD_OPTION_CONNECTION_TIMEOUT, 10, NULL @}, + @{ MHD_OPTION_END, 0, NULL @} +@}; +d = MHD_start_daemon(0, 8080, NULL, NULL, dh, NULL, + MHD_OPTION_ARRAY, ops, + MHD_OPTION_END); +@end example +For options that expect a single pointer argument, the +second member of the @code{struct MHD_OptionItem} is ignored. +For options that expect two pointer arguments, the first +argument must be cast to @code{intptr_t}. + +@item MHD_OPTION_UNESCAPE_CALLBACK +@cindex internationalization +@cindex escaping + +Specify a function that should be called for unescaping escape +sequences in URIs and URI arguments. Note that this function will NOT +be used by the MHD_PostProcessor. If this option is not specified, +the default method will be used which decodes escape sequences of the +form "%HH". This option should be followed by two arguments, the +first one must be of the form + +@example + size_t my_unescaper(void * cls, struct MHD_Connection *c, char *s) +@end example + +where the return value must be @code{strlen(s)} and @code{s} should be +updated. Note that the unescape function must not lengthen @code{s} +(the result must be shorter than the input and still be 0-terminated). +@code{cls} will be set to the second argument following +MHD_OPTION_UNESCAPE_CALLBACK. + + +@item MHD_OPTION_THREAD_STACK_SIZE +@cindex stack +@cindex thread +@cindex pthread +@cindex embedded systems +Maximum stack size for threads created by MHD. This option must be +followed by a @code{size_t}). Not specifying this option or using +a value of zero means using the system default (which is likely to +differ based on your platform). + +@end table +@end deftp + + +@deftp {C Struct} MHD_OptionItem +Entry in an MHD_OPTION_ARRAY. See the @code{MHD_OPTION_ARRAY} option +argument for its use. + +The @code{option} member is used to specify which option is specified +in the array. The other members specify the respective argument. + +Note that for options taking only a single pointer, the +@code{ptr_value} member should be set. For options taking two pointer +arguments, the first pointer must be cast to @code{intptr_t} and both +the @code{value} and the @code{ptr_value} members should be used to +pass the two pointers. +@end deftp + + +@deftp {Enumeration} MHD_ValueKind +The @code{MHD_ValueKind} specifies the source of the key-value pairs in +the HTTP protocol. + +@table @code +@item MHD_RESPONSE_HEADER_KIND +Response header. + +@item MHD_HEADER_KIND +HTTP header. + +@item MHD_COOKIE_KIND +@cindex cookie +Cookies. Note that the original HTTP header containing the cookie(s) +will still be available and intact. + +@item MHD_POSTDATA_KIND +@cindex POST method +@code{POST} data. This is available only if a content encoding +supported by MHD is used (currently only @acronym{URL} encoding), and +only if the posted content fits within the available memory pool. Note +that in that case, the upload data given to the +@code{MHD_AccessHandlerCallback()} will be empty (since it has +already been processed). + +@item MHD_GET_ARGUMENT_KIND +@code{GET} (URI) arguments. + +@item MHD_FOOTER_KIND +HTTP footer (only for http 1.1 chunked encodings). + +@end table +@end deftp + + +@deftp {Enumeration} MHD_RequestTerminationCode +The @code{MHD_RequestTerminationCode} specifies reasons why a request +has been terminated (or completed). + +@table @code +@item MHD_REQUEST_TERMINATED_COMPLETED_OK +We finished sending the response. + +@item MHD_REQUEST_TERMINATED_WITH_ERROR +Error handling the connection (resources exhausted, other side closed +connection, application error accepting request, etc.) + +@item MHD_REQUEST_TERMINATED_TIMEOUT_REACHED +No activity on the connection for the number of seconds specified using +@code{MHD_OPTION_CONNECTION_TIMEOUT}. + +@item MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN +We had to close the session since MHD was being shut down. +@end table +@end deftp + + +@deftp {Enumeration} MHD_ResponseMemoryMode +The @code{MHD_ResponeMemoryMode} specifies how MHD should treat +the memory buffer given for the response in +@code{MHD_create_response_from_buffer}. + +@table @code +@item MHD_RESPMEM_PERSISTENT +Buffer is a persistent (static/global) buffer that won't change +for at least the lifetime of the response, MHD should just use +it, not free it, not copy it, just keep an alias to it. + +@item MHD_RESPMEM_MUST_FREE +Buffer is heap-allocated with @code{malloc} (or equivalent) and +should be freed by MHD after processing the response has +concluded (response reference counter reaches zero). + +@item MHD_RESPMEM_MUST_COPY +Buffer is in transient memory, but not on the heap (for example, +on the stack or non-malloc allocated) and only valid during the +call to @code{MHD_create_response_from_buffer}. MHD must make its +own private copy of the data for processing. + +@end table +@end deftp + + + + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-struct +@chapter Structures type definition + + +@deftp {C Struct} MHD_Daemon +Handle for the daemon (listening on a socket for HTTP traffic). +@end deftp + + +@deftp {C Struct} MHD_Connection +Handle for a connection / HTTP request. With HTTP/1.1, multiple +requests can be run over the same connection. However, MHD will only +show one request per TCP connection to the client at any given time. +@end deftp + + +@deftp {C Struct} MHD_Response +Handle for a response. +@end deftp + + +@deftp {C Struct} MHD_PostProcessor +@cindex POST method +Handle for @code{POST} processing. +@end deftp + + +@deftp {C Union} MHD_ConnectionInfo +Information about a connection. +@end deftp + + +@deftp {C Union} MHD_DaemonInfo +Information about an MHD daemon. +@end deftp + + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-cb +@chapter Callback functions definition + + +@deftypefn {Function Pointer} int {*MHD_AcceptPolicyCallback} (void *cls, const struct sockaddr * addr, socklen_t addrlen) +Invoked in the context of a connection to allow or deny a client to +connect. This callback return @code{MHD_YES} if connection is allowed, +@code{MHD_NO} if not. + +@table @var +@item cls +custom value selected at callback registration time; +@item addr +address information from the client; +@item addrlen +length of the address information. +@end table +@end deftypefn + + +@deftypefn {Function Pointer} int {*MHD_AccessHandlerCallback} (void *cls, struct MHD_Connection * connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) +Invoked in the context of a connection to answer a request from the +client. This callback must call MHD functions (example: the +@code{MHD_Response} ones) to provide content to give back to the client +and return an HTTP status code (i.e. @code{200} for OK, @code{404}, +etc.). + +@ref{microhttpd-post}, for details on how to code this callback. + +Must return @code{MHD_YES} if the connection was handled successfully, +@code{MHD_NO} if the socket must be closed due to a serious error while +handling the request + +@table @var +@item cls +custom value selected at callback registration time; + +@item url +the URL requested by the client; + +@item method +the HTTP method used by the client (@code{GET}, @code{PUT}, +@code{DELETE}, @code{POST}, etc.); + +@item version +the HTTP version string (i.e. @code{HTTP/1.1}); + +@item upload_data +the data being uploaded (excluding headers): +@cindex POST method +@cindex PUT method + +@itemize +@item +for a @code{POST} that fits into memory and that is encoded with a +supported encoding, the @code{POST} data will @strong{NOT} be given in +@var{upload_data} and is instead available as part of +@code{MHD_get_connection_values()}; + +@item +very large @code{POST} data @strong{will} be made available +incrementally in @var{upload_data}; +@end itemize + +@item upload_data_size +set initially to the size of the @var{upload_data} provided; this +callback must update this value to the number of bytes @strong{NOT} +processed; unless external select is used, the callback maybe +required to process at least some data. If the callback fails to +process data in multi-threaded or internal-select mode and if the +read-buffer is already at the maximum size that MHD is willing to +use for reading (about half of the maximum amount of memory allowed +for the connection), then MHD will abort handling the connection +and return an internal server error to the client. In order to +avoid this, clients must be able to process upload data incrementally +and reduce the value of @code{upload_data_size}. + +@item con_cls +reference to a pointer, initially set to @code{NULL}, that this callback can +set to some address and that will be preserved by MHD for future +calls for this request; + +since the access handler may be called many times (i.e., for a +@code{PUT}/@code{POST} operation with plenty of upload data) this allows +the application to easily associate some request-specific state; + +if necessary, this state can be cleaned up in the global +@code{MHD_RequestCompletedCallback} (which can be set with the +@code{MHD_OPTION_NOTIFY_COMPLETED}). +@end table +@end deftypefn + + +@deftypefn {Function Pointer} void {*MHD_RequestCompletedCallback} (void *cls, struct MHD_Connectionconnection, void **con_cls, enum MHD_RequestTerminationCode toe) +Signature of the callback used by MHD to notify the application about +completed requests. + +@table @var +@item cls +custom value selected at callback registration time; + +@item connection +connection handle; + +@item con_cls +value as set by the last call to the +@code{MHD_AccessHandlerCallback}; + +@item toe +reason for request termination see @code{MHD_OPTION_NOTIFY_COMPLETED}. +@end table +@end deftypefn + + +@deftypefn {Function Pointer} int {*MHD_KeyValueIterator} (void *cls, enum MHD_ValueKind kind, const char *key, const char *value) +Iterator over key-value pairs. This iterator can be used to iterate +over all of the cookies, headers, or @code{POST}-data fields of a +request, and also to iterate over the headers that have been added to a +response. + +Return @code{MHD_YES} to continue iterating, @code{MHD_NO} to abort the +iteration. +@end deftypefn + + +@deftypefn {Function Pointer} int {*MHD_ContentReaderCallback} (void *cls, uint64_t pos, char *buf, size_t max) +Callback used by MHD in order to obtain content. The callback has to +copy at most @var{max} bytes of content into @var{buf}. The total +number of bytes that has been placed into @var{buf} should be returned. + +Note that returning zero will cause MHD to try again, either +``immediately'' if in multi-threaded mode (in which case the callback +may want to do blocking operations to avoid busy waiting) or in the +next round if @code{MHD_run} is used. Returning zero for a daemon +that runs in internal @code{select}-mode is an error (since it +would result in busy waiting) and cause the program to be aborted +(@code{abort()}). + +While usually the callback simply returns the number of bytes written +into @var{buf}, there are two special return value: + +@code{MHD_CONTENT_READER_END_OF_STREAM} (-1) should be returned +for the regular end of transmission (with chunked encoding, MHD will then +terminate the chunk and send any HTTP footers that might be +present; without chunked encoding and given an unknown +response size, MHD will simply close the connection; note +that while returning @code{MHD_CONTENT_READER_END_OF_STREAM} is not technically +legal if a response size was specified, MHD accepts this +and treats it just as @code{MHD_CONTENT_READER_END_WITH_ERROR}. + +@code{MHD_CONTENT_READER_END_WITH_ERROR} (-2) is used to indicate a server +error generating the response; this will cause MHD to simply +close the connection immediately. If a response size was +given or if chunked encoding is in use, this will indicate +an error to the client. Note, however, that if the client +does not know a response size and chunked encoding is not in +use, then clients will not be able to tell the difference between +@code{MHD_CONTENT_READER_END_WITH_ERROR} and +@code{MHD_CONTENT_READER_END_OF_STREAM}. +This is not a limitation of MHD but rather of the HTTP protocol. + +@table @var +@item cls +custom value selected at callback registration time; + +@item pos +position in the datastream to access; note that if an +@code{MHD_Response} object is re-used, it is possible for the same +content reader to be queried multiple times for the same data; however, +if an @code{MHD_Response} is not re-used, MHD guarantees that +@var{pos} will be the sum of all non-negative return values obtained +from the content reader so far. +@end table + +Return @code{-1} on error (MHD will no longer try to read content and +instead close the connection with the client). +@end deftypefn + + +@deftypefn {Function Pointer} void {*MHD_ContentReaderFreeCallback} (void *cls) +This method is called by MHD if we are done with a content reader. +It should be used to free resources associated with the content reader. +@end deftypefn + + +@deftypefn {Function Pointer} int {*MHD_PostDataIterator} (void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) +Iterator over key-value pairs where the value maybe made available in +increments and/or may not be zero-terminated. Used for processing +@code{POST} data. + +@table @var +@item cls +custom value selected at callback registration time; + +@item kind +type of the value; + +@item key +zero-terminated key for the value; + +@item filename +name of the uploaded file, @code{NULL} if not known; + +@item content_type +mime-type of the data, @code{NULL} if not known; + +@item transfer_encoding +encoding of the data, @code{NULL} if not known; + +@item data +pointer to size bytes of data at the specified offset; + +@item off +offset of data in the overall value; + +@item size +number of bytes in data available. +@end table + +Return @code{MHD_YES} to continue iterating, @code{MHD_NO} to abort the +iteration. +@end deftypefn + + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-init +@chapter Starting and stopping the server + +@deftypefun {void} MHD_set_panic_func (MHD_PanicCallback cb, void *cls) +Set a handler for fatal errors. + +@table @var +@item cb +function to call if MHD encounters a fatal internal error. If no handler was set explicitly, MHD will call @code{abort}. + +@item cls +closure argument for cb; the other arguments are the name of the source file, line number and a string describing the nature of the fatal error (which can be @code{NULL}) +@end table +@end deftypefun + +@deftypefun {struct MHD_Daemon *} MHD_start_daemon (unsigned int flags, unsigned short port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls, ...) +Start a webserver on the given port. + +@table @var +@item flags +OR-ed combination of @code{MHD_FLAG} values; + +@item port +port to bind to; + +@item apc +callback to call to check which clients will be allowed to connect; you +can pass @code{NULL} in which case connections from any @acronym{IP} will be +accepted; + +@item apc_cls +extra argument to @var{apc}; + +@item dh +default handler for all URIs; + +@item dh_cls +extra argument to @var{dh}. +@end table + +Additional arguments are a list of options (type-value pairs, +terminated with @code{MHD_OPTION_END}). It is mandatory to use +@code{MHD_OPTION_END} as last argument, even when there are no +additional arguments. + +Return @code{NULL} on error, handle to daemon on success. +@end deftypefun + + +@deftypefun void MHD_stop_daemon (struct MHD_Daemon *daemon) +Shutdown an HTTP daemon. +@end deftypefun + + +@deftypefun int MHD_run (struct MHD_Daemon *daemon) +Run webserver operations (without blocking unless in client callbacks). +This method should be called by clients in combination with +@code{MHD_get_fdset()} if the client-controlled @code{select}-method is used. + +Return @code{MHD_YES} on success, @code{MHD_NO} if this daemon was not +started with the right options for this call. +@end deftypefun + + +@deftypefun void MHD_add_connection (struct MHD_Daemon *daemon, int client_socket, const struct sockaddr *addr, socklen_t addrlen) +Add another client connection to the set of connections +managed by MHD. This API is usually not needed (since +MHD will accept inbound connections on the server socket). +Use this API in special cases, for example if your HTTP +server is behind NAT and needs to connect out to the +HTTP client. + +The given client socket will be managed (and closed!) by MHD after +this call and must no longer be used directly by the application +afterwards. + +@table @var +@item daemon +daemon that manages the connection +@item client_socket +socket to manage (MHD will expect to receive an HTTP request from this socket next). +@item addr +IP address of the client +@item addrlen +number of bytes in addr +@end table + +This function will return @code{MHD_YES} on success, +@code{MHD_NO} if this daemon could +not handle the connection (i.e. malloc failed, etc). +The socket will be closed in any case. +@end deftypefun + + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ----------------------------------------------------------- +@node microhttpd-inspect +@chapter Implementing external @code{select} + + +@deftypefun int MHD_get_fdset (struct MHD_Daemon *daemon, fd_set * read_fd_set, fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd) +Obtain the @code{select()} sets for this daemon. The daemon's socket +is added to @var{read_fd_set}. The list of currently existent +connections is scanned and their file descriptors added to the correct +set. + +After the call completed successfully: the variable referenced by +@var{max_fd} references the file descriptor with highest integer +identifier. The variable must be set to zero before invoking this +function. + +Return @code{MHD_YES} on success, @code{MHD_NO} if: the arguments are +invalid (example: @code{NULL} pointers); this daemon was not started with +the right options for this call. +@end deftypefun + + +@deftypefun int MHD_get_timeout (struct MHD_Daemon *daemon, unsigned long long *timeout) +@cindex timeout +Obtain timeout value for select for this daemon (only needed if +connection timeout is used). The returned value is how long +@code{select} should at most block, not the timeout value set for +connections. This function must not be called if the +@code{MHD_USE_THREAD_PER_CONNECTION} mode is in use (since then it +is not meaningful to ask for a timeout, after all, there is +concurrenct activity). The function must also not be called by +user-code if @code{MHD_USE_INTERNAL_SELECT} is in use. In the latter +case, the behavior is undefined. + +@table @var +@cindex timeout +set to the timeout (in milliseconds). +@end table + +Return @code{MHD_YES} on success, @code{MHD_NO} if timeouts are not used +(or no connections exist that would necessiate the use of a timeout +right now). +@end deftypefun + + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ----------------------------------------------------------- +@node microhttpd-requests +@chapter Handling requests + + +@deftypefun int MHD_get_connection_values (struct MHD_Connection *connection, enum MHD_ValueKind kind, MHD_KeyValueIterator iterator, void *iterator_cls) +Get all the headers matching @var{kind} from the request. + +The @var{iterator} callback is invoked once for each header, with +@var{iterator_cls} as first argument. After version 0.9.19, the +headers are iterated in the same order as they were received from +the network; previous versions iterated over the headers in reverse +order. + +@code{MHD_get_connection_values} returns the number of entries +iterated over; this can be less than the number of headers if, while +iterating, @var{iterator} returns @code{MHD_NO}. + +@var{iterator} can be @code{NULL}: in this case this function just counts +and returns the number of headers. + +In the case of @code{MHD_GET_ARGUMENT_KIND}, the @var{value} argument +will be @code{NULL} if the URL contained a key without an equals operator. +For example, for a HTTP request to the URL ``http://foo/bar?key'', the +@var{value} argument is @code{NULL}; in contrast, a HTTP request to the URL +``http://foo/bar?key='', the @var{value} argument is the empty string. +The normal case is that the URL contains ``http://foo/bar?key=value'' +in which case @var{value} would be the string ``value'' and @var{key} +would contain the string ``key''. +@end deftypefun + + +@deftypefun int MHD_set_connection_value (struct MHD_Connection *connection, enum MHD_ValueKind kind, const char * key, const char * value) +This function can be used to append an entry to +the list of HTTP headers of a connection (so that the +@code{MHD_get_connection_values function} will return +them -- and the MHD PostProcessor will also +see them). This maybe required in certain +situations (see Mantis #1399) where (broken) +HTTP implementations fail to supply values needed +by the post processor (or other parts of the +application). + +This function MUST only be called from within +the MHD_AccessHandlerCallback (otherwise, access +maybe improperly synchronized). Furthermore, +the client must guarantee that the key and +value arguments are 0-terminated strings that +are NOT freed until the connection is closed. +(The easiest way to do this is by passing only +arguments to permanently allocated strings.). + +@var{connection} is the connection for which +the entry for @var{key} of the given @var{kind} +should be set to the given @var{value}. + +The function returns @code{MHD_NO} if the operation +could not be performed due to insufficient memory +and @code{MHD_YES} on success. +@end deftypefun + + +@deftypefun {const char *} MHD_lookup_connection_value (struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key) +Get a particular header value. If multiple values match the +@var{kind}, return one of them (the ``first'', whatever that means). +@var{key} must reference a zero-terminated ASCII-coded string +representing the header to look for: it is compared against the +headers using @code{strcasecmp()}, so case is ignored. A value of +@code{NULL} for @var{key} can be used to lookup 'trailing' values without a +key, for example if a URI is of the form +``http://example.com/?trailer'', a @var{key} of @code{NULL} can be used to +access ``tailer" The function returns @code{NULL} if no matching item +was found. +@end deftypefun + + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-responses +@chapter Building responses to requests + + +@noindent +Response objects handling by MHD is asynchronous with respect to the +application execution flow. Instances of the @code{MHD_Response} +structure are not associated to a daemon and neither to a client +connection: they are managed with reference counting. + +In the simplest case: we allocate a new @code{MHD_Response} structure +for each response, we use it once and finally we destroy it. + +MHD allows more efficient resources usages. + +Example: we allocate a new @code{MHD_Response} structure for each +response @strong{kind}, we use it every time we have to give that +response and we finally destroy it only when the daemon shuts down. + +@menu +* microhttpd-response enqueue:: Enqueuing a response. +* microhttpd-response create:: Creating a response object. +* microhttpd-response headers:: Adding headers to a response. +* microhttpd-response inspect:: Inspecting a response object. +@end menu + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-response enqueue +@section Enqueuing a response + + +@deftypefun int MHD_queue_response (struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response) +Queue a response to be transmitted to the client as soon as possible +but only after MHD_AccessHandlerCallback returns. This function +checks that it is legal to queue a response at this time for the +given connection. It also increments the internal reference +counter for the response object (the counter will be decremented +automatically once the response has been transmitted). + +@table @var +@item connection +the connection identifying the client; + +@item status_code +HTTP status code (i.e. @code{200} for OK); + +@item response +response to transmit. +@end table + +Return @code{MHD_YES} on success or if message has been queued. Return +@code{MHD_NO}: if arguments are invalid (example: @code{NULL} pointer); on +error (i.e. reply already sent). +@end deftypefun + + +@deftypefun void MHD_destroy_response (struct MHD_Response *response) +Destroy a response object and associated resources (decrement the +reference counter). Note that MHD may keep some of the resources +around if the response is still in the queue for some clients, so the +memory may not necessarily be freed immediately. +@end deftypefun + + +An explanation of reference counting@footnote{Note to readers acquainted +to the Tcl API: reference counting on @code{MHD_Connection} +structures is handled in the same way as Tcl handles @code{Tcl_Obj} +structures through @code{Tcl_IncrRefCount()} and +@code{Tcl_DecrRefCount()}.}: + +@enumerate +@item +a @code{MHD_Response} object is allocated: + +@example +struct MHD_Response * response = MHD_create_response_from_buffer(...); +/* here: reference counter = 1 */ +@end example + +@item +the @code{MHD_Response} object is enqueued in a @code{MHD_Connection}: + +@example +MHD_queue_response(connection, , response); +/* here: reference counter = 2 */ +@end example + +@item +the creator of the response object discharges responsibility for it: + +@example +MHD_destroy_response(response); +/* here: reference counter = 1 */ +@end example + +@item +the daemon handles the connection sending the response's data to the +client then decrements the reference counter by calling +@code{MHD_destroy_response()}: the counter's value drops to zero and +the @code{MHD_Response} object is released. +@end enumerate + + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-response create +@section Creating a response object + + +@deftypefun {struct MHD_Response *} MHD_create_response_from_callback (uint64_t size, size_t block_size, MHD_ContentReaderCallback crc, void *crc_cls, MHD_ContentReaderFreeCallback crfc) +Create a response object. The response object can be extended with +header information and then it can be used any number of times. + +@table @var +@item size +size of the data portion of the response, @code{-1} for unknown; + +@item block_size +preferred block size for querying @var{crc} (advisory only, MHD may +still call @var{crc} using smaller chunks); this is essentially the +buffer size used for @acronym{IO}, clients should pick a value that is +appropriate for @acronym{IO} and memory performance requirements; + +@item crc +callback to use to obtain response data; + +@item crc_cls +extra argument to @var{crc}; + +@item crfc +callback to call to free @var{crc_cls} resources. +@end table + +Return @code{NULL} on error (i.e. invalid arguments, out of memory). +@end deftypefun + + + +@deftypefun {struct MHD_Response *} MHD_create_response_from_fd (uint64_t size, int fd) +Create a response object. The response object can be extended with +header information and then it can be used any number of times. + +@table @var +@item size +size of the data portion of the response (should be smaller or equal to the +size of the file) + +@item fd +file descriptor referring to a file on disk with the data; will be +closed when response is destroyed; note that 'fd' must be an actual +file descriptor (not a pipe or socket) since MHD might use 'sendfile' +or 'seek' on it. The descriptor should be in blocking-IO mode. +@end table + +Return @code{NULL} on error (i.e. invalid arguments, out of memory). +@end deftypefun + + +@deftypefun {struct MHD_Response *} MHD_create_response_from_fd_at_offset (uint64_t size, int fd, off_t offset) +Create a response object. The response object can be extended with +header information and then it can be used any number of times. +Note that you need to be a bit careful about @code{off_t} when +writing this code. Depending on your platform, MHD is likely +to have been compiled with support for 64-bit files. When you +compile your own application, you must make sure that @code{off_t} +is also a 64-bit value. If not, your compiler may pass a 32-bit +value as @code{off_t}, which will result in 32-bits of garbage. + +If you use the autotools, use the @code{AC_SYS_LARGEFILE} autoconf +macro and make sure to include the generated @file{config.h} file +before @file{microhttpd.h} to avoid problems. If you do not have a +build system and only want to run on a GNU/Linux system, you could +also use +@verbatim +#define _FILE_OFFSET_BITS 64 +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <microhttpd.h> +@end verbatim +to ensure 64-bit @code{off_t}. Note that if your operating system +does not support 64-bit files, MHD will be compiled with a 32-bit +@code{off_t} (in which case the above would be wrong). + +@table @var +@item size +size of the data portion of the response (number of bytes to transmit from the +file starting at offset). + +@item fd +file descriptor referring to a file on disk with the data; will be +closed when response is destroyed; note that 'fd' must be an actual +file descriptor (not a pipe or socket) since MHD might use 'sendfile' +or 'seek' on it. The descriptor should be in blocking-IO mode. + +@item offset +offset to start reading from in the file +@end table + +Return @code{NULL} on error (i.e. invalid arguments, out of memory). +@end deftypefun + + +@deftypefun {struct MHD_Response *} MHD_create_response_from_buffer (size_t size, void *data, enum MHD_ResponseMemoryMode mode) +Create a response object. The response object can be extended with +header information and then it can be used any number of times. + +@table @var +@item size +size of the data portion of the response; + +@item buffer +the data itself; + +@item mode +memory management options for buffer; use +MHD_RESPMEM_PERSISTENT if the buffer is static/global memory, +use MHD_RESPMEM_MUST_FREE if the buffer is heap-allocated and +should be freed by MHD and MHD_RESPMEM_MUST_COPY if the +buffer is in transient memory (i.e. on the stack) and must +be copied by MHD; +@end table + +Return @code{NULL} on error (i.e. invalid arguments, out of memory). +@end deftypefun + + +@deftypefun {struct MHD_Response *} MHD_create_response_from_data (size_t size, void *data, int must_free, int must_copy) +Create a response object. The response object can be extended with +header information and then it can be used any number of times. +This function is deprecated, use @code{MHD_create_response_from_buffer} instead. + +@table @var +@item size +size of the data portion of the response; + +@item data +the data itself; + +@item must_free +if true: MHD should free data when done; + +@item must_copy +if true: MHD allocates a block of memory and use it to make a copy of +@var{data} embedded in the returned @code{MHD_Response} structure; +handling of the embedded memory is responsibility of MHD; @var{data} +can be released anytime after this call returns. +@end table + +Return @code{NULL} on error (i.e. invalid arguments, out of memory). +@end deftypefun + + +Example: create a response from a statically allocated string: + +@example +const char * data = "<html><body><p>Error!</p></body></html>"; + +struct MHD_Connection * connection = ...; +struct MHD_Response * response; + +response = MHD_create_response_from_buffer (strlen(data), data, + MHD_RESPMEM_PERSISTENT); +MHD_queue_response(connection, 404, response); +MHD_destroy_response(response); +@end example + + + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-response headers +@section Adding headers to a response + + +@deftypefun int MHD_add_response_header (struct MHD_Response *response, const char *header, const char *content) +Add a header line to the response. The strings referenced by +@var{header} and @var{content} must be zero-terminated and they are +duplicated into memory blocks embedded in @var{response}. + +Notice that the strings must not hold newlines, carriage returns or tab +chars. + +Return @code{MHD_NO} on error (i.e. invalid header or content format or +memory allocation error). +@end deftypefun + + +@deftypefun int MHD_add_response_footer (struct MHD_Response *response, const char *footer, const char *content) +Add a footer line to the response. The strings referenced by +@var{footer} and @var{content} must be zero-terminated and they are +duplicated into memory blocks embedded in @var{response}. + +Notice that the strings must not hold newlines, carriage returns or tab +chars. You can add response footers at any time before signalling the +end of the response to MHD (not just before calling 'MHD_queue_response'). +Footers are useful for adding cryptographic checksums to the reply or to +signal errors encountered during data generation. This call was introduced +in MHD 0.9.3. + +Return @code{MHD_NO} on error (i.e. invalid header or content format or +memory allocation error). +@end deftypefun + + + +@deftypefun int MHD_del_response_header (struct MHD_Response *response, const char *header, const char *content) +Delete a header (or footer) line from the response. Return @code{MHD_NO} on error +(arguments are invalid or no such header known). +@end deftypefun + + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-response inspect +@section Inspecting a response object + + +@deftypefun int MHD_get_response_headers (struct MHD_Response *response, MHD_KeyValueIterator iterator, void *iterator_cls) +Get all of the headers added to a response. + +Invoke the @var{iterator} callback for each header in the response, +using @var{iterator_cls} as first argument. Return number of entries +iterated over. @var{iterator} can be @code{NULL}: in this case the function +just counts headers. + +@var{iterator} should not modify the its key and value arguments, unless +we know what we are doing. +@end deftypefun + + +@deftypefun {const char *} MHD_get_response_header (struct MHD_Response *response, const char *key) +Find and return a pointer to the value of a particular header from the +response. @var{key} must reference a zero-terminated string +representing the header to look for. The search is case sensitive. +Return @code{NULL} if header does not exist or @var{key} is @code{NULL}. + +We should not modify the value, unless we know what we are doing. +@end deftypefun + + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-dauth +@chapter Utilizing Authentication + +@noindent +MHD support three types of client authentication. + +Basic authentication uses a simple authentication method based +on BASE64 algorithm. Username and password are exchanged in clear +between the client and the server, so this method must only be used +for non-sensitive content or when the session is protected with https. +When using basic authentication MHD will have access to the clear +password, possibly allowing to create a chained authentication +toward an external authentication server. + +Digest authentication uses a one-way authentication method based +on MD5 hash algorithm. Only the hash will transit over the network, +hence protecting the user password. The nonce will prevent replay +attacks. This method is appropriate for general use, especially +when https is not used to encrypt the session. + +Client certificate authentication uses a X.509 certificate from +the client. This is the strongest authentication mechanism but it +requires the use of HTTPS. Client certificate authentication can +be used simultaneously with Basic or Digest Authentication in order +to provide a two levels authentication (like for instance separate +machine and user authentication). A code example for using +client certificates is presented in the MHD tutorial. + +@menu +* microhttpd-dauth basic:: Using Basic Authentication. +* microhttpd-dauth digest:: Using Digest Authentication. +@end menu + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-dauth basic +@section Using Basic Authentication + +@deftypefun {char *} MHD_basic_auth_get_username_password (struct MHD_Connection *connection, char** password) +Get the username and password from the basic authorization header sent by the client. +Return @code{NULL} if no username could be found, a pointer to the username if found. +If returned value is not @code{NULL}, the value must be @code{free()}'ed. + +@var{password} reference a buffer to store the password. It can be @code{NULL}. +If returned value is not @code{NULL}, the value must be @code{free()}'ed. +@end deftypefun + +@deftypefun {int} MHD_queue_basic_auth_fail_response (struct MHD_Connection *connection, const char *realm, struct MHD_Response *response) +Queues a response to request basic authentication from the client. +Return @code{MHD_YES} if successful, otherwise @code{MHD_NO}. + +@var{realm} must reference to a zero-terminated string representing the realm. + +@var{response} a response structure to specify what shall be presented to the +client with a 401 HTTP status. +@end deftypefun + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-dauth digest +@section Using Digest Authentication + +@deftypefun {char *} MHD_digest_auth_get_username (struct MHD_Connection *connection) +Find and return a pointer to the username value from the request header. +Return @code{NULL} if the value is not found or header does not exist. +If returned value is not @code{NULL}, the value must be @code{free()}'ed. +@end deftypefun + +@deftypefun int MHD_digest_auth_check (struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout) +Checks if the provided values in the WWW-Authenticate header are valid +and sound according to RFC2716. If valid return @code{MHD_YES}, otherwise return @code{MHD_NO}. + +@var{realm} must reference to a zero-terminated string representing the realm. + +@var{username} must reference to a zero-terminated string representing the username, +it is usually the returned value from MHD_digest_auth_get_username. + +@var{password} must reference to a zero-terminated string representing the password, +most probably it will be the result of a lookup of the username against a local database. + +@var{nonce_timeout} is the amount of time in seconds for a nonce to be invalid. +Most of the time it is sound to specify 300 seconds as its values. +@end deftypefun + +@deftypefun int MHD_queue_auth_fail_response (struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale) +Queues a response to request authentication from the client, +return @code{MHD_YES} if successful, otherwise @code{MHD_NO}. + +@var{realm} must reference to a zero-terminated string representing the realm. + +@var{opaque} must reference to a zero-terminated string representing a value +that gets passed to the client and expected to be passed again to the server +as-is. This value can be a hexadecimal or base64 string. + +@var{response} a response structure to specify what shall be presented to the +client with a 401 HTTP status. + +@var{signal_stale} a value that signals "stale=true" in the response header to +indicate the invalidity of the nonce and no need to ask for authentication +parameters and only a new nonce gets generated. @code{MHD_YES} to generate a new +nonce, @code{MHD_NO} to ask for authentication parameters. +@end deftypefun + +Example: handling digest authentication requests and responses. + +@example +#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>" +#define DENIED "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>" +#define OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4" + +static int +ahc_echo (void *cls, + struct MHD_Connection *connection, + const char *url, + const char *method, + const char *version, + const char *upload_data, size_t *upload_data_size, void **ptr) +@{ + struct MHD_Response *response; + char *username; + const char *password = "testpass"; + const char *realm = "test@@example.com"; + int ret; + + username = MHD_digest_auth_get_username(connection); + if (username == NULL) + @{ + response = MHD_create_response_from_buffer(strlen (DENIED), + DENIED, + MHD_RESPMEM_PERSISTENT); + ret = MHD_queue_auth_fail_response(connection, realm, + OPAQUE, + response, + MHD_NO); + MHD_destroy_response(response); + return ret; + @} + ret = MHD_digest_auth_check(connection, realm, + username, + password, + 300); + free(username); + if ( (ret == MHD_INVALID_NONCE) || + (ret == MHD_NO) ) + @{ + response = MHD_create_response_from_buffer(strlen (DENIED), + DENIED, + MHD_RESPMEM_PERSISTENT); + if (NULL == response) + return MHD_NO; + ret = MHD_queue_auth_fail_response(connection, realm, + OPAQUE, + response, + (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO); + MHD_destroy_response(response); + return ret; + @} + response = MHD_create_response_from_buffer (strlen(PAGE), PAGE, + MHD_RESPMEM_PERSISTENT); + ret = MHD_queue_response(connection, MHD_HTTP_OK, response); + MHD_destroy_response(response); + return ret; +@} +@end example + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-post +@chapter Adding a @code{POST} processor +@cindex POST method + +@menu +* microhttpd-post api:: Programming interface for the + @code{POST} processor. +@end menu + + +@noindent +MHD provides the post processor API to make it easier for applications to +parse the data of a client's @code{POST} request: the +@code{MHD_AccessHandlerCallback} will be invoked multiple times to +process data as it arrives; at each invocation a new chunk of data must +be processed. The arguments @var{upload_data} and @var{upload_data_size} +are used to reference the chunk of data. + +When @code{MHD_AccessHandlerCallback} is invoked for a new connection: +its @code{*@var{con_cls}} argument is set to @code{NULL}. When @code{POST} +data comes in the upload buffer it is @strong{mandatory} to use the +@var{con_cls} to store a reference to per-connection data. The fact +that the pointer was initially @code{NULL} can be used to detect that +this is a new request. + +One method to detect that a new connection was established is +to set @code{*con_cls} to an unused integer: + +@example +int +access_handler (void *cls, + struct MHD_Connection * connection, + const char *url, + const char *method, const char *version, + const char *upload_data, size_t *upload_data_size, + void **con_cls) +@{ + static int old_connection_marker; + int new_connection = (NULL == *con_cls); + + if (new_connection) + @{ + /* new connection with POST */ + *con_cls = &old_connection_marker; + @} + + ... +@} +@end example + +@noindent +In contrast to the previous example, for @code{POST} requests in particular, +it is more common to use the value of @code{*con_cls} to keep track of +actual state used during processing, such as the post processor (or a +struct containing a post processor): + +@example +int +access_handler (void *cls, + struct MHD_Connection * connection, + const char *url, + const char *method, const char *version, + const char *upload_data, size_t *upload_data_size, + void **con_cls) +@{ + struct MHD_PostProcessor * pp = *con_cls; + + if (pp == NULL) + @{ + pp = MHD_create_post_processor(connection, ...); + *con_cls = pp; + return MHD_YES; + @} + if (*upload_data_size) + @{ + MHD_post_process(pp, upload_data, *upload_data_size); + *upload_data_size = 0; + return MHD_YES; + @} + else + @{ + MHD_destroy_post_processor(pp); + return MHD_queue_response(...); + @} +@} +@end example + +Note that the callback from @code{MHD_OPTION_NOTIFY_COMPLETED} +should be used to destroy the post processor. This cannot be +done inside of the access handler since the connection may not +always terminate normally. + + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-post api +@section Programming interface for the @code{POST} processor +@cindex POST method + +@deftypefun {struct MHD_PostProcessor *} MHD_create_post_processor (struct MHD_Connection *connection, size_t buffer_size, MHD_PostDataIterator iterator, void *iterator_cls) +Create a PostProcessor. A PostProcessor can be used to (incrementally) +parse the data portion of a @code{POST} request. + +@table @var +@item connection +the connection on which the @code{POST} is happening (used to determine +the @code{POST} format); + +@item buffer_size +maximum number of bytes to use for internal buffering (used only for the +parsing, specifically the parsing of the keys). A tiny value (256-1024) +should be sufficient; do @strong{NOT} use a value smaller than 256; + +@item iterator +iterator to be called with the parsed data; must @strong{NOT} be +@code{NULL}; + +@item iterator_cls +custom value to be used as first argument to @var{iterator}. +@end table + +Return @code{NULL} on error (out of memory, unsupported encoding), otherwise +a PP handle. +@end deftypefun + + +@deftypefun int MHD_post_process (struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len) +Parse and process @code{POST} data. Call this function when @code{POST} +data is available (usually during an @code{MHD_AccessHandlerCallback}) +with the @var{upload_data} and @var{upload_data_size}. Whenever +possible, this will then cause calls to the +@code{MHD_IncrementalKeyValueIterator}. + +@table @var +@item pp +the post processor; + +@item post_data +@var{post_data_len} bytes of @code{POST} data; + +@item post_data_len +length of @var{post_data}. +@end table + +Return @code{MHD_YES} on success, @code{MHD_NO} on error +(out-of-memory, iterator aborted, parse error). +@end deftypefun + + +@deftypefun int MHD_destroy_post_processor (struct MHD_PostProcessor *pp) +Release PostProcessor resources. After this function is being called, +the PostProcessor is guaranteed to no longer call its iterator. There +is no special call to the iterator to indicate the end of the post processing +stream. After destroying the PostProcessor, the programmer should +perform any necessary work to complete the processing of the iterator. + +Return @code{MHD_YES} if processing completed nicely, @code{MHD_NO} +if there were spurious characters or formatting problems with +the post request. It is common to ignore the return value +of this function. + + +@end deftypefun + + + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +@c ------------------------------------------------------------ +@node microhttpd-info +@chapter Obtaining and modifying status information. + + +@menu +* microhttpd-info daemon:: State information about an MHD daemon +* microhttpd-info conn:: State information about a connection +* microhttpd-option conn:: Modify per-connection options +@end menu + + +@c ------------------------------------------------------------ +@node microhttpd-info daemon +@section Obtaining state information about an MHD daemon + +@deftypefun {const union MHD_DaemonInfo *} MHD_get_daemon_info (struct MHD_Daemon *daemon, enum MHD_DaemonInfoType infoType, ...) +Obtain information about the given daemon. This function +is currently not fully implemented. + +@table @var +@item daemon +the daemon about which information is desired; + +@item infoType +type of information that is desired + +@item ... +additional arguments about the desired information (depending on +infoType) +@end table + +Returns a union with the respective member (depending on +infoType) set to the desired information), or @code{NULL} +in case the desired information is not available or +applicable. +@end deftypefun + + +@deftp {Enumeration} MHD_DaemonInfoType +Values of this enum are used to specify what +information about a daemon is desired. +@table @code +@item MHD_DAEMON_INFO_KEY_SIZE +Request information about the key size for a particular cipher +algorithm. The cipher algorithm should be passed as an extra argument +(of type 'enum MHD_GNUTLS_CipherAlgorithm'). + +@item MHD_DAEMON_INFO_MAC_KEY_SIZE +Request information about the key size for a particular cipher +algorithm. The cipher algorithm should be passed as an extra argument +(of type 'enum MHD_GNUTLS_HashAlgorithm'). + +@item MHD_DAEMON_INFO_LISTEN_FD +@cindex listen +Request the file-descriptor number that MHD is using to listen to the +server socket. This can be useful if no port +was specified and a client needs to learn what port +is actually being used by MHD. +No extra arguments should be passed. + +@end table +@end deftp + + + +@c ------------------------------------------------------------ +@node microhttpd-info conn +@section Obtaining state information about a connection + + +@deftypefun {const union MHD_ConnectionInfo *} MHD_get_connection_info (struct MHD_Connection *daemon, enum MHD_ConnectionInfoType infoType, ...) +Obtain information about the given connection. + +@table @var +@item connection +the connection about which information is desired; + +@item infoType +type of information that is desired + +@item ... +additional arguments about the desired information (depending on +infoType) +@end table + +Returns a union with the respective member (depending on +infoType) set to the desired information), or @code{NULL} +in case the desired information is not available or +applicable. +@end deftypefun + +@deftp {Enumeration} MHD_ConnectionInfoType +Values of this enum are used to specify what information about a +connection is desired. + +@table @code + +@item MHD_CONNECTION_INFO_CIPHER_ALGO +What cipher algorithm is being used (HTTPS connections only). +Takes no extra arguments. +@code{NULL} is returned for non-HTTPS connections. + +@item MHD_CONNECTION_INFO_PROTOCOL, +Takes no extra arguments. Allows finding out the TLS/SSL protocol used +(HTTPS connections only). +@code{NULL} is returned for non-HTTPS connections. + +@item MHD_CONNECTION_INFO_CLIENT_ADDRESS +Returns information about the address of the client. Returns +essentially a @code{struct sockaddr **} (since the API returns +a @code{union MHD_ConnectionInfo *} and that union contains +a @code{struct sockaddr *}). + +@item MHD_CONNECTION_INFO_GNUTLS_SESSION, +Takes no extra arguments. Allows access to the underlying GNUtls session, +including access to the underlying GNUtls client certificate +(HTTPS connections only). Takes no extra arguments. +@code{NULL} is returned for non-HTTPS connections. + +@item MHD_CONNECTION_INFO_GNUTLS_CLIENT_CERT, +Dysfunctional (never implemented, deprecated). Use +MHD_CONNECTION_INFO_GNUTLS_SESSION to get the @code{gnutls_session_t} +and then call @code{gnutls_certificate_get_peers()}. + +@item MHD_CONNECTION_INFO_DAEMON +Returns information about @code{struct MHD_Daemon} which manages +this connection. + +@end table +@end deftp + + + +@c ------------------------------------------------------------ +@node microhttpd-option conn +@section Setting custom options for an individual connection +@cindex timeout + + + +@deftypefun {int} MHD_set_connection_option (struct MHD_Connection *daemon, enum MHD_CONNECTION_OPTION option, ...) +Set a custom option for the given connection. + +@table @var +@item connection +the connection for which an option should be set or modified; + +@item option +option to set + +@item ... +additional arguments for the option (depending on option) +@end table + +Returns @code{MHD_YES} on success, @code{MHD_NO} for errors +(i.e. option argument invalid or option unknown). +@end deftypefun + + +@deftp {Enumeration} MHD_CONNECTION_OPTION +Values of this enum are used to specify which option for a +connection should be changed. + +@table @code + +@item MHD_CONNECTION_OPTION_TIMEOUT +Set a custom timeout for the given connection. Specified +as the number of seconds, given as an @code{unsigned int}. Use +zero for no timeout. + +@end table +@end deftp + + +@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + +@c ********************************************************** +@c ******************* Appendices ************************* +@c ********************************************************** + +@node GNU-LGPL +@unnumbered GNU-LGPL +@cindex license +@include lgpl.texi + +@node GNU GPL with eCos Extension +@unnumbered GNU GPL with eCos Extension +@cindex license +@include ecos.texi + +@node GNU-FDL +@unnumbered GNU-FDL +@cindex license +@include fdl-1.3.texi + +@node Concept Index +@unnumbered Concept Index + +@printindex cp + +@node Function and Data Index +@unnumbered Function and Data Index + +@printindex fn + +@node Type Index +@unnumbered Type Index + +@printindex tp + +@bye diff --git a/doc/microhttpd-tutorial.texi b/doc/microhttpd-tutorial.texi @@ -1,174 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@finalout -@setfilename microhttpd-tutorial.info -@set UPDATED 2 Nov 2011 -@set UPDATED-MONTH Nov 2011 -@set EDITION 0.9.16 -@set VERSION 0.9.16 -@settitle A tutorial for GNU libmicrohttpd - -@dircategory GNU Libraries -@direntry -* libmicrohttpdtutorial: (microhttpd). A tutorial for GNU libmicrohttpd. -@end direntry - -@copying -This tutorial documents GNU libmicrohttpd version @value{VERSION}, last -updated @value{UPDATED}. - -Copyright (c) 2008 Sebastian Gerhardt. - -Copyright (c) 2010, 2011 Christian Grothoff. -@quotation -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, no Front-Cover Texts, and no Back-Cover -Texts. A copy of the license is included in the section entitled "GNU -Free Documentation License". -@end quotation -@end copying - -@titlepage -@title A Tutorial for GNU libmicrohttpd -@subtitle Version @value{VERSION} -@subtitle @value{UPDATED} -@author Sebastian Gerhardt (@email{sebgerhardt@@gmx.net}) -@author Christian Grothoff (@email{christian@@grothoff.org}) -@author Matthieu Speder (@email{mspeder@@users.sourceforge.net}) - -@page -@vskip 0pt plus 1filll -@insertcopying -@end titlepage - - - -@contents - -@ifnottex -@node Top -@top Top -@end ifnottex - -@menu -* Introduction:: -* Hello browser example:: -* Exploring requests:: -* Response headers:: -* Supporting basic authentication:: -* Processing POST data:: -* Improved processing of POST data:: -* Session management:: -* Adding a layer of security:: -* Bibliography:: -* License text:: -* Example programs:: -@end menu - -@node Introduction -@chapter Introduction -@include chapters/introduction.inc - -@node Hello browser example -@chapter Hello browser example -@include chapters/hellobrowser.inc - -@node Exploring requests -@chapter Exploring requests -@include chapters/exploringrequests.inc - -@node Response headers -@chapter Response headers -@include chapters/responseheaders.inc - -@node Supporting basic authentication -@chapter Supporting basic authentication -@include chapters/basicauthentication.inc - -@node Processing POST data -@chapter Processing POST data -@include chapters/processingpost.inc - -@node Improved processing of POST data -@chapter Improved processing of POST data -@include chapters/largerpost.inc - -@node Session management -@chapter Session management -@include chapters/sessions.inc - -@node Adding a layer of security -@chapter Adding a layer of security -@include chapters/tlsauthentication.inc - -@node Bibliography -@appendix Bibliography -@include chapters/bibliography.inc - -@node License text -@appendix GNU Free Documentation License -@include fdl-1.3.texi - -@node Example programs -@appendix Example programs -@menu -* hellobrowser.c:: -* logging.c:: -* responseheaders.c:: -* basicauthentication.c:: -* simplepost.c:: -* largepost.c:: -* sessions.c:: -* tlsauthentication.c:: -@end menu - -@node hellobrowser.c -@section hellobrowser.c -@smalldisplay -@verbatiminclude examples/hellobrowser.c -@end smalldisplay - -@node logging.c -@section logging.c -@smalldisplay -@verbatiminclude examples/logging.c -@end smalldisplay - -@node responseheaders.c -@section responseheaders.c -@smalldisplay -@verbatiminclude examples/responseheaders.c -@end smalldisplay - -@node basicauthentication.c -@section basicauthentication.c -@smalldisplay -@verbatiminclude examples/basicauthentication.c -@end smalldisplay - -@node simplepost.c -@section simplepost.c -@smalldisplay -@verbatiminclude examples/simplepost.c -@end smalldisplay - -@node largepost.c -@section largepost.c -@smalldisplay -@verbatiminclude examples/largepost.c -@end smalldisplay - -@node sessions.c -@section sessions.c -@smalldisplay -@verbatiminclude examples/sessions.c -@end smalldisplay - -@node tlsauthentication.c -@section tlsauthentication.c -@smalldisplay -@verbatiminclude examples/tlsauthentication.c -@end smalldisplay - -@bye diff --git a/doc/microhttpd.texi b/doc/microhttpd.texi @@ -1,2189 +0,0 @@ -\input texinfo -@setfilename microhttpd.info -@include version.texi -@settitle The GNU libmicrohttpd Reference Manual -@copying -This manual documents GNU libmicrohttpd version @value{VERSION}, last -updated @value{UPDATED}. It is built upon the documentation in the -header file @file{microhttpd.h}. - -@noindent - -Copyright @copyright{} 2007, 2008, 2009, 2010, 2011 Christian Grothoff - -@quotation -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.3 -or any later version published by the Free Software Foundation; -with no Invariant Sections, no Front-Cover Texts, and no Back-Cover -Texts. A copy of the license is included in the section entitled "GNU -Free Documentation License". -@end quotation -GNU libmicrohttpd is a GNU package. -@end copying - -@dircategory GNU Libraries -@direntry -* libmicrohttpd: (microhttpd). Embedded HTTP server library. -@end direntry - -@c -@c Titlepage -@c -@titlepage -@title The GNU libmicrohttpd Reference Manual -@subtitle Version @value{VERSION} -@subtitle @value{UPDATED} -@author Marco Maggi (@email{marco.maggi-ipsu@@poste.it}) -@author Christian Grothoff (@email{christian@@grothoff.org}) - -@page -@vskip 0pt plus 1filll -@insertcopying -@end titlepage - -@summarycontents -@contents - - -@macro gnu{} -@acronym{GNU} -@end macro - -@macro gpl{} -@acronym{LGPL} -@end macro - -@macro http{} -@acronym{HTTP} -@end macro - -@macro tcp{} -@acronym{TCP} -@end macro - -@macro api{} -@acronym{API} -@end macro - -@macro urloc{} -@acronym{URL} -@end macro - -@macro uri{} -@acronym{URI} -@end macro - -@macro ascii{} -@acronym{ASCII} -@end macro - -@c ............................................................ - -@macro cfunction{arg} -@code{\arg\()} -@end macro - -@macro mynull{} -@code{NULL} -@end macro - -@macro mhd{} -@acronym{MHD} -@end macro - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - -@c ------------------------------------------------------------ -@ifnottex -@node Top -@top The GNU libmicrohttpd Library -@insertcopying -@end ifnottex - -@menu -* microhttpd-intro:: Introduction. -* microhttpd-const:: Constants. -* microhttpd-struct:: Structures type definition. -* microhttpd-cb:: Callback functions definition. -* microhttpd-init:: Starting and stopping the server. -* microhttpd-inspect:: Implementing external @code{select}. -* microhttpd-requests:: Handling requests. -* microhttpd-responses:: Building responses to requests. -* microhttpd-dauth:: Utilizing Authentication. -* microhttpd-post:: Adding a @code{POST} processor. -* microhttpd-info:: Obtaining and modifying status information. - -Appendices - -* GNU-LGPL:: The GNU Lesser General Public License says how you - can copy and share almost all of `libmicrohttpd'. -* GNU GPL with eCos Extension:: The GNU General Public License with eCos extension says how you - can copy and share some parts of `libmicrohttpd'. -* GNU-FDL:: The GNU Free Documentation License says how you - can copy and share the documentation of `libmicrohttpd'. - -Indices - -* Concept Index:: Index of concepts and programs. -* Function and Data Index:: Index of functions, variables and data types. -* Type Index:: Index of data types. -@end menu - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-intro -@chapter Introduction - - -@noindent -All symbols defined in the public @api{} start with @code{MHD_}. @mhd{} -is a small @http{} daemon library. As such, it does not have any @api{} -for logging errors (you can only enable or disable logging to stderr). -Also, it may not support all of the @http{} features directly, where -applicable, portions of @http{} may have to be handled by clients of the -library. - -The library is supposed to handle everything that it must handle -(because the @api{} would not allow clients to do this), such as basic -connection management; however, detailed interpretations of headers --- -such as range requests --- and @http{} methods are left to clients. The -library does understand @code{HEAD} and will only send the headers of -the response and not the body, even if the client supplied a body. The -library also understands headers that control connection management -(specifically, @code{Connection: close} and @code{Expect: 100 continue} -are understood and handled automatically). - -@mhd{} understands @code{POST} data and is able to decode certain -formats (at the moment only @code{application/x-www-form-urlencoded} -and @code{multipart/form-data}) using the post processor API. The -data stream of a POST is also provided directly to the main -application, so unsupported encodings could still be processed, just -not conveniently by @mhd{}. - -The header file defines various constants used by the @http{} protocol. -This does not mean that @mhd{} actually interprets all of these values. -The provided constants are exported as a convenience for users of the -library. @mhd{} does not verify that transmitted @http{} headers are -part of the standard specification; users of the library are free to -define their own extensions of the @http{} standard and use those with -@mhd{}. - -All functions are guaranteed to be completely reentrant and -thread-safe. @mhd{} checks for allocation failures and tries to -recover gracefully (for example, by closing the connection). -Additionally, clients can specify resource limits on the overall -number of connections, number of connections per IP address and memory -used per connection to avoid resource exhaustion. - -@section Scope - -@mhd{} is currently used in a wide range of implementations. -Examples based on reports we've received from developers include: -@itemize -@item Embedded HTTP server on a cortex M3 (128 KB code space) -@item Large-scale multimedia server (reportedly serving at the - simulator limit of 7.5 GB/s) -@item Administrative console (via HTTP/HTTPS) for network appliances -@c If you have other interesting examples, please let us know -@end itemize - - -@section Compiling GNU libmicrohttpd -@cindex compilation -@cindex embedded systems -@cindex portability - -@mhd{} uses the standard GNU system where the usual build process -involves running -@verbatim -$ ./configure -$ make -$ make install -@end verbatim - -@mhd{} supports various options to be given to configure to tailor the -binary to a specific situation. Note that some of these options will -remove portions of the @mhd{} code that are required for -binary-compatibility. They should only be used on embedded systems -with tight resource constraints and no concerns about library -versioning. Standard distributions including @mhd{} are expected to -always ship with all features enabled, otherwise unexpected -incompatibilities can arise! - -Here is a list of @mhd{}-specific options that can be given to configure -(canonical configure options such as ``--prefix'' are also supported, for a -full list of options run ``./configure --help''): - -@table @code -@item ``--disable-curl'' -disable running testcases using libcurl - -@item ``--disable-largefile'' -disable support for 64-bit files - -@item ``--disable-messages'' -disable logging of error messages (smaller binary size, not so much fun for debugging) - -@item ``--disable-https'' -disable HTTPS support, even if GNUtls is found; this option must be used if eCOS license is desired as an option (in all cases the resulting binary falls under a GNU LGPL-only license) - -@item ``--disable-postprocessor'' -do not include the post processor API (results in binary incompatibility) - -@item ``--disable-dauth'' -do not include the authentication APIs (results in binary incompatibility) - -@item ``--enable-coverage'' -set flags for analysis of code-coverage with gcc/gcov (results in slow, large binaries) - -@item ``--with-gcrypt=PATH'' -specifies path to libgcrypt installation - -@item ``--with-gnutls=PATH'' -specifies path to libgnutls installation - - - -@end table - -@section Including the microhttpd.h header -@cindex portability -@cindex microhttpd.h - -Ideally, before including "microhttpd.h" you should add the necessary -includes to define the @code{uint64_t}, @code{size_t}, @code{fd_set}, -@code{socklen_t} and @code{struct sockaddr} data types. Which -specific headers are needed may depend on your platform and your build -system might include some tests to provide you with the necessary -conditional operations. For possible suggestions consult -@code{platform.h} and @code{configure.ac} in the MHD distribution. - -Once you have ensured that you manually (!) included the right headers -for your platform before "microhttpd.h", you should also add a line -with @code{#define MHD_PLATFORM_H} which will prevent the -"microhttpd.h" header from trying (and, depending on your platform, -failing) to include the right headers. - -If you do not define MHD_PLATFORM_H, the "microhttpd.h" header will -automatically include headers needed on GNU/Linux systems (possibly -causing problems when porting to other platforms). - -@section SIGPIPE -@cindex signals -@mhd{} does not install a signal handler for SIGPIPE. On platforms -where this is possible (such as GNU/Linux), it disables SIGPIPE for -its I/O operations (by passing MSG_NOSIGNAL). On other platforms, -SIGPIPE signals may be generated from network operations by -@mhd{} and will cause the process to die unless the developer -explicitly installs a signal handler for SIGPIPE. - -Hence portable code using MHD must install a SIGPIPE handler or -explicitly block the SIGPIPE signal. MHD does not do so in order -to avoid messing with other parts of the application that may -need to handle SIGPIPE in a particular way. You can make your application handle SIGPIPE by calling the following function in @code{main}: - -@verbatim -static void -catcher (int sig) -{ -} - -static void -ignore_sigpipe () -{ - struct sigaction oldsig; - struct sigaction sig; - - sig.sa_handler = &catcher; - sigemptyset (&sig.sa_mask); -#ifdef SA_INTERRUPT - sig.sa_flags = SA_INTERRUPT; /* SunOS */ -#else - sig.sa_flags = SA_RESTART; -#endif - if (0 != sigaction (SIGPIPE, &sig, &oldsig)) - fprintf (stderr, - "Failed to install SIGPIPE handler: %s\n", strerror (errno)); -} -@end verbatim - -@section MHD_LONG_LONG -@cindex long long -@cindex IAR -@cindex ARM -@cindex cortex m3 -@cindex embedded systems - -Some platforms do not support @code{long long}. Hence MHD defines -a macro @code{MHD_LONG_LONG} which will default to @code{long long}. -If your platform does not support @code{long long}, you should -change "platform.h" to define @code{MHD_LONG_LONG} to an appropriate -alternative type and also define @code{MHD_LONG_LONG_PRINTF} to the -corresponding format string for printing such a data type (without -the percent sign). - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-const -@chapter Constants - - -@deftp {Enumeration} MHD_FLAG -Options for the @mhd{} daemon. - -Note that if neither @code{MHD_USE_THREAD_PER_CONNECTION} nor -@code{MHD_USE_SELECT_INTERNALLY} is used, the client wants control over -the process and will call the appropriate microhttpd callbacks. - -Starting the daemon may also fail if a particular option is not -implemented or not supported on the target platform (i.e. no support for -@acronym{SSL}, threads or IPv6). SSL support generally depends on -options given during @mhd{} compilation. Threaded operations -(including @code{MHD_USE_SELECT_INTERNALLY}) are not supported on -Symbian. - -@table @code -@item MHD_NO_FLAG -No options selected. - -@item MHD_USE_DEBUG -@cindex debugging -Run in debug mode. If this flag is used, the library should print error -messages and warnings to stderr. Note that for this -run-time option to have any effect, @mhd{} needs to be -compiled with messages enabled. This is done by default except you ran -configure with the @code{--disable-messages} flag set. - -@item MHD_USE_SSL -Run in https mode (this option may not work with all threading modes yet). - -@item MHD_USE_THREAD_PER_CONNECTION -Run using one thread per connection. - -@item MHD_USE_SELECT_INTERNALLY -Run using an internal thread doing @code{SELECT}. - -@item MHD_USE_IPv6 -@cindex IPv6 -Run using the IPv6 protocol (otherwise, @mhd{} will just support IPv4). - - -@item MHD_USE_PEDANTIC_CHECKS -Be pedantic about the protocol (as opposed to as tolerant as possible). -Specifically, at the moment, this flag causes @mhd{} to reject @http{} -1.1 connections without a @code{Host} header. This is required by the -standard, but of course in violation of the ``be as liberal as possible -in what you accept'' norm. It is recommended to turn this @strong{ON} -if you are testing clients against @mhd{}, and @strong{OFF} in -production. - -@item MHD_USE_POLL -@cindex FD_SETSIZE -@cindex poll -@cindex select -Use poll instead of select. This allows sockets with descriptors -@code{>= FD_SETSIZE}. This option only works in conjunction with -@code{MHD_USE_THREAD_PER_CONNECTION} (at this point). - -@item MHD_SUPPRESS_DATE_NO_CLOCK -@cindex date -@cindex clock -@cindex embedded systems -Suppress (automatically) adding the 'Date:' header to HTTP responses. -This option should ONLY be used on systems that do not have a clock -and that DO provide other mechanisms for cache control. See also -RFC 2616, section 14.18 (exception 3). - - -@item MHD_USE_NO_LISTEN_SOCKET -@cindex listen -@cindex proxy -@cindex embedded systems -Run the HTTP server without any listen socket. This option only makes -sense if @code{MHD_add_connection} is going to be used exclusively to -connect HTTP clients to the HTTP server. This option is incompatible -with using a thread pool; if it is used, -@code{MHD_OPTION_THREAD_POOL_SIZE} is ignored. - -@end table -@end deftp - - -@deftp {Enumeration} MHD_OPTION -@mhd{} options. Passed in the varargs portion of -@cfunction{MHD_start_daemon}. - -@table @code -@item MHD_OPTION_END -No more options / last option. This is used to terminate the VARARGs -list. - -@item MHD_OPTION_CONNECTION_MEMORY_LIMIT -@cindex memory, limiting memory utilization -Maximum memory size per connection (followed by a @code{size_t}). The -default is 32 kB (32*1024 bytes) as defined by the internal constant -@code{MHD_POOL_SIZE_DEFAULT}. - -@item MHD_OPTION_CONNECTION_LIMIT -@cindex connection, limiting number of connections -Maximum number of concurrent connections to accept (followed by an -@code{unsigned int}). The default is @code{FD_SETSIZE - 4} (the -maximum number of file descriptors supported by @code{select} minus -four for @code{stdin}, @code{stdout}, @code{stderr} and the server -socket). In other words, the default is as large as possible. - -Note that if you set a low connection limit, you can easily get into -trouble with browsers doing request pipelining. For example, if your -connection limit is ``1'', a browser may open a first connection to -access your ``index.html'' file, keep it open but use a second -connection to retrieve CSS files, images and the like. In fact, modern -browsers are typically by default configured for up to 15 parallel -connections to a single server. If this happens, MHD will refuse to -even accept the second connection until the first connection is -closed --- which does not happen until timeout. As a result, the -browser will fail to render the page and seem to hang. If you expect -your server to operate close to the connection limit, you should -first consider using a lower timeout value and also possibly add -a ``Connection: close'' header to your response to ensure that -request pipelining is not used and connections are closed immediately -after the request has completed: -@example -MHD_add_response_header (response, - MHD_HTTP_HEADER_CONNECTION, - "close"); -@end example - -@item MHD_OPTION_CONNECTION_TIMEOUT -@cindex timeout -After how many seconds of inactivity should a connection automatically -be timed out? (followed by an @code{unsigned int}; use zero for no -timeout). The default is zero (no timeout). - -@item MHD_OPTION_NOTIFY_COMPLETED -Register a function that should be called whenever a request has been -completed (this can be used for application-specific clean up). -Requests that have never been presented to the application (via -@cfunction{MHD_AccessHandlerCallback}) will not result in -notifications. - -This option should be followed by @strong{TWO} pointers. First a -pointer to a function of type @cfunction{MHD_RequestCompletedCallback} -and second a pointer to a closure to pass to the request completed -callback. The second pointer maybe @mynull{}. - - -@item MHD_OPTION_PER_IP_CONNECTION_LIMIT -Limit on the number of (concurrent) connections made to the -server from the same IP address. Can be used to prevent one -IP from taking over all of the allowed connections. If the -same IP tries to establish more than the specified number of -connections, they will be immediately rejected. The option -should be followed by an @code{unsigned int}. The default is -zero, which means no limit on the number of connections -from the same IP address. - -@item MHD_OPTION_SOCK_ADDR -@cindex bind, restricting bind -Bind daemon to the supplied socket address. This option should be followed by a -@code{struct sockaddr *}. If @code{MHD_USE_IPv6} is specified, -the @code{struct sockaddr*} should point to a @code{struct sockaddr_in6}, -otherwise to a @code{struct sockaddr_in}. If this option is not specified, -the daemon will listen to incoming connections from anywhere. If you use this -option, the 'port' argument from @code{MHD_start_daemon} is ignored and the port -from the given @code{struct sockaddr *} will be used instead. - -@item MHD_OPTION_URI_LOG_CALLBACK -@cindex debugging -@cindex logging -@cindex query string -Specify a function that should be called before parsing the URI from -the client. The specified callback function can be used for processing -the URI (including the options) before it is parsed. The URI after -parsing will no longer contain the options, which maybe inconvenient for -logging. This option should be followed by two arguments, the first -one must be of the form -@example - void * my_logger(void * cls, const char * uri) -@end example -where the return value will be passed as -@code{*con_cls} in calls to the @code{MHD_AccessHandlerCallback} -when this request is processed later; returning a -value of NULL has no special significance; (however, -note that if you return non-NULL, you can no longer -rely on the first call to the access handler having -@code{NULL == *con_cls} on entry) -@code{cls} will be set to the second argument following -MHD_OPTION_URI_LOG_CALLBACK. Finally, @code{uri} will -be the 0-terminated URI of the request. - -@item MHD_OPTION_HTTPS_MEM_KEY -@cindex SSL -@cindex TLS -Memory pointer to the private key to be used by the -HTTPS daemon. This option should be followed by an -"const char*" argument. -This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_CERT'. - -@item MHD_OPTION_HTTPS_MEM_CERT -@cindex SSL -@cindex TLS -Memory pointer to the certificate to be used by the -HTTPS daemon. This option should be followed by an -"const char*" argument. -This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_KEY'. - -@item MHD_OPTION_HTTPS_MEM_TRUST -@cindex SSL -@cindex TLS -Memory pointer to the CA certificate to be used by the -HTTPS daemon to authenticate and trust clients certificates. -This option should be followed by an "const char*" argument. -The presence of this option activates the request of certificate -to the client. The request to the client is marked optional, and -it is the responsibility of the server to check the presence -of the certificate if needed. -Note that most browsers will only present a client certificate -only if they have one matching the specified CA, not sending -any certificate otherwise. - -@item MHD_OPTION_HTTPS_CRED_TYPE -@cindex SSL -@cindex TLS -Daemon credentials type. Either certificate or anonymous, -this option should be followed by one of the values listed in -"enum gnutls_credentials_type_t". - -@item MHD_OPTION_HTTPS_PRIORITIES -@cindex SSL -@cindex TLS -@cindex cipher -SSL/TLS protocol version and ciphers. -This option must be followed by an "const char *" argument -specifying the SSL/TLS protocol versions and ciphers that -are acceptable for the application. The string is passed -unchanged to gnutls_priority_init. If this option is not -specified, ``NORMAL'' is used. - -@item MHD_OPTION_DIGEST_AUTH_RANDOM -@cindex digest auth -@cindex random -Digest Authentication nonce's seed. - -This option should be followed by two arguments. First an integer of -type "size_t" which specifies the size of the buffer pointed to by the -second argument in bytes. Note that the application must ensure that -the buffer of the second argument remains allocated and unmodified -while the daemon is running. For security, you SHOULD provide a fresh -random nonce when using MHD with Digest Authentication. - -@item MHD_OPTION_NONCE_NC_SIZE -@cindex digest auth -@cindex replay attack - -Size of an array of nonce and nonce counter map. This option must be -followed by an "unsigned int" argument that have the size (number of -elements) of a map of a nonce and a nonce-counter. If this option -is not specified, a default value of 4 will be used (which might be -too small for servers handling many requests). If you do not use -digest authentication at all, you can specify a value of zero to -save some memory. - -You should calculate the value of NC_SIZE based on the number of -connections per second multiplied by your expected session duration -plus a factor of about two for hash table collisions. For example, if -you expect 100 digest-authenticated connections per second and the -average user to stay on your site for 5 minutes, then you likely need -a value of about 60000. On the other hand, if you can only expect -only 10 digest-authenticated connections per second, tolerate browsers -getting a fresh nonce for each request and expect a HTTP request -latency of 250 ms, then a value of about 5 should be fine. - - -@item MHD_OPTION_LISTEN_SOCKET -@cindex systemd -Listen socket to use. Pass a listen socket for MHD to use -(systemd-style). If this option is used, MHD will not open its own -listen socket(s). The argument passed must be of type "int" and refer -to an existing socket that has been bound to a port and is listening. - -@item MHD_OPTION_EXTERNAL_LOGGER -@cindex logging -Use the given function for logging error messages. -This option must be followed by two arguments; the -first must be a pointer to a function -of type 'void fun(void * arg, const char * fmt, va_list ap)' -and the second a pointer of type 'void*' which will -be passed as the "arg" argument to "fun". - -Note that MHD will not generate any log messages without -the MHD_USE_DEBUG flag set and if MHD was compiled -with the "--disable-messages" flag. - -@item MHD_OPTION_THREAD_POOL_SIZE -@cindex performance -Number (unsigned int) of threads in thread pool. Enable -thread pooling by setting this value to to something -greater than 1. Currently, thread model must be -MHD_USE_SELECT_INTERNALLY if thread pooling is enabled -(MHD_start_daemon returns NULL for an unsupported thread -model). - -@item MHD_OPTION_ARRAY -@cindex options -@cindex foreign-function interface -This option can be used for initializing MHD using options from an -array. A common use for this is writing an FFI for MHD. The actual -options given are in an array of 'struct MHD_OptionItem', so this -option requires a single argument of type 'struct MHD_OptionItem'. -The array must be terminated with an entry @code{MHD_OPTION_END}. - -An example for code using MHD_OPTION_ARRAY is: -@example -struct MHD_OptionItem ops[] = @{ - @{ MHD_OPTION_CONNECTION_LIMIT, 100, NULL @}, - @{ MHD_OPTION_CONNECTION_TIMEOUT, 10, NULL @}, - @{ MHD_OPTION_END, 0, NULL @} -@}; -d = MHD_start_daemon(0, 8080, NULL, NULL, dh, NULL, - MHD_OPTION_ARRAY, ops, - MHD_OPTION_END); -@end example -For options that expect a single pointer argument, the -second member of the @code{struct MHD_OptionItem} is ignored. -For options that expect two pointer arguments, the first -argument must be cast to @code{intptr_t}. - -@item MHD_OPTION_UNESCAPE_CALLBACK -@cindex internationalization -@cindex escaping - -Specify a function that should be called for unescaping escape -sequences in URIs and URI arguments. Note that this function will NOT -be used by the MHD_PostProcessor. If this option is not specified, -the default method will be used which decodes escape sequences of the -form "%HH". This option should be followed by two arguments, the -first one must be of the form - -@example - size_t my_unescaper(void * cls, struct MHD_Connection *c, char *s) -@end example - -where the return value must be @code{strlen(s)} and @code{s} should be -updated. Note that the unescape function must not lengthen @code{s} -(the result must be shorter than the input and still be 0-terminated). -@code{cls} will be set to the second argument following -MHD_OPTION_UNESCAPE_CALLBACK. - - -@item MHD_OPTION_THREAD_STACK_SIZE -@cindex stack -@cindex thread -@cindex pthread -@cindex embedded systems -Maximum stack size for threads created by MHD. This option must be -followed by a @code{size_t}). Not specifying this option or using -a value of zero means using the system default (which is likely to -differ based on your platform). - -@end table -@end deftp - - -@deftp {C Struct} MHD_OptionItem -Entry in an MHD_OPTION_ARRAY. See the @code{MHD_OPTION_ARRAY} option -argument for its use. - -The @code{option} member is used to specify which option is specified -in the array. The other members specify the respective argument. - -Note that for options taking only a single pointer, the -@code{ptr_value} member should be set. For options taking two pointer -arguments, the first pointer must be cast to @code{intptr_t} and both -the @code{value} and the @code{ptr_value} members should be used to -pass the two pointers. -@end deftp - - -@deftp {Enumeration} MHD_ValueKind -The @code{MHD_ValueKind} specifies the source of the key-value pairs in -the @http{} protocol. - -@table @code -@item MHD_RESPONSE_HEADER_KIND -Response header. - -@item MHD_HEADER_KIND -@http{} header. - -@item MHD_COOKIE_KIND -@cindex cookie -Cookies. Note that the original @http{} header containing the cookie(s) -will still be available and intact. - -@item MHD_POSTDATA_KIND -@cindex POST method -@code{POST} data. This is available only if a content encoding -supported by @mhd{} is used (currently only @acronym{URL} encoding), and -only if the posted content fits within the available memory pool. Note -that in that case, the upload data given to the -@cfunction{MHD_AccessHandlerCallback} will be empty (since it has -already been processed). - -@item MHD_GET_ARGUMENT_KIND -@code{GET} (@uri{}) arguments. - -@item MHD_FOOTER_KIND -@http{} footer (only for http 1.1 chunked encodings). - -@end table -@end deftp - - -@deftp {Enumeration} MHD_RequestTerminationCode -The @code{MHD_RequestTerminationCode} specifies reasons why a request -has been terminated (or completed). - -@table @code -@item MHD_REQUEST_TERMINATED_COMPLETED_OK -We finished sending the response. - -@item MHD_REQUEST_TERMINATED_WITH_ERROR -Error handling the connection (resources exhausted, other side closed -connection, application error accepting request, etc.) - -@item MHD_REQUEST_TERMINATED_TIMEOUT_REACHED -No activity on the connection for the number of seconds specified using -@code{MHD_OPTION_CONNECTION_TIMEOUT}. - -@item MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN -We had to close the session since @mhd{} was being shut down. -@end table -@end deftp - - -@deftp {Enumeration} MHD_ResponseMemoryMode -The @code{MHD_ResponeMemoryMode} specifies how MHD should treat -the memory buffer given for the response in -@code{MHD_create_response_from_buffer}. - -@table @code -@item MHD_RESPMEM_PERSISTENT -Buffer is a persistent (static/global) buffer that won't change -for at least the lifetime of the response, MHD should just use -it, not free it, not copy it, just keep an alias to it. - -@item MHD_RESPMEM_MUST_FREE -Buffer is heap-allocated with @code{malloc} (or equivalent) and -should be freed by MHD after processing the response has -concluded (response reference counter reaches zero). - -@item MHD_RESPMEM_MUST_COPY -Buffer is in transient memory, but not on the heap (for example, -on the stack or non-malloc allocated) and only valid during the -call to @code{MHD_create_response_from_buffer}. MHD must make its -own private copy of the data for processing. - -@end table -@end deftp - - - - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-struct -@chapter Structures type definition - - -@deftp {C Struct} MHD_Daemon -Handle for the daemon (listening on a socket for @http{} traffic). -@end deftp - - -@deftp {C Struct} MHD_Connection -Handle for a connection / @http{} request. With @http{}/1.1, multiple -requests can be run over the same connection. However, @mhd{} will only -show one request per @tcp{} connection to the client at any given time. -@end deftp - - -@deftp {C Struct} MHD_Response -Handle for a response. -@end deftp - - -@deftp {C Struct} MHD_PostProcessor -@cindex POST method -Handle for @code{POST} processing. -@end deftp - - -@deftp {C Union} MHD_ConnectionInfo -Information about a connection. -@end deftp - - -@deftp {C Union} MHD_DaemonInfo -Information about an MHD daemon. -@end deftp - - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-cb -@chapter Callback functions definition - - -@deftypefn {Function Pointer} int {*MHD_AcceptPolicyCallback} (void *cls, const struct sockaddr * addr, socklen_t addrlen) -Invoked in the context of a connection to allow or deny a client to -connect. This callback return @code{MHD_YES} if connection is allowed, -@code{MHD_NO} if not. - -@table @var -@item cls -custom value selected at callback registration time; -@item addr -address information from the client; -@item addrlen -length of the address information. -@end table -@end deftypefn - - -@deftypefn {Function Pointer} int {*MHD_AccessHandlerCallback} (void *cls, struct MHD_Connection * connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) -Invoked in the context of a connection to answer a request from the -client. This callback must call @mhd{} functions (example: the -@code{MHD_Response} ones) to provide content to give back to the client -and return an @http{} status code (i.e. @code{200} for OK, @code{404}, -etc.). - -@ref{microhttpd-post}, for details on how to code this callback. - -Must return @code{MHD_YES} if the connection was handled successfully, -@code{MHD_NO} if the socket must be closed due to a serious error while -handling the request - -@table @var -@item cls -custom value selected at callback registration time; - -@item url -the @urloc{} requested by the client; - -@item method -the @http{} method used by the client (@code{GET}, @code{PUT}, -@code{DELETE}, @code{POST}, etc.); - -@item version -the @http{} version string (i.e. @code{HTTP/1.1}); - -@item upload_data -the data being uploaded (excluding headers): -@cindex POST method -@cindex PUT method - -@itemize -@item -for a @code{POST} that fits into memory and that is encoded with a -supported encoding, the @code{POST} data will @strong{NOT} be given in -@var{upload_data} and is instead available as part of -@cfunction{MHD_get_connection_values}; - -@item -very large @code{POST} data @strong{will} be made available -incrementally in @var{upload_data}; -@end itemize - -@item upload_data_size -set initially to the size of the @var{upload_data} provided; this -callback must update this value to the number of bytes @strong{NOT} -processed; unless external select is used, the callback maybe -required to process at least some data. If the callback fails to -process data in multi-threaded or internal-select mode and if the -read-buffer is already at the maximum size that MHD is willing to -use for reading (about half of the maximum amount of memory allowed -for the connection), then MHD will abort handling the connection -and return an internal server error to the client. In order to -avoid this, clients must be able to process upload data incrementally -and reduce the value of @code{upload_data_size}. - -@item con_cls -reference to a pointer, initially set to @mynull{}, that this callback can -set to some address and that will be preserved by @mhd{} for future -calls for this request; - -since the access handler may be called many times (i.e., for a -@code{PUT}/@code{POST} operation with plenty of upload data) this allows -the application to easily associate some request-specific state; - -if necessary, this state can be cleaned up in the global -@code{MHD_RequestCompletedCallback} (which can be set with the -@code{MHD_OPTION_NOTIFY_COMPLETED}). -@end table -@end deftypefn - - -@deftypefn {Function Pointer} void {*MHD_RequestCompletedCallback} (void *cls, struct MHD_Connectionconnection, void **con_cls, enum MHD_RequestTerminationCode toe) -Signature of the callback used by @mhd{} to notify the application about -completed requests. - -@table @var -@item cls -custom value selected at callback registration time; - -@item connection -connection handle; - -@item con_cls -value as set by the last call to the -@code{MHD_AccessHandlerCallback}; - -@item toe -reason for request termination see @code{MHD_OPTION_NOTIFY_COMPLETED}. -@end table -@end deftypefn - - -@deftypefn {Function Pointer} int {*MHD_KeyValueIterator} (void *cls, enum MHD_ValueKind kind, const char *key, const char *value) -Iterator over key-value pairs. This iterator can be used to iterate -over all of the cookies, headers, or @code{POST}-data fields of a -request, and also to iterate over the headers that have been added to a -response. - -Return @code{MHD_YES} to continue iterating, @code{MHD_NO} to abort the -iteration. -@end deftypefn - - -@deftypefn {Function Pointer} int {*MHD_ContentReaderCallback} (void *cls, uint64_t pos, char *buf, size_t max) -Callback used by @mhd{} in order to obtain content. The callback has to -copy at most @var{max} bytes of content into @var{buf}. The total -number of bytes that has been placed into @var{buf} should be returned. - -Note that returning zero will cause @mhd{} to try again, either -``immediately'' if in multi-threaded mode (in which case the callback -may want to do blocking operations to avoid busy waiting) or in the -next round if @code{MHD_run} is used. Returning zero for a daemon -that runs in internal @cfunction{select} mode is an error (since it -would result in busy waiting) and cause the program to be aborted -(@cfunction{abort}). - -While usually the callback simply returns the number of bytes written -into @var{buf}, there are two special return value: - -@code{MHD_CONTENT_READER_END_OF_STREAM} (-1) should be returned -for the regular end of transmission (with chunked encoding, MHD will then -terminate the chunk and send any HTTP footers that might be -present; without chunked encoding and given an unknown -response size, @mhd{} will simply close the connection; note -that while returning @code{MHD_CONTENT_READER_END_OF_STREAM} is not technically -legal if a response size was specified, MHD accepts this -and treats it just as @code{MHD_CONTENT_READER_END_WITH_ERROR}. - -@code{MHD_CONTENT_READER_END_WITH_ERROR} (-2) is used to indicate a server -error generating the response; this will cause @mhd{} to simply -close the connection immediately. If a response size was -given or if chunked encoding is in use, this will indicate -an error to the client. Note, however, that if the client -does not know a response size and chunked encoding is not in -use, then clients will not be able to tell the difference between -@code{MHD_CONTENT_READER_END_WITH_ERROR} and -@code{MHD_CONTENT_READER_END_OF_STREAM}. -This is not a limitation of @mhd{} but rather of the HTTP protocol. - -@table @var -@item cls -custom value selected at callback registration time; - -@item pos -position in the datastream to access; note that if an -@code{MHD_Response} object is re-used, it is possible for the same -content reader to be queried multiple times for the same data; however, -if an @code{MHD_Response} is not re-used, @mhd{} guarantees that -@var{pos} will be the sum of all non-negative return values obtained -from the content reader so far. -@end table - -Return @code{-1} on error (@mhd{} will no longer try to read content and -instead close the connection with the client). -@end deftypefn - - -@deftypefn {Function Pointer} void {*MHD_ContentReaderFreeCallback} (void *cls) -This method is called by @mhd{} if we are done with a content reader. -It should be used to free resources associated with the content reader. -@end deftypefn - - -@deftypefn {Function Pointer} int {*MHD_PostDataIterator} (void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) -Iterator over key-value pairs where the value maybe made available in -increments and/or may not be zero-terminated. Used for processing -@code{POST} data. - -@table @var -@item cls -custom value selected at callback registration time; - -@item kind -type of the value; - -@item key -zero-terminated key for the value; - -@item filename -name of the uploaded file, @mynull{} if not known; - -@item content_type -mime-type of the data, @mynull{} if not known; - -@item transfer_encoding -encoding of the data, @mynull{} if not known; - -@item data -pointer to size bytes of data at the specified offset; - -@item off -offset of data in the overall value; - -@item size -number of bytes in data available. -@end table - -Return @code{MHD_YES} to continue iterating, @code{MHD_NO} to abort the -iteration. -@end deftypefn - - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-init -@chapter Starting and stopping the server - -@deftypefun {void} MHD_set_panic_func (MHD_PanicCallback cb, void *cls) -Set a handler for fatal errors. - -@table @var -@item cb -function to call if MHD encounters a fatal internal error. If no handler was set explicitly, MHD will call @code{abort}. - -@item cls -closure argument for cb; the other arguments are the name of the source file, line number and a string describing the nature of the fatal error (which can be NULL) -@end table -@end deftypefun - -@deftypefun {struct MHD_Daemon *} MHD_start_daemon (unsigned int flags, unsigned short port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls, ...) -Start a webserver on the given port. - -@table @var -@item flags -OR-ed combination of @code{MHD_FLAG} values; - -@item port -port to bind to; - -@item apc -callback to call to check which clients will be allowed to connect; you -can pass @mynull{} in which case connections from any @acronym{IP} will be -accepted; - -@item apc_cls -extra argument to @var{apc}; - -@item dh -default handler for all @uri{}s; - -@item dh_cls -extra argument to @var{dh}. -@end table - -Additional arguments are a list of options (type-value pairs, -terminated with @code{MHD_OPTION_END}). It is mandatory to use -@code{MHD_OPTION_END} as last argument, even when there are no -additional arguments. - -Return @mynull{} on error, handle to daemon on success. -@end deftypefun - - -@deftypefun void MHD_stop_daemon (struct MHD_Daemon *daemon) -Shutdown an @http{} daemon. -@end deftypefun - - -@deftypefun int MHD_run (struct MHD_Daemon *daemon) -Run webserver operations (without blocking unless in client callbacks). -This method should be called by clients in combination with -@cfunction{MHD_get_fdset} if the client-controlled @cfunction{select} -method is used. - -Return @code{MHD_YES} on success, @code{MHD_NO} if this daemon was not -started with the right options for this call. -@end deftypefun - - -@deftypefun void MHD_add_connection (struct MHD_Daemon *daemon, int client_socket, const struct sockaddr *addr, socklen_t addrlen) -Add another client connection to the set of connections -managed by MHD. This API is usually not needed (since -MHD will accept inbound connections on the server socket). -Use this API in special cases, for example if your HTTP -server is behind NAT and needs to connect out to the -HTTP client. - -The given client socket will be managed (and closed!) by MHD after -this call and must no longer be used directly by the application -afterwards. - -@table @var -@item daemon -daemon that manages the connection -@item client_socket -socket to manage (MHD will expect to receive an HTTP request from this socket next). -@item addr -IP address of the client -@item addrlen -number of bytes in addr -@end table - -This function will return @code{MHD_YES} on success, -@code{MHD_NO} if this daemon could -not handle the connection (i.e. malloc failed, etc). -The socket will be closed in any case. -@end deftypefun - - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ----------------------------------------------------------- -@node microhttpd-inspect -@chapter Implementing external @code{select} - - -@deftypefun int MHD_get_fdset (struct MHD_Daemon *daemon, fd_set * read_fd_set, fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd) -Obtain the @cfunction{select} sets for this daemon. The daemon's socket -is added to @var{read_fd_set}. The list of currently existent -connections is scanned and their file descriptors added to the correct -set. - -After the call completed successfully: the variable referenced by -@var{max_fd} references the file descriptor with highest integer -identifier. The variable must be set to zero before invoking this -function. - -Return @code{MHD_YES} on success, @code{MHD_NO} if: the arguments are -invalid (example: @mynull{} pointers); this daemon was not started with -the right options for this call. -@end deftypefun - - -@deftypefun int MHD_get_timeout (struct MHD_Daemon *daemon, unsigned long long *timeout) -@cindex timeout -Obtain timeout value for select for this daemon (only needed if -connection timeout is used). The returned value is how long -@cfunction{select} should at most block, not the timeout value set for -connections. This function must not be called if the -@code{MHD_USE_THREAD_PER_CONNECTION} mode is in use (since then it -is not meaningful to ask for a timeout, after all, there is -concurrenct activity). The function must also not be called by -user-code if @code{MHD_USE_INTERNAL_SELECT} is in use. In the latter -case, the behavior is undefined. - -@table @var -@cindex timeout -set to the timeout (in milliseconds). -@end table - -Return @code{MHD_YES} on success, @code{MHD_NO} if timeouts are not used -(or no connections exist that would necessiate the use of a timeout -right now). -@end deftypefun - - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ----------------------------------------------------------- -@node microhttpd-requests -@chapter Handling requests - - -@deftypefun int MHD_get_connection_values (struct MHD_Connection *connection, enum MHD_ValueKind kind, MHD_KeyValueIterator iterator, void *iterator_cls) -Get all the headers matching @var{kind} from the request. - -The @var{iterator} callback is invoked once for each header, with -@var{iterator_cls} as first argument. After version 0.9.19, the -headers are iterated in the same order as they were received from -the network; previous versions iterated over the headers in reverse -order. - -@code{MHD_get_connection_values} returns the number of entries -iterated over; this can be less than the number of headers if, while -iterating, @var{iterator} returns @code{MHD_NO}. - -@var{iterator} can be @mynull{}: in this case this function just counts -and returns the number of headers. - -In the case of @code{MHD_GET_ARGUMENT_KIND}, the @var{value} argument -will be NULL if the URL contained a key without an equals operator. -For example, for a HTTP request to the URL ``http://foo/bar?key'', the -@var{value} argument is NULL; in contrast, a HTTP request to the URL -``http://foo/bar?key='', the @var{value} argument is the empty string. -The normal case is that the URL contains ``http://foo/bar?key=value'' -in which case @var{value} would be the string ``value'' and @var{key} -would contain the string ``key''. -@end deftypefun - - -@deftypefun int MHD_set_connection_value (struct MHD_Connection *connection, enum MHD_ValueKind kind, const char * key, const char * value) -This function can be used to append an entry to -the list of HTTP headers of a connection (so that the -@code{MHD_get_connection_values function} will return -them -- and the MHD PostProcessor will also -see them). This maybe required in certain -situations (see Mantis #1399) where (broken) -HTTP implementations fail to supply values needed -by the post processor (or other parts of the -application). - -This function MUST only be called from within -the MHD_AccessHandlerCallback (otherwise, access -maybe improperly synchronized). Furthermore, -the client must guarantee that the key and -value arguments are 0-terminated strings that -are NOT freed until the connection is closed. -(The easiest way to do this is by passing only -arguments to permanently allocated strings.). - -@var{connection} is the connection for which -the entry for @var{key} of the given @var{kind} -should be set to the given @var{value}. - -The function returns @code{MHD_NO} if the operation -could not be performed due to insufficient memory -and @code{MHD_YES} on success. -@end deftypefun - - -@deftypefun {const char *} MHD_lookup_connection_value (struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key) -Get a particular header value. If multiple values match the -@var{kind}, return one of them (the ``first'', whatever that means). -@var{key} must reference a zero-terminated @ascii{}-coded string -representing the header to look for: it is compared against the -headers using @cfunction{strcasecmp}, so case is ignored. A value of -NULL for @var{key} can be used to lookup 'trailing' values without a -key, for example if a URI is of the form -``http://example.com/?trailer'', a @var{key} of NULL can be used to -access ``tailer" The function returns @mynull{} if no matching item -was found. -@end deftypefun - - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-responses -@chapter Building responses to requests - - -@noindent -Response objects handling by @mhd{} is asynchronous with respect to the -application execution flow. Instances of the @code{MHD_Response} -structure are not associated to a daemon and neither to a client -connection: they are managed with reference counting. - -In the simplest case: we allocate a new @code{MHD_Response} structure -for each response, we use it once and finally we destroy it. - -@mhd{} allows more efficient resources usages. - -Example: we allocate a new @code{MHD_Response} structure for each -response @strong{kind}, we use it every time we have to give that -response and we finally destroy it only when the daemon shuts down. - -@menu -* microhttpd-response enqueue:: Enqueuing a response. -* microhttpd-response create:: Creating a response object. -* microhttpd-response headers:: Adding headers to a response. -* microhttpd-response inspect:: Inspecting a response object. -@end menu - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-response enqueue -@section Enqueuing a response - - -@deftypefun int MHD_queue_response (struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response) -Queue a response to be transmitted to the client as soon as possible -but only after MHD_AccessHandlerCallback returns. This function -checks that it is legal to queue a response at this time for the -given connection. It also increments the internal reference -counter for the response object (the counter will be decremented -automatically once the response has been transmitted). - -@table @var -@item connection -the connection identifying the client; - -@item status_code -@http{} status code (i.e. @code{200} for OK); - -@item response -response to transmit. -@end table - -Return @code{MHD_YES} on success or if message has been queued. Return -@code{MHD_NO}: if arguments are invalid (example: @mynull{} pointer); on -error (i.e. reply already sent). -@end deftypefun - - -@deftypefun void MHD_destroy_response (struct MHD_Response *response) -Destroy a response object and associated resources (decrement the -reference counter). Note that @mhd{} may keep some of the resources -around if the response is still in the queue for some clients, so the -memory may not necessarily be freed immediately. -@end deftypefun - - -An explanation of reference counting@footnote{Note to readers acquainted -to the Tcl @api{}: reference counting on @code{MHD_Connection} -structures is handled in the same way as Tcl handles @code{Tcl_Obj} -structures through @cfunction{Tcl_IncrRefCount} and -@cfunction{Tcl_DecrRefCount}.}: - -@enumerate -@item -a @code{MHD_Response} object is allocated: - -@example -struct MHD_Response * response = MHD_create_response_from_buffer(...); -/* here: reference counter = 1 */ -@end example - -@item -the @code{MHD_Response} object is enqueued in a @code{MHD_Connection}: - -@example -MHD_queue_response(connection, , response); -/* here: reference counter = 2 */ -@end example - -@item -the creator of the response object discharges responsibility for it: - -@example -MHD_destroy_response(response); -/* here: reference counter = 1 */ -@end example - -@item -the daemon handles the connection sending the response's data to the -client then decrements the reference counter by calling -@cfunction{MHD_destroy_response}: the counter's value drops to zero and -the @code{MHD_Response} object is released. -@end enumerate - - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-response create -@section Creating a response object - - -@deftypefun {struct MHD_Response *} MHD_create_response_from_callback (uint64_t size, size_t block_size, MHD_ContentReaderCallback crc, void *crc_cls, MHD_ContentReaderFreeCallback crfc) -Create a response object. The response object can be extended with -header information and then it can be used any number of times. - -@table @var -@item size -size of the data portion of the response, @code{-1} for unknown; - -@item block_size -preferred block size for querying @var{crc} (advisory only, @mhd{} may -still call @var{crc} using smaller chunks); this is essentially the -buffer size used for @acronym{IO}, clients should pick a value that is -appropriate for @acronym{IO} and memory performance requirements; - -@item crc -callback to use to obtain response data; - -@item crc_cls -extra argument to @var{crc}; - -@item crfc -callback to call to free @var{crc_cls} resources. -@end table - -Return @mynull{} on error (i.e. invalid arguments, out of memory). -@end deftypefun - - - -@deftypefun {struct MHD_Response *} MHD_create_response_from_fd (uint64_t size, int fd) -Create a response object. The response object can be extended with -header information and then it can be used any number of times. - -@table @var -@item size -size of the data portion of the response (should be smaller or equal to the -size of the file) - -@item fd -file descriptor referring to a file on disk with the data; will be -closed when response is destroyed; note that 'fd' must be an actual -file descriptor (not a pipe or socket) since MHD might use 'sendfile' -or 'seek' on it. The descriptor should be in blocking-IO mode. -@end table - -Return @mynull{} on error (i.e. invalid arguments, out of memory). -@end deftypefun - - -@deftypefun {struct MHD_Response *} MHD_create_response_from_fd_at_offset (uint64_t size, int fd, off_t offset) -Create a response object. The response object can be extended with -header information and then it can be used any number of times. -Note that you need to be a bit careful about @code{off_t} when -writing this code. Depending on your platform, @mhd{} is likely -to have been compiled with support for 64-bit files. When you -compile your own application, you must make sure that @code{off_t} -is also a 64-bit value. If not, your compiler may pass a 32-bit -value as @code{off_t}, which will result in 32-bits of garbage. - -If you use the autotools, use the @code{AC_SYS_LARGEFILE} autoconf -macro and make sure to include the generated @file{config.h} file -before @file{microhttpd.h} to avoid problems. If you do not have a -build system and only want to run on a GNU/Linux system, you could -also use -@verbatim -#define _FILE_OFFSET_BITS 64 -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <microhttpd.h> -@end verbatim -to ensure 64-bit @code{off_t}. Note that if your operating system -does not support 64-bit files, @mhd{} will be compiled with a 32-bit -@code{off_t} (in which case the above would be wrong...). - -@table @var -@item size -size of the data portion of the response (number of bytes to transmit from the -file starting at offset). - -@item fd -file descriptor referring to a file on disk with the data; will be -closed when response is destroyed; note that 'fd' must be an actual -file descriptor (not a pipe or socket) since MHD might use 'sendfile' -or 'seek' on it. The descriptor should be in blocking-IO mode. - -@item offset -offset to start reading from in the file -@end table - -Return @mynull{} on error (i.e. invalid arguments, out of memory). -@end deftypefun - - -@deftypefun {struct MHD_Response *} MHD_create_response_from_buffer (size_t size, void *data, enum MHD_ResponseMemoryMode mode) -Create a response object. The response object can be extended with -header information and then it can be used any number of times. - -@table @var -@item size -size of the data portion of the response; - -@item buffer -the data itself; - -@item mode -memory management options for buffer; use -MHD_RESPMEM_PERSISTENT if the buffer is static/global memory, -use MHD_RESPMEM_MUST_FREE if the buffer is heap-allocated and -should be freed by @mhd{} and MHD_RESPMEM_MUST_COPY if the -buffer is in transient memory (i.e. on the stack) and must -be copied by @mhd{}; -@end table - -Return @mynull{} on error (i.e. invalid arguments, out of memory). -@end deftypefun - - -@deftypefun {struct MHD_Response *} MHD_create_response_from_data (size_t size, void *data, int must_free, int must_copy) -Create a response object. The response object can be extended with -header information and then it can be used any number of times. -This function is deprecated, use @code{MHD_create_response_from_buffer} instead. - -@table @var -@item size -size of the data portion of the response; - -@item data -the data itself; - -@item must_free -if true: @mhd{} should free data when done; - -@item must_copy -if true: @mhd{} allocates a block of memory and use it to make a copy of -@var{data} embedded in the returned @code{MHD_Response} structure; -handling of the embedded memory is responsibility of @mhd{}; @var{data} -can be released anytime after this call returns. -@end table - -Return @mynull{} on error (i.e. invalid arguments, out of memory). -@end deftypefun - - -Example: create a response from a statically allocated string: - -@example -const char * data = "<html><body><p>Error!</p></body></html>"; - -struct MHD_Connection * connection = ...; -struct MHD_Response * response; - -response = MHD_create_response_from_buffer (strlen(data), data, - MHD_RESPMEM_PERSISTENT); -MHD_queue_response(connection, 404, response); -MHD_destroy_response(response); -@end example - - - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-response headers -@section Adding headers to a response - - -@deftypefun int MHD_add_response_header (struct MHD_Response *response, const char *header, const char *content) -Add a header line to the response. The strings referenced by -@var{header} and @var{content} must be zero-terminated and they are -duplicated into memory blocks embedded in @var{response}. - -Notice that the strings must not hold newlines, carriage returns or tab -chars. - -Return @code{MHD_NO} on error (i.e. invalid header or content format or -memory allocation error). -@end deftypefun - - -@deftypefun int MHD_add_response_footer (struct MHD_Response *response, const char *footer, const char *content) -Add a footer line to the response. The strings referenced by -@var{footer} and @var{content} must be zero-terminated and they are -duplicated into memory blocks embedded in @var{response}. - -Notice that the strings must not hold newlines, carriage returns or tab -chars. You can add response footers at any time before signalling the -end of the response to MHD (not just before calling 'MHD_queue_response'). -Footers are useful for adding cryptographic checksums to the reply or to -signal errors encountered during data generation. This call was introduced -in MHD 0.9.3. - -Return @code{MHD_NO} on error (i.e. invalid header or content format or -memory allocation error). -@end deftypefun - - - -@deftypefun int MHD_del_response_header (struct MHD_Response *response, const char *header, const char *content) -Delete a header (or footer) line from the response. Return @code{MHD_NO} on error -(arguments are invalid or no such header known). -@end deftypefun - - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-response inspect -@section Inspecting a response object - - -@deftypefun int MHD_get_response_headers (struct MHD_Response *response, MHD_KeyValueIterator iterator, void *iterator_cls) -Get all of the headers added to a response. - -Invoke the @var{iterator} callback for each header in the response, -using @var{iterator_cls} as first argument. Return number of entries -iterated over. @var{iterator} can be @mynull{}: in this case the function -just counts headers. - -@var{iterator} should not modify the its key and value arguments, unless -we know what we are doing. -@end deftypefun - - -@deftypefun {const char *} MHD_get_response_header (struct MHD_Response *response, const char *key) -Find and return a pointer to the value of a particular header from the -response. @var{key} must reference a zero-terminated string -representing the header to look for. The search is case sensitive. -Return @mynull{} if header does not exist or @var{key} is @mynull{}. - -We should not modify the value, unless we know what we are doing. -@end deftypefun - - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-dauth -@chapter Utilizing Authentication - -@noindent -@mhd{} support three types of client authentication. - -Basic authentication uses a simple authentication method based -on BASE64 algorithm. Username and password are exchanged in clear -between the client and the server, so this method must only be used -for non-sensitive content or when the session is protected with https. -When using basic authentication @mhd{} will have access to the clear -password, possibly allowing to create a chained authentication -toward an external authentication server. - -Digest authentication uses a one-way authentication method based -on MD5 hash algorithm. Only the hash will transit over the network, -hence protecting the user password. The nonce will prevent replay -attacks. This method is appropriate for general use, especially -when https is not used to encrypt the session. - -Client certificate authentication uses a X.509 certificate from -the client. This is the strongest authentication mechanism but it -requires the use of HTTPS. Client certificate authentication can -be used simultaneously with Basic or Digest Authentication in order -to provide a two levels authentication (like for instance separate -machine and user authentication). A code example for using -client certificates is presented in the @mhd{} tutorial. - -@menu -* microhttpd-dauth basic:: Using Basic Authentication. -* microhttpd-dauth digest:: Using Digest Authentication. -@end menu - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-dauth basic -@section Using Basic Authentication - -@deftypefun {char *} MHD_basic_auth_get_username_password (struct MHD_Connection *connection, char** password) -Get the username and password from the basic authorization header sent by the client. -Return @mynull{} if no username could be found, a pointer to the username if found. -If returned value is not @mynull{}, the value must be @code{free()}'ed. - -@var{password} reference a buffer to store the password. It can be @mynull{}. -If returned value is not @mynull{}, the value must be @code{free()}'ed. -@end deftypefun - -@deftypefun {int} MHD_queue_basic_auth_fail_response (struct MHD_Connection *connection, const char *realm, struct MHD_Response *response) -Queues a response to request basic authentication from the client. -Return @code{MHD_YES} if successful, otherwise @code{MHD_NO}. - -@var{realm} must reference to a zero-terminated string representing the realm. - -@var{response} a response structure to specify what shall be presented to the -client with a 401 HTTP status. -@end deftypefun - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-dauth digest -@section Using Digest Authentication - -@deftypefun {char *} MHD_digest_auth_get_username (struct MHD_Connection *connection) -Find and return a pointer to the username value from the request header. -Return @mynull{} if the value is not found or header does not exist. -If returned value is not @mynull{}, the value must be @code{free()}'ed. -@end deftypefun - -@deftypefun int MHD_digest_auth_check (struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout) -Checks if the provided values in the WWW-Authenticate header are valid -and sound according to RFC2716. If valid return @code{MHD_YES}, otherwise return @code{MHD_NO}. - -@var{realm} must reference to a zero-terminated string representing the realm. - -@var{username} must reference to a zero-terminated string representing the username, -it is usually the returned value from MHD_digest_auth_get_username. - -@var{password} must reference to a zero-terminated string representing the password, -most probably it will be the result of a lookup of the username against a local database. - -@var{nonce_timeout} is the amount of time in seconds for a nonce to be invalid. -Most of the time it is sound to specify 300 seconds as its values. -@end deftypefun - -@deftypefun int MHD_queue_auth_fail_response (struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale) -Queues a response to request authentication from the client, -return @code{MHD_YES} if successful, otherwise @code{MHD_NO}. - -@var{realm} must reference to a zero-terminated string representing the realm. - -@var{opaque} must reference to a zero-terminated string representing a value -that gets passed to the client and expected to be passed again to the server -as-is. This value can be a hexadecimal or base64 string. - -@var{response} a response structure to specify what shall be presented to the -client with a 401 HTTP status. - -@var{signal_stale} a value that signals "stale=true" in the response header to -indicate the invalidity of the nonce and no need to ask for authentication -parameters and only a new nonce gets generated. @code{MHD_YES} to generate a new -nonce, @code{MHD_NO} to ask for authentication parameters. -@end deftypefun - -Example: handling digest authentication requests and responses. - -@example -#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>" -#define DENIED "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>" -#define OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4" - -static int -ahc_echo (void *cls, - struct MHD_Connection *connection, - const char *url, - const char *method, - const char *version, - const char *upload_data, size_t *upload_data_size, void **ptr) -@{ - struct MHD_Response *response; - char *username; - const char *password = "testpass"; - const char *realm = "test@@example.com"; - int ret; - - username = MHD_digest_auth_get_username(connection); - if (username == NULL) - @{ - response = MHD_create_response_from_buffer(strlen (DENIED), - DENIED, - MHD_RESPMEM_PERSISTENT); - ret = MHD_queue_auth_fail_response(connection, realm, - OPAQUE, - response, - MHD_NO); - MHD_destroy_response(response); - return ret; - @} - ret = MHD_digest_auth_check(connection, realm, - username, - password, - 300); - free(username); - if ( (ret == MHD_INVALID_NONCE) || - (ret == MHD_NO) ) - @{ - response = MHD_create_response_from_buffer(strlen (DENIED), - DENIED, - MHD_RESPMEM_PERSISTENT); - if (NULL == response) - return MHD_NO; - ret = MHD_queue_auth_fail_response(connection, realm, - OPAQUE, - response, - (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO); - MHD_destroy_response(response); - return ret; - @} - response = MHD_create_response_from_buffer (strlen(PAGE), PAGE, - MHD_RESPMEM_PERSISTENT); - ret = MHD_queue_response(connection, MHD_HTTP_OK, response); - MHD_destroy_response(response); - return ret; -@} -@end example - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-post -@chapter Adding a @code{POST} processor -@cindex POST method - -@menu -* microhttpd-post api:: Programming interface for the - @code{POST} processor. -@end menu - - -@noindent -@mhd{} provides the post processor API to make it easier for applications to -parse the data of a client's @code{POST} request: the -@code{MHD_AccessHandlerCallback} will be invoked multiple times to -process data as it arrives; at each invocation a new chunk of data must -be processed. The arguments @var{upload_data} and @var{upload_data_size} -are used to reference the chunk of data. - -When @code{MHD_AccessHandlerCallback} is invoked for a new connection: -its @code{*@var{con_cls}} argument is set to @mynull{}. When @code{POST} -data comes in the upload buffer it is @strong{mandatory} to use the -@var{con_cls} to store a reference to per-connection data. The fact -that the pointer was initially @mynull{} can be used to detect that -this is a new request. - -One method to detect that a new connection was established is -to set @code{*con_cls} to an unused integer: - -@example -int -access_handler (void *cls, - struct MHD_Connection * connection, - const char *url, - const char *method, const char *version, - const char *upload_data, size_t *upload_data_size, - void **con_cls) -@{ - static int old_connection_marker; - int new_connection = (MYNULL == *con_cls); - - if (new_connection) - @{ - /* new connection with POST */ - *con_cls = &old_connection_marker; - @} - - ... -@} -@end example - -@noindent -In contrast to the previous example, for @code{POST} requests in particular, -it is more common to use the value of @code{*con_cls} to keep track of -actual state used during processing, such as the post processor (or a -struct containing a post processor): - -@example -int -access_handler (void *cls, - struct MHD_Connection * connection, - const char *url, - const char *method, const char *version, - const char *upload_data, size_t *upload_data_size, - void **con_cls) -@{ - struct MHD_PostProcessor * pp = *con_cls; - - if (pp == NULL) - @{ - pp = MHD_create_post_processor(connection, ...); - *con_cls = pp; - return MHD_YES; - @} - if (*upload_data_size) - @{ - MHD_post_process(pp, upload_data, *upload_data_size); - *upload_data_size = 0; - return MHD_YES; - @} - else - @{ - MHD_destroy_post_processor(pp); - return MHD_queue_response(...); - @} -@} -@end example - -Note that the callback from @code{MHD_OPTION_NOTIFY_COMPLETED} -should be used to destroy the post processor. This cannot be -done inside of the access handler since the connection may not -always terminate normally. - - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-post api -@section Programming interface for the @code{POST} processor -@cindex POST method - -@deftypefun {struct MHD_PostProcessor *} MHD_create_post_processor (struct MHD_Connection *connection, size_t buffer_size, MHD_PostDataIterator iterator, void *iterator_cls) -Create a PostProcessor. A PostProcessor can be used to (incrementally) -parse the data portion of a @code{POST} request. - -@table @var -@item connection -the connection on which the @code{POST} is happening (used to determine -the @code{POST} format); - -@item buffer_size -maximum number of bytes to use for internal buffering (used only for the -parsing, specifically the parsing of the keys). A tiny value (256-1024) -should be sufficient; do @strong{NOT} use a value smaller than 256; - -@item iterator -iterator to be called with the parsed data; must @strong{NOT} be -@mynull{}; - -@item iterator_cls -custom value to be used as first argument to @var{iterator}. -@end table - -Return @mynull{} on error (out of memory, unsupported encoding), otherwise -a PP handle. -@end deftypefun - - -@deftypefun int MHD_post_process (struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len) -Parse and process @code{POST} data. Call this function when @code{POST} -data is available (usually during an @code{MHD_AccessHandlerCallback}) -with the @var{upload_data} and @var{upload_data_size}. Whenever -possible, this will then cause calls to the -@code{MHD_IncrementalKeyValueIterator}. - -@table @var -@item pp -the post processor; - -@item post_data -@var{post_data_len} bytes of @code{POST} data; - -@item post_data_len -length of @var{post_data}. -@end table - -Return @code{MHD_YES} on success, @code{MHD_NO} on error -(out-of-memory, iterator aborted, parse error). -@end deftypefun - - -@deftypefun int MHD_destroy_post_processor (struct MHD_PostProcessor *pp) -Release PostProcessor resources. After this function is being called, -the PostProcessor is guaranteed to no longer call its iterator. There -is no special call to the iterator to indicate the end of the post processing -stream. After destroying the PostProcessor, the programmer should -perform any necessary work to complete the processing of the iterator. - -Return @code{MHD_YES} if processing completed nicely, @code{MHD_NO} -if there were spurious characters or formatting problems with -the post request. It is common to ignore the return value -of this function. - - -@end deftypefun - - - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -@c ------------------------------------------------------------ -@node microhttpd-info -@chapter Obtaining and modifying status information. - - -@menu -* microhttpd-info daemon:: State information about an MHD daemon -* microhttpd-info conn:: State information about a connection -* microhttpd-option conn:: Modify per-connection options -@end menu - - -@c ------------------------------------------------------------ -@node microhttpd-info daemon -@section Obtaining state information about an MHD daemon - -@deftypefun {const union MHD_DaemonInfo *} MHD_get_daemon_info (struct MHD_Daemon *daemon, enum MHD_DaemonInfoType infoType, ...) -Obtain information about the given daemon. This function -is currently not fully implemented. - -@table @var -@item daemon -the daemon about which information is desired; - -@item infoType -type of information that is desired - -@item ... -additional arguments about the desired information (depending on -infoType) -@end table - -Returns a union with the respective member (depending on -infoType) set to the desired information), or NULL -in case the desired information is not available or -applicable. -@end deftypefun - - -@deftp {Enumeration} MHD_DaemonInfoType -Values of this enum are used to specify what -information about a daemon is desired. -@table @code -@item MHD_DAEMON_INFO_KEY_SIZE -Request information about the key size for a particular cipher -algorithm. The cipher algorithm should be passed as an extra argument -(of type 'enum MHD_GNUTLS_CipherAlgorithm'). - -@item MHD_DAEMON_INFO_MAC_KEY_SIZE -Request information about the key size for a particular cipher -algorithm. The cipher algorithm should be passed as an extra argument -(of type 'enum MHD_GNUTLS_HashAlgorithm'). - -@item MHD_DAEMON_INFO_LISTEN_FD -@cindex listen -Request the file-descriptor number that MHD is using to listen to the -server socket. This can be useful if no port -was specified and a client needs to learn what port -is actually being used by MHD. -No extra arguments should be passed. - -@end table -@end deftp - - - -@c ------------------------------------------------------------ -@node microhttpd-info conn -@section Obtaining state information about a connection - - -@deftypefun {const union MHD_ConnectionInfo *} MHD_get_connection_info (struct MHD_Connection *daemon, enum MHD_ConnectionInfoType infoType, ...) -Obtain information about the given connection. - -@table @var -@item connection -the connection about which information is desired; - -@item infoType -type of information that is desired - -@item ... -additional arguments about the desired information (depending on -infoType) -@end table - -Returns a union with the respective member (depending on -infoType) set to the desired information), or NULL -in case the desired information is not available or -applicable. -@end deftypefun - -@deftp {Enumeration} MHD_ConnectionInfoType -Values of this enum are used to specify what information about a -connection is desired. - -@table @code - -@item MHD_CONNECTION_INFO_CIPHER_ALGO -What cipher algorithm is being used (HTTPS connections only). -Takes no extra arguments. -NULL is returned for non-HTTPS connections. - -@item MHD_CONNECTION_INFO_PROTOCOL, -Takes no extra arguments. Allows finding out the TLS/SSL protocol used -(HTTPS connections only). -NULL is returned for non-HTTPS connections. - -@item MHD_CONNECTION_INFO_CLIENT_ADDRESS -Returns information about the address of the client. Returns -essentially a @code{struct sockaddr **} (since the API returns -a @code{union MHD_ConnectionInfo *} and that union contains -a @code{struct sockaddr *}). - -@item MHD_CONNECTION_INFO_GNUTLS_SESSION, -Takes no extra arguments. Allows access to the underlying GNUtls session, -including access to the underlying GNUtls client certificate -(HTTPS connections only). Takes no extra arguments. -NULL is returned for non-HTTPS connections. - -@item MHD_CONNECTION_INFO_GNUTLS_CLIENT_CERT, -Dysfunctional (never implemented, deprecated). Use -MHD_CONNECTION_INFO_GNUTLS_SESSION to get the @code{gnutls_session_t} -and then call @code{gnutls_certificate_get_peers()}. - -@item MHD_CONNECTION_INFO_DAEMON -Returns information about @code{struct MHD_Daemon} which manages -this connection. - -@end table -@end deftp - - - -@c ------------------------------------------------------------ -@node microhttpd-option conn -@section Setting custom options for an individual connection -@cindex timeout - - - -@deftypefun {int} MHD_set_connection_option (struct MHD_Connection *daemon, enum MHD_CONNECTION_OPTION option, ...) -Set a custom option for the given connection. - -@table @var -@item connection -the connection for which an option should be set or modified; - -@item option -option to set - -@item ... -additional arguments for the option (depending on option) -@end table - -Returns @code{MHD_YES} on success, @code{MHD_NO} for errors -(i.e. option argument invalid or option unknown). -@end deftypefun - - -@deftp {Enumeration} MHD_CONNECTION_OPTION -Values of this enum are used to specify which option for a -connection should be changed. - -@table @code - -@item MHD_CONNECTION_OPTION_TIMEOUT -Set a custom timeout for the given connection. Specified -as the number of seconds, given as an @code{unsigned int}. Use -zero for no timeout. - -@end table -@end deftp - - -@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - -@c ********************************************************** -@c ******************* Appendices ************************* -@c ********************************************************** - -@node GNU-LGPL -@unnumbered GNU-LGPL -@cindex license -@include lgpl.texi - -@node GNU GPL with eCos Extension -@unnumbered GNU GPL with eCos Extension -@cindex license -@include ecos.texi - -@node GNU-FDL -@unnumbered GNU-FDL -@cindex license -@include fdl-1.3.texi - -@node Concept Index -@unnumbered Concept Index - -@printindex cp - -@node Function and Data Index -@unnumbered Function and Data Index - -@printindex fn - -@node Type Index -@unnumbered Type Index - -@printindex tp - -@bye diff --git a/doc/texinfo.tex b/doc/texinfo.tex @@ -3,11 +3,11 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2009-08-14.15} +\def\texinfoversion{2012-03-11.15} % % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, -% 2007, 2008, 2009 Free Software Foundation, Inc. +% 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. % % This texinfo.tex file is free software: you can redistribute it and/or % modify it under the terms of the GNU General Public License as @@ -65,7 +65,6 @@ \everyjob{\message{[Texinfo version \texinfoversion]}% \catcode`+=\active \catcode`\_=\active} - \chardef\other=12 % We never want plain's \outer definition of \+ in Texinfo. @@ -93,14 +92,13 @@ \let\ptexnewwrite\newwrite \let\ptexnoindent=\noindent \let\ptexplus=+ +\let\ptexraggedright=\raggedright \let\ptexrbrace=\} \let\ptexslash=\/ \let\ptexstar=\* \let\ptext=\t \let\ptextop=\top -{\catcode`\'=\active -\global\let\ptexquoteright'}% Math-mode def from plain.tex. -\let\ptexraggedright=\raggedright +{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode % If this character appears in an error message or help string, it % starts a new line in the output. @@ -118,10 +116,11 @@ % Set up fixed words for English if not already set. \ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi \ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi +\ifx\putworderror\undefined \gdef\putworderror{error}\fi \ifx\putwordfile\undefined \gdef\putwordfile{file}\fi \ifx\putwordin\undefined \gdef\putwordin{in}\fi -\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi -\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi +\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi +\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi \ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi \ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi \ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi @@ -160,15 +159,18 @@ \def\spaceisspace{\catcode`\ =\spacecat} % sometimes characters are active, so we need control sequences. +\chardef\ampChar = `\& \chardef\colonChar = `\: \chardef\commaChar = `\, \chardef\dashChar = `\- \chardef\dotChar = `\. \chardef\exclamChar= `\! +\chardef\hashChar = `\# \chardef\lquoteChar= `\` \chardef\questChar = `\? \chardef\rquoteChar= `\' \chardef\semiChar = `\; +\chardef\slashChar = `\/ \chardef\underChar = `\_ % Ignore a token. @@ -199,36 +201,7 @@ % that mark overfull boxes (in case you have decided % that the text looks ok even though it passes the margin). % -\def\finalout{\overfullrule=0pt} - -% @| inserts a changebar to the left of the current line. It should -% surround any changed text. This approach does *not* work if the -% change spans more than two lines of output. To handle that, we would -% have adopt a much more difficult approach (putting marks into the main -% vertical list for the beginning and end of each change). -% -\def\|{% - % \vadjust can only be used in horizontal mode. - \leavevmode - % - % Append this vertical mode material after the current line in the output. - \vadjust{% - % We want to insert a rule with the height and depth of the current - % leading; that is exactly what \strutbox is supposed to record. - \vskip-\baselineskip - % - % \vadjust-items are inserted at the left edge of the type. So - % the \llap here moves out into the left-hand margin. - \llap{% - % - % For a thicker or thinner bar, change the `1pt'. - \vrule height\baselineskip width1pt - % - % This is the space between the bar and the text. - \hskip 12pt - }% - }% -} +\def\finalout{\overfullrule=0pt } % Sometimes it is convenient to have everything in the transcript file % and nothing on the terminal. We don't just call \tracingall here, @@ -246,7 +219,7 @@ \tracingmacros2 \tracingrestores1 \showboxbreadth\maxdimen \showboxdepth\maxdimen - \ifx\eTeXversion\undefined\else % etex gives us more logging + \ifx\eTeXversion\thisisundefined\else % etex gives us more logging \tracingscantokens1 \tracingifs1 \tracinggroups1 @@ -257,6 +230,13 @@ \errorcontextlines16 }% +% @errormsg{MSG}. Do the index-like expansions on MSG, but if things +% aren't perfect, it's not the end of the world, being an error message, +% after all. +% +\def\errormsg{\begingroup \indexnofonts \doerrormsg} +\def\doerrormsg#1{\errmessage{#1}} + % add check for \lastpenalty to plain's definitions. If the last thing % we did was a \nobreak, we don't want to insert more space. % @@ -267,7 +247,6 @@ \def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount \removelastskip\penalty-200\bigskip\fi\fi} -% For @cropmarks command. % Do @cropmarks to get crop marks. % \newif\ifcropmarks @@ -577,7 +556,7 @@ } \def\inenvironment#1{% \ifx#1\empty - out of any environment% + outside of any environment% \else in environment \expandafter\string#1% \fi @@ -589,7 +568,7 @@ \parseargdef\end{% \if 1\csname iscond.#1\endcsname \else - % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03 + % The general wording of \badenverr may not be ideal. \expandafter\checkenv\csname#1\endcsname \csname E#1\endcsname \endgroup @@ -599,85 +578,6 @@ \newhelp\EMsimple{Press RETURN to continue.} -%% Simple single-character @ commands - -% @@ prints an @ -% Kludge this until the fonts are right (grr). -\def\@{{\tt\char64}} - -% This is turned off because it was never documented -% and you can use @w{...} around a quote to suppress ligatures. -%% Define @` and @' to be the same as ` and ' -%% but suppressing ligatures. -%\def\`{{`}} -%\def\'{{'}} - -% Used to generate quoted braces. -\def\mylbrace {{\tt\char123}} -\def\myrbrace {{\tt\char125}} -\let\{=\mylbrace -\let\}=\myrbrace -\begingroup - % Definitions to produce \{ and \} commands for indices, - % and @{ and @} for the aux/toc files. - \catcode`\{ = \other \catcode`\} = \other - \catcode`\[ = 1 \catcode`\] = 2 - \catcode`\! = 0 \catcode`\\ = \other - !gdef!lbracecmd[\{]% - !gdef!rbracecmd[\}]% - !gdef!lbraceatcmd[@{]% - !gdef!rbraceatcmd[@}]% -!endgroup - -% @comma{} to avoid , parsing problems. -\let\comma = , - -% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent -% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. -\let\, = \c -\let\dotaccent = \. -\def\ringaccent#1{{\accent23 #1}} -\let\tieaccent = \t -\let\ubaraccent = \b -\let\udotaccent = \d - -% Other special characters: @questiondown @exclamdown @ordf @ordm -% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. -\def\questiondown{?`} -\def\exclamdown{!`} -\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}} -\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}} - -% Dotless i and dotless j, used for accents. -\def\imacro{i} -\def\jmacro{j} -\def\dotless#1{% - \def\temp{#1}% - \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi - \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi - \else \errmessage{@dotless can be used only with i or j}% - \fi\fi -} - -% The \TeX{} logo, as in plain, but resetting the spacing so that a -% period following counts as ending a sentence. (Idea found in latex.) -% -\edef\TeX{\TeX \spacefactor=1000 } - -% @LaTeX{} logo. Not quite the same results as the definition in -% latex.ltx, since we use a different font for the raised A; it's most -% convenient for us to use an explicitly smaller font, rather than using -% the \scriptstyle font (since we don't reset \scriptstyle and -% \scriptscriptstyle). -% -\def\LaTeX{% - L\kern-.36em - {\setbox0=\hbox{T}% - \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}% - \kern-.15em - \TeX -} - % Be sure we're in horizontal mode when doing a tie, since we make space % equivalent to this in @example-like environments. Otherwise, a space % at the beginning of a line will start with \penalty -- and @@ -719,7 +619,7 @@ \else\ifx\temp\offword \plainnonfrenchspacing \else \errhelp = \EMsimple - \errmessage{Unknown @frenchspacing option `\temp', must be on/off}% + \errmessage{Unknown @frenchspacing option `\temp', must be on|off}% \fi\fi } @@ -801,15 +701,6 @@ where each line of input produces a line of output.} \newdimen\mil \mil=0.001in -% Old definition--didn't work. -%\parseargdef\need{\par % -%% This method tries to make TeX break the page naturally -%% if the depth of the box does not fit. -%{\baselineskip=0pt% -%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak -%\prevdepth=-1000pt -%}} - \parseargdef\need{% % Ensure vertical mode, so we don't make a big box in the middle of a % paragraph. @@ -873,7 +764,7 @@ where each line of input produces a line of output.} % @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current % paragraph. For more general purposes, use the \margin insertion -% class. WHICH is `l' or `r'. +% class. WHICH is `l' or `r'. Not documented, written for gawk manual. % \newskip\inmarginspacing \inmarginspacing=1cm \def\strutdepth{\dp\strutbox} @@ -920,6 +811,36 @@ where each line of input produces a line of output.} \temp } +% @| inserts a changebar to the left of the current line. It should +% surround any changed text. This approach does *not* work if the +% change spans more than two lines of output. To handle that, we would +% have adopt a much more difficult approach (putting marks into the main +% vertical list for the beginning and end of each change). This command +% is not documented, not supported, and doesn't work. +% +\def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% +} + % @include FILE -- \input text of FILE. % \def\include{\parseargusing\filenamecatcodes\includezzz} @@ -930,6 +851,7 @@ where each line of input produces a line of output.} \makevalueexpandable % we want to expand any @value in FILE. \turnoffactive % and allow special characters in the expansion \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @include of #1^^J}% \edef\temp{\noexpand\input #1 }% % % This trickery is to read FILE outside of a group, in case it makes @@ -965,7 +887,7 @@ where each line of input produces a line of output.} \def\popthisfilestack{\errthisfilestackempty} \def\errthisfilestackempty{\errmessage{Internal error: the stack of filenames is empty.}} - +% \def\thisfile{} % @center line @@ -973,36 +895,46 @@ where each line of input produces a line of output.} % \parseargdef\center{% \ifhmode - \let\next\centerH + \let\centersub\centerH \else - \let\next\centerV + \let\centersub\centerV \fi - \next{\hfil \ignorespaces#1\unskip \hfil}% + \centersub{\hfil \ignorespaces#1\unskip \hfil}% + \let\centersub\relax % don't let the definition persist, just in case } -\def\centerH#1{% - {% - \hfil\break - \advance\hsize by -\leftskip - \advance\hsize by -\rightskip - \line{#1}% - \break - }% +\def\centerH#1{{% + \hfil\break + \advance\hsize by -\leftskip + \advance\hsize by -\rightskip + \line{#1}% + \break +}} +% +\newcount\centerpenalty +\def\centerV#1{% + % The idea here is the same as in \startdefun, \cartouche, etc.: if + % @center is the first thing after a section heading, we need to wipe + % out the negative parskip inserted by \sectionheading, but still + % prevent a page break here. + \centerpenalty = \lastpenalty + \ifnum\centerpenalty>10000 \vskip\parskip \fi + \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi + \line{\kern\leftskip #1\kern\rightskip}% } -\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}} % @sp n outputs n lines of vertical space - +% \parseargdef\sp{\vskip #1\baselineskip} % @comment ...line which is ignored... % @c is the same as @comment % @ignore ... @end ignore is another way to write a comment - +% \def\comment{\begingroup \catcode`\^^M=\other% \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% \commentxxx} {\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} - +% \let\c=\comment % @paragraphindent NCHARS @@ -1095,109 +1027,6 @@ where each line of input produces a line of output.} } -% @asis just yields its argument. Used with @table, for example. -% -\def\asis#1{#1} - -% @math outputs its argument in math mode. -% -% One complication: _ usually means subscripts, but it could also mean -% an actual _ character, as in @math{@var{some_variable} + 1}. So make -% _ active, and distinguish by seeing if the current family is \slfam, -% which is what @var uses. -{ - \catcode`\_ = \active - \gdef\mathunderscore{% - \catcode`\_=\active - \def_{\ifnum\fam=\slfam \_\else\sb\fi}% - } -} -% Another complication: we want \\ (and @\) to output a \ character. -% FYI, plain.tex uses \\ as a temporary control sequence (why?), but -% this is not advertised and we don't care. Texinfo does not -% otherwise define @\. -% -% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. -\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} -% -\def\math{% - \tex - \mathunderscore - \let\\ = \mathbackslash - \mathactive - % make the texinfo accent commands work in math mode - \let\"=\ddot - \let\'=\acute - \let\==\bar - \let\^=\hat - \let\`=\grave - \let\u=\breve - \let\v=\check - \let\~=\tilde - \let\dotaccent=\dot - $\finishmath -} -\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. - -% Some active characters (such as <) are spaced differently in math. -% We have to reset their definitions in case the @math was an argument -% to a command which sets the catcodes (such as @item or @section). -% -{ - \catcode`^ = \active - \catcode`< = \active - \catcode`> = \active - \catcode`+ = \active - \catcode`' = \active - \gdef\mathactive{% - \let^ = \ptexhat - \let< = \ptexless - \let> = \ptexgtr - \let+ = \ptexplus - \let' = \ptexquoteright - } -} - -% Some math mode symbols. -\def\bullet{$\ptexbullet$} -\def\geq{\ifmmode \ge\else $\ge$\fi} -\def\leq{\ifmmode \le\else $\le$\fi} -\def\minus{\ifmmode -\else $-$\fi} - -% @dots{} outputs an ellipsis using the current font. -% We do .5em per period so that it has the same spacing in the cm -% typewriter fonts as three actual period characters; on the other hand, -% in other typewriter fonts three periods are wider than 1.5em. So do -% whichever is larger. -% -\def\dots{% - \leavevmode - \setbox0=\hbox{...}% get width of three periods - \ifdim\wd0 > 1.5em - \dimen0 = \wd0 - \else - \dimen0 = 1.5em - \fi - \hbox to \dimen0{% - \hskip 0pt plus.25fil - .\hskip 0pt plus1fil - .\hskip 0pt plus1fil - .\hskip 0pt plus.5fil - }% -} - -% @enddots{} is an end-of-sentence ellipsis. -% -\def\enddots{% - \dots - \spacefactor=\endofsentencespacefactor -} - -% @comma{} is so commas can be inserted into text without messing up -% Texinfo's parsing. -% -\let\comma = , - % @refill is a no-op. \let\refill=\relax @@ -1262,9 +1091,8 @@ where each line of input produces a line of output.} \newif\ifpdfmakepagedest % when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 -% can be set). So we test for \relax and 0 as well as \undefined, -% borrowed from ifpdf.sty. -\ifx\pdfoutput\undefined +% can be set). So we test for \relax and 0 as well as being undefined. +\ifx\pdfoutput\thisisundefined \else \ifx\pdfoutput\relax \else @@ -1279,50 +1107,24 @@ where each line of input produces a line of output.} % for display in the outlines, and in other places. Thus, we have to % double any backslashes. Otherwise, a name like "\node" will be % interpreted as a newline (\n), followed by o, d, e. Not good. -% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html -% (and related messages, the final outcome is that it is up to the TeX -% user to double the backslashes and otherwise make the string valid, so -% that's what we do). - -% double active backslashes. -% -{\catcode`\@=0 \catcode`\\=\active - @gdef@activebackslashdouble{% - @catcode`@\=@active - @let\=@doublebackslash} -} - -% To handle parens, we must adopt a different approach, since parens are -% not active characters. hyperref.dtx (which has the same problem as -% us) handles it with this amazing macro to replace tokens, with minor -% changes for Texinfo. It is included here under the GPL by permission -% from the author, Heiko Oberdiek. -% -% #1 is the tokens to replace. -% #2 is the replacement. -% #3 is the control sequence with the string. -% -\def\HyPsdSubst#1#2#3{% - \def\HyPsdReplace##1#1##2\END{% - ##1% - \ifx\\##2\\% - \else - #2% - \HyReturnAfterFi{% - \HyPsdReplace##2\END - }% - \fi - }% - \xdef#3{\expandafter\HyPsdReplace#3#1\END}% -} -\long\def\HyReturnAfterFi#1\fi{\fi#1} - -% #1 is a control sequence in which to do the replacements. -\def\backslashparens#1{% - \xdef#1{#1}% redefine it as its expansion; the definition is simply - % \lastnode when called from \setref -> \pdfmkdest. - \HyPsdSubst{(}{\realbackslash(}{#1}% - \HyPsdSubst{)}{\realbackslash)}{#1}% +% +% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and +% related messages. The final outcome is that it is up to the TeX user +% to double the backslashes and otherwise make the string valid, so +% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to +% do this reliably, so we use it. + +% #1 is a control sequence in which to do the replacements, +% which we \xdef. +\def\txiescapepdf#1{% + \ifx\pdfescapestring\relax + % No primitive available; should we give a warning or log? + % Many times it won't matter. + \else + % The expandable \pdfescapestring primitive escapes parentheses, + % backslashes, and other special chars. + \xdef#1{\pdfescapestring{#1}}% + \fi } \newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images @@ -1381,32 +1183,34 @@ output) for that.)} % % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). \def\dopdfimage#1#2#3{% - \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% - \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% % - % pdftex (and the PDF format) support .png, .jpg, .pdf (among - % others). Let's try in that order. + % pdftex (and the PDF format) support .pdf, .png, .jpg (among + % others). Let's try in that order, PDF first since if + % someone has a scalable image, presumably better to use that than a + % bitmap. \let\pdfimgext=\empty \begingroup - \openin 1 #1.png \ifeof 1 - \openin 1 #1.jpg \ifeof 1 - \openin 1 #1.jpeg \ifeof 1 - \openin 1 #1.JPG \ifeof 1 - \openin 1 #1.pdf \ifeof 1 - \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 \errhelp = \nopdfimagehelp \errmessage{Could not find image file #1 for pdf}% - \else \gdef\pdfimgext{PDF}% + \else \gdef\pdfimgext{JPG}% \fi - \else \gdef\pdfimgext{pdf}% + \else \gdef\pdfimgext{jpeg}% \fi - \else \gdef\pdfimgext{JPG}% + \else \gdef\pdfimgext{jpg}% \fi - \else \gdef\pdfimgext{jpeg}% + \else \gdef\pdfimgext{png}% \fi - \else \gdef\pdfimgext{jpg}% + \else \gdef\pdfimgext{PDF}% \fi - \else \gdef\pdfimgext{png}% + \else \gdef\pdfimgext{pdf}% \fi \closein 1 \endgroup @@ -1418,8 +1222,8 @@ output) for that.)} \else \immediate\pdfximage \fi - \ifdim \wd0 >0pt width \imagewidth \fi - \ifdim \wd2 >0pt height \imageheight \fi + \ifdim \wd0 >0pt width \pdfimagewidth \fi + \ifdim \wd2 >0pt height \pdfimageheight \fi \ifnum\pdftexversion<13 #1.\pdfimgext \else @@ -1434,10 +1238,9 @@ output) for that.)} % such as \, aren't expanded when present in a section title. \indexnofonts \turnoffactive - \activebackslashdouble \makevalueexpandable \def\pdfdestname{#1}% - \backslashparens\pdfdestname + \txiescapepdf\pdfdestname \safewhatsit{\pdfdest name{\pdfdestname} xyz}% }} % @@ -1469,29 +1272,24 @@ output) for that.)} % page number. We could generate a destination for the section % text in the case where a section has no node, but it doesn't % seem worth the trouble, since most documents are normally structured. - \def\pdfoutlinedest{#3}% + \edef\pdfoutlinedest{#3}% \ifx\pdfoutlinedest\empty \def\pdfoutlinedest{#4}% \else - % Doubled backslashes in the name. - {\activebackslashdouble \xdef\pdfoutlinedest{#3}% - \backslashparens\pdfoutlinedest}% + \txiescapepdf\pdfoutlinedest \fi % - % Also double the backslashes in the display string. - {\activebackslashdouble \xdef\pdfoutlinetext{#1}% - \backslashparens\pdfoutlinetext}% + % Also escape PDF chars in the display string. + \edef\pdfoutlinetext{#1}% + \txiescapepdf\pdfoutlinetext % \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}% } % \def\pdfmakeoutlines{% \begingroup - % Thanh's hack / proper braces in bookmarks - \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace - \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace - % % Read toc silently, to get counts of subentries for \pdfoutline. + \def\partentry##1##2##3##4{}% ignore parts in the outlines \def\numchapentry##1##2##3##4{% \def\thischapnum{##2}% \def\thissecnum{0}% @@ -1545,15 +1343,26 @@ output) for that.)} % Latin 2 (0xea) gets translated to a | character. Info from % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. % - % xx to do this right, we have to translate 8-bit characters to - % their "best" equivalent, based on the @documentencoding. Right - % now, I guess we'll just let the pdf reader have its way. + % TODO this right, we have to translate 8-bit characters to + % their "best" equivalent, based on the @documentencoding. Too + % much work for too little return. Just use the ASCII equivalents + % we use for the index sort strings. + % \indexnofonts \setupdatafile + % We can have normal brace characters in the PDF outlines, unlike + % Texinfo index files. So set that up. + \def\{{\lbracecharliteral}% + \def\}{\rbracecharliteral}% \catcode`\\=\active \otherbackslash \input \tocreadfilename \endgroup } + {\catcode`[=1 \catcode`]=2 + \catcode`{=\other \catcode`}=\other + \gdef\lbracecharliteral[{]% + \gdef\rbracecharliteral[}]% + ] % \def\skipspaces#1{\def\PP{#1}\def\D{|}% \ifx\PP\D\let\nextsp\relax @@ -1563,7 +1372,13 @@ output) for that.)} \fi \fi \nextsp} - \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} + \def\getfilename#1{% + \filenamelength=0 + % If we don't expand the argument now, \skipspaces will get + % snagged on things like "@value{foo}". + \edef\temp{#1}% + \expandafter\skipspaces\temp|\relax + } \ifnum\pdftexversion < 14 \let \startlink \pdfannotlink \else @@ -1695,7 +1510,7 @@ output) for that.)} % if we are producing pdf, and we have \pdffontattr, then define cmaps. % (\pdffontattr was introduced many years ago, but people still run % older pdftex's; it's easy to conditionalize, so we do.) -\ifpdf \ifx\pdffontattr\undefined \else +\ifpdf \ifx\pdffontattr\thisisundefined \else \begingroup \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap @@ -1962,7 +1777,7 @@ end % Use cm as the default font prefix. % To specify the font prefix, you must define \fontprefix % before you read in texinfo.tex. -\ifx\fontprefix\undefined +\ifx\fontprefix\thisisundefined \def\fontprefix{cm} \fi % Support font families that don't use the same naming scheme as CM. @@ -2105,8 +1920,8 @@ end \font\reducedsy=cmsy10 \def\reducedecsize{1000} -% reset the current fonts -\textfonts +\textleading = 13.2pt % line spacing for 11pt CM +\textfonts % reset the current fonts \rm } % end of 11pt text font size definitions @@ -2236,11 +2051,9 @@ end \font\reducedsy=cmsy9 \def\reducedecsize{0900} -% reduce space between paragraphs -\divide\parskip by 2 - -% reset the current fonts -\textfonts +\divide\parskip by 2 % reduce space between paragraphs +\textleading = 12pt % line spacing for 10pt CM +\textfonts % reset the current fonts \rm } % end of 10pt text font size definitions @@ -2249,12 +2062,13 @@ end % @fonttextsize 10 % (or 11) to redefine the text font size. pt is assumed. % -\def\xword{10} \def\xiword{11} +\def\xword{10} +\def\xwordpt{10pt} % \parseargdef\fonttextsize{% \def\textsizearg{#1}% - \wlog{doing @fonttextsize \textsizearg}% + %\wlog{doing @fonttextsize \textsizearg}% % % Set \globaldefs so that documents can use this inside @tex, since % makeinfo 4.8 does not support it, but we need it nonetheless. @@ -2308,7 +2122,7 @@ end \let\tenttsl=\titlettsl \def\curfontsize{title}% \def\lsize{chap}\def\lllsize{subsec}% - \resetmathfonts \setleading{25pt}} + \resetmathfonts \setleading{27pt}} \def\titlefont#1{{\titlefonts\rmisbold #1}} \def\chapfonts{% \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl @@ -2436,12 +2250,14 @@ end % Markup style setup for left and right quotes. \defmarkupstylesetup\markupsetuplq{% - \expandafter\let\expandafter \temp \csname markupsetuplq\currentmarkupstyle\endcsname + \expandafter\let\expandafter \temp + \csname markupsetuplq\currentmarkupstyle\endcsname \ifx\temp\relax \markupsetuplqdefault \else \temp \fi } \defmarkupstylesetup\markupsetuprq{% - \expandafter\let\expandafter \temp \csname markupsetuprq\currentmarkupstyle\endcsname + \expandafter\let\expandafter \temp + \csname markupsetuprq\currentmarkupstyle\endcsname \ifx\temp\relax \markupsetuprqdefault \else \temp \fi } @@ -2460,22 +2276,26 @@ end \let\markupsetuplqcode \markupsetcodequoteleft \let\markupsetuprqcode \markupsetcodequoteright +% \let\markupsetuplqexample \markupsetcodequoteleft \let\markupsetuprqexample \markupsetcodequoteright +% +\let\markupsetuplqsamp \markupsetcodequoteleft +\let\markupsetuprqsamp \markupsetcodequoteright +% \let\markupsetuplqverb \markupsetcodequoteleft \let\markupsetuprqverb \markupsetcodequoteright +% \let\markupsetuplqverbatim \markupsetcodequoteleft \let\markupsetuprqverbatim \markupsetcodequoteright -\let\markupsetuplqsamp \markupsetnoligaturesquoteleft \let\markupsetuplqkbd \markupsetnoligaturesquoteleft -% Allow an option to not replace quotes with a regular directed right -% quote/apostrophe (char 0x27), but instead use the undirected quote -% from cmtt (char 0x0d). The undirected quote is ugly, so don't make it -% the default, but it works for pasting with more pdf viewers (at least -% evince), the lilypond developers report. xpdf does work with the -% regular 0x27. +% Allow an option to not use regular directed right quote/apostrophe +% (char 0x27), but instead the undirected quote from cmtt (char 0x0d). +% The undirected quote is ugly, so don't make it the default, but it +% works for pasting with more pdf viewers (at least evince), the +% lilypond developers report. xpdf does work with the regular 0x27. % \def\codequoteright{% \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax @@ -2499,33 +2319,84 @@ end \else \char'22 \fi } -% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font. +% Commands to set the quote options. +% +\parseargdef\codequoteundirected{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}% + \fi\fi +} +% +\parseargdef\codequotebacktick{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}% + \fi\fi +} + +% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font. \def\noligaturesquoteleft{\relax\lq} % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 -%% Add scribe-like font environments, plus @l for inline lisp (usually sans -%% serif) and @ii for TeX italic +% Font commands. -% \smartitalic{ARG} outputs arg in italics, followed by an italic correction -% unless the following character is such as not to need one. -\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else - \ptexslash\fi\fi\fi} -\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx} -\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx} +% #1 is the font command (\sl or \it), #2 is the text to slant. +% If we are in a monospaced environment, however, 1) always use \ttsl, +% and 2) do not add an italic correction. +\def\dosmartslant#1#2{% + \ifusingtt + {{\ttsl #2}\let\next=\relax}% + {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}% + \next +} +\def\smartslanted{\dosmartslant\sl} +\def\smartitalic{\dosmartslant\it} + +% Output an italic correction unless \next (presumed to be the following +% character) is such as not to need one. +\def\smartitaliccorrection{% + \ifx\next,% + \else\ifx\next-% + \else\ifx\next.% + \else\ptexslash + \fi\fi\fi + \aftersmartic +} -% like \smartslanted except unconditionally uses \ttsl. +% like \smartslanted except unconditionally uses \ttsl, and no ic. % @var is set to this for defun arguments. -\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx} +\def\ttslanted#1{{\ttsl #1}} % @cite is like \smartslanted except unconditionally use \sl. We never want % ttsl for book titles, do we? -\def\cite#1{{\sl #1}\futurelet\next\smartitalicx} +\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection} + +\def\aftersmartic{} +\def\var#1{% + \let\saveaftersmartic = \aftersmartic + \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}% + \smartslanted{#1}% +} \let\i=\smartitalic \let\slanted=\smartslanted -\def\var#1{{\setupmarkupstyle{var}\smartslanted{#1}}} \let\dfn=\smartslanted \let\emph=\smartitalic @@ -2621,7 +2492,7 @@ end \plainfrenchspacing #1% }% - \null + \null % reset spacefactor to 1000 } % We *must* turn on hyphenation at `-' and `_' in @code. @@ -2653,6 +2524,8 @@ end } } +\def\codex #1{\tclose{#1}\endgroup} + \def\realdash{-} \def\codedash{-\discretionary{}{}{}} \def\codeunder{% @@ -2666,7 +2539,6 @@ end \discretionary{}{}{}}% {\_}% } -\def\codex #1{\tclose{#1}\endgroup} % An additional complication: the above will allow breaks after, e.g., % each of the four underscores in __typeof__. This is undesirable in @@ -2686,10 +2558,156 @@ end \allowcodebreaksfalse \else \errhelp = \EMsimple - \errmessage{Unknown @allowcodebreaks option `\txiarg'}% + \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}% \fi\fi } +% @uref (abbreviation for `urlref') takes an optional (comma-separated) +% second argument specifying the text to display and an optional third +% arg as text to display instead of (rather than in addition to) the url +% itself. First (mandatory) arg is the url. +% (This \urefnobreak definition isn't used now, leaving it for a while +% for comparison.) +\def\urefnobreak#1{\dourefnobreak #1,,,\finish} +\def\dourefnobreak#1,#2,#3,#4\finish{\begingroup + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \code{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% This \urefbreak definition is the active one. +\def\urefbreak{\begingroup \urefcatcodes \dourefbreak} +\let\uref=\urefbreak +\def\dourefbreak#1{\urefbreakfinish #1,,,\finish} +\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \urefcode{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% Allow line breaks around only a few characters (only). +\def\urefcatcodes{% + \catcode\ampChar=\active \catcode\dotChar=\active + \catcode\hashChar=\active \catcode\questChar=\active + \catcode\slashChar=\active +} +{ + \urefcatcodes + % + \global\def\urefcode{\begingroup + \setupmarkupstyle{code}% + \urefcatcodes + \let&\urefcodeamp + \let.\urefcodedot + \let#\urefcodehash + \let?\urefcodequest + \let/\urefcodeslash + \codex + } + % + % By default, they are just regular characters. + \global\def&{\normalamp} + \global\def.{\normaldot} + \global\def#{\normalhash} + \global\def?{\normalquest} + \global\def/{\normalslash} +} + +% we put a little stretch before and after the breakable chars, to help +% line breaking of long url's. The unequal skips make look better in +% cmtt at least, especially for dots. +\def\urefprestretch{\urefprebreak \hskip0pt plus.13em } +\def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em } +% +\def\urefcodeamp{\urefprestretch \&\urefpoststretch} +\def\urefcodedot{\urefprestretch .\urefpoststretch} +\def\urefcodehash{\urefprestretch \#\urefpoststretch} +\def\urefcodequest{\urefprestretch ?\urefpoststretch} +\def\urefcodeslash{\futurelet\next\urefcodeslashfinish} +{ + \catcode`\/=\active + \global\def\urefcodeslashfinish{% + \urefprestretch \slashChar + % Allow line break only after the final / in a sequence of + % slashes, to avoid line break between the slashes in http://. + \ifx\next/\else \urefpoststretch \fi + } +} + +% One more complication: by default we'll break after the special +% characters, but some people like to break before the special chars, so +% allow that. Also allow no breaking at all, for manual control. +% +\parseargdef\urefbreakstyle{% + \def\txiarg{#1}% + \ifx\txiarg\wordnone + \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordbefore + \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordafter + \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak} + \else + \errhelp = \EMsimple + \errmessage{Unknown @urefbreakstyle setting `\txiarg'}% + \fi\fi\fi +} +\def\wordafter{after} +\def\wordbefore{before} +\def\wordnone{none} + +\urefbreakstyle after + +% @url synonym for @uref, since that's how everyone uses it. +% +\let\url=\uref + +% rms does not like angle brackets --karl, 17may97. +% So now @email is just like @uref, unless we are pdf. +% +%\def\email#1{\angleleft{\tt #1}\angleright} +\ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} +\else + \let\email=\uref +\fi + % @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. \def\kbd#1{{\setupmarkupstyle{kbd}\def\look{#1}\expandafter\kbdfoo\look??\par}} @@ -2707,7 +2725,7 @@ end \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% \else \errhelp = \EMsimple - \errmessage{Unknown @kbdinputstyle option `\txiarg'}% + \errmessage{Unknown @kbdinputstyle setting `\txiarg'}% \fi\fi\fi } \def\worddistinct{distinct} @@ -2735,93 +2753,254 @@ end \parseargdef\clickstyle{\def\click{#1}} \def\click{\arrow} -% @uref (abbreviation for `urlref') takes an optional (comma-separated) -% second argument specifying the text to display and an optional third -% arg as text to display instead of (rather than in addition to) the url -% itself. First (mandatory) arg is the url. Perhaps eventually put in -% a hypertex \special here. +% Typeset a dimension, e.g., `in' or `pt'. The only reason for the +% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. % -\def\uref#1{\douref #1,,,\finish} -\def\douref#1,#2,#3,#4\finish{\begingroup - \unsepspaces - \pdfurl{#1}% - \setbox0 = \hbox{\ignorespaces #3}% - \ifdim\wd0 > 0pt - \unhbox0 % third arg given, show only that - \else - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0 > 0pt - \ifpdf - \unhbox0 % PDF: 2nd arg given, show only it - \else - \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url - \fi - \else - \code{#1}% only url given, so show it - \fi +\def\dmn#1{\thinspace #1} + +% @l was never documented to mean ``switch to the Lisp font'', +% and it is not used as such in any manual I can find. We need it for +% Polish suppressed-l. --karl, 22sep96. +%\def\l#1{{\li #1}\null} + +% @acronym for "FBI", "NATO", and the like. +% We print this one point size smaller, since it's intended for +% all-uppercase. +% +\def\acronym#1{\doacronym #1,,\finish} +\def\doacronym#1,#2,#3\finish{% + {\selectfonts\lsize #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% \fi - \endlink -\endgroup} + \null % reset \spacefactor=1000 +} -% @url synonym for @uref, since that's how everyone uses it. +% @abbr for "Comput. J." and the like. +% No font change, but don't do end-of-sentence spacing. % -\let\url=\uref +\def\abbr#1{\doabbr #1,,\finish} +\def\doabbr#1,#2,#3\finish{% + {\plainfrenchspacing #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi + \null % reset \spacefactor=1000 +} -% rms does not like angle brackets --karl, 17may97. -% So now @email is just like @uref, unless we are pdf. +% @asis just yields its argument. Used with @table, for example. % -%\def\email#1{\angleleft{\tt #1}\angleright} -\ifpdf - \def\email#1{\doemail#1,,\finish} - \def\doemail#1,#2,#3\finish{\begingroup - \unsepspaces - \pdfurl{mailto:#1}% - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi - \endlink - \endgroup} -\else - \let\email=\uref -\fi +\def\asis#1{#1} -% Typeset a dimension, e.g., `in' or `pt'. The only reason for the -% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. +% @math outputs its argument in math mode. % -\def\dmn#1{\thinspace #1} +% One complication: _ usually means subscripts, but it could also mean +% an actual _ character, as in @math{@var{some_variable} + 1}. So make +% _ active, and distinguish by seeing if the current family is \slfam, +% which is what @var uses. +{ + \catcode`\_ = \active + \gdef\mathunderscore{% + \catcode`\_=\active + \def_{\ifnum\fam=\slfam \_\else\sb\fi}% + } +} +% Another complication: we want \\ (and @\) to output a math (or tt) \. +% FYI, plain.tex uses \\ as a temporary control sequence (for no +% particular reason), but this is not advertised and we don't care. +% +% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. +\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} +% +\def\math{% + \tex + \mathunderscore + \let\\ = \mathbackslash + \mathactive + % make the texinfo accent commands work in math mode + \let\"=\ddot + \let\'=\acute + \let\==\bar + \let\^=\hat + \let\`=\grave + \let\u=\breve + \let\v=\check + \let\~=\tilde + \let\dotaccent=\dot + $\finishmath +} +\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. + +% Some active characters (such as <) are spaced differently in math. +% We have to reset their definitions in case the @math was an argument +% to a command which sets the catcodes (such as @item or @section). +% +{ + \catcode`^ = \active + \catcode`< = \active + \catcode`> = \active + \catcode`+ = \active + \catcode`' = \active + \gdef\mathactive{% + \let^ = \ptexhat + \let< = \ptexless + \let> = \ptexgtr + \let+ = \ptexplus + \let' = \ptexquoteright + } +} + +% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. +% Ignore unless FMTNAME == tex; then it is like @iftex and @tex, +% except specified as a normal braced arg, so no newlines to worry about. +% +\def\outfmtnametex{tex} +% +\long\def\inlinefmt#1{\doinlinefmt #1,\finish} +\long\def\doinlinefmt#1,#2,\finish{% + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi +} +% For raw, must switch into @tex before parsing the argument, to avoid +% setting catcodes prematurely. Doing it this way means that, for +% example, @inlineraw{html, foo{bar} gets a parse error instead of being +% ignored. But this isn't important because if people want a literal +% *right* brace they would have to use a command anyway, so they may as +% well use a command to get a left brace too. We could re-use the +% delimiter character idea from \verb, but it seems like overkill. +% +\long\def\inlineraw{\tex \doinlineraw} +\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish} +\def\doinlinerawtwo#1,#2,\finish{% + \def\inlinerawname{#1}% + \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi + \endgroup % close group opened by \tex. +} + + +\message{glyphs,} +% and logos. + +% @@ prints an @, as does @atchar{}. +\def\@{\char64 } +\let\atchar=\@ + +% @{ @} @lbracechar{} @rbracechar{} all generate brace characters. +% Unless we're in typewriter, use \ecfont because the CM text fonts do +% not have braces, and we don't want to switch into math. +\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}} +\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}} +\let\{=\mylbrace \let\lbracechar=\{ +\let\}=\myrbrace \let\rbracechar=\} +\begingroup + % Definitions to produce \{ and \} commands for indices, + % and @{ and @} for the aux/toc files. + \catcode`\{ = \other \catcode`\} = \other + \catcode`\[ = 1 \catcode`\] = 2 + \catcode`\! = 0 \catcode`\\ = \other + !gdef!lbracecmd[\{]% + !gdef!rbracecmd[\}]% + !gdef!lbraceatcmd[@{]% + !gdef!rbraceatcmd[@}]% +!endgroup + +% @comma{} to avoid , parsing problems. +\let\comma = , + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. +\let\, = \ptexc +\let\dotaccent = \ptexdot +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \ptext +\let\ubaraccent = \ptexb +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown @ordf @ordm +% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} +\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}} +\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi + \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% The \TeX{} logo, as in plain, but resetting the spacing so that a +% period following counts as ending a sentence. (Idea found in latex.) +% +\edef\TeX{\TeX \spacefactor=1000 } + +% @LaTeX{} logo. Not quite the same results as the definition in +% latex.ltx, since we use a different font for the raised A; it's most +% convenient for us to use an explicitly smaller font, rather than using +% the \scriptstyle font (since we don't reset \scriptstyle and +% \scriptscriptstyle). +% +\def\LaTeX{% + L\kern-.36em + {\setbox0=\hbox{T}% + \vbox to \ht0{\hbox{% + \ifx\textnominalsize\xwordpt + % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX. + % Revert to plain's \scriptsize, which is 7pt. + \count255=\the\fam $\fam\count255 \scriptstyle A$% + \else + % For 11pt, we can use our lllsize. + \selectfonts\lllsize A% + \fi + }% + \vss + }}% + \kern-.15em + \TeX +} -% @l was never documented to mean ``switch to the Lisp font'', -% and it is not used as such in any manual I can find. We need it for -% Polish suppressed-l. --karl, 22sep96. -%\def\l#1{{\li #1}\null} +% Some math mode symbols. +\def\bullet{$\ptexbullet$} +\def\geq{\ifmmode \ge\else $\ge$\fi} +\def\leq{\ifmmode \le\else $\le$\fi} +\def\minus{\ifmmode -\else $-$\fi} -% @acronym for "FBI", "NATO", and the like. -% We print this one point size smaller, since it's intended for -% all-uppercase. +% @dots{} outputs an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in the cm +% typewriter fonts as three actual period characters; on the other hand, +% in other typewriter fonts three periods are wider than 1.5em. So do +% whichever is larger. % -\def\acronym#1{\doacronym #1,,\finish} -\def\doacronym#1,#2,#3\finish{% - {\selectfonts\lsize #1}% - \def\temp{#2}% - \ifx\temp\empty \else - \space ({\unsepspaces \ignorespaces \temp \unskip})% +\def\dots{% + \leavevmode + \setbox0=\hbox{...}% get width of three periods + \ifdim\wd0 > 1.5em + \dimen0 = \wd0 + \else + \dimen0 = 1.5em \fi + \hbox to \dimen0{% + \hskip 0pt plus.25fil + .\hskip 0pt plus1fil + .\hskip 0pt plus1fil + .\hskip 0pt plus.5fil + }% } -% @abbr for "Comput. J." and the like. -% No font change, but don't do end-of-sentence spacing. +% @enddots{} is an end-of-sentence ellipsis. % -\def\abbr#1{\doabbr #1,,\finish} -\def\doabbr#1,#2,#3\finish{% - {\plainfrenchspacing #1}% - \def\temp{#2}% - \ifx\temp\empty \else - \space ({\unsepspaces \ignorespaces \temp \unskip})% - \fi +\def\enddots{% + \dots + \spacefactor=\endofsentencespacefactor } - -\message{glyphs,} - % @point{}, @result{}, @expansion{}, @print{}, @equiv{}. % % Since these characters are used in examples, they should be an even number of @@ -2842,7 +3021,7 @@ end {\tentt \global\dimen0 = 3em}% Width of the box. \dimen2 = .55pt % Thickness of rules % The text. (`r' is open on the right, `e' somewhat less so on the left.) -\setbox0 = \hbox{\kern-.75pt \reducedsf error\kern-1.5pt} +\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt} % \setbox\errorbox=\hbox to \dimen0{\hfil \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. @@ -2991,7 +3170,7 @@ end % Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 % so we'll define it if necessary. % -\ifx\Orb\undefined +\ifx\Orb\thisisundefined \def\Orb{\mathhexbox20D} \fi @@ -3019,8 +3198,9 @@ end \newif\ifsetshortcontentsaftertitlepage \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue -\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% - \endgroup\page\hbox{}\page} +\parseargdef\shorttitlepage{% + \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} \envdef\titlepage{% % Open one extra group, as we want to close it in the middle of \Etitlepage. @@ -3080,7 +3260,7 @@ end \finishedtitlepagetrue } -%%% Macros to be used within @titlepage: +% Macros to be used within @titlepage: \let\subtitlerm=\tenrm \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} @@ -3113,7 +3293,7 @@ end } -%%% Set up page headings and footings. +% Set up page headings and footings. \let\thispage=\folio @@ -3207,10 +3387,14 @@ end \def\headings #1 {\csname HEADINGS#1\endcsname} -\def\HEADINGSoff{% -\global\evenheadline={\hfil} \global\evenfootline={\hfil} -\global\oddheadline={\hfil} \global\oddfootline={\hfil}} -\HEADINGSoff +\def\headingsoff{% non-global headings elimination + \evenheadline={\hfil}\evenfootline={\hfil}% + \oddheadline={\hfil}\oddfootline={\hfil}% +} + +\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting +\HEADINGSoff % it's the default + % When we turn headings on, set the page number to 1. % For double-sided printing, put current file name in lower left corner, % chapter name on inside top of right hand pages, document @@ -3261,7 +3445,7 @@ end % This produces Day Month Year style of output. % Only define if not already defined, in case a txi-??.tex file has set % up a different format (e.g., txi-cs.tex does this). -\ifx\today\undefined +\ifx\today\thisisundefined \def\today{% \number\day\space \ifcase\month @@ -3322,7 +3506,7 @@ end \begingroup \advance\leftskip by-\tableindent \advance\hsize by\tableindent - \advance\rightskip by0pt plus1fil + \advance\rightskip by0pt plus1fil\relax \leavevmode\unhbox0\par \endgroup % @@ -3808,18 +3992,18 @@ end \setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip \global\advance\multitablelinespace by-\ht0 \fi -%% Test to see if parskip is larger than space between lines of -%% table. If not, do nothing. -%% If so, set to same dimension as multitablelinespace. +% Test to see if parskip is larger than space between lines of +% table. If not, do nothing. +% If so, set to same dimension as multitablelinespace. \ifdim\multitableparskip>\multitablelinespace \global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller - %% than skip between lines in the table. +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. \fi% \ifdim\multitableparskip=0pt \global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller - %% than skip between lines in the table. +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. \fi} @@ -4134,11 +4318,14 @@ end \def\@{@}% change to @@ when we switch to @ as escape char in index files. \def\ {\realbackslash\space }% % - % Need these in case \tex is in effect and \{ is a \delimiter again. - % But can't use \lbracecmd and \rbracecmd because texindex assumes - % braces and backslashes are used only as delimiters. - \let\{ = \mylbrace - \let\} = \myrbrace + % Need these unexpandable (because we define \tt as a dummy) + % definitions when @{ or @} appear in index entry text. Also, more + % complicated, when \tex is in effect and \{ is a \delimiter again. + % We can't use \lbracecmd and \rbracecmd because texindex assumes + % braces and backslashes are used only as delimiters. Perhaps we + % should define @lbrace and @rbrace commands a la @comma. + \def\{{{\tt\char123}}% + \def\}{{\tt\char125}}% % % I don't entirely understand this, but when an index entry is % generated from a macro call, the \endinput which \scanmacro inserts @@ -4191,7 +4378,7 @@ end \def\commondummies{% % % \definedummyword defines \#1 as \string\#1\space, thus effectively - % preventing its expansion. This is used only for control% words, + % preventing its expansion. This is used only for control words, % not control letters, because the \space would be incorrect for % control characters, but is needed to separate the control word % from whatever follows. @@ -4210,6 +4397,7 @@ end \commondummiesnofonts % \definedummyletter\_% + \definedummyletter\-% % % Non-English letters. \definedummyword\AA @@ -4246,20 +4434,24 @@ end \definedummyword\TeX % % Assorted special characters. + \definedummyword\arrow \definedummyword\bullet \definedummyword\comma \definedummyword\copyright \definedummyword\registeredsymbol \definedummyword\dots \definedummyword\enddots + \definedummyword\entrybreak \definedummyword\equiv \definedummyword\error \definedummyword\euro + \definedummyword\expansion + \definedummyword\geq \definedummyword\guillemetleft \definedummyword\guillemetright \definedummyword\guilsinglleft \definedummyword\guilsinglright - \definedummyword\expansion + \definedummyword\leq \definedummyword\minus \definedummyword\ogonek \definedummyword\pounds @@ -4316,19 +4508,24 @@ end \definedummyword\b \definedummyword\i \definedummyword\r + \definedummyword\sansserif \definedummyword\sc + \definedummyword\slanted \definedummyword\t % % Commands that take arguments. \definedummyword\acronym + \definedummyword\anchor \definedummyword\cite \definedummyword\code \definedummyword\command \definedummyword\dfn + \definedummyword\dmn \definedummyword\email \definedummyword\emph \definedummyword\env \definedummyword\file + \definedummyword\indicateurl \definedummyword\kbd \definedummyword\key \definedummyword\math @@ -4356,7 +4553,7 @@ end \def\definedummyaccent##1{\let##1\asis}% % We can just ignore other control letters. \def\definedummyletter##1{\let##1\empty}% - % Hopefully, all control words can become @asis. + % All control words become @asis by default; overrides below. \let\definedummyword\definedummyaccent % \commondummiesnofonts @@ -4368,8 +4565,14 @@ end % \def\ { }% \def\@{@}% - % how to handle braces? \def\_{\normalunderscore}% + \def\-{}% @- shouldn't affect sorting + % + % Unfortunately, texindex is not prepared to handle braces in the + % content at all. So for index sorting, we map @{ and @} to strings + % starting with |, since that ASCII character is between ASCII { and }. + \def\{{|a}% + \def\}{|b}% % % Non-English letters. \def\AA{AA}% @@ -4397,6 +4600,7 @@ end % % Assorted special characters. % (The following {} will end up in the sort string, but that's ok.) + \def\arrow{->}% \def\bullet{bullet}% \def\comma{,}% \def\copyright{copyright}% @@ -4406,10 +4610,12 @@ end \def\error{error}% \def\euro{euro}% \def\expansion{==>}% + \def\geq{>=}% \def\guillemetleft{<<}% \def\guillemetright{>>}% \def\guilsinglleft{<}% \def\guilsinglright{>}% + \def\leq{<=}% \def\minus{-}% \def\point{.}% \def\pounds{pounds}% @@ -4424,6 +4630,9 @@ end \def\result{=>}% \def\textdegree{o}% % + \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax + \else \indexlquoteignore \fi + % % We need to get rid of all macros, leaving only the arguments (if present). % Of course this is not nearly correct, but it is the best we can do for now. % makeinfo does not expand macros in the argument to @deffn, which ends up @@ -4437,6 +4646,11 @@ end \macrolist } +% Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us +% ignore left quotes in the sort term. +{\catcode`\`=\active + \gdef\indexlquoteignore{\let`=\empty}} + \let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax % put index entries in margin (undocumented)? @@ -4534,10 +4748,9 @@ end % % ..., ready, GO: % -\def\safewhatsit#1{% -\ifhmode +\def\safewhatsit#1{\ifhmode #1% -\else + \else % \lastskip and \lastpenalty cannot both be nonzero simultaneously. \whatsitskip = \lastskip \edef\lastskipmacro{\the\lastskip}% @@ -4561,7 +4774,6 @@ end % to re-insert the same penalty (values >10000 are used for various % signals); since we just inserted a non-discardable item, any % following glue (such as a \parskip) would be a breakpoint. For example: - % % @deffn deffn-whatever % @vindex index-whatever % Description. @@ -4574,8 +4786,7 @@ end % (the whatsit from the \write), so we must insert a \nobreak. \nobreak\vskip\whatsitskip \fi -\fi -} +\fi} % The index entry written in the file actually looks like % \entry {sortstring}{page}{topic} @@ -4694,7 +4905,6 @@ end % But this freezes the catcodes in the argument, and can cause problems to % @code, which sets - active. This problem was fixed by a kludge--- % ``-'' was active throughout whole index, but this isn't really right. -% % The right solution is to prevent \entry from swallowing the whole text. % --kasal, 21nov03 \def\entry{% @@ -4731,10 +4941,17 @@ end % columns. \vskip 0pt plus1pt % + % When reading the text of entry, convert explicit line breaks + % from @* into spaces. The user might give these in long section + % titles, for instance. + \def\*{\unskip\space\ignorespaces}% + \def\entrybreak{\hfil\break}% + % % Swallow the left brace of the text (first parameter): \afterassignment\doentry \let\temp = } +\def\entrybreak{\unskip\space\ignorespaces}% \def\doentry{% \bgroup % Instead of the swallowed brace. \noindent @@ -4967,7 +5184,22 @@ end \message{sectioning,} % Chapters, sections, etc. -% \unnumberedno is an oxymoron, of course. But we count the unnumbered +% Let's start with @part. +\outer\parseargdef\part{\partzzz{#1}} +\def\partzzz#1{% + \chapoddpage + \null + \vskip.3\vsize % move it down on the page a bit + \begingroup + \noindent \titlefonts\rmisbold #1\par % the text + \let\lastnode=\empty % no node to associate with + \writetocentry{part}{#1}{}% but put it in the toc + \headingsoff % no headline or footline on the part page + \chapoddpage + \endgroup +} + +% \unnumberedno is an oxymoron. But we count the unnumbered % sections so that we can refer to them unambiguously in the pdf % outlines by their "section number". We avoid collisions with chapter % numbers by starting them at 10000. (If a document ever has 10000 @@ -5046,8 +5278,8 @@ end \chardef\maxseclevel = 3 % % A numbered section within an unnumbered changes to unnumbered too. -% To achive this, remember the "biggest" unnum. sec. we are currently in: -\chardef\unmlevel = \maxseclevel +% To achieve this, remember the "biggest" unnum. sec. we are currently in: +\chardef\unnlevel = \maxseclevel % % Trace whether the current chapter is an appendix or not: % \chapheadtype is "N" or "A", unnumbered chapters are ignored. @@ -5072,8 +5304,8 @@ end % The heading type: \def\headtype{#1}% \if \headtype U% - \ifnum \absseclevel < \unmlevel - \chardef\unmlevel = \absseclevel + \ifnum \absseclevel < \unnlevel + \chardef\unnlevel = \absseclevel \fi \else % Check for appendix sections: @@ -5085,10 +5317,10 @@ end \fi\fi \fi % Check for numbered within unnumbered: - \ifnum \absseclevel > \unmlevel + \ifnum \absseclevel > \unnlevel \def\headtype{U}% \else - \chardef\unmlevel = 3 + \chardef\unnlevel = 3 \fi \fi % Now print the heading: @@ -5174,7 +5406,8 @@ end \global\let\subsubsection = \appendixsubsubsec } -\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz +% normally unnmhead0 calls unnumberedzzz: +\outer\parseargdef\unnumbered{\unnmhead0{#1}} \def\unnumberedzzz#1{% \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 \global\advance\unnumberedno by 1 @@ -5218,40 +5451,47 @@ end \let\top\unnumbered % Sections. +% \outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz \def\seczzz#1{% \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% } -\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz +% normally calls appendixsectionzzz: +\outer\parseargdef\appendixsection{\apphead1{#1}} \def\appendixsectionzzz#1{% \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% } \let\appendixsec\appendixsection -\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz +% normally calls unnumberedseczzz: +\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} \def\unnumberedseczzz#1{% \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% } % Subsections. -\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz +% +% normally calls numberedsubseczzz: +\outer\parseargdef\numberedsubsec{\numhead2{#1}} \def\numberedsubseczzz#1{% \global\subsubsecno=0 \global\advance\subsecno by 1 \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% } -\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz +% normally calls appendixsubseczzz: +\outer\parseargdef\appendixsubsec{\apphead2{#1}} \def\appendixsubseczzz#1{% \global\subsubsecno=0 \global\advance\subsecno by 1 \sectionheading{#1}{subsec}{Yappendix}% {\appendixletter.\the\secno.\the\subsecno}% } -\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz +% normally calls unnumberedsubseczzz: +\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} \def\unnumberedsubseczzz#1{% \global\subsubsecno=0 \global\advance\subsecno by 1 \sectionheading{#1}{subsec}{Ynothing}% @@ -5259,21 +5499,25 @@ end } % Subsubsections. -\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz +% +% normally numberedsubsubseczzz: +\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} \def\numberedsubsubseczzz#1{% \global\advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Ynumbered}% {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% } -\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz +% normally appendixsubsubseczzz: +\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} \def\appendixsubsubseczzz#1{% \global\advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Yappendix}% {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% } -\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz +% normally unnumberedsubsubseczzz: +\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} \def\unnumberedsubsubseczzz#1{% \global\advance\subsubsecno by 1 \sectionheading{#1}{subsubsec}{Ynothing}% @@ -5323,14 +5567,13 @@ end % (including whitespace, linebreaking, etc. around it), % given all the information in convenient, parsed form. -%%% Args are the skip and penalty (usually negative) +% Args are the skip and penalty (usually negative) \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} -%%% Define plain chapter starts, and page on/off switching for it % Parameter controlling skip before chapter headings (if needed) - \newskip\chapheadingskip +% Define plain chapter starts, and page on/off switching for it. \def\chapbreak{\dobreak \chapheadingskip {-4000}} \def\chappager{\par\vfill\supereject} % Because \domark is called before \chapoddpage, the filler page will @@ -5340,9 +5583,8 @@ end \chappager \ifodd\pageno \else \begingroup - \evenheadline={\hfil}\evenfootline={\hfil}% - \oddheadline={\hfil}\oddfootline={\hfil}% - \hbox to 0pt{}% + \headingsoff + \null \chappager \endgroup \fi @@ -5534,6 +5776,8 @@ end % \def\sectionheading#1#2#3#4{% {% + \checkenv{}% should not be in an environment. + % % Switch to the right set of fonts. \csname #2fonts\endcsname \rmisbold % @@ -5645,15 +5889,15 @@ end % % We'll almost certainly start a paragraph next, so don't let that % glue accumulate. (Not a breakpoint because it's preceded by a - % discardable item.) + % discardable item.) However, when a paragraph is not started next + % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out + % or the negative glue will cause weirdly wrong output, typically + % obscuring the section heading with something else. \vskip-\parskip % - % This is purely so the last item on the list is a known \penalty > - % 10000. This is so \startdefun can avoid allowing breakpoints after - % section headings. Otherwise, it would insert a valid breakpoint between: - % - % @section sec-whatever - % @deffn def-whatever + % This is so the last item on the main vertical list is a known + % \penalty > 10000, so \startdefun, etc., can recognize the situation + % and do the needful. \penalty 10001 } @@ -5785,6 +6029,7 @@ end \def\summarycontents{% \startcontents{\putwordShortTOC}% % + \let\partentry = \shortpartentry \let\numchapentry = \shortchapentry \let\appentry = \shortchapentry \let\unnchapentry = \shortunnchapentry @@ -5840,6 +6085,19 @@ end % The last argument is the page number. % The arguments in between are the chapter number, section number, ... +% Parts, in the main contents. Replace the part number, which doesn't +% exist, with an empty box. Let's hope all the numbers have the same width. +% Also ignore the page number, which is conventionally not printed. +\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}} +\def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}} +% +% Parts, in the short toc. +\def\shortpartentry#1#2#3#4{% + \penalty-300 + \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip + \shortchapentry{{\bf #1}}{\numeralbox}{}{}% +} + % Chapters, in the main contents. \def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} % @@ -5929,9 +6187,9 @@ end \message{environments,} % @foo ... @end foo. -% @tex ... @end tex escapes into raw Tex temporarily. +% @tex ... @end tex escapes into raw TeX temporarily. % One exception: @ is still an escape character, so that @end tex works. -% But \@ or @@ will get a plain tex @ character. +% But \@ or @@ will get a plain @ character. \envdef\tex{% \setupmarkupstyle{tex}% @@ -5948,6 +6206,10 @@ end \catcode`\'=\other \escapechar=`\\ % + % ' is active in math mode (mathcode"8000). So reset it, and all our + % other math active characters (just in case), to plain's definitions. + \mathactive + % \let\b=\ptexb \let\bullet=\ptexbullet \let\c=\ptexc @@ -6051,6 +6313,12 @@ end \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip % Flag to tell @lisp, etc., not to narrow margin. \let\nonarrowing = t% + % + % If this cartouche directly follows a sectioning command, we need the + % \parskip glue (backspaced over by default) or the cartouche can + % collide with the section heading. + \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi + % \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop @@ -6064,7 +6332,7 @@ end \lineskip=\normlskip \parskip=\normpskip \vskip -\parskip - \comment % For explanation, see the end of \def\group. + \comment % For explanation, see the end of def\group. } \def\Ecartouche{% \ifhmode\par\fi @@ -6150,41 +6418,42 @@ end } % We often define two environments, @foo and @smallfoo. -% Let's do it by one command: -\def\makedispenv #1#2{ - \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2} - \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2} +% Let's do it in one command. #1 is the env name, #2 the definition. +\def\makedispenvdef#1#2{% + \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}% + \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}% \expandafter\let\csname E#1\endcsname \afterenvbreak \expandafter\let\csname Esmall#1\endcsname \afterenvbreak } -% Define two synonyms: -\def\maketwodispenvs #1#2#3{ - \makedispenv{#1}{#3} - \makedispenv{#2}{#3} +% Define two environment synonyms (#1 and #2) for an environment. +\def\maketwodispenvdef#1#2#3{% + \makedispenvdef{#1}{#3}% + \makedispenvdef{#2}{#3}% } - -% @lisp: indented, narrowed, typewriter font; @example: same as @lisp. +% +% @lisp: indented, narrowed, typewriter font; +% @example: same as @lisp. % % @smallexample and @smalllisp: use smaller fonts. % Originally contributed by Pavel@xerox. % -\maketwodispenvs {lisp}{example}{% +\maketwodispenvdef{lisp}{example}{% \nonfillstart \tt\setupmarkupstyle{example}% \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. - \gobble % eat return + \gobble % eat return } % @display/@smalldisplay: same as @lisp except keep current font. % -\makedispenv {display}{% +\makedispenvdef{display}{% \nonfillstart \gobble } % @format/@smallformat: same as @display except don't narrow margins. % -\makedispenv{format}{% +\makedispenvdef{format}{% \let\nonarrowing = t% \nonfillstart \gobble @@ -6203,7 +6472,7 @@ end \envdef\flushright{% \let\nonarrowing = t% \nonfillstart - \advance\leftskip by 0pt plus 1fill + \advance\leftskip by 0pt plus 1fill\relax \gobble } \let\Eflushright = \afterenvbreak @@ -6238,6 +6507,8 @@ end % we're doing normal filling. So, when using \aboveenvbreak and % \afterenvbreak, temporarily make \parskip 0. % +\makedispenvdef{quotation}{\quotationstart} +% \def\quotationstart{% {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip \parindent=0pt @@ -6253,28 +6524,18 @@ end \parsearg\quotationlabel } -\envdef\quotation{% - \setnormaldispenv - \quotationstart -} - -\envdef\smallquotation{% - \setsmalldispenv - \quotationstart -} -\let\Esmallquotation = \Equotation - % We have retained a nonzero parskip for the environment, since we're % doing normal filling. % \def\Equotation{% \par - \ifx\quotationauthor\undefined\else + \ifx\quotationauthor\thisisundefined\else % indent a bit. \leftline{\kern 2\leftskip \sl ---\quotationauthor}% \fi {\parskip=0pt \afterenvbreak}% } +\def\Esmallquotation{\Equotation} % If we're given an argument, typeset it in bold with a colon after. \def\quotationlabel#1{% @@ -6331,21 +6592,28 @@ end % Setup for the @verbatim environment % -% Real tab expansion +% Real tab expansion. \newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount % -\def\starttabbox{\setbox0=\hbox\bgroup} +% We typeset each line of the verbatim in an \hbox, so we can handle +% tabs. The \global is in case the verbatim line starts with an accent, +% or some other command that starts with a begin-group. Otherwise, the +% entire \verbbox would disappear at the corresponding end-group, before +% it is typeset. Meanwhile, we can't have nested verbatim commands +% (can we?), so the \global won't be overwriting itself. +\newbox\verbbox +\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup} % \begingroup \catcode`\^^I=\active \gdef\tabexpand{% \catcode`\^^I=\active \def^^I{\leavevmode\egroup - \dimen0=\wd0 % the width so far, or since the previous tab - \divide\dimen0 by\tabw - \multiply\dimen0 by\tabw % compute previous multiple of \tabw - \advance\dimen0 by\tabw % advance to next multiple of \tabw - \wd0=\dimen0 \box0 \starttabbox + \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab + \divide\dimen\verbbox by\tabw + \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw + \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw + \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox }% } \endgroup @@ -6354,15 +6622,16 @@ end \def\setupverbatim{% \let\nonarrowing = t% \nonfillstart - % Easiest (and conventionally used) font for verbatim - \tt - \def\par{\leavevmode\egroup\box0\endgraf}% + \tt % easiest (and conventionally used) font for verbatim + % The \leavevmode here is for blank lines. Otherwise, we would + % never \starttabox and the \egroup would end verbatim mode. + \def\par{\leavevmode\egroup\box\verbbox\endgraf}% \tabexpand \setupmarkupstyle{verbatim}% % Respect line breaks, % print special symbols as themselves, and - % make each space count - % must do in this order: + % make each space count. + % Must do in this order: \obeylines \uncatcodespecials \sepspaces \everypar{\starttabbox}% } @@ -6419,6 +6688,7 @@ end \makevalueexpandable \setupverbatim \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}% \input #1 \afterenvbreak }% @@ -6468,7 +6738,7 @@ end % commands also insert a nobreak penalty, and we don't want to allow % a break between a section heading and a defun. % - % As a minor refinement, we avoid "club" headers by signalling + % As a further refinement, we avoid "club" headers by signalling % with penalty of 10003 after the very first @deffn in the % sequence (see above), and penalty of 10002 after any following % @def command. @@ -6505,7 +6775,7 @@ end #1#2 \endheader % common ending: \interlinepenalty = 10000 - \advance\rightskip by 0pt plus 1fil + \advance\rightskip by 0pt plus 1fil\relax \endgraf \nobreak\vskip -\parskip \penalty\defunpenalty % signal to \startdefun and \dodefunx @@ -6535,13 +6805,36 @@ end \def\domakedefun#1#2#3{% \envdef#1{% \startdefun + \doingtypefnfalse % distinguish typed functions from all else \parseargusing\activeparens{\printdefunline#3}% }% \def#2{\dodefunx#1}% \def#3% } -%%% Untyped functions: +\newif\ifdoingtypefn % doing typed function? +\newif\ifrettypeownline % typeset return type on its own line? + +% @deftypefnnewline on|off says whether the return type of typed functions +% are printed on their own line. This affects @deftypefn, @deftypefun, +% @deftypeop, and @deftypemethod. +% +\parseargdef\deftypefnnewline{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @txideftypefnnl value `\temp', + must be on|off}% + \fi\fi +} + +% Untyped functions: % @deffn category name args \makedefun{deffn}{\deffngeneral{}} @@ -6560,7 +6853,7 @@ end \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% } -%%% Typed functions: +% Typed functions: % @deftypefn category type name args \makedefun{deftypefn}{\deftypefngeneral{}} @@ -6575,10 +6868,11 @@ end % \def\deftypefngeneral#1#2 #3 #4 #5\endheader{% \dosubind{fn}{\code{#4}}{#1}% + \doingtypefntrue \defname{#2}{#3}{#4}\defunargs{#5\unskip}% } -%%% Typed variables: +% Typed variables: % @deftypevr category type var args \makedefun{deftypevr}{\deftypecvgeneral{}} @@ -6596,7 +6890,7 @@ end \defname{#2}{#3}{#4}\defunargs{#5\unskip}% } -%%% Untyped variables: +% Untyped variables: % @defvr category var args \makedefun{defvr}#1 {\deftypevrheader{#1} {} } @@ -6607,7 +6901,8 @@ end % \defcvof {category of}class var args \def\defcvof#1#2 {\deftypecvof{#1}#2 {} } -%%% Type: +% Types: + % @deftp category name args \makedefun{deftp}#1 #2 #3\endheader{% \doind{tp}{\code{#2}}% @@ -6635,25 +6930,49 @@ end % We are followed by (but not passed) the arguments, if any. % \def\defname#1#2#3{% + \par % Get the values of \leftskip and \rightskip as they were outside the @def... \advance\leftskip by -\defbodyindent % - % How we'll format the type name. Putting it in brackets helps + % Determine if we are typesetting the return type of a typed function + % on a line by itself. + \rettypeownlinefalse + \ifdoingtypefn % doing a typed function specifically? + % then check user option for putting return type on its own line: + \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else + \rettypeownlinetrue + \fi + \fi + % + % How we'll format the category name. Putting it in brackets helps % distinguish it from the body text that may end up on the next line % just below it. \def\temp{#1}% \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} % - % Figure out line sizes for the paragraph shape. + % Figure out line sizes for the paragraph shape. We'll always have at + % least two. + \tempnum = 2 + % % The first line needs space for \box0; but if \rightskip is nonzero, % we need only space for the part of \box0 which exceeds it: \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip + % + % If doing a return type on its own line, we'll have another line. + \ifrettypeownline + \advance\tempnum by 1 + \def\maybeshapeline{0in \hsize}% + \else + \def\maybeshapeline{}% + \fi + % % The continuations: \dimen2=\hsize \advance\dimen2 by -\defargsindent - % (plain.tex says that \dimen1 should be used only as global.) - \parshape 2 0in \dimen0 \defargsindent \dimen2 % - % Put the type name to the right margin. + % The final paragraph shape: + \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2 + % + % Put the category name at the right margin. \noindent \hbox to 0pt{% \hfil\box0 \kern-\hsize @@ -6675,8 +6994,16 @@ end % . this still does not fix the ?` and !` ligatures, but so far no % one has made identifiers using them :). \df \tt - \def\temp{#2}% return value type - \ifx\temp\empty\else \tclose{\temp} \fi + \def\temp{#2}% text of the return type + \ifx\temp\empty\else + \tclose{\temp}% typeset the return type + \ifrettypeownline + % put return type on its own line; prohibit line break following: + \hfil\vadjust{\nobreak}\break + \else + \space % type on same line, so just followed by a space + \fi + \fi % no return type #3% output function name }% {\rm\enskip}% hskip 0.5 em of \tenrm @@ -6794,7 +7121,7 @@ end % To do this right we need a feature of e-TeX, \scantokens, % which we arrange to emulate with a temporary file in ordinary TeX. -\ifx\eTeXversion\undefined +\ifx\eTeXversion\thisisundefined \newwrite\macscribble \def\scantokens#1{% \toks0={#1}% @@ -6805,25 +7132,30 @@ end } \fi -\def\scanmacro#1{% - \begingroup - \newlinechar`\^^M - \let\xeatspaces\eatspaces - % Undo catcode changes of \startcontents and \doprintindex - % When called from @insertcopying or (short)caption, we need active - % backslash to get it printed correctly. Previously, we had - % \catcode`\\=\other instead. We'll see whether a problem appears - % with macro expansion. --kasal, 19aug04 - \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ - % ... and \example - \spaceisspace - % - % Append \endinput to make sure that TeX does not see the ending newline. - % I've verified that it is necessary both for e-TeX and for ordinary TeX - % --kasal, 29nov03 - \scantokens{#1\endinput}% - \endgroup -} +\def\scanmacro#1{\begingroup + \newlinechar`\^^M + \let\xeatspaces\eatspaces + % + % Undo catcode changes of \startcontents and \doprintindex + % When called from @insertcopying or (short)caption, we need active + % backslash to get it printed correctly. Previously, we had + % \catcode`\\=\other instead. We'll see whether a problem appears + % with macro expansion. --kasal, 19aug04 + \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ + % + % ... and for \example: + \spaceisspace + % + % The \empty here causes a following catcode 5 newline to be eaten as + % part of reading whitespace after a control sequence. It does not + % eat a catcode 13 newline. There's no good way to handle the two + % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX + % would then have different behavior). See the Macro Details node in + % the manual for the workaround we recommend for macros and + % line-oriented commands. + % + \scantokens{#1\empty}% +\endgroup} \def\scanexp#1{% \edef\temp{\noexpand\scanmacro{#1}}% @@ -6877,17 +7209,18 @@ end % Macro bodies are absorbed as an argument in a context where % all characters are catcode 10, 11 or 12, except \ which is active -% (as in normal texinfo). It is necessary to change the definition of \. - +% (as in normal texinfo). It is necessary to change the definition of \ +% to recognize macro arguments; this is the job of \mbodybackslash. +% % Non-ASCII encodings make 8-bit characters active, so un-activate % them to avoid their expansion. Must do this non-globally, to % confine the change to the current group. - +% % It's necessary to have hard CRs when the macro is executed. This is -% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% done by making ^^M (\endlinechar) catcode 12 when reading the macro % body, and then making it the \newlinechar in \scanmacro. - -\def\scanctxt{% +% +\def\scanctxt{% used as subroutine \catcode`\"=\other \catcode`\+=\other \catcode`\<=\other @@ -6900,13 +7233,13 @@ end \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi } -\def\scanargctxt{% +\def\scanargctxt{% used for copying and captions, not macros. \scanctxt \catcode`\\=\other \catcode`\^^M=\other } -\def\macrobodyctxt{% +\def\macrobodyctxt{% used for @macro definitions \scanctxt \catcode`\{=\other \catcode`\}=\other @@ -6914,32 +7247,56 @@ end \usembodybackslash } -\def\macroargctxt{% +\def\macroargctxt{% used when scanning invocations \scanctxt - \catcode`\\=\other + \catcode`\\=0 } +% why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes" +% for the single characters \ { }. Thus, we end up with the "commands" +% that would be written @\ @{ @} in a Texinfo document. +% +% We already have @{ and @}. For @\, we define it here, and only for +% this purpose, to produce a typewriter backslash (so, the @\ that we +% define for @math can't be used with @macro calls): +% +\def\\{\normalbackslash}% +% +% We would like to do this for \, too, since that is what makeinfo does. +% But it is not possible, because Texinfo already has a command @, for a +% cedilla accent. Documents must use @comma{} instead. +% +% \anythingelse will almost certainly be an error of some kind. + % \mbodybackslash is the definition of \ in @macro bodies. % It maps \foo\ => \csname macarg.foo\endcsname => #N % where N is the macro parameter number. % We define \csname macarg.\endcsname to be \realbackslash, so % \\ in macro replacement text gets you a backslash. - +% {\catcode`@=0 @catcode`@\=@active @gdef@usembodybackslash{@let\=@mbodybackslash} @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} } \expandafter\def\csname macarg.\endcsname{\realbackslash} +\def\margbackslash#1{\char`\#1 } + \def\macro{\recursivefalse\parsearg\macroxxx} \def\rmacro{\recursivetrue\parsearg\macroxxx} \def\macroxxx#1{% - \getargs{#1}% now \macname is the macname and \argl the arglist + \getargs{#1}% now \macname is the macname and \argl the arglist \ifx\argl\empty % no arguments - \paramno=0% + \paramno=0\relax \else \expandafter\parsemargdef \argl;% + \if\paramno>256\relax + \ifx\eTeXversion\thisisundefined + \errhelp = \EMsimple + \errmessage{You need eTeX to compile a file with macros with more than 256 arguments} + \fi + \fi \fi \if1\csname ismacro.\the\macname\endcsname \message{Warning: redefining \the\macname}% @@ -6986,46 +7343,269 @@ end % an opening brace, and that opening brace is not consumed. \def\getargs#1{\getargsxxx#1{}} \def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} -\def\getmacname #1 #2\relax{\macname={#1}} +\def\getmacname#1 #2\relax{\macname={#1}} \def\getmacargs#1{\def\argl{#1}} +% For macro processing make @ a letter so that we can make Texinfo private macro names. +\edef\texiatcatcode{\the\catcode`\@} +\catcode `@=11\relax + % Parse the optional {params} list. Set up \paramno and \paramlist -% so \defmacro knows what to do. Define \macarg.blah for each blah -% in the params list, to be ##N where N is the position in that list. +% so \defmacro knows what to do. Define \macarg.BLAH for each BLAH +% in the params list to some hook where the argument si to be expanded. If +% there are less than 10 arguments that hook is to be replaced by ##N where N +% is the position in that list, that is to say the macro arguments are to be +% defined `a la TeX in the macro body. +% % That gets used by \mbodybackslash (above). - +% % We need to get `macro parameter char #' into several definitions. -% The technique used is stolen from LaTeX: let \hash be something +% The technique used is stolen from LaTeX: let \hash be something % unexpandable, insert that wherever you need a #, and then redefine % it to # just before using the token list produced. % % The same technique is used to protect \eatspaces till just before % the macro is used. - -\def\parsemargdef#1;{\paramno=0\def\paramlist{}% - \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} +% +% If there are 10 or more arguments, a different technique is used, where the +% hook remains in the body, and when macro is to be expanded the body is +% processed again to replace the arguments. +% +% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the +% argument N value and then \edef the body (nothing else will expand because of +% the catcode regime underwhich the body was input). +% +% If you compile with TeX (not eTeX), and you have macros with 10 or more +% arguments, you need that no macro has more than 256 arguments, otherwise an +% error is produced. +\def\parsemargdef#1;{% + \paramno=0\def\paramlist{}% + \let\hash\relax + \let\xeatspaces\relax + \parsemargdefxxx#1,;,% + % In case that there are 10 or more arguments we parse again the arguments + % list to set new definitions for the \macarg.BLAH macros corresponding to + % each BLAH argument. It was anyhow needed to parse already once this list + % in order to count the arguments, and as macros with at most 9 arguments + % are by far more frequent than macro with 10 or more arguments, defining + % twice the \macarg.BLAH macros does not cost too much processing power. + \ifnum\paramno<10\relax\else + \paramno0\relax + \parsemmanyargdef@@#1,;,% 10 or more arguments + \fi +} \def\parsemargdefxxx#1,{% \if#1;\let\next=\relax \else \let\next=\parsemargdefxxx - \advance\paramno by 1% + \advance\paramno by 1 \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname {\xeatspaces{\hash\the\paramno}}% \edef\paramlist{\paramlist\hash\the\paramno,}% \fi\next} +\def\parsemmanyargdef@@#1,{% + \if#1;\let\next=\relax + \else + \let\next=\parsemmanyargdef@@ + \edef\tempb{\eatspaces{#1}}% + \expandafter\def\expandafter\tempa + \expandafter{\csname macarg.\tempb\endcsname}% + % Note that we need some extra \noexpand\noexpand, this is because we + % don't want \the to be expanded in the \parsermacbody as it uses an + % \xdef . + \expandafter\edef\tempa + {\noexpand\noexpand\noexpand\the\toks\the\paramno}% + \advance\paramno by 1\relax + \fi\next} + % These two commands read recursive and nonrecursive macro bodies. % (They're different since rec and nonrec macros end differently.) +% +\catcode `\@\texiatcatcode \long\def\parsemacbody#1@end macro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% \long\def\parsermacbody#1@end rmacro% {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +\catcode `\@=11\relax + +\let\endargs@\relax +\let\nil@\relax +\def\nilm@{\nil@}% +\long\def\nillm@{\nil@}% + +% This macro is expanded during the Texinfo macro expansion, not during its +% definition. It gets all the arguments values and assigns them to macros +% macarg.ARGNAME +% +% #1 is the macro name +% #2 is the list of argument names +% #3 is the list of argument values +\def\getargvals@#1#2#3{% + \def\macargdeflist@{}% + \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion. + \def\paramlist{#2,\nil@}% + \def\macroname{#1}% + \begingroup + \macroargctxt + \def\argvaluelist{#3,\nil@}% + \def\@tempa{#3}% + \ifx\@tempa\empty + \setemptyargvalues@ + \else + \getargvals@@ + \fi +} + +% +\def\getargvals@@{% + \ifx\paramlist\nilm@ + % Some sanity check needed here that \argvaluelist is also empty. + \ifx\argvaluelist\nillm@ + \else + \errhelp = \EMsimple + \errmessage{Too many arguments in macro `\macroname'!}% + \fi + \let\next\macargexpandinbody@ + \else + \ifx\argvaluelist\nillm@ + % No more arguments values passed to macro. Set remaining named-arg + % macros to empty. + \let\next\setemptyargvalues@ + \else + % pop current arg name into \@tempb + \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}% + \expandafter\@tempa\expandafter{\paramlist}% + % pop current argument value into \@tempc + \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}% + \expandafter\@tempa\expandafter{\argvaluelist}% + % Here \@tempb is the current arg name and \@tempc is the current arg value. + % First place the new argument macro definition into \@tempd + \expandafter\macname\expandafter{\@tempc}% + \expandafter\let\csname macarg.\@tempb\endcsname\relax + \expandafter\def\expandafter\@tempe\expandafter{% + \csname macarg.\@tempb\endcsname}% + \edef\@tempd{\long\def\@tempe{\the\macname}}% + \push@\@tempd\macargdeflist@ + \let\next\getargvals@@ + \fi + \fi + \next +} + +\def\push@#1#2{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter#2% + \expandafter\expandafter\expandafter{% + \expandafter#1#2}% +} + +% Replace arguments by their values in the macro body, and place the result +% in macro \@tempa +\def\macvalstoargs@{% + % To do this we use the property that token registers that are \the'ed + % within an \edef expand only once. So we are going to place all argument + % values into respective token registers. + % + % First we save the token context, and initialize argument numbering. + \begingroup + \paramno0\relax + % Then, for each argument number #N, we place the corresponding argument + % value into a new token list register \toks#N + \expandafter\putargsintokens@\saveparamlist@,;,% + % Then, we expand the body so that argument are replaced by their + % values. The trick for values not to be expanded themselves is that they + % are within tokens and that tokens expand only once in an \edef . + \edef\@tempc{\csname mac.\macroname .body\endcsname}% + % Now we restore the token stack pointer to free the token list registers + % which we have used, but we make sure that expanded body is saved after + % group. + \expandafter + \endgroup + \expandafter\def\expandafter\@tempa\expandafter{\@tempc}% + } + +\def\macargexpandinbody@{% + %% Define the named-macro outside of this group and then close this group. + \expandafter + \endgroup + \macargdeflist@ + % First the replace in body the macro arguments by their values, the result + % is in \@tempa . + \macvalstoargs@ + % Then we point at the \norecurse or \gobble (for recursive) macro value + % with \@tempb . + \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname + % Depending on whether it is recursive or not, we need some tailing + % \egroup . + \ifx\@tempb\gobble + \let\@tempc\relax + \else + \let\@tempc\egroup + \fi + % And now we do the real job: + \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}% + \@tempd +} + +\def\putargsintokens@#1,{% + \if#1;\let\next\relax + \else + \let\next\putargsintokens@ + % First we allocate the new token list register, and give it a temporary + % alias \@tempb . + \toksdef\@tempb\the\paramno + % Then we place the argument value into that token list register. + \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname + \expandafter\@tempb\expandafter{\@tempa}% + \advance\paramno by 1\relax + \fi + \next +} + +% Save the token stack pointer into macro #1 +\def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}} +% Restore the token stack pointer from number in macro #1 +\def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax} +% newtoks that can be used non \outer . +\def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi} + +% Tailing missing arguments are set to empty +\def\setemptyargvalues@{% + \ifx\paramlist\nilm@ + \let\next\macargexpandinbody@ + \else + \expandafter\setemptyargvaluesparser@\paramlist\endargs@ + \let\next\setemptyargvalues@ + \fi + \next +} + +\def\setemptyargvaluesparser@#1,#2\endargs@{% + \expandafter\def\expandafter\@tempa\expandafter{% + \expandafter\def\csname macarg.#1\endcsname{}}% + \push@\@tempa\macargdeflist@ + \def\paramlist{#2}% +} + +% #1 is the element target macro +% #2 is the list macro +% #3,#4\endargs@ is the list value +\def\pop@#1#2#3,#4\endargs@{% + \def#1{#3}% + \def#2{#4}% +} +\long\def\longpop@#1#2#3,#4\endargs@{% + \long\def#1{#3}% + \long\def#2{#4}% +} -% This defines the macro itself. There are six cases: recursive and -% nonrecursive macros of zero, one, and many arguments. +% This defines a Texinfo @macro. There are eight cases: recursive and +% nonrecursive macros of zero, one, up to nine, and many arguments. % Much magic with \expandafter here. % \xdef is used so that macro definitions will survive the file % they're defined in; @include reads the file inside a group. +% \def\defmacro{% \let\hash=##% convert placeholders to macro parameter chars \ifrecursive @@ -7040,17 +7620,25 @@ end \expandafter\noexpand\csname\the\macname xxx\endcsname}% \expandafter\xdef\csname\the\macname xxx\endcsname##1{% \egroup\noexpand\scanmacro{\temp}}% - \else % many - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \else + \ifnum\paramno<10\relax % at most 9 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \else % 10 or more + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble + \fi \fi \else \ifcase\paramno @@ -7067,29 +7655,40 @@ end \egroup \noexpand\norecurse{\the\macname}% \noexpand\scanmacro{\temp}\egroup}% - \else % many - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \expandafter\noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{% - \egroup - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% + \else % at most 9 + \ifnum\paramno<10\relax + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \expandafter\noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % 10 or more: + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse + \fi \fi \fi} +\catcode `\@\texiatcatcode\relax + \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} % \braceorline decides whether the next nonwhitespace character is a % {. If so it reads up to the closing }, if not, it reads the whole % line. Whatever was read is then fed to the next control sequence -% as an argument (by \parsebrace or \parsearg) +% as an argument (by \parsebrace or \parsearg). +% \def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} \def\braceorlinexxx{% \ifx\nchar\bgroup\else @@ -7099,7 +7698,8 @@ end % @alias. % We need some trickery to remove the optional spaces around the equal -% sign. Just make them active and then expand them all to nothing. +% sign. Make them active and then expand them all to nothing. +% \def\alias{\parseargusing\obeyspaces\aliasxxx} \def\aliasxxx #1{\aliasyyy#1\relax} \def\aliasyyy #1=#2\relax{% @@ -7120,7 +7720,8 @@ end % @inforef is relatively simple. \def\inforef #1{\inforefzzz #1,,,,**} -\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, +\def\inforefzzz #1,#2,#3,#4**{% + \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} % @node's only job in TeX is to define \lastnode, which is used in @@ -7181,11 +7782,32 @@ end \toks0 = \expandafter{\lastsection}% \immediate \writexrdef{title}{\the\toks0 }% \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. - \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, during \shipout + \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout }% \fi } +% @xrefautosectiontitle on|off says whether @section(ing) names are used +% automatically in xrefs, if the third arg is not explicitly specified. +% This was provided as a "secret" @set xref-automatic-section-title +% variable, now it's official. +% +\parseargdef\xrefautomaticsectiontitle{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @xrefautomaticsectiontitle value `\temp', + must be on|off}% + \fi\fi +} + + % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is % the node name, #2 the name of the Info cross-reference, #3 the printed % node name, #4 the name of the Info file, #5 the name of the printed @@ -7194,26 +7816,36 @@ end \def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} \def\ref#1{\xrefX[#1,,,,,,,]} +% +\newbox\topbox +\newbox\printedrefnamebox +\newbox\printedmanualbox +% \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \unsepspaces - \def\printedmanual{\ignorespaces #5}% + % \def\printedrefname{\ignorespaces #3}% - \setbox1=\hbox{\printedmanual\unskip}% - \setbox0=\hbox{\printedrefname\unskip}% - \ifdim \wd0 = 0pt + \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% + % + \def\printedmanual{\ignorespaces #5}% + \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% + % + % If the printed reference name (arg #3) was not explicitly given in + % the @xref, figure out what we want to use. + \ifdim \wd\printedrefnamebox = 0pt % No printed node name was explicitly given. - \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax - % Use the node name inside the square brackets. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax + % Not auto section-title: use node name inside the square brackets. \def\printedrefname{\ignorespaces #1}% \else - % Use the actual chapter/section title appear inside - % the square brackets. Use the real section title if we have it. - \ifdim \wd1 > 0pt - % It is in another manual, so we don't have it. + % Auto section-title: use chapter/section title inside + % the square brackets if we have it. + \ifdim \wd\printedmanualbox > 0pt + % It is in another manual, so we don't have it; use node name. \def\printedrefname{\ignorespaces #1}% \else \ifhavexrefs - % We know the real title if we have the xref values. + % We (should) know the real title if we have the xref values. \def\printedrefname{\refx{#1-title}{}}% \else % Otherwise just copy the Info node name. @@ -7227,13 +7859,13 @@ end \ifpdf {\indexnofonts \turnoffactive + \makevalueexpandable % This expands tokens, so do it after making catcode changes, so _ % etc. don't get their TeX definitions. \getfilename{#4}% % - % See comments at \activebackslashdouble. - {\activebackslashdouble \xdef\pdfxrefdest{#1}% - \backslashparens\pdfxrefdest}% + \edef\pdfxrefdest{#1}% + \txiescapepdf\pdfxrefdest % \leavevmode \startlink attr{/Border [0 0 0]}% @@ -7260,7 +7892,7 @@ end \iffloat\Xthisreftitle % If the user specified the print name (third arg) to the ref, % print it instead of our usual "Figure 1.2". - \ifdim\wd0 = 0pt + \ifdim\wd\printedrefnamebox = 0pt \refx{#1-snt}{}% \else \printedrefname @@ -7268,21 +7900,46 @@ end % % if the user also gave the printed manual name (fifth arg), append % "in MANUALNAME". - \ifdim \wd1 > 0pt + \ifdim \wd\printedmanualbox > 0pt \space \putwordin{} \cite{\printedmanual}% \fi \else % node/anchor (non-float) references. - % - % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not - % insert empty discretionaries after hyphens, which means that it will - % not find a line break at a hyphen in a node names. Since some manuals - % are best written with fairly long node names, containing hyphens, this - % is a loss. Therefore, we give the text of the node name again, so it - % is as if TeX is seeing it for the first time. - \ifdim \wd1 > 0pt - \putwordSection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}% + % + % If we use \unhbox to print the node names, TeX does not insert + % empty discretionaries after hyphens, which means that it will not + % find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, + % this is a loss. Therefore, we give the text of the node name + % again, so it is as if TeX is seeing it for the first time. + % + % Cross-manual reference. Only include the "Section ``foo'' in" if + % the foo is neither missing or Top. Thus, @xref{,,,foo,The Foo Manual} + % outputs simply "see The Foo Manual". + \ifdim \wd\printedmanualbox > 0pt + % What is the 7sp about? The idea is that we also want to omit + % the Section part if we would be printing "Top", since they are + % clearly trying to refer to the whole manual. But, this being + % TeX, we can't easily compare strings while ignoring the possible + % spaces before and after in the input. By adding the arbitrary + % 7sp, we make it much less likely that a real node name would + % happen to have the same width as "Top" (e.g., in a monospaced font). + % I hope it will never happen in practice. + % + % For the same basic reason, we retypeset the "Top" at every + % reference, since the current font is indeterminate. + % + \setbox\topbox = \hbox{Top\kern7sp}% + \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% + \ifdim \wd2 > 7sp + \ifdim \wd2 = \wd\topbox \else + \putwordSection{} ``\printedrefname'' \putwordin{}\space + \fi + \fi + \cite{\printedmanual}% \else + % Reference in this manual. + % % _ (for example) has to be the character _ for the purposes of the % control sequence corresponding to the node, but it has to expand % into the usual \leavevmode...\vrule stuff for purposes of @@ -7294,7 +7951,7 @@ end \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi }% - % output the `[mynode]' via a macro so it can be overridden. + % output the `[mynode]' via the macro below so it can be overridden. \xrefprintnodename\printedrefname % % But we always want a comma and a space: @@ -7357,7 +8014,8 @@ end \angleleft un\-de\-fined\angleright \iflinks \ifhavexrefs - \message{\linenumber Undefined cross reference `#1'.}% + {\toks0 = {#1}% avoid expansion of possibly-complex value + \message{\linenumber Undefined cross reference `\the\toks0'.}}% \else \ifwarnedxrefs\else \global\warnedxrefstrue @@ -7521,7 +8179,7 @@ end % space to prevent strange expansion errors.) \def\supereject{\par\penalty -20000\footnoteno =0 } -% @footnotestyle is meaningful for info output only. +% @footnotestyle is meaningful for Info output only. \let\footnotestyle=\comment {\catcode `\@=11 @@ -7584,6 +8242,8 @@ end % expands into a box, it must come within the paragraph, lest it % provide a place where TeX can split the footnote. \footstrut + % + % Invoke rest of plain TeX footnote routine. \futurelet\next\fo@t } }%end \catcode `\@=11 @@ -7671,7 +8331,7 @@ end it from ftp://tug.org/tex/epsf.tex.} % \def\image#1{% - \ifx\epsfbox\undefined + \ifx\epsfbox\thisisundefined \ifwarnednoepsf \else \errhelp = \noepsfhelp \errmessage{epsf.tex not found, images will be ignored}% @@ -7687,7 +8347,7 @@ end % #2 is (optional) width, #3 is (optional) height. % #4 is (ignored optional) html alt text. % #5 is (ignored optional) extension. -% #6 is just the usual extra ignored arg for parsing this stuff. +% #6 is just the usual extra ignored arg for parsing stuff. \newif\ifimagevmode \def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup \catcode`\^^M = 5 % in case we're inside an example @@ -7695,6 +8355,13 @@ end % If the image is by itself, center it. \ifvmode \imagevmodetrue + \else \ifx\centersub\centerV + % for @center @image, we need a vbox so we can have our vertical space + \imagevmodetrue + \vbox\bgroup % vbox has better behavior than vtop herev + \fi\fi + % + \ifimagevmode \nobreak\medskip % Usually we'll have text after the image which will insert % \parskip glue, so insert it here too to equalize the space @@ -7704,9 +8371,13 @@ end \fi % % Leave vertical mode so that indentation from an enclosing - % environment such as @quotation is respected. On the other hand, if - % it's at the top level, we don't want the normal paragraph indentation. - \noindent + % environment such as @quotation is respected. + % However, if we're at the top level, we don't want the + % normal paragraph indentation. + % On the other hand, if we are in the case of @center @image, we don't + % want to start a paragraph, which will create a hsize-width box and + % eradicate the centering. + \ifx\centersub\centerV\else \noindent \fi % % Output the image. \ifpdf @@ -7718,7 +8389,10 @@ end \epsfbox{#1.eps}% \fi % - \ifimagevmode \medskip \fi % space after the standalone image + \ifimagevmode + \medskip % space after a standalone image + \fi + \ifx\centersub\centerV \egroup \fi \endgroup} @@ -8136,7 +8810,7 @@ directory should work if nowhere else does.} % % Latin1 (ISO-8859-1) character definitions. \def\latonechardefs{% - \gdef^^a0{~} + \gdef^^a0{\tie} \gdef^^a1{\exclamdown} \gdef^^a2{\missingcharmsg{CENT SIGN}} \gdef^^a3{{\pounds}} @@ -8166,7 +8840,7 @@ directory should work if nowhere else does.} \gdef^^b9{$^1$} \gdef^^ba{\ordm} % - \gdef^^bb{\guilletright} + \gdef^^bb{\guillemetright} \gdef^^bc{$1\over4$} \gdef^^bd{$1\over2$} \gdef^^be{$3\over4$} @@ -8258,7 +8932,7 @@ directory should work if nowhere else does.} % Latin2 (ISO-8859-2) character definitions. \def\lattwochardefs{% - \gdef^^a0{~} + \gdef^^a0{\tie} \gdef^^a1{\ogonek{A}} \gdef^^a2{\u{}} \gdef^^a3{\L} @@ -8339,8 +9013,8 @@ directory should work if nowhere else does.} \gdef^^ea{\ogonek{e}} \gdef^^eb{\"e} \gdef^^ec{\v e} - \gdef^^ed{\'\i} - \gdef^^ee{\^\i} + \gdef^^ed{\'{\dotless{i}}} + \gdef^^ee{\^{\dotless{i}}} \gdef^^ef{\v d} % \gdef^^f0{\dh} @@ -8431,7 +9105,7 @@ directory should work if nowhere else does.} \gdef\DeclareUnicodeCharacter#1#2{% \countUTFz = "#1\relax - \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}% + %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}% \begingroup \parseXMLCharref \def\UTFviiiTwoOctets##1##2{% @@ -8899,8 +9573,8 @@ directory should work if nowhere else does.} % Prevent underfull vbox error messages. \vbadness = 10000 -% Don't be so finicky about underfull hboxes, either. -\hbadness = 2000 +% Don't be very finicky about underfull hboxes, either. +\hbadness = 6666 % Following George Bush, get rid of widows and orphans. \widowpenalty=10000 @@ -9107,28 +9781,21 @@ directory should work if nowhere else does.} \message{and turning on texinfo input format.} +\def^^L{\par} % remove \outer, so ^L can appear in an @comment + % DEL is a comment character, in case @c does not suffice. \catcode`\^^? = 14 % Define macros to output various characters with catcode for normal text. -\catcode`\"=\other -\catcode`\~=\other -\catcode`\^=\other -\catcode`\_=\other -\catcode`\|=\other -\catcode`\<=\other -\catcode`\>=\other -\catcode`\+=\other -\catcode`\$=\other -\def\normaldoublequote{"} -\def\normaltilde{~} -\def\normalcaret{^} -\def\normalunderscore{_} -\def\normalverticalbar{|} -\def\normalless{<} -\def\normalgreater{>} -\def\normalplus{+} -\def\normaldollar{$}%$ font-lock fix +\catcode`\"=\other \def\normaldoublequote{"} +\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix +\catcode`\+=\other \def\normalplus{+} +\catcode`\<=\other \def\normalless{<} +\catcode`\>=\other \def\normalgreater{>} +\catcode`\^=\other \def\normalcaret{^} +\catcode`\_=\other \def\normalunderscore{_} +\catcode`\|=\other \def\normalverticalbar{|} +\catcode`\~=\other \def\normaltilde{~} % This macro is used to make a character print one way in \tt % (where it can probably be output as-is), and another way in other fonts, @@ -9206,14 +9873,24 @@ directory should work if nowhere else does.} % In texinfo, backslash is an active character; it prints the backslash % in fixed width font. -\catcode`\\=\active -@def@normalbackslash{{@tt@backslashcurfont}} +\catcode`\\=\active % @ for escape char from now on. + +% The story here is that in math mode, the \char of \backslashcurfont +% ends up printing the roman \ from the math symbol font (because \char +% in math mode uses the \mathcode, and plain.tex sets +% \mathcode`\\="026E). It seems better for @backslashchar{} to always +% print a typewriter backslash, hence we use an explicit \mathchar, +% which is the decimal equivalent of "715c (class 7, e.g., use \fam; +% ignored family value; char position "5C). We can't use " for the +% usual hex value because it has already been made active. +@def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} +@let@backslashchar = @normalbackslash % @backslashchar{} is for user documents. + % On startup, @fixbackslash assigns: % @let \ = @normalbackslash - % \rawbackslash defines an active \ to do \backslashcurfont. % \otherbackslash defines an active \ to be a literal `\' character with -% catcode other. +% catcode other. We switch back and forth between these. @gdef@rawbackslash{@let\=@backslashcurfont} @gdef@otherbackslash{@let\=@realbackslash} @@ -9221,16 +9898,16 @@ directory should work if nowhere else does.} % the literal character `\'. % @def@normalturnoffactive{% - @let\=@normalbackslash @let"=@normaldoublequote - @let~=@normaltilde + @let$=@normaldollar %$ font-lock fix + @let+=@normalplus + @let<=@normalless + @let>=@normalgreater + @let\=@normalbackslash @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar - @let<=@normalless - @let>=@normalgreater - @let+=@normalplus - @let$=@normaldollar %$ font-lock fix + @let~=@normaltilde @markupsetuplqdefault @markupsetuprqdefault @unsepspaces @@ -9262,10 +9939,19 @@ directory should work if nowhere else does.} % Say @foo, not \foo, in error messages. @escapechar = `@@ +% These (along with & and #) are made active for url-breaking, so need +% active definitions as the normal characters. +@def@normaldot{.} +@def@normalquest{?} +@def@normalslash{/} + % These look ok in all fonts, so just make them not special. -@catcode`@& = @other -@catcode`@# = @other -@catcode`@% = @other +% @hashchar{} gets its own user-level command, because of #line. +@catcode`@& = @other @def@normalamp{&} +@catcode`@# = @other @def@normalhash{#} +@catcode`@% = @other @def@normalpercent{%} + +@let @hashchar = @normalhash @c Finally, make ` and ' active, so that txicodequoteundirected and @c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we