[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r7637 - in libmicrohttpd/doc: . chapters
From: |
gnunet |
Subject: |
[GNUnet-SVN] r7637 - in libmicrohttpd/doc: . chapters |
Date: |
Thu, 28 Aug 2008 13:29:47 -0600 (MDT) |
Author: sebdocwriter
Date: 2008-08-28 13:29:47 -0600 (Thu, 28 Aug 2008)
New Revision: 7637
Added:
libmicrohttpd/doc/chapters/
libmicrohttpd/doc/chapters/basicauthentication.inc
libmicrohttpd/doc/chapters/bibliography.inc
libmicrohttpd/doc/chapters/exploringrequests.inc
libmicrohttpd/doc/chapters/hellobrowser.inc
libmicrohttpd/doc/chapters/introduction.inc
libmicrohttpd/doc/chapters/processingpost.inc
libmicrohttpd/doc/chapters/responseheaders.inc
Removed:
libmicrohttpd/doc/basicauthentication.inc
libmicrohttpd/doc/bibliography.inc
libmicrohttpd/doc/exploringrequests.inc
libmicrohttpd/doc/hellobrowser.inc
libmicrohttpd/doc/introduction.inc
libmicrohttpd/doc/processingpost.inc
libmicrohttpd/doc/responseheaders.inc
Modified:
libmicrohttpd/doc/texinfo.tex
libmicrohttpd/doc/tutorial.texi
Log:
moved tutorial chapters to separate dir
Deleted: libmicrohttpd/doc/basicauthentication.inc
===================================================================
--- libmicrohttpd/doc/basicauthentication.inc 2008-08-28 06:51:01 UTC (rev
7636)
+++ libmicrohttpd/doc/basicauthentication.inc 2008-08-28 19:29:47 UTC (rev
7637)
@@ -1,207 +0,0 @@
-With the small exception of IP address based access control,
-requests from all connecting clients where served equally until now.
-This chapter discusses a first method of client's authentication and
-its limits.
-
-A very simple approach feasible with the means already discussed would
-be to expect the password in the @emph{URI} string before granting access to
-the secured areas. The password could be separated from the actual resource
identifier
-by a certain character, thus the request line might look like
address@hidden
-GET /picture.png?mypassword
address@hidden verbatim
address@hidden
-
-In a situation, where the client is customized enough and the connection occurs
-through secured lines (e.g., a embedded device directly attached to another
via wire),
-this can be a reasonable choice.
-
-But when it is assumed that the user connecting does so with an ordinary
Internet browser,
-this implementation brings some problems about. For example, the URI including
the password
-stays in the address field or at least in the history of the browser for
anybody near enough to see.
-It will also be inconvenient to add the password manually to any new URI when
the browser does
-not know how to compose this automatically.
-
-At least the convenience issue can be addressed by employing the simplest
built-in password
-facilities of HTTP compliant browsers, hence we want to start there. It will
however turn out
-to have still severe weaknesses in terms of security which need consideration.
-
-Before we will start implementing @emph{Basic Authentication} as described in
@emph{RFC 2617},
-we should finally abandon the bad practice of responding every request the
first time our callback
-is called for a given connection. This is becoming more important now because
the client and
-the server will have to talk in a more bi-directional way than before to
-
-But how can we tell whether the callback has been called before for the
particular connection?
-Initially, the pointer this parameter references is set by @emph{MHD} in the
callback. But it will
-also be "remembered" on the next call (for the same connection).
-Thus, we will generate no response until the parameter is non-null---implying
the callback was
-called before at least once. We do not need to share information between
different calls of the callback,
-so we can set the parameter to any adress that is assured to be not null. The
pointer to the
address@hidden structure will be pointing to a legal adress, so we take this.
-
-Not even the headers will be looked at on the first iteration.
-
address@hidden
-int answer_to_connection (void *cls, struct MHD_Connection *connection,
- const char *url, const char *method, const char
*version,
- const char *upload_data, unsigned int
*upload_data_size,
- void **con_cls)
-{
- if (0 != strcmp(method, "GET")) return MHD_NO;
- if (NULL == *con_cls) {*con_cls = connection; return MHD_YES;}
-
- ...
- /* else respond accordingly */
- ...
-}
address@hidden verbatim
address@hidden
-
-Note how we lop off the connection on the first condition, but return asking
for more on
-the other one with @code{MHD_YES}.
-With the framework improved, we can proceed to implement the actual
authentication process.
-
address@hidden Request for authentication
-
-Let us assume we had only files not intended to be handed out without the
correct username/password,
-so every "GET" request will be challenged.
address@hidden 2617} describes how the server shall ask for authentication by
adding a
address@hidden response header with the name of the @emph{realm} protected.
-
-We let an extra function function do this.
address@hidden
-int ask_for_authentication (struct MHD_Connection *connection, const char
*realm)
-{
- int ret;
- struct MHD_Response *response;
- char *headervalue;
- const char *strbase = "Basic realm=";
-
- response = MHD_create_response_from_data (0, NULL, MHD_NO, MHD_NO);
- if (!response) return MHD_NO;
-
- headervalue = malloc (strlen (strbase) + strlen (realm) + 1);
- if (!headervalue) return MHD_NO;
-
- strcpy (headervalue, strbase);
- strcat (headervalue, realm);
-
- ret = MHD_add_response_header (response, "WWW-Authenticate", headervalue);
- free (headervalue);
- if (!ret) {MHD_destroy_response (response); return MHD_NO;}
-
- ret = MHD_queue_response (connection, MHD_HTTP_UNAUTHORIZED, response);
-
- MHD_destroy_response (response);
-
- return ret;
-}
address@hidden verbatim
address@hidden
-
address@hidden the realm name according to your own taste, e.g. "Maintenance"
or "Area51" but
-it will need to have extra quotes.
-
-But the client may send the authentication right away, so it would be wrong to
ask for
-it without checking the request's header--where the authentication is expected
to be found.
-
address@hidden Authentication in detail
-Checking @emph{RFC 2617} again, we find that the client will pack the username
and password, by
-whatever means he might have obtained them, in a line separated by a
colon---and then encodes
-them to @emph{Base64}. The actual implementation of this encoding are not
within the scope of
-this tutorial although a working function is included in the complete source
file of the example.
-
-An unencoded word describing the authentication method (here "Basic") will
precede the code
-and the resulting line is the value of a request header of the type
"Authorization".
-
-This header line thus is of interest to the function checking a connection for
a given username/password:
address@hidden
-int is_authenticated (struct MHD_Connection *connection,
- const char *username, const char *password)
-{
- const char *headervalue;
- ...
-
- headervalue = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
- "Authorization");
- if (NULL == headervalue) return 0;
address@hidden verbatim
address@hidden
-
-where, firstly, the authentication method will be checked.
address@hidden
-const char *strbase = "Basic ";
-...
-if (0 != strncmp (headervalue, strbase, strlen (strbase))) return 0;
address@hidden verbatim
address@hidden
-
-Of course, we could decode the passed credentials in the next step and compare
them directly to
-the given strings. But as this would involve string parsing, which is more
complicated then string
-composing, it is done the other way around---the clear text credentials will
be encoded to @emph{Base64}
-and then compared against the headerline. The authentication method string
will be left out here as
-it has been checked already at this point.
address@hidden
- char *expected_b64, *expected;
- int authenticated;
-
- ...
- strcpy (expected, username);
- strcat (expected, ":");
- strcat (expected, password);
-
- expected_b64 = string_to_base64 (expected);
- if (NULL == expected_b64) return 0;
-
- strcpy (expected, strbase);
- authenticated = (strcmp (headervalue + strlen (strbase), expected_b64) == 0);
-
- free (expected_b64);
-
- return authenticated;
-}
address@hidden verbatim
address@hidden
-
-These two functions---together with a response function in case of positive
authentication doing little
-new---allow the rest of the callback function to be rather short.
address@hidden
- if (!is_authenticated (connection, USER, PASSWORD))
- return ask_for_authentication (connection, REALM);
-
- return secret_page (connection);
-}
address@hidden verbatim
address@hidden
-
-See the @code{examples} directory for the complete example file.
-
address@hidden Remarks
-For a proper server, the conditional statements leading to a return of
@code{MHD_NO} should yield a
-response with a more precise status code instead of silently closing the
connection. For example,
-failures of memory allocation are best reported as @emph{internal server
error} and unexpected
-authentication methods as @emph{400 bad request}.
-
address@hidden Exercises
address@hidden @bullet
address@hidden
-Make the server respond to wrong credentials (but else correct requests) with
the recommended
address@hidden unauthorized} status code. If the client still does not
authenticate correctly within the
-same connection, close it and store the client's IP address for a certain
time. (It is OK to check for
-expiration not until the main thread wakes up again on the next connection.)
If the client fails
-authenticating three times during this period, add it to another list whose
entries the
address@hidden function denies connection (temporally).
-
address@hidden
-With the network utility @emph{netcat} connect and log the response of a "GET"
request as you
-did in the exercise of the first example, this time to a file. Now stop the
server and let @emph{netcat}
-listen on the same port the server used to listen on and have it fake being
the proper server by giving
-the file's content as the response (e.g. @code{cat log | nc -l -p 8888}).
Pretending to think your were
-connecting to the actual server, browse to the eavesdropper and give the
correct credentials.
-
-Copy and paste the encoded string you see in netcat's output to some of the
Base64 decode tools available online
-and see how both the user's name and password could be completely restored.
-
address@hidden itemize
-
-
Deleted: libmicrohttpd/doc/bibliography.inc
===================================================================
--- libmicrohttpd/doc/bibliography.inc 2008-08-28 06:51:01 UTC (rev 7636)
+++ libmicrohttpd/doc/bibliography.inc 2008-08-28 19:29:47 UTC (rev 7637)
@@ -1,30 +0,0 @@
address@hidden @bullet
address@hidden API reference
address@hidden
-The @emph{GNU libmicrohttpd} manual by Christian Grothoff 2008
address@hidden://gnunet.org/libmicrohttpd/microhttpd.html}
-
address@hidden Requests for comments
-All referenced RFCs can be found on the website of @emph{The Internet
Engineering Task Force}
address@hidden://www.ietf.org/}
-
address@hidden
address@hidden 2616}: Fielding, R., Gettys, J., Mogul, J., Frystyk, H., and T.
Berners-Lee,
-"Hypertext Transfer Protocol -- HTTP/1.1", RFC 2016, January 1997.
-
address@hidden
address@hidden 2617}: Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence,
S., Leach, P.,
-Luotonen, A., and L. Stewart, "HTTP Authentication: Basic and Digest Access
Authentication", RFC 2617, June 1999.
-
-
address@hidden Recommended readings
address@hidden
-A well--structured @emph{HTML} reference can be found on
address@hidden://www.echoecho.com/html.htm}
-
-For those readers understanding German or French, there is an excellent
document both for learning
address@hidden and for reference, whose English version unfortunately has been
discontinued.
address@hidden://de.selfhtml.org/} and @uref{http://fr.selfhtml.org/}
-
-
address@hidden itemize
Copied: libmicrohttpd/doc/chapters/basicauthentication.inc (from rev 7636,
libmicrohttpd/doc/basicauthentication.inc)
===================================================================
--- libmicrohttpd/doc/chapters/basicauthentication.inc
(rev 0)
+++ libmicrohttpd/doc/chapters/basicauthentication.inc 2008-08-28 19:29:47 UTC
(rev 7637)
@@ -0,0 +1,207 @@
+With the small exception of IP address based access control,
+requests from all connecting clients where served equally until now.
+This chapter discusses a first method of client's authentication and
+its limits.
+
+A very simple approach feasible with the means already discussed would
+be to expect the password in the @emph{URI} string before granting access to
+the secured areas. The password could be separated from the actual resource
identifier
+by a certain character, thus the request line might look like
address@hidden
+GET /picture.png?mypassword
address@hidden verbatim
address@hidden
+
+In a situation, where the client is customized enough and the connection occurs
+through secured lines (e.g., a embedded device directly attached to another
via wire),
+this can be a reasonable choice.
+
+But when it is assumed that the user connecting does so with an ordinary
Internet browser,
+this implementation brings some problems about. For example, the URI including
the password
+stays in the address field or at least in the history of the browser for
anybody near enough to see.
+It will also be inconvenient to add the password manually to any new URI when
the browser does
+not know how to compose this automatically.
+
+At least the convenience issue can be addressed by employing the simplest
built-in password
+facilities of HTTP compliant browsers, hence we want to start there. It will
however turn out
+to have still severe weaknesses in terms of security which need consideration.
+
+Before we will start implementing @emph{Basic Authentication} as described in
@emph{RFC 2617},
+we should finally abandon the bad practice of responding every request the
first time our callback
+is called for a given connection. This is becoming more important now because
the client and
+the server will have to talk in a more bi-directional way than before to
+
+But how can we tell whether the callback has been called before for the
particular connection?
+Initially, the pointer this parameter references is set by @emph{MHD} in the
callback. But it will
+also be "remembered" on the next call (for the same connection).
+Thus, we will generate no response until the parameter is non-null---implying
the callback was
+called before at least once. We do not need to share information between
different calls of the callback,
+so we can set the parameter to any adress that is assured to be not null. The
pointer to the
address@hidden structure will be pointing to a legal adress, so we take this.
+
+Not even the headers will be looked at on the first iteration.
+
address@hidden
+int answer_to_connection (void *cls, struct MHD_Connection *connection,
+ const char *url, const char *method, const char
*version,
+ const char *upload_data, unsigned int
*upload_data_size,
+ void **con_cls)
+{
+ if (0 != strcmp(method, "GET")) return MHD_NO;
+ if (NULL == *con_cls) {*con_cls = connection; return MHD_YES;}
+
+ ...
+ /* else respond accordingly */
+ ...
+}
address@hidden verbatim
address@hidden
+
+Note how we lop off the connection on the first condition, but return asking
for more on
+the other one with @code{MHD_YES}.
+With the framework improved, we can proceed to implement the actual
authentication process.
+
address@hidden Request for authentication
+
+Let us assume we had only files not intended to be handed out without the
correct username/password,
+so every "GET" request will be challenged.
address@hidden 2617} describes how the server shall ask for authentication by
adding a
address@hidden response header with the name of the @emph{realm} protected.
+
+We let an extra function function do this.
address@hidden
+int ask_for_authentication (struct MHD_Connection *connection, const char
*realm)
+{
+ int ret;
+ struct MHD_Response *response;
+ char *headervalue;
+ const char *strbase = "Basic realm=";
+
+ response = MHD_create_response_from_data (0, NULL, MHD_NO, MHD_NO);
+ if (!response) return MHD_NO;
+
+ headervalue = malloc (strlen (strbase) + strlen (realm) + 1);
+ if (!headervalue) return MHD_NO;
+
+ strcpy (headervalue, strbase);
+ strcat (headervalue, realm);
+
+ ret = MHD_add_response_header (response, "WWW-Authenticate", headervalue);
+ free (headervalue);
+ if (!ret) {MHD_destroy_response (response); return MHD_NO;}
+
+ ret = MHD_queue_response (connection, MHD_HTTP_UNAUTHORIZED, response);
+
+ MHD_destroy_response (response);
+
+ return ret;
+}
address@hidden verbatim
address@hidden
+
address@hidden the realm name according to your own taste, e.g. "Maintenance"
or "Area51" but
+it will need to have extra quotes.
+
+But the client may send the authentication right away, so it would be wrong to
ask for
+it without checking the request's header--where the authentication is expected
to be found.
+
address@hidden Authentication in detail
+Checking @emph{RFC 2617} again, we find that the client will pack the username
and password, by
+whatever means he might have obtained them, in a line separated by a
colon---and then encodes
+them to @emph{Base64}. The actual implementation of this encoding are not
within the scope of
+this tutorial although a working function is included in the complete source
file of the example.
+
+An unencoded word describing the authentication method (here "Basic") will
precede the code
+and the resulting line is the value of a request header of the type
"Authorization".
+
+This header line thus is of interest to the function checking a connection for
a given username/password:
address@hidden
+int is_authenticated (struct MHD_Connection *connection,
+ const char *username, const char *password)
+{
+ const char *headervalue;
+ ...
+
+ headervalue = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
+ "Authorization");
+ if (NULL == headervalue) return 0;
address@hidden verbatim
address@hidden
+
+where, firstly, the authentication method will be checked.
address@hidden
+const char *strbase = "Basic ";
+...
+if (0 != strncmp (headervalue, strbase, strlen (strbase))) return 0;
address@hidden verbatim
address@hidden
+
+Of course, we could decode the passed credentials in the next step and compare
them directly to
+the given strings. But as this would involve string parsing, which is more
complicated then string
+composing, it is done the other way around---the clear text credentials will
be encoded to @emph{Base64}
+and then compared against the headerline. The authentication method string
will be left out here as
+it has been checked already at this point.
address@hidden
+ char *expected_b64, *expected;
+ int authenticated;
+
+ ...
+ strcpy (expected, username);
+ strcat (expected, ":");
+ strcat (expected, password);
+
+ expected_b64 = string_to_base64 (expected);
+ if (NULL == expected_b64) return 0;
+
+ strcpy (expected, strbase);
+ authenticated = (strcmp (headervalue + strlen (strbase), expected_b64) == 0);
+
+ free (expected_b64);
+
+ return authenticated;
+}
address@hidden verbatim
address@hidden
+
+These two functions---together with a response function in case of positive
authentication doing little
+new---allow the rest of the callback function to be rather short.
address@hidden
+ if (!is_authenticated (connection, USER, PASSWORD))
+ return ask_for_authentication (connection, REALM);
+
+ return secret_page (connection);
+}
address@hidden verbatim
address@hidden
+
+See the @code{examples} directory for the complete example file.
+
address@hidden Remarks
+For a proper server, the conditional statements leading to a return of
@code{MHD_NO} should yield a
+response with a more precise status code instead of silently closing the
connection. For example,
+failures of memory allocation are best reported as @emph{internal server
error} and unexpected
+authentication methods as @emph{400 bad request}.
+
address@hidden Exercises
address@hidden @bullet
address@hidden
+Make the server respond to wrong credentials (but else correct requests) with
the recommended
address@hidden unauthorized} status code. If the client still does not
authenticate correctly within the
+same connection, close it and store the client's IP address for a certain
time. (It is OK to check for
+expiration not until the main thread wakes up again on the next connection.)
If the client fails
+authenticating three times during this period, add it to another list whose
entries the
address@hidden function denies connection (temporally).
+
address@hidden
+With the network utility @emph{netcat} connect and log the response of a "GET"
request as you
+did in the exercise of the first example, this time to a file. Now stop the
server and let @emph{netcat}
+listen on the same port the server used to listen on and have it fake being
the proper server by giving
+the file's content as the response (e.g. @code{cat log | nc -l -p 8888}).
Pretending to think your were
+connecting to the actual server, browse to the eavesdropper and give the
correct credentials.
+
+Copy and paste the encoded string you see in netcat's output to some of the
Base64 decode tools available online
+and see how both the user's name and password could be completely restored.
+
address@hidden itemize
+
+
Copied: libmicrohttpd/doc/chapters/bibliography.inc (from rev 7636,
libmicrohttpd/doc/bibliography.inc)
===================================================================
--- libmicrohttpd/doc/chapters/bibliography.inc (rev 0)
+++ libmicrohttpd/doc/chapters/bibliography.inc 2008-08-28 19:29:47 UTC (rev
7637)
@@ -0,0 +1,30 @@
address@hidden @bullet
address@hidden API reference
address@hidden
+The @emph{GNU libmicrohttpd} manual by Christian Grothoff 2008
address@hidden://gnunet.org/libmicrohttpd/microhttpd.html}
+
address@hidden Requests for comments
+All referenced RFCs can be found on the website of @emph{The Internet
Engineering Task Force}
address@hidden://www.ietf.org/}
+
address@hidden
address@hidden 2616}: Fielding, R., Gettys, J., Mogul, J., Frystyk, H., and T.
Berners-Lee,
+"Hypertext Transfer Protocol -- HTTP/1.1", RFC 2016, January 1997.
+
address@hidden
address@hidden 2617}: Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence,
S., Leach, P.,
+Luotonen, A., and L. Stewart, "HTTP Authentication: Basic and Digest Access
Authentication", RFC 2617, June 1999.
+
+
address@hidden Recommended readings
address@hidden
+A well--structured @emph{HTML} reference can be found on
address@hidden://www.echoecho.com/html.htm}
+
+For those readers understanding German or French, there is an excellent
document both for learning
address@hidden and for reference, whose English version unfortunately has been
discontinued.
address@hidden://de.selfhtml.org/} and @uref{http://fr.selfhtml.org/}
+
+
address@hidden itemize
Copied: libmicrohttpd/doc/chapters/exploringrequests.inc (from rev 7636,
libmicrohttpd/doc/exploringrequests.inc)
===================================================================
--- libmicrohttpd/doc/chapters/exploringrequests.inc
(rev 0)
+++ libmicrohttpd/doc/chapters/exploringrequests.inc 2008-08-28 19:29:47 UTC
(rev 7637)
@@ -0,0 +1,103 @@
+This chapter will deal with the information which the client sends to the
+server at every request. We are going to examine the most useful fields of
such an request
+and print them out in a readable manner. This could be useful for logging
facilities.
+
+The starting point is the @emph{hellobrowser} program with the former response
removed.
+
+This time, we just want to collect information in the callback function, thus
we will
+just return MHD_NO after we have probed the request. This way, the connection
is closed
+without much ado by the server.
+
address@hidden
+int answer_to_connection (void *cls, struct MHD_Connection *connection, const
char *url,
+ const char *method, const char *version, const char
*upload_data,
+ unsigned int *upload_data_size, void **con_cls)
+{
+ ...
+ return MHD_NO;
+}
address@hidden verbatim
address@hidden
+The ellipsis marks the position where the following instructions shall be
inserted.
+
+
+We begin with the most obvious information available to the server, the
request line. You should
+already have noted that a request consists of a command (or "method") and a
URI (e.g. a filename).
+It also contains a string for the version of the protocol which can be found
in @code{version}.
+To call it a "new request" is justified because we return only @code{MHD_NO},
thus ensuring the
+function will not be called again for this connection.
address@hidden
+printf ("New request %s for %s using version %s\n", method, url, version);
address@hidden verbatim
address@hidden
+
+The rest of the information is a bit more hidden. Nevertheless, there is lot
of it sent from common
+Internet browsers. It is stored in "key-name" pairs and we want to list what
we find in the header.
+As there is no mandatory set of keys a client has to send, each key--name pair
is printed out one by
+one until there are no more left. We do this by writing a separate function
which will be called for
+each pair just like the above function is called for each HTTP request.
+It can then print out the content of this pair.
address@hidden
+int print_out_key (void *cls, enum MHD_ValueKind kind, const char *key, const
char *value)
+{
+ printf ("%s = %s\n", key, value);
+ return MHD_YES;
+}
address@hidden verbatim
address@hidden
+
+To start the iteration process that calls our new function for every key, the
line
address@hidden
+MHD_get_connection_values (connection, MHD_HEADER_KIND, print_out_key, NULL);
address@hidden verbatim
address@hidden
+needs to be inserted in the connection callback function too. The second
parameter tells the function
+that we are only interested in keys from the general HTTP header of the
request. Our iterating
+function @code{PrintOutKey} does not rely on any additional information to
fulfill its duties
+so the last parameter can be NULL.
+
+All in all, this constitutes the complete @code{logger.c} program for this
chapter which can be
+found in the @code{examples} section.
+
+Connecting with any modern Internet browser should yield a handful of keys.
You should try to
+interpret them with the aid of @emph{RFC 2616}.
+Especially worth mentioning is the host key which is often used to serve
several different websites
+hosted under one single IP address but reachable by different domain names.
+
address@hidden Conclusion
+The introduced capabilities to itemize the content of a simple GET
request---especially the
+URI---should already allow the server to satisfy clients' requests for small
specific resources
+(e.g. files) or even induce alteration of how the server operates. However,
the latter is not
+recommended as the GET method (including its header data) is by convention
considered a "SAFE"
+operation, which should not change the server's state in a significant way,
but temporally actions
+like searching for a passed string is fine.
+
+Of course, no transmission can occur while the return value is still set to
@code{MHD_NO} in the
+callback function.
+
address@hidden Exercises
address@hidden @bullet
address@hidden
+By parsing the @code{url} string and delivering responses accordingly,
implement a small server for
+"virtual" files. When asked for @code{/address@hidden@}}, let the response
consist of a HTML page
+containing a link to @code{/another.html} page which is also to be created "on
the fly" in case of
+being requested. If neither of these two pages are requested,
@code{MHD_HTTP_NOT_FOUND} shall be
+returned accompanied by an informative message.
+
address@hidden
+A very interesting information has still been ignored by our logger---the
client's IP address.
+Implement a callback function
address@hidden
+int on_client_connect (void *cls,
+ const struct sockaddr *addr,socklen_t addrlen)
address@hidden verbatim
address@hidden
+that prints out the IP address in an appropriate format. You might want to use
the posix function
address@hidden but bear in mind that @code{addr} is actually just a structure
containing other
+substructures and is @emph{not} the variable this function expects.
+Make sure to return @code{MHD_YES} so that the library knows the client is
allowed to connect
+(and to request). If one wanted to limit access basing on IP addresses, this
would be the place
+to do it. The address of your function will then be passed as the third
parameter of the
address@hidden call.
+
address@hidden itemize
Copied: libmicrohttpd/doc/chapters/hellobrowser.inc (from rev 7636,
libmicrohttpd/doc/hellobrowser.inc)
===================================================================
--- libmicrohttpd/doc/chapters/hellobrowser.inc (rev 0)
+++ libmicrohttpd/doc/chapters/hellobrowser.inc 2008-08-28 19:29:47 UTC (rev
7637)
@@ -0,0 +1,203 @@
+The most basic task for a HTTP server is to deliver a static text message to
any client connecting to it.
+Given that this is also easy to implement, it is an excellent problem to start
with.
+
+For now, the particular filename the client asks for shall have no effect on
the message that will
+be returned. In addition, the server shall end the connection after the
message has been sent so that
+the client will know there is nothing more to expect.
+
+The C program @code{hellobrowser.c}, which is to be found in the examples
section, does just that.
+If you are very eager, you can compile and start it right away but it is
advisable to type the
+lines in by yourself as they will be discussed and explained in detail.
+
+After the unexciting includes and the definition of the port which our server
should listen on
address@hidden
+#include <microhttpd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
address@hidden verbatim
address@hidden
+the desired behaviour of our server when HTTP request arrive have to be
implemented. We already have
+agreed that it should not care about the particular details of the request,
such as who is requesting
+what. The server will respond merely with the same small HTML page to every
request.
+
+The function we are going to write now will be called by @emph{GNU
libmicrohttpd} every time an
+appropriate request comes in. While the name of this callback function is
arbitrary, its parameter
+list has to follow a certain layout. So please, ignore the lot of parameters
for now, they will be
+explained at the point they are needed. We have to use only one of them,
address@hidden MHD_Connection *connection}, for the minimalistic functionality
we want to archive at the moment.
+
+This parameter is set by the @emph{libmicrohttpd} daemon and holds the
necessary information to
+relate the call with a certain connection. Keep in mind that a server might
have to satisfy hundreds
+of concurrent connections and we have to make sure that the correct data is
sent to the destined
+client. Therefore, this variable is a means to refer to a particular
connection if we ask the
+daemon to sent the reply.
+
+Talking about the reply, it is defined as a string right after the function
header
address@hidden
+int answer_to_connection (void *cls, struct MHD_Connection *connection, const
char *url,
+ const char *method, const char *version, const char
*upload_data,
+ unsigned int *upload_data_size, void **con_cls)
+{
+ const char *page = "<html><body>Hello, browser!</body></html>";
address@hidden verbatim
address@hidden
+HTTP is a rather strict protocol and the client would certainly consider it
"inappropriate" if we
+just sent the answer string "as is". Instead, it has to be wrapped in certain
layers, called headers,
+of additional information. Luckily, most of the work in this area is done by
the library for us---we
+just have to ask. Our reply string packed in the necessary layers will be
called a "response".
+To obtain such a response we hand our data (the reply--string) and its size
over to the
address@hidden function. The last two parameters basically tell @emph{MHD}
+that we do not want it to dispose the message data for us when it has been
sent and there also needs
+no internal copy to be done because the @emph{constant} string won't change
anyway.
+
address@hidden
+ struct MHD_Response *response;
+ int ret;
+
+ response = MHD_create_response_from_data (strlen (page),
+ (void*) page, MHD_NO, MHD_NO);
address@hidden verbatim
address@hidden
+Now that the the response has been laced up, it is ready for delivery and can
be queued for sending.
+This is done by passing it to another @emph{GNU libmicrohttpd} function. As
all our work was done in
+the scope of one function, the recipient is without doubt the one associated
with the
+local variable @code{connection} and consequently this variable is given to
the queue function.
+Every HTTP response is accompanied by a status code, here "OK", so that the
client knows
+this response is the intended result of his request and not due to some error
or malfunction.
+
+Finally, the packet is destroyed and the return value from the queue returned,
+already being set at this point to either MHD_YES or MHD_NO in case of success
or failure.
+
address@hidden
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+
+ return ret;
+}
address@hidden verbatim
address@hidden
+With the primary task of our server implemented, we can start the actual
server daemon which will listen
+on @code{PORT} for connections. This is done in the main function.
address@hidden
+int main ()
+{
+ struct MHD_Daemon *daemon;
+
+ daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
+ &answer_to_connection, NULL, MHD_OPTION_END);
+ if (NULL == daemon) return 1;
address@hidden verbatim
address@hidden
+The first parameter is one of three possible modes of operation. Here we want
the daemon to run in
+a separate thread and to manage all incoming connections in the same thread.
This means that while
+producing the response for one connection, the other connections will be put
on hold. In this
+chapter, where the reply is already known and therefore the request is served
quickly, this poses no problem.
+
+We will allow all clients to connect regardless of their name or location,
therefore we do not check
+them on connection and set the forth and fifth parameter to NULL.
+
+Parameter six is the address of the function we want to be called whenever a
new connection has been
+established. Our @code{AnswerToConnection} knows best what the client wants
and needs no additional
+information (which could be passed via the next parameter) so the next
parameter is NULL. Likewise,
+we do not need to pass extra options to the daemon so we just write the
MHD_OPTION_END as the last parameter.
+
+As the server daemon runs in the background in its own thread, the execution
flow in our main
+function will contine right after the call. Because of this, we must delay the
execution flow in the
+main thread or else the program will terminate prematurely. We let it pause in
a processing-time
+friendly manner by waiting for the enter key to be pressed. In the end, we
stop the daemon so it can
+do its cleanup tasks.
address@hidden
+ getchar ();
+
+ MHD_stop_daemon (daemon);
+ return 0;
+}
+
address@hidden verbatim
address@hidden
+The first example is now complete.
+
+Compile it with
address@hidden
+cc hellobrowser.c -o hellobrowser -I$PATH_TO_LIBMHD_INCLUDES
+ -L$PATH_TO_LIBMHD_INCLUDES -static -lmicrohttpd -pthread
address@hidden verbatim
+with the two paths set accordingly and run it.
+
+Now open your favorite Internet browser and go to the address
@code{localhost:8888}, provided that
+is the port you chose. If everything works as expected, the browser will
present the message of the
+static HTML page it got from our minimal server.
+
address@hidden Remarks
+To keep this first example as small as possible, some drastic shortcuts were
taken and are to be
+discussed now.
+
+Firstly, there is no distinction made between the kinds of requests a client
could send. We implied
+that the client sends a GET request, that means, that he actually asked for
some data. Even when
+it is not intended to accept POST requests, a good server should at least
recognize that this
+request does not constitute a legal request and answer with an error code.
This can be easily
+implemented by checking if the parameter @code{method} equals the string "GET"
and returning a
address@hidden if not so.
+
+Secondly, the above practice of queuing a response upon the first call of the
callback function
+brings with it some limitations. This is because the content of the message
body will not be
+received if a response is queued in the first iteration. Furthermore, the
connection will be closed
+right after the response has been transferred then.
+
+Both of these issues you will find addressed in the official
@code{minimal_example.c} residing in
+the @code{src/examples} directory of the @emph{GNU libmicrohttpd} package. The
source code of this
+program should look very familiar to you by now and easy to understand.
+
+For our example, the @code{must_copy} and @code{must_free} parameter at the
response construction
+function could be set to @code{MHD_NO}. In the usual case, responses cannot be
sent immediately
+after being queued. For example, there might be other data on the system that
needs to be sent with
+a higher priority. Nevertheless, the queue function will return
successfully---raising the problem
+that the data we have pointed to may be invalid by the time it is about being
sent. This is not an
+issue here because we can expect the @code{page} string, which is a constant
@emph{string literal}
+here, to be static. That means it will be present and unchanged for as long as
the program runs.
+For dynamic data, one could choose to either have @emph{MHD} free the memory
@code{page} points
+to itself when it is not longer needed or, alternatively, have the library to
make and manage
+its own copy of it.
+
address@hidden Exercises
address@hidden @bullet
address@hidden
+While the server is running, use a program like telnet or netcat to connect to
it. Try to form a
+valid HTTP1.1 request yourself like
address@hidden
+GET /dontcare HTTP1.1
+Host: itsme
+<enter>
address@hidden verbatim
address@hidden
+and see what the server returns to you.
+
+
address@hidden
+Also, try other requests, like POST, and see how our server does not mind and
why.
+How far in malforming a request can you go before the builtin functionality of
@emph{MHD} intervenes
+and an altered response is sent? Make sure you read about the status codes in
the @emph{RFC}.
+
+
address@hidden
+Add the option @code{MHD_USE_PEDANTIC_CHECKS} to the start function of the
daemon in @code{main}.
+Mind the special format of the parameter list here which is described in the
manual. How indulgent
+is the server now to your input?
+
+
address@hidden
+Let the main function take a string as the first command line argument and
pass @code{argv[1]} to
+the @code{MHD_start_daemon} function as the sixth parameter. The address of
this string will be
+passed to the callback function via the @code{cls} variable. Decorate the text
given at the command
+line when the server is started with proper HTML tags and send it as the
response instead of the
+former static string.
+
+
address@hidden
address@hidden:} Write a separate function returning a string containing some
useful information,
+for example, the time. Pass the function's address as the sixth parameter and
evaluate this function
+on every request anew in @code{AnswerToConnection}. Remember to free the
memory of the string
+every time after satisfying the request.
+
address@hidden itemize
Copied: libmicrohttpd/doc/chapters/introduction.inc (from rev 7636,
libmicrohttpd/doc/introduction.inc)
===================================================================
--- libmicrohttpd/doc/chapters/introduction.inc (rev 0)
+++ libmicrohttpd/doc/chapters/introduction.inc 2008-08-28 19:29:47 UTC (rev
7637)
@@ -0,0 +1,17 @@
+This tutorial is for developers who want to learn how they can add HTTP
serving
+capabilities to their applications with the @emph{GNU libmicrohttpd} library,
+abbreviated @emph{MHD}. The reader will learn how to
+implement basic HTTP functions from simple executable
+sample programs that implement various features.
+
+The text is supposed to be a supplement to the API reference manual of
address@hidden libmicrohttpd} and for that reason does not explain many of the
parameters.
+Therefore, the reader should always consult the manual to find the exact
meaning
+of the functions used in the tutorial. Furthermore, the reader is
+encouraged to study the relevant @emph{RFCs}, which document the HTTP standard.
+
address@hidden libmicrohttpd} is assumed to be already installed. This tutorial
+is written for version @value{VERSION}. At the time being,
+this tutorial has only been tested on @emph{GNU/Linux} machines even though
+efforts were made not to rely on anything that would prevent the samples from
being
+built on similar systems.
Copied: libmicrohttpd/doc/chapters/processingpost.inc (from rev 7636,
libmicrohttpd/doc/processingpost.inc)
===================================================================
--- libmicrohttpd/doc/chapters/processingpost.inc
(rev 0)
+++ libmicrohttpd/doc/chapters/processingpost.inc 2008-08-28 19:29:47 UTC
(rev 7637)
@@ -0,0 +1,231 @@
+The previous chapters already have demonstrated a variety of possibilities to
send information
+to the HTTP server, but it is not recommended that the @emph{GET} method is
used to alter the way
+the server operates. To induce changes on the server, the @emph{POST} method
is preferred over
+and is much more powerful than @emph{GET} and will be introduced in this
chapter.
+
+We are going to write an application that asks for the visitor's name and,
after the user has posted it,
+composes an individual response text. Even though it was not mandatory to use
the @emph{post} method here,
+as there is no permanent change caused by the post, it is an illustrative
example on how to share data
+between different functions for the same connection. Furthermore, the reader
should be able to extend
+it easily.
+
address@hidden GET request
+When the first @emph{GET} request arrives, the server shall respond with a
HTML page containing an
+edit field for the name.
+
address@hidden
+const char* askpage = "<html><body>\
+ What's your name, Sir?<br>\
+ <form action=\"/namepost\" method=\"post\">\
+ <input name=\"name\" type=\"text\"\
+ <input type=\"submit\" value=\" Send \"></form>\
+ </body></html>";
address@hidden verbatim
address@hidden
+
+The @code{action} entry is the @emph{URI} to be called by the browser when
posting, and the
address@hidden will be used later to be sure it is the editbox's content that
has been posted.
+
+We also prepare the answer page, where the name is to be filled in later, and
an error page
+as the response for anything but proper @emph{GET} and @emph{POST} requests:
+
address@hidden
+const char* greatingpage="<html><body><h1>Welcome,
%s!</center></h1></body></html>";
+
+const char* errorpage="<html><body>This doesn't seem to be
right.</body></html>";
address@hidden verbatim
address@hidden
+
+Whenever we need to send a page, we use an extra function
address@hidden SendPage(struct MHD_Connection *connection, const char* page)}
+for this, which does not contain anything new and whose implementation is
therefore left out here.
+
+
address@hidden POST request
+Posted data can be of arbitrary and considerable size; for example, if a user
uploads a big
+image to the server. Similar to the case of the header fields, there may also
be different streams
+of posted data, such as one containing the text of an editbox and another the
state of a button.
+Likewise, we will have to register an iterator function that is going to be
called maybe several times
+not only if there are different POSTs but also if one POST has only been
received partly yet and
+needs processing before another chunk can be received.
+
+Such an iterator function is called by a @emph{postprocessor}, which must be
created upon arriving
+of the post request. We want the iterator function to read the first post
data which is tagged
address@hidden and to create an individual greeting string based on the
template and the name.
+But in order to pass this string to other functions and still be able to
differentiate different
+connections, we must first define a structure to share the information,
holding the most import entries.
+
address@hidden
+struct connection_info_struct
+{
+ int connectiontype;
+ char *answerstring;
+ struct MHD_PostProcessor *postprocessor;
+};
address@hidden verbatim
address@hidden
+
+With these information available to the iterator function, it is able to
fulfill its task.
+Once it has composed the greeting string, it returns @code{MHD_NO} to inform
the post processor
+that it does not need to be called again. Note that this function does not
handle processing
+of data for the same @code{key}. If we were to expect that the name will be
posted in several
+chunks, we had to expand the namestring dynamically as additional parts of it
with the same @code{key}
+came in. But in this example, the name is assumed to fit entirely inside one
single packet.
+
address@hidden
+int iterate_post (void *coninfo_cls, enum MHD_ValueKind kind, const char *key,
+ const char *filename, const char *content_type,
+ const char *transfer_encoding, const char *data, size_t off,
size_t size)
+{
+ struct connection_info_struct *con_info = (struct connection_info_struct*)
coninfo_cls;
+
+
+ if (0 == strcmp (key, "name"))
+ {
+ if ((size > 0) && (size <= MAXNAMESIZE))
+ {
+ char *answerstring;
+ answerstring = malloc (MAXANSWERSIZE);
+ if (!answerstring) return MHD_NO;
+
+ snprintf (answerstring, MAXANSWERSIZE, greatingpage, data);
+ con_info->answerstring = answerstring;
+ }
+ else con_info->answerstring = NULL;
+
+ return MHD_NO;
+ }
+
+ return MHD_YES;
+}
address@hidden verbatim
address@hidden
+
+Once a connection has been established, it can be terminated for many reasons.
As these
+reasons include unexpected events, we have to register another function that
cleans up any resources
+that might have been allocated for that connection by us, namely the post
processor and the greetings
+string. This cleanup function must take into account that it will also be
called for finished
+requests other than @emph{POST} requests.
+
address@hidden
+void request_completed (void *cls, struct MHD_Connection *connection, void
**con_cls,
+ enum MHD_RequestTerminationCode toe)
+{
+ struct connection_info_struct *con_info = (struct connection_info_struct*)
*con_cls;
+
+
+ if (NULL == con_info) return;
+
+ if (con_info->connectiontype == POST)
+ {
+ MHD_destroy_post_processor (con_info->postprocessor);
+ if (con_info->answerstring) free (con_info->answerstring);
+ }
+
+ free (con_info);
+ *con_cls = NULL;
+}
address@hidden verbatim
address@hidden
+
address@hidden libmicrohttpd} is informed that it shall call the above function
when the daemon is started
+in the main function.
+
address@hidden
+...
+daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
+ &answer_to_connection, NULL,
MHD_OPTION_NOTIFY_COMPLETED,
+ request_completed, NULL, MHD_OPTION_END);
+...
address@hidden verbatim
address@hidden
+
address@hidden Request handling
+With all other functions prepared, we can now discuss the actual request
handling.
+
+On the first iteration for a new request, we start by allocating a new
instance of a
address@hidden structure, which will store all necessary information for later
+iterations and other functions.
+
address@hidden
+int answer_to_connection (void *cls, struct MHD_Connection *connection, const
char *url,
+ const char *method, const char *version, const char
*upload_data,
+ unsigned int *upload_data_size, void **con_cls)
+{
+ if(NULL == *con_cls)
+ {
+ struct connection_info_struct *con_info;
+
+ con_info = malloc (sizeof (struct connection_info_struct));
+ if (NULL == con_info) return MHD_NO;
+ con_info->answerstring = NULL;
address@hidden verbatim
address@hidden
+
+If the new request is a @emph{POST}, the postprocessor must be created now. In
addition, the type
+of the request is stored for convenience.
address@hidden
+ if (0 == strcmp (method, "POST"))
+ {
+ con_info->postprocessor = MHD_create_post_processor (connection,
POSTBUFFERSIZE,
+ iterate_post,
(void*) con_info);
+
+ if (NULL == con_info->postprocessor)
+ {
+ free (con_info);
+ return MHD_NO;
+ }
+
+ con_info->connectiontype = POST;
+ }
+ else con_info->connectiontype = GET;
address@hidden verbatim
address@hidden
+
+The address of our structure will both serve as the indicator for successive
iterations and to remember
+the particular details about the connection.
address@hidden
+ *con_cls = (void*) con_info;
+ return MHD_YES;
+ }
address@hidden verbatim
address@hidden
+
+The rest of the function will not be executed on the first iteration. A
@emph{GET} request is easily
+satisfied by sending the question form.
address@hidden
+ if (0 == strcmp (method, "GET"))
+ {
+ return send_page (connection, askpage);
+ }
address@hidden verbatim
address@hidden
+
+In case of @emph{POST}, we invoke the post processor for as long as data keeps
incoming, setting
address@hidden to zero in order to indicate that we have processed---or at
least have
+considered---all of it.
address@hidden
+ if (0 == strcmp (method, "POST"))
+ {
+ struct connection_info_struct *con_info = *con_cls;
+
+ if (*upload_data_size != 0)
+ {
+ MHD_post_process(con_info->postprocessor, upload_data,
*upload_data_size);
+ *upload_data_size = 0;
+
+ return MHD_YES;
+ }
+ else if (NULL != con_info->answerstring) return send_page (connection,
con_info->answerstring);
+ }
address@hidden verbatim
address@hidden
+
+If they are neither @emph{GET} nor @emph{POST} requests, the error page is
returned finally.
address@hidden
+ return send_page(connection, errorpage);
+}
address@hidden verbatim
address@hidden
+
+These were the important parts of the program @code{simplepost.c}.
Copied: libmicrohttpd/doc/chapters/responseheaders.inc (from rev 7636,
libmicrohttpd/doc/responseheaders.inc)
===================================================================
--- libmicrohttpd/doc/chapters/responseheaders.inc
(rev 0)
+++ libmicrohttpd/doc/chapters/responseheaders.inc 2008-08-28 19:29:47 UTC
(rev 7637)
@@ -0,0 +1,177 @@
+Now that we are able to inspect the incoming request in great detail,
+this chapter discusses the means to enrich the outgoing responses likewise.
+
+As you have learned in the @emph{Hello, Browser} chapter, some obligatory
+header fields are added and set automatically for simple responses by the
library
+itself but if more advanced features are desired, additional fields have to be
created.
+One of the possible fields is the content type field and an example will be
developed around it.
+This will lead to an application capable of correctly serving different types
of files.
+
+
+When we responded with HTML page packed in the static string previously, the
client had no choice
+but guessing about how to handle the response, because the server hadn't told
him.
+What if we had sent a picture or a sound file? Would the message have been
understood
+or merely been displayed as an endless stream of random characters in the
browser?
+This is what the mime content types are for. The header of the response is
extended
+by certain information about how the data is to be interpreted.
+
+To introduce the concept, a picture of the format @emph{PNG} will be sent to
the client
+and labeled accordingly with @code{image/png}.
+Once again, we can base the new example on the @code{hellobrowser} program.
+
address@hidden
+#define FILENAME "picture.png"
+#define MIMETYPE "image/png"
+
+int answer_to_connection (void *cls, struct MHD_Connection *connection, const
char *url,
+ const char *method, const char *version, const char
*upload_data,
+ unsigned int *upload_data_size, void **con_cls)
+{
+ unsigned char *buffer = NULL;
+ struct MHD_Response *response;
address@hidden verbatim
address@hidden
+
+We want the program to load the graphics file into memory:
address@hidden
+ long size;
+ FILE *fp;
+ int ret = 0;
+
+ if (0 != strcmp(method, "GET")) return MHD_NO;
+
+ size = get_file_size (FILENAME);
+ if (size != 0)
+ {
+ fp = fopen (FILENAME, "rb");
+ if (fp)
+ {
+ buffer = malloc (size);
+
+ if (buffer)
+ if (size == fread (buffer, 1, size, fp)) ret = 1;
+
+ fclose(fp);
+ }
+ }
address@hidden verbatim
address@hidden
+
+The @code{GetFileSize} function, which returns a size of zero if the file
could not be opened or
+found, is left out on this page for tidiness.
+
+When dealing with files and allocating memory, there is a lot that could go
wrong on the
+server side and if so, the client should be informed with
@code{MHD_HTTP_INTERNAL_SERVER_ERROR}.
+
address@hidden
+ if (!ret)
+ {
+ const char *errorstr = "<html><body>An internal server error has
occured!\
+ </body></html>";
+
+ if (buffer) free(buffer);
+
+ response = MHD_create_response_from_data(strlen(errorstr),
(void*)errorstr,
+ MHD_NO, MHD_NO);
+
+ if (response)
+ {
+ ret = MHD_queue_response (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR, response);
+ MHD_destroy_response (response);
+
+ return MHD_YES;
+ }
+ else return MHD_NO;
+ }
address@hidden verbatim
address@hidden
+
+Note that we nevertheless have to create a response object even for sending a
simple error code.
+Otherwise, the connection would just be closed without comment, leaving the
client curious about
+what has happened.
+
+But in the case of success a response will be constructed that contains the
buffer filled with the
+file's content.
+
address@hidden
+response = MHD_create_response_from_data (size, (void*)buffer, MHD_YES,
MHD_NO);
address@hidden verbatim
address@hidden
+
+Contrary to the above case where a static string will be sent, this time we
have to
+keep track of the dynamically allocated buffer. As discussed in the @ref{Hello
browser example},
+the buffer cannot be safely freed as soon as the function call returns.
Instead, we ask the function
+to keep charge of freeing the buffer itself when it is not longer needed.
Thus, no further @code{free}
+command is invoked by us.
+
+Up to this point, there was little new. The actual novelty is that we enhance
the header with the
+meta data about the content. Aware of the field's name we want to add, it is
as easy as that:
address@hidden
+MHD_add_response_header(response, "Content-Type", MIMETYPE);
address@hidden verbatim
address@hidden
+We do not have to append a colon expected by the protocol hehind the first
address@hidden libhttpdmicro} will take care of this.
+
+The function finishes with the well-known lines
address@hidden
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ return ret;
+}
address@hidden verbatim
address@hidden
+
+The complete program @code{responseheaders.c} is in the @code{examples}
section as usual.
+Find a @emph{PNG} file you like and save it to the directory the example is
run from under the name
address@hidden You should find the image displayed on your browser if
everything worked well.
+
address@hidden Remarks
+The include file of the @emph{MHD} library comes with the header types
mentioned in @emph{RFC 2616}
+already defined as macros. Thus, we could have written
@code{MHD_HTTP_HEADER_CONTENT_TYPE} instead
+of @code{"Content-Type"} as well. However, one is not limited to these
standard headers and could
+add custom response headers without violating the protocol. Whether, and how,
the client would react
+to these custom header is up to the receiver. Likewise, the client is allowed
to send custom request
+headers to the server as well, opening up yet more possibilities how client
and server could
+communicate with each other.
+
+The method of creating the response from one big chunk of data is only
feasible for smaller files.
+A public file server satisfying many request at the same time would be choking
under these high
+demands on memory very soon. Serving responses in smaller parts would be more
adequate here and
+will be a topic of a future chapter.
+
address@hidden Exercises
address@hidden @bullet
+
address@hidden
+Remember that the original program was written under a few assumptions---a
small, static response
+being one of them. In order to simulate a very large or hard to reach file
that cannot be provided
+instantly, postpone the queuing in the callback with the @code{sleep} function
for 30 seconds
address@hidden the file @code{/big.png} is requested (but deliver the same as
above). A request for
address@hidden/picture.png} should provide just the same but without any
artificial delays.
+
+Now start two instances of your browser (or even use two machines) and see how
the second client
+is put on hold while the first waits for his request on the slow file to be
fulfilled.
+
+Finally, change the sourcecode to use @code{MHD_USE_THREAD_PER_CONNECTION}
when the daemon is
+started and try again.
+
+
address@hidden
+Did you succeed in implementing the clock exercise yet? This time, let the
server save the
+program's start time @code{t} and implement a response simulating a countdown
that reaches 0 at
address@hidden Returning a message saying on which point the countdown is, the
response should
+ultimately be to reply "Done" if the program has been running long enough,
+
+A non official, but widely understood, response header line is @code{Refresh:
DELAY; url=URL} with
+the uppercase words substituted to tell the client it should request the given
resource after
+the given delay again. Improve your program in that the browser (any modern
browser should work)
+automatically reconnects and asks for the status again every 5 seconds or so.
The URL would have
+to be composed so that it begins with "http://", followed by the @emph{URI}
the server is reachable
+from the client's point of view.
+
+Maybe you want also to visualize the countdown as a status bar by creating a
address@hidden<table>} consisting of one row and @code{n} columns whose fields
contain small images of either
+a red or a green light.
+
address@hidden itemize
Deleted: libmicrohttpd/doc/exploringrequests.inc
===================================================================
--- libmicrohttpd/doc/exploringrequests.inc 2008-08-28 06:51:01 UTC (rev
7636)
+++ libmicrohttpd/doc/exploringrequests.inc 2008-08-28 19:29:47 UTC (rev
7637)
@@ -1,103 +0,0 @@
-This chapter will deal with the information which the client sends to the
-server at every request. We are going to examine the most useful fields of
such an request
-and print them out in a readable manner. This could be useful for logging
facilities.
-
-The starting point is the @emph{hellobrowser} program with the former response
removed.
-
-This time, we just want to collect information in the callback function, thus
we will
-just return MHD_NO after we have probed the request. This way, the connection
is closed
-without much ado by the server.
-
address@hidden
-int answer_to_connection (void *cls, struct MHD_Connection *connection, const
char *url,
- const char *method, const char *version, const char
*upload_data,
- unsigned int *upload_data_size, void **con_cls)
-{
- ...
- return MHD_NO;
-}
address@hidden verbatim
address@hidden
-The ellipsis marks the position where the following instructions shall be
inserted.
-
-
-We begin with the most obvious information available to the server, the
request line. You should
-already have noted that a request consists of a command (or "method") and a
URI (e.g. a filename).
-It also contains a string for the version of the protocol which can be found
in @code{version}.
-To call it a "new request" is justified because we return only @code{MHD_NO},
thus ensuring the
-function will not be called again for this connection.
address@hidden
-printf ("New request %s for %s using version %s\n", method, url, version);
address@hidden verbatim
address@hidden
-
-The rest of the information is a bit more hidden. Nevertheless, there is lot
of it sent from common
-Internet browsers. It is stored in "key-name" pairs and we want to list what
we find in the header.
-As there is no mandatory set of keys a client has to send, each key--name pair
is printed out one by
-one until there are no more left. We do this by writing a separate function
which will be called for
-each pair just like the above function is called for each HTTP request.
-It can then print out the content of this pair.
address@hidden
-int print_out_key (void *cls, enum MHD_ValueKind kind, const char *key, const
char *value)
-{
- printf ("%s = %s\n", key, value);
- return MHD_YES;
-}
address@hidden verbatim
address@hidden
-
-To start the iteration process that calls our new function for every key, the
line
address@hidden
-MHD_get_connection_values (connection, MHD_HEADER_KIND, print_out_key, NULL);
address@hidden verbatim
address@hidden
-needs to be inserted in the connection callback function too. The second
parameter tells the function
-that we are only interested in keys from the general HTTP header of the
request. Our iterating
-function @code{PrintOutKey} does not rely on any additional information to
fulfill its duties
-so the last parameter can be NULL.
-
-All in all, this constitutes the complete @code{logger.c} program for this
chapter which can be
-found in the @code{examples} section.
-
-Connecting with any modern Internet browser should yield a handful of keys.
You should try to
-interpret them with the aid of @emph{RFC 2616}.
-Especially worth mentioning is the host key which is often used to serve
several different websites
-hosted under one single IP address but reachable by different domain names.
-
address@hidden Conclusion
-The introduced capabilities to itemize the content of a simple GET
request---especially the
-URI---should already allow the server to satisfy clients' requests for small
specific resources
-(e.g. files) or even induce alteration of how the server operates. However,
the latter is not
-recommended as the GET method (including its header data) is by convention
considered a "SAFE"
-operation, which should not change the server's state in a significant way,
but temporally actions
-like searching for a passed string is fine.
-
-Of course, no transmission can occur while the return value is still set to
@code{MHD_NO} in the
-callback function.
-
address@hidden Exercises
address@hidden @bullet
address@hidden
-By parsing the @code{url} string and delivering responses accordingly,
implement a small server for
-"virtual" files. When asked for @code{/address@hidden@}}, let the response
consist of a HTML page
-containing a link to @code{/another.html} page which is also to be created "on
the fly" in case of
-being requested. If neither of these two pages are requested,
@code{MHD_HTTP_NOT_FOUND} shall be
-returned accompanied by an informative message.
-
address@hidden
-A very interesting information has still been ignored by our logger---the
client's IP address.
-Implement a callback function
address@hidden
-int on_client_connect (void *cls,
- const struct sockaddr *addr,socklen_t addrlen)
address@hidden verbatim
address@hidden
-that prints out the IP address in an appropriate format. You might want to use
the posix function
address@hidden but bear in mind that @code{addr} is actually just a structure
containing other
-substructures and is @emph{not} the variable this function expects.
-Make sure to return @code{MHD_YES} so that the library knows the client is
allowed to connect
-(and to request). If one wanted to limit access basing on IP addresses, this
would be the place
-to do it. The address of your function will then be passed as the third
parameter of the
address@hidden call.
-
address@hidden itemize
Deleted: libmicrohttpd/doc/hellobrowser.inc
===================================================================
--- libmicrohttpd/doc/hellobrowser.inc 2008-08-28 06:51:01 UTC (rev 7636)
+++ libmicrohttpd/doc/hellobrowser.inc 2008-08-28 19:29:47 UTC (rev 7637)
@@ -1,203 +0,0 @@
-The most basic task for a HTTP server is to deliver a static text message to
any client connecting to it.
-Given that this is also easy to implement, it is an excellent problem to start
with.
-
-For now, the particular filename the client asks for shall have no effect on
the message that will
-be returned. In addition, the server shall end the connection after the
message has been sent so that
-the client will know there is nothing more to expect.
-
-The C program @code{hellobrowser.c}, which is to be found in the examples
section, does just that.
-If you are very eager, you can compile and start it right away but it is
advisable to type the
-lines in by yourself as they will be discussed and explained in detail.
-
-After the unexciting includes and the definition of the port which our server
should listen on
address@hidden
-#include <microhttpd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
address@hidden verbatim
address@hidden
-the desired behaviour of our server when HTTP request arrive have to be
implemented. We already have
-agreed that it should not care about the particular details of the request,
such as who is requesting
-what. The server will respond merely with the same small HTML page to every
request.
-
-The function we are going to write now will be called by @emph{GNU
libmicrohttpd} every time an
-appropriate request comes in. While the name of this callback function is
arbitrary, its parameter
-list has to follow a certain layout. So please, ignore the lot of parameters
for now, they will be
-explained at the point they are needed. We have to use only one of them,
address@hidden MHD_Connection *connection}, for the minimalistic functionality
we want to archive at the moment.
-
-This parameter is set by the @emph{libmicrohttpd} daemon and holds the
necessary information to
-relate the call with a certain connection. Keep in mind that a server might
have to satisfy hundreds
-of concurrent connections and we have to make sure that the correct data is
sent to the destined
-client. Therefore, this variable is a means to refer to a particular
connection if we ask the
-daemon to sent the reply.
-
-Talking about the reply, it is defined as a string right after the function
header
address@hidden
-int answer_to_connection (void *cls, struct MHD_Connection *connection, const
char *url,
- const char *method, const char *version, const char
*upload_data,
- unsigned int *upload_data_size, void **con_cls)
-{
- const char *page = "<html><body>Hello, browser!</body></html>";
address@hidden verbatim
address@hidden
-HTTP is a rather strict protocol and the client would certainly consider it
"inappropriate" if we
-just sent the answer string "as is". Instead, it has to be wrapped in certain
layers, called headers,
-of additional information. Luckily, most of the work in this area is done by
the library for us---we
-just have to ask. Our reply string packed in the necessary layers will be
called a "response".
-To obtain such a response we hand our data (the reply--string) and its size
over to the
address@hidden function. The last two parameters basically tell @emph{MHD}
-that we do not want it to dispose the message data for us when it has been
sent and there also needs
-no internal copy to be done because the @emph{constant} string won't change
anyway.
-
address@hidden
- struct MHD_Response *response;
- int ret;
-
- response = MHD_create_response_from_data (strlen (page),
- (void*) page, MHD_NO, MHD_NO);
address@hidden verbatim
address@hidden
-Now that the the response has been laced up, it is ready for delivery and can
be queued for sending.
-This is done by passing it to another @emph{GNU libmicrohttpd} function. As
all our work was done in
-the scope of one function, the recipient is without doubt the one associated
with the
-local variable @code{connection} and consequently this variable is given to
the queue function.
-Every HTTP response is accompanied by a status code, here "OK", so that the
client knows
-this response is the intended result of his request and not due to some error
or malfunction.
-
-Finally, the packet is destroyed and the return value from the queue returned,
-already being set at this point to either MHD_YES or MHD_NO in case of success
or failure.
-
address@hidden
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
- MHD_destroy_response (response);
-
- return ret;
-}
address@hidden verbatim
address@hidden
-With the primary task of our server implemented, we can start the actual
server daemon which will listen
-on @code{PORT} for connections. This is done in the main function.
address@hidden
-int main ()
-{
- struct MHD_Daemon *daemon;
-
- daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
- &answer_to_connection, NULL, MHD_OPTION_END);
- if (NULL == daemon) return 1;
address@hidden verbatim
address@hidden
-The first parameter is one of three possible modes of operation. Here we want
the daemon to run in
-a separate thread and to manage all incoming connections in the same thread.
This means that while
-producing the response for one connection, the other connections will be put
on hold. In this
-chapter, where the reply is already known and therefore the request is served
quickly, this poses no problem.
-
-We will allow all clients to connect regardless of their name or location,
therefore we do not check
-them on connection and set the forth and fifth parameter to NULL.
-
-Parameter six is the address of the function we want to be called whenever a
new connection has been
-established. Our @code{AnswerToConnection} knows best what the client wants
and needs no additional
-information (which could be passed via the next parameter) so the next
parameter is NULL. Likewise,
-we do not need to pass extra options to the daemon so we just write the
MHD_OPTION_END as the last parameter.
-
-As the server daemon runs in the background in its own thread, the execution
flow in our main
-function will contine right after the call. Because of this, we must delay the
execution flow in the
-main thread or else the program will terminate prematurely. We let it pause in
a processing-time
-friendly manner by waiting for the enter key to be pressed. In the end, we
stop the daemon so it can
-do its cleanup tasks.
address@hidden
- getchar ();
-
- MHD_stop_daemon (daemon);
- return 0;
-}
-
address@hidden verbatim
address@hidden
-The first example is now complete.
-
-Compile it with
address@hidden
-cc hellobrowser.c -o hellobrowser -I$PATH_TO_LIBMHD_INCLUDES
- -L$PATH_TO_LIBMHD_INCLUDES -static -lmicrohttpd -pthread
address@hidden verbatim
-with the two paths set accordingly and run it.
-
-Now open your favorite Internet browser and go to the address
@code{localhost:8888}, provided that
-is the port you chose. If everything works as expected, the browser will
present the message of the
-static HTML page it got from our minimal server.
-
address@hidden Remarks
-To keep this first example as small as possible, some drastic shortcuts were
taken and are to be
-discussed now.
-
-Firstly, there is no distinction made between the kinds of requests a client
could send. We implied
-that the client sends a GET request, that means, that he actually asked for
some data. Even when
-it is not intended to accept POST requests, a good server should at least
recognize that this
-request does not constitute a legal request and answer with an error code.
This can be easily
-implemented by checking if the parameter @code{method} equals the string "GET"
and returning a
address@hidden if not so.
-
-Secondly, the above practice of queuing a response upon the first call of the
callback function
-brings with it some limitations. This is because the content of the message
body will not be
-received if a response is queued in the first iteration. Furthermore, the
connection will be closed
-right after the response has been transferred then.
-
-Both of these issues you will find addressed in the official
@code{minimal_example.c} residing in
-the @code{src/examples} directory of the @emph{GNU libmicrohttpd} package. The
source code of this
-program should look very familiar to you by now and easy to understand.
-
-For our example, the @code{must_copy} and @code{must_free} parameter at the
response construction
-function could be set to @code{MHD_NO}. In the usual case, responses cannot be
sent immediately
-after being queued. For example, there might be other data on the system that
needs to be sent with
-a higher priority. Nevertheless, the queue function will return
successfully---raising the problem
-that the data we have pointed to may be invalid by the time it is about being
sent. This is not an
-issue here because we can expect the @code{page} string, which is a constant
@emph{string literal}
-here, to be static. That means it will be present and unchanged for as long as
the program runs.
-For dynamic data, one could choose to either have @emph{MHD} free the memory
@code{page} points
-to itself when it is not longer needed or, alternatively, have the library to
make and manage
-its own copy of it.
-
address@hidden Exercises
address@hidden @bullet
address@hidden
-While the server is running, use a program like telnet or netcat to connect to
it. Try to form a
-valid HTTP1.1 request yourself like
address@hidden
-GET /dontcare HTTP1.1
-Host: itsme
-<enter>
address@hidden verbatim
address@hidden
-and see what the server returns to you.
-
-
address@hidden
-Also, try other requests, like POST, and see how our server does not mind and
why.
-How far in malforming a request can you go before the builtin functionality of
@emph{MHD} intervenes
-and an altered response is sent? Make sure you read about the status codes in
the @emph{RFC}.
-
-
address@hidden
-Add the option @code{MHD_USE_PEDANTIC_CHECKS} to the start function of the
daemon in @code{main}.
-Mind the special format of the parameter list here which is described in the
manual. How indulgent
-is the server now to your input?
-
-
address@hidden
-Let the main function take a string as the first command line argument and
pass @code{argv[1]} to
-the @code{MHD_start_daemon} function as the sixth parameter. The address of
this string will be
-passed to the callback function via the @code{cls} variable. Decorate the text
given at the command
-line when the server is started with proper HTML tags and send it as the
response instead of the
-former static string.
-
-
address@hidden
address@hidden:} Write a separate function returning a string containing some
useful information,
-for example, the time. Pass the function's address as the sixth parameter and
evaluate this function
-on every request anew in @code{AnswerToConnection}. Remember to free the
memory of the string
-every time after satisfying the request.
-
address@hidden itemize
Deleted: libmicrohttpd/doc/introduction.inc
===================================================================
--- libmicrohttpd/doc/introduction.inc 2008-08-28 06:51:01 UTC (rev 7636)
+++ libmicrohttpd/doc/introduction.inc 2008-08-28 19:29:47 UTC (rev 7637)
@@ -1,17 +0,0 @@
-This tutorial is for developers who want to learn how they can add HTTP
serving
-capabilities to their applications with the @emph{GNU libmicrohttpd} library,
-abbreviated @emph{MHD}. The reader will learn how to
-implement basic HTTP functions from simple executable
-sample programs that implement various features.
-
-The text is supposed to be a supplement to the API reference manual of
address@hidden libmicrohttpd} and for that reason does not explain many of the
parameters.
-Therefore, the reader should always consult the manual to find the exact
meaning
-of the functions used in the tutorial. Furthermore, the reader is
-encouraged to study the relevant @emph{RFCs}, which document the HTTP standard.
-
address@hidden libmicrohttpd} is assumed to be already installed. This tutorial
-is written for version @value{VERSION}. At the time being,
-this tutorial has only been tested on @emph{GNU/Linux} machines even though
-efforts were made not to rely on anything that would prevent the samples from
being
-built on similar systems.
Deleted: libmicrohttpd/doc/processingpost.inc
===================================================================
--- libmicrohttpd/doc/processingpost.inc 2008-08-28 06:51:01 UTC (rev
7636)
+++ libmicrohttpd/doc/processingpost.inc 2008-08-28 19:29:47 UTC (rev
7637)
@@ -1,231 +0,0 @@
-The previous chapters already have demonstrated a variety of possibilities to
send information
-to the HTTP server, but it is not recommended that the @emph{GET} method is
used to alter the way
-the server operates. To induce changes on the server, the @emph{POST} method
is preferred over
-and is much more powerful than @emph{GET} and will be introduced in this
chapter.
-
-We are going to write an application that asks for the visitor's name and,
after the user has posted it,
-composes an individual response text. Even though it was not mandatory to use
the @emph{post} method here,
-as there is no permanent change caused by the post, it is an illustrative
example on how to share data
-between different functions for the same connection. Furthermore, the reader
should be able to extend
-it easily.
-
address@hidden GET request
-When the first @emph{GET} request arrives, the server shall respond with a
HTML page containing an
-edit field for the name.
-
address@hidden
-const char* askpage = "<html><body>\
- What's your name, Sir?<br>\
- <form action=\"/namepost\" method=\"post\">\
- <input name=\"name\" type=\"text\"\
- <input type=\"submit\" value=\" Send \"></form>\
- </body></html>";
address@hidden verbatim
address@hidden
-
-The @code{action} entry is the @emph{URI} to be called by the browser when
posting, and the
address@hidden will be used later to be sure it is the editbox's content that
has been posted.
-
-We also prepare the answer page, where the name is to be filled in later, and
an error page
-as the response for anything but proper @emph{GET} and @emph{POST} requests:
-
address@hidden
-const char* greatingpage="<html><body><h1>Welcome,
%s!</center></h1></body></html>";
-
-const char* errorpage="<html><body>This doesn't seem to be
right.</body></html>";
address@hidden verbatim
address@hidden
-
-Whenever we need to send a page, we use an extra function
address@hidden SendPage(struct MHD_Connection *connection, const char* page)}
-for this, which does not contain anything new and whose implementation is
therefore left out here.
-
-
address@hidden POST request
-Posted data can be of arbitrary and considerable size; for example, if a user
uploads a big
-image to the server. Similar to the case of the header fields, there may also
be different streams
-of posted data, such as one containing the text of an editbox and another the
state of a button.
-Likewise, we will have to register an iterator function that is going to be
called maybe several times
-not only if there are different POSTs but also if one POST has only been
received partly yet and
-needs processing before another chunk can be received.
-
-Such an iterator function is called by a @emph{postprocessor}, which must be
created upon arriving
-of the post request. We want the iterator function to read the first post
data which is tagged
address@hidden and to create an individual greeting string based on the
template and the name.
-But in order to pass this string to other functions and still be able to
differentiate different
-connections, we must first define a structure to share the information,
holding the most import entries.
-
address@hidden
-struct connection_info_struct
-{
- int connectiontype;
- char *answerstring;
- struct MHD_PostProcessor *postprocessor;
-};
address@hidden verbatim
address@hidden
-
-With these information available to the iterator function, it is able to
fulfill its task.
-Once it has composed the greeting string, it returns @code{MHD_NO} to inform
the post processor
-that it does not need to be called again. Note that this function does not
handle processing
-of data for the same @code{key}. If we were to expect that the name will be
posted in several
-chunks, we had to expand the namestring dynamically as additional parts of it
with the same @code{key}
-came in. But in this example, the name is assumed to fit entirely inside one
single packet.
-
address@hidden
-int iterate_post (void *coninfo_cls, enum MHD_ValueKind kind, const char *key,
- const char *filename, const char *content_type,
- const char *transfer_encoding, const char *data, size_t off,
size_t size)
-{
- struct connection_info_struct *con_info = (struct connection_info_struct*)
coninfo_cls;
-
-
- if (0 == strcmp (key, "name"))
- {
- if ((size > 0) && (size <= MAXNAMESIZE))
- {
- char *answerstring;
- answerstring = malloc (MAXANSWERSIZE);
- if (!answerstring) return MHD_NO;
-
- snprintf (answerstring, MAXANSWERSIZE, greatingpage, data);
- con_info->answerstring = answerstring;
- }
- else con_info->answerstring = NULL;
-
- return MHD_NO;
- }
-
- return MHD_YES;
-}
address@hidden verbatim
address@hidden
-
-Once a connection has been established, it can be terminated for many reasons.
As these
-reasons include unexpected events, we have to register another function that
cleans up any resources
-that might have been allocated for that connection by us, namely the post
processor and the greetings
-string. This cleanup function must take into account that it will also be
called for finished
-requests other than @emph{POST} requests.
-
address@hidden
-void request_completed (void *cls, struct MHD_Connection *connection, void
**con_cls,
- enum MHD_RequestTerminationCode toe)
-{
- struct connection_info_struct *con_info = (struct connection_info_struct*)
*con_cls;
-
-
- if (NULL == con_info) return;
-
- if (con_info->connectiontype == POST)
- {
- MHD_destroy_post_processor (con_info->postprocessor);
- if (con_info->answerstring) free (con_info->answerstring);
- }
-
- free (con_info);
- *con_cls = NULL;
-}
address@hidden verbatim
address@hidden
-
address@hidden libmicrohttpd} is informed that it shall call the above function
when the daemon is started
-in the main function.
-
address@hidden
-...
-daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
- &answer_to_connection, NULL,
MHD_OPTION_NOTIFY_COMPLETED,
- request_completed, NULL, MHD_OPTION_END);
-...
address@hidden verbatim
address@hidden
-
address@hidden Request handling
-With all other functions prepared, we can now discuss the actual request
handling.
-
-On the first iteration for a new request, we start by allocating a new
instance of a
address@hidden structure, which will store all necessary information for later
-iterations and other functions.
-
address@hidden
-int answer_to_connection (void *cls, struct MHD_Connection *connection, const
char *url,
- const char *method, const char *version, const char
*upload_data,
- unsigned int *upload_data_size, void **con_cls)
-{
- if(NULL == *con_cls)
- {
- struct connection_info_struct *con_info;
-
- con_info = malloc (sizeof (struct connection_info_struct));
- if (NULL == con_info) return MHD_NO;
- con_info->answerstring = NULL;
address@hidden verbatim
address@hidden
-
-If the new request is a @emph{POST}, the postprocessor must be created now. In
addition, the type
-of the request is stored for convenience.
address@hidden
- if (0 == strcmp (method, "POST"))
- {
- con_info->postprocessor = MHD_create_post_processor (connection,
POSTBUFFERSIZE,
- iterate_post,
(void*) con_info);
-
- if (NULL == con_info->postprocessor)
- {
- free (con_info);
- return MHD_NO;
- }
-
- con_info->connectiontype = POST;
- }
- else con_info->connectiontype = GET;
address@hidden verbatim
address@hidden
-
-The address of our structure will both serve as the indicator for successive
iterations and to remember
-the particular details about the connection.
address@hidden
- *con_cls = (void*) con_info;
- return MHD_YES;
- }
address@hidden verbatim
address@hidden
-
-The rest of the function will not be executed on the first iteration. A
@emph{GET} request is easily
-satisfied by sending the question form.
address@hidden
- if (0 == strcmp (method, "GET"))
- {
- return send_page (connection, askpage);
- }
address@hidden verbatim
address@hidden
-
-In case of @emph{POST}, we invoke the post processor for as long as data keeps
incoming, setting
address@hidden to zero in order to indicate that we have processed---or at
least have
-considered---all of it.
address@hidden
- if (0 == strcmp (method, "POST"))
- {
- struct connection_info_struct *con_info = *con_cls;
-
- if (*upload_data_size != 0)
- {
- MHD_post_process(con_info->postprocessor, upload_data,
*upload_data_size);
- *upload_data_size = 0;
-
- return MHD_YES;
- }
- else if (NULL != con_info->answerstring) return send_page (connection,
con_info->answerstring);
- }
address@hidden verbatim
address@hidden
-
-If they are neither @emph{GET} nor @emph{POST} requests, the error page is
returned finally.
address@hidden
- return send_page(connection, errorpage);
-}
address@hidden verbatim
address@hidden
-
-These were the important parts of the program @code{simplepost.c}.
Deleted: libmicrohttpd/doc/responseheaders.inc
===================================================================
--- libmicrohttpd/doc/responseheaders.inc 2008-08-28 06:51:01 UTC (rev
7636)
+++ libmicrohttpd/doc/responseheaders.inc 2008-08-28 19:29:47 UTC (rev
7637)
@@ -1,177 +0,0 @@
-Now that we are able to inspect the incoming request in great detail,
-this chapter discusses the means to enrich the outgoing responses likewise.
-
-As you have learned in the @emph{Hello, Browser} chapter, some obligatory
-header fields are added and set automatically for simple responses by the
library
-itself but if more advanced features are desired, additional fields have to be
created.
-One of the possible fields is the content type field and an example will be
developed around it.
-This will lead to an application capable of correctly serving different types
of files.
-
-
-When we responded with HTML page packed in the static string previously, the
client had no choice
-but guessing about how to handle the response, because the server hadn't told
him.
-What if we had sent a picture or a sound file? Would the message have been
understood
-or merely been displayed as an endless stream of random characters in the
browser?
-This is what the mime content types are for. The header of the response is
extended
-by certain information about how the data is to be interpreted.
-
-To introduce the concept, a picture of the format @emph{PNG} will be sent to
the client
-and labeled accordingly with @code{image/png}.
-Once again, we can base the new example on the @code{hellobrowser} program.
-
address@hidden
-#define FILENAME "picture.png"
-#define MIMETYPE "image/png"
-
-int answer_to_connection (void *cls, struct MHD_Connection *connection, const
char *url,
- const char *method, const char *version, const char
*upload_data,
- unsigned int *upload_data_size, void **con_cls)
-{
- unsigned char *buffer = NULL;
- struct MHD_Response *response;
address@hidden verbatim
address@hidden
-
-We want the program to load the graphics file into memory:
address@hidden
- long size;
- FILE *fp;
- int ret = 0;
-
- if (0 != strcmp(method, "GET")) return MHD_NO;
-
- size = get_file_size (FILENAME);
- if (size != 0)
- {
- fp = fopen (FILENAME, "rb");
- if (fp)
- {
- buffer = malloc (size);
-
- if (buffer)
- if (size == fread (buffer, 1, size, fp)) ret = 1;
-
- fclose(fp);
- }
- }
address@hidden verbatim
address@hidden
-
-The @code{GetFileSize} function, which returns a size of zero if the file
could not be opened or
-found, is left out on this page for tidiness.
-
-When dealing with files and allocating memory, there is a lot that could go
wrong on the
-server side and if so, the client should be informed with
@code{MHD_HTTP_INTERNAL_SERVER_ERROR}.
-
address@hidden
- if (!ret)
- {
- const char *errorstr = "<html><body>An internal server error has
occured!\
- </body></html>";
-
- if (buffer) free(buffer);
-
- response = MHD_create_response_from_data(strlen(errorstr),
(void*)errorstr,
- MHD_NO, MHD_NO);
-
- if (response)
- {
- ret = MHD_queue_response (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR, response);
- MHD_destroy_response (response);
-
- return MHD_YES;
- }
- else return MHD_NO;
- }
address@hidden verbatim
address@hidden
-
-Note that we nevertheless have to create a response object even for sending a
simple error code.
-Otherwise, the connection would just be closed without comment, leaving the
client curious about
-what has happened.
-
-But in the case of success a response will be constructed that contains the
buffer filled with the
-file's content.
-
address@hidden
-response = MHD_create_response_from_data (size, (void*)buffer, MHD_YES,
MHD_NO);
address@hidden verbatim
address@hidden
-
-Contrary to the above case where a static string will be sent, this time we
have to
-keep track of the dynamically allocated buffer. As discussed in the @ref{Hello
browser example},
-the buffer cannot be safely freed as soon as the function call returns.
Instead, we ask the function
-to keep charge of freeing the buffer itself when it is not longer needed.
Thus, no further @code{free}
-command is invoked by us.
-
-Up to this point, there was little new. The actual novelty is that we enhance
the header with the
-meta data about the content. Aware of the field's name we want to add, it is
as easy as that:
address@hidden
-MHD_add_response_header(response, "Content-Type", MIMETYPE);
address@hidden verbatim
address@hidden
-We do not have to append a colon expected by the protocol hehind the first
address@hidden libhttpdmicro} will take care of this.
-
-The function finishes with the well-known lines
address@hidden
- ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
- MHD_destroy_response (response);
- return ret;
-}
address@hidden verbatim
address@hidden
-
-The complete program @code{responseheaders.c} is in the @code{examples}
section as usual.
-Find a @emph{PNG} file you like and save it to the directory the example is
run from under the name
address@hidden You should find the image displayed on your browser if
everything worked well.
-
address@hidden Remarks
-The include file of the @emph{MHD} library comes with the header types
mentioned in @emph{RFC 2616}
-already defined as macros. Thus, we could have written
@code{MHD_HTTP_HEADER_CONTENT_TYPE} instead
-of @code{"Content-Type"} as well. However, one is not limited to these
standard headers and could
-add custom response headers without violating the protocol. Whether, and how,
the client would react
-to these custom header is up to the receiver. Likewise, the client is allowed
to send custom request
-headers to the server as well, opening up yet more possibilities how client
and server could
-communicate with each other.
-
-The method of creating the response from one big chunk of data is only
feasible for smaller files.
-A public file server satisfying many request at the same time would be choking
under these high
-demands on memory very soon. Serving responses in smaller parts would be more
adequate here and
-will be a topic of a future chapter.
-
address@hidden Exercises
address@hidden @bullet
-
address@hidden
-Remember that the original program was written under a few assumptions---a
small, static response
-being one of them. In order to simulate a very large or hard to reach file
that cannot be provided
-instantly, postpone the queuing in the callback with the @code{sleep} function
for 30 seconds
address@hidden the file @code{/big.png} is requested (but deliver the same as
above). A request for
address@hidden/picture.png} should provide just the same but without any
artificial delays.
-
-Now start two instances of your browser (or even use two machines) and see how
the second client
-is put on hold while the first waits for his request on the slow file to be
fulfilled.
-
-Finally, change the sourcecode to use @code{MHD_USE_THREAD_PER_CONNECTION}
when the daemon is
-started and try again.
-
-
address@hidden
-Did you succeed in implementing the clock exercise yet? This time, let the
server save the
-program's start time @code{t} and implement a response simulating a countdown
that reaches 0 at
address@hidden Returning a message saying on which point the countdown is, the
response should
-ultimately be to reply "Done" if the program has been running long enough,
-
-A non official, but widely understood, response header line is @code{Refresh:
DELAY; url=URL} with
-the uppercase words substituted to tell the client it should request the given
resource after
-the given delay again. Improve your program in that the browser (any modern
browser should work)
-automatically reconnects and asks for the status again every 5 seconds or so.
The URL would have
-to be composed so that it begins with "http://", followed by the @emph{URI}
the server is reachable
-from the client's point of view.
-
-Maybe you want also to visualize the countdown as a status bar by creating a
address@hidden<table>} consisting of one row and @code{n} columns whose fields
contain small images of either
-a red or a green light.
-
address@hidden itemize
Modified: libmicrohttpd/doc/texinfo.tex
===================================================================
--- libmicrohttpd/doc/texinfo.tex 2008-08-28 06:51:01 UTC (rev 7636)
+++ libmicrohttpd/doc/texinfo.tex 2008-08-28 19:29:47 UTC (rev 7637)
@@ -3,16 +3,16 @@
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2007-12-02.17}
+\def\texinfoversion{2005-07-05.19}
%
-% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 2007,
-% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-% 2007 Free Software Foundation, Inc.
+% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software
+% Foundation, Inc.
%
-% This texinfo.tex file is free software: you can redistribute it and/or
+% 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
-% published by the Free Software Foundation, either version 3 of the
-% License, or (at your option) any later version.
+% published by the Free Software Foundation; either version 2, or (at
+% your option) any later version.
%
% This texinfo.tex file is distributed in the hope that it will be
% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
@@ -20,7 +20,9 @@
% General Public License for more details.
%
% You should have received a copy of the GNU General Public License
-% along with this program. If not, see <http://www.gnu.org/licenses/>.
+% along with this texinfo.tex file; see the file COPYING. If not, write
+% to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+% Boston, MA 02110-1301, USA.
%
% As a special exception, when this file is read by TeX when processing
% a Texinfo source document, you may use the result without
@@ -65,7 +67,7 @@
\everyjob{\message{[Texinfo version \texinfoversion]}%
\catcode`+=\active \catcode`\_=\active}
-
+\message{Basics,}
\chardef\other=12
% We never want plain's \outer definition of \+ in Texinfo.
@@ -151,22 +153,28 @@
\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi
\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi
-% Since the category of space is not known, we have to be careful.
-\chardef\spacecat = 10
-\def\spaceisspace{\catcode`\ =\spacecat}
-
-% sometimes characters are active, so we need control sequences.
+% In some macros, we cannot use the `\? notation---the left quote is
+% in some cases the escape char.
+\chardef\backChar = `\\
\chardef\colonChar = `\:
\chardef\commaChar = `\,
-\chardef\dashChar = `\-
\chardef\dotChar = `\.
\chardef\exclamChar= `\!
-\chardef\lquoteChar= `\`
+\chardef\plusChar = `\+
\chardef\questChar = `\?
-\chardef\rquoteChar= `\'
\chardef\semiChar = `\;
\chardef\underChar = `\_
+\chardef\spaceChar = `\ %
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode\spaceChar=\spacecat}
+
+{% for help with debugging.
+ % example usage: \expandafter\show\activebackslash
+ \catcode`\! = 0 \catcode`\\ = \active
+ !global!def!activebackslash{\}
+}
+
% Ignore a token.
%
\def\gobble#1{}
@@ -277,50 +285,6 @@
\newdimen\cornerthick \cornerthick=.3pt
\newdimen\topandbottommargin \topandbottommargin=.75in
-% Output a mark which sets \thischapter, \thissection and \thiscolor.
-% We dump everything together because we only have one kind of mark.
-% This works because we only use \botmark / \topmark, not \firstmark.
-%
-% A mark contains a subexpression of the \ifcase ... \fi construct.
-% \get*marks macros below extract the needed part using \ifcase.
-%
-% Another complication is to let the user choose whether \thischapter
-% (\thissection) refers to the chapter (section) in effect at the top
-% of a page, or that at the bottom of a page. The solution is
-% described on page 260 of The TeXbook. It involves outputting two
-% marks for the sectioning macros, one before the section break, and
-% one after. I won't pretend I can describe this better than DEK...
-\def\domark{%
- \toks0=\expandafter{\lastchapterdefs}%
- \toks2=\expandafter{\lastsectiondefs}%
- \toks4=\expandafter{\prevchapterdefs}%
- \toks6=\expandafter{\prevsectiondefs}%
- \toks8=\expandafter{\lastcolordefs}%
- \mark{%
- \the\toks0 \the\toks2
- \noexpand\or \the\toks4 \the\toks6
- \noexpand\else \the\toks8
- }%
-}
-% \topmark doesn't work for the very first chapter (after the title
-% page or the contents), so we use \firstmark there -- this gets us
-% the mark with the chapter defs, unless the user sneaks in, e.g.,
-% @setcolor (or @url, or @link, etc.) between @contents and the very
-% first @chapter.
-\def\gettopheadingmarks{%
- \ifcase0\topmark\fi
- \ifx\thischapter\empty \ifcase0\firstmark\fi \fi
-}
-\def\getbottomheadingmarks{\ifcase1\botmark\fi}
-\def\getcolormarks{\ifcase2\topmark\fi}
-
-% Avoid "undefined control sequence" errors.
-\def\lastchapterdefs{}
-\def\lastsectiondefs{}
-\def\prevchapterdefs{}
-\def\prevsectiondefs{}
-\def\lastcolordefs{}
-
% Main output routine.
\chardef\PAGE = 255
\output = {\onepageout{\pagecontents\PAGE}}
@@ -338,9 +302,7 @@
%
% Do this outside of the \shipout so @code etc. will be expanded in
% the headline as they should be, not taken literally (outputting ''code).
- \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
\setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
- \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
\setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
%
{%
@@ -349,13 +311,6 @@
% before the \shipout runs.
%
\indexdummies % don't expand commands in the output.
- \normalturnoffactive % \ in index entries must not stay \, e.g., if
- % the page break happens to be in the middle of an example.
- % We don't want .vr (or whatever) entries like this:
- % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
- % "\acronym" won't work when it's read back in;
- % it needs to be
- % {\code {{\tt \backslashcurfont }acronym}
\shipout\vbox{%
% Do this early so pdf references go to the beginning of the page.
\ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
@@ -383,9 +338,9 @@
\pagebody{#1}%
\ifdim\ht\footlinebox > 0pt
% Only leave this space if the footline is nonempty.
- % (We lessened \vsize for it in \oddfootingyyy.)
+ % (We lessened \vsize for it in \oddfootingxxx.)
% The \baselineskip=24pt in plain's \makefootline has no effect.
- \vskip 24pt
+ \vskip 2\baselineskip
\unvbox\footlinebox
\fi
%
@@ -419,7 +374,7 @@
% marginal hacks, address@hidden (Juha Takala)
\ifvoid\margin\else % marginal info is present
\rlap{\kern\hsize\vbox address@hidden \vss}}\fi
address@hidden \unvbox#1\relax
address@hidden \unvbox#1
\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
address@hidden \kern-\dimen@ \vfil \fi}
}
@@ -441,7 +396,7 @@
%
\def\parsearg{\parseargusing{}}
\def\parseargusing#1#2{%
- \def\argtorun{#2}%
+ \def\next{#2}%
\begingroup
\obeylines
\spaceisspace
@@ -472,7 +427,8 @@
\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
\def\temp{#3}%
\ifx\temp\empty
- % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
+ % We cannot use \next here, as it holds the macro to run;
+ % thus we reuse \temp.
\let\temp\finishparsearg
\else
\let\temp\argcheckspaces
@@ -484,14 +440,14 @@
% If a _delimited_ argument is enclosed in braces, they get stripped; so
% to get _exactly_ the rest of the line, we had to prevent such situation.
% We prepended an \empty token at the very beginning and we expand it now,
-% just before passing the control to \argtorun.
+% just before passing the control to \next.
% (Similarily, we have to think about #3 of \argcheckspacesY above: it is
% either the null string, or it ends with \^^M---thus there is no danger
% that a pair of braces would be stripped.
%
% But first, we have to remove the trailing space token.
%
-\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+\def\finishparsearg#1 \ArgTerm{\expandafter\next\expandafter{#1}}
% \parseargdef\foo{...}
% is roughly equivalent to
@@ -1095,9 +1051,9 @@
% _ active, and distinguish by seeing if the current family is \slfam,
% which is what @var uses.
{
- \catcode`\_ = \active
+ \catcode\underChar = \active
\gdef\mathunderscore{%
- \catcode`\_=\active
+ \catcode\underChar=\active
\def_{\ifnum\fam=\slfam \_\else\sb\fi}%
}
}
@@ -1140,24 +1096,15 @@
\def\minus{$-$}
% @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.
+% We do .5em per period so that it has the same spacing in a typewriter
+% font as three actual period characters.
%
\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
+ \hbox to 1.5em{%
+ \hskip 0pt plus 0.25fil
+ .\hfil.\hfil.%
+ \hskip 0pt plus 0.5fil
}%
}
@@ -1250,28 +1197,28 @@
\fi
\fi
-% PDF uses PostScript string constants for the names of xref targets,
+% PDF uses PostScript string constants for the names of xref targets, to
% 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).
+% that's we do).
% double active backslashes.
%
address@hidden \catcode`\\=\active
+ @address@hidden@address@hidden@active @otherbackslash}
@address@hidden
- @address@hidden@active
+ @address@hidden@active
@address@hidden
}
% 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.
+% us) handles it with this amazing macro to replace tokens. I've
+% tinkered with it a little for texinfo, but it's definitely from there.
%
% #1 is the tokens to replace.
% #2 is the replacement.
@@ -1296,87 +1243,21 @@
\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}%
+ \HyPsdSubst{(}{\backslashlparen}{#1}%
+ \HyPsdSubst{)}{\backslashrparen}{#1}%
}
-\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
-with PDF output, and none of those formats could be found. (.eps cannot
-be supported due to the design of the PDF format; use regular TeX (DVI
-output) for that.)}
+{\catcode\exclamChar = 0 \catcode\backChar = \other
+ !gdef!backslashlparen{\(}%
+ !gdef!backslashrparen{\)}%
+}
\ifpdf
- %
- % Color manipulation macros based on pdfcolor.tex.
- \def\cmykDarkRed{0.28 1 1 0.35}
- \def\cmykBlack{0 0 0 1}
- %
- \def\pdfsetcolor#1{\pdfliteral{#1 k}}
- % Set color, and create a mark which defines \thiscolor accordingly,
- % so that \makeheadline knows which color to restore.
- \def\setcolor#1{%
- \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}%
- \domark
- \pdfsetcolor{#1}%
- }
- %
- \def\maincolor{\cmykBlack}
- \pdfsetcolor{\maincolor}
- \edef\thiscolor{\maincolor}
- \def\lastcolordefs{}
- %
- \def\makefootline{%
- \baselineskip24pt
- \line{\pdfsetcolor{\maincolor}\the\footline}%
- }
- %
- \def\makeheadline{%
- \vbox to 0pt{%
- \vskip-22.5pt
- \line{%
- \vbox to8.5pt{}%
- % Extract \thiscolor definition from the marks.
- \getcolormarks
- % Typeset the headline with \maincolor, then restore the color.
- \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}%
- }%
- \vss
- }%
- \nointerlineskip
- }
- %
- %
- \pdfcatalog{/PageMode /UseOutlines}
- %
- % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
+ \input pdfcolor
+ \pdfcatalog{/PageMode /UseOutlines}%
\def\dopdfimage#1#2#3{%
- \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
- \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
- %
- % pdftex (and the PDF format) support .png, .jpg, .pdf (among
- % others). Let's try in that order.
- \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
- \errhelp = \nopdfimagehelp
- \errmessage{Could not find image file #1 for pdf}%
- \else \gdef\pdfimgext{pdf}%
- \fi
- \else \gdef\pdfimgext{JPG}%
- \fi
- \else \gdef\pdfimgext{jpeg}%
- \fi
- \else \gdef\pdfimgext{jpg}%
- \fi
- \else \gdef\pdfimgext{png}%
- \fi
- \closein 1
- \endgroup
- %
+ \def\imagewidth{#2}%
+ \def\imageheight{#3}%
% without \immediate, pdftex seg faults when the same image is
% included twice. (Version 3.14159-pre-1.0-unofficial-20010704.)
\ifnum\pdftexversion < 14
@@ -1384,38 +1265,31 @@
\else
\immediate\pdfximage
\fi
- \ifdim \wd0 >0pt width \imagewidth \fi
- \ifdim \wd2 >0pt height \imageheight \fi
+ \ifx\empty\imagewidth\else width \imagewidth \fi
+ \ifx\empty\imageheight\else height \imageheight \fi
\ifnum\pdftexversion<13
- #1.\pdfimgext
+ #1.pdf%
\else
- {#1.\pdfimgext}%
+ {#1.pdf}%
\fi
\ifnum\pdftexversion < 14 \else
\pdfrefximage \pdflastximage
\fi}
- %
\def\pdfmkdest#1{{%
% We have to set dummies so commands such as @code, and characters
% such as \, aren't expanded when present in a section title.
- \indexnofonts
- \turnoffactive
+ \atdummies
\activebackslashdouble
- \makevalueexpandable
\def\pdfdestname{#1}%
\backslashparens\pdfdestname
- \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
- }}
+ \pdfdest name{\pdfdestname} xyz%
+ }}%
%
% used to mark target names; must be expandable.
- \def\pdfmkpgn#1{#1}
+ \def\pdfmkpgn#1{#1}%
%
- % by default, use a color that is dark enough to print on paper as
- % nearly black, but still distinguishable for online viewing.
- \def\urlcolor{\cmykDarkRed}
- \def\linkcolor{\cmykDarkRed}
- \def\endlink{\setcolor{\maincolor}\pdfendlink}
- %
+ \let\linkcolor = \Blue % was Cyan, but that seems light?
+ \def\endlink{\Black\pdfendlink}
% Adding outlines to PDF; macros for calculating structure of outlines
% come from Petr Olsak
\def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
@@ -1516,8 +1390,8 @@
% now, I guess we'll just let the pdf reader have its way.
\indexnofonts
\setupdatafile
- \catcode`\\=\active \otherbackslash
- \input \tocreadfilename
+ \activebackslash
+ \input \jobname.toc
\endgroup
}
%
@@ -1535,19 +1409,11 @@
\else
\let \startlink \pdfstartlink
\fi
- % make a live url in pdf output.
\def\pdfurl#1{%
\begingroup
- % it seems we really need yet another set of dummies; have not
- % tried to figure out what each command should do in the context
- % of @url. for now, just make @/ a no-op, that's the only one
- % people have actually reported a problem with.
- %
- \normalturnoffactive
- address@hidden@}%
- \let\/=\empty
+ address@hidden@}%
\makevalueexpandable
- \leavevmode\setcolor{\urlcolor}%
+ \leavevmode\Red
\startlink attr{/Border [0 0 0]}%
user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
\endgroup}
@@ -1574,14 +1440,13 @@
{\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
\def\pdflink#1{%
\startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
- \setcolor{\linkcolor}#1\endlink}
+ \linkcolor #1\endlink}
\def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
\else
\let\pdfmkdest = \gobble
\let\pdfurl = \gobble
\let\endlink = \relax
- \let\setcolor = \gobble
- \let\pdfsetcolor = \gobble
+ \let\linkcolor = \relax
\let\pdfmakeoutlines = \relax
\fi % \ifx\pdfoutput
@@ -1616,7 +1481,6 @@
% We don't need math for this font style.
\def\ttsl{\setfontstyle{ttsl}}
-
% Default leading.
\newdimen\textleading \textleading = 13.2pt
@@ -1628,12 +1492,8 @@
\def\strutheightpercent{.70833}
\def\strutdepthpercent {.29167}
%
-% can get a sort of poor man's double spacing by redefining this.
-\def\baselinefactor{1}
-%
\def\setleading#1{%
- \dimen0 = #1\relax
- \normalbaselineskip = \baselinefactor\dimen0
+ \normalbaselineskip = #1\relax
\normallineskip = \lineskipfactor\normalbaselineskip
\normalbaselines
\setbox\strutbox =\hbox{%
@@ -1642,279 +1502,10 @@
}%
}
-% PDF CMaps. See also LaTeX's t1.cmap.
-%
-% do nothing with this by default.
-\expandafter\let\csname cmapOT1\endcsname\gobble
-\expandafter\let\csname cmapOT1IT\endcsname\gobble
-\expandafter\let\csname cmapOT1TT\endcsname\gobble
-
-% 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
- \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
-%%DocumentNeededResources: ProcSet (CIDInit)
-%%IncludeResource: ProcSet (CIDInit)
-%%BeginResource: CMap (TeX-OT1-0)
-%%Title: (TeX-OT1-0 TeX OT1 0)
-%%Version: 1.000
-%%EndComments
-/CIDInit /ProcSet findresource begin
-12 dict begin
-begincmap
-/CIDSystemInfo
-<< /Registry (TeX)
-/Ordering (OT1)
-/Supplement 0
->> def
-/CMapName /TeX-OT1-0 def
-/CMapType 2 def
-1 begincodespacerange
-<00> <7F>
-endcodespacerange
-8 beginbfrange
-<00> <01> <0393>
-<09> <0A> <03A8>
-<23> <26> <0023>
-<28> <3B> <0028>
-<3F> <5B> <003F>
-<5D> <5E> <005D>
-<61> <7A> <0061>
-<7B> <7C> <2013>
-endbfrange
-40 beginbfchar
-<02> <0398>
-<03> <039B>
-<04> <039E>
-<05> <03A0>
-<06> <03A3>
-<07> <03D2>
-<08> <03A6>
-<0B> <00660066>
-<0C> <00660069>
-<0D> <0066006C>
-<0E> <006600660069>
-<0F> <00660066006C>
-<10> <0131>
-<11> <0237>
-<12> <0060>
-<13> <00B4>
-<14> <02C7>
-<15> <02D8>
-<16> <00AF>
-<17> <02DA>
-<18> <00B8>
-<19> <00DF>
-<1A> <00E6>
-<1B> <0153>
-<1C> <00F8>
-<1D> <00C6>
-<1E> <0152>
-<1F> <00D8>
-<21> <0021>
-<22> <201D>
-<27> <2019>
-<3C> <00A1>
-<3D> <003D>
-<3E> <00BF>
-<5C> <201C>
-<5F> <02D9>
-<60> <2018>
-<7D> <02DD>
-<7E> <007E>
-<7F> <00A8>
-endbfchar
-endcmap
-CMapName currentdict /CMap defineresource pop
-end
-end
-%%EndResource
-%%EOF
- }\endgroup
- \expandafter\edef\csname cmapOT1\endcsname#1{%
- \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
- }%
-%
-% \cmapOT1IT
- \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
-%%DocumentNeededResources: ProcSet (CIDInit)
-%%IncludeResource: ProcSet (CIDInit)
-%%BeginResource: CMap (TeX-OT1IT-0)
-%%Title: (TeX-OT1IT-0 TeX OT1IT 0)
-%%Version: 1.000
-%%EndComments
-/CIDInit /ProcSet findresource begin
-12 dict begin
-begincmap
-/CIDSystemInfo
-<< /Registry (TeX)
-/Ordering (OT1IT)
-/Supplement 0
->> def
-/CMapName /TeX-OT1IT-0 def
-/CMapType 2 def
-1 begincodespacerange
-<00> <7F>
-endcodespacerange
-8 beginbfrange
-<00> <01> <0393>
-<09> <0A> <03A8>
-<25> <26> <0025>
-<28> <3B> <0028>
-<3F> <5B> <003F>
-<5D> <5E> <005D>
-<61> <7A> <0061>
-<7B> <7C> <2013>
-endbfrange
-42 beginbfchar
-<02> <0398>
-<03> <039B>
-<04> <039E>
-<05> <03A0>
-<06> <03A3>
-<07> <03D2>
-<08> <03A6>
-<0B> <00660066>
-<0C> <00660069>
-<0D> <0066006C>
-<0E> <006600660069>
-<0F> <00660066006C>
-<10> <0131>
-<11> <0237>
-<12> <0060>
-<13> <00B4>
-<14> <02C7>
-<15> <02D8>
-<16> <00AF>
-<17> <02DA>
-<18> <00B8>
-<19> <00DF>
-<1A> <00E6>
-<1B> <0153>
-<1C> <00F8>
-<1D> <00C6>
-<1E> <0152>
-<1F> <00D8>
-<21> <0021>
-<22> <201D>
-<23> <0023>
-<24> <00A3>
-<27> <2019>
-<3C> <00A1>
-<3D> <003D>
-<3E> <00BF>
-<5C> <201C>
-<5F> <02D9>
-<60> <2018>
-<7D> <02DD>
-<7E> <007E>
-<7F> <00A8>
-endbfchar
-endcmap
-CMapName currentdict /CMap defineresource pop
-end
-end
-%%EndResource
-%%EOF
- }\endgroup
- \expandafter\edef\csname cmapOT1IT\endcsname#1{%
- \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
- }%
-%
-% \cmapOT1TT
- \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
-%%DocumentNeededResources: ProcSet (CIDInit)
-%%IncludeResource: ProcSet (CIDInit)
-%%BeginResource: CMap (TeX-OT1TT-0)
-%%Title: (TeX-OT1TT-0 TeX OT1TT 0)
-%%Version: 1.000
-%%EndComments
-/CIDInit /ProcSet findresource begin
-12 dict begin
-begincmap
-/CIDSystemInfo
-<< /Registry (TeX)
-/Ordering (OT1TT)
-/Supplement 0
->> def
-/CMapName /TeX-OT1TT-0 def
-/CMapType 2 def
-1 begincodespacerange
-<00> <7F>
-endcodespacerange
-5 beginbfrange
-<00> <01> <0393>
-<09> <0A> <03A8>
-<21> <26> <0021>
-<28> <5F> <0028>
-<61> <7E> <0061>
-endbfrange
-32 beginbfchar
-<02> <0398>
-<03> <039B>
-<04> <039E>
-<05> <03A0>
-<06> <03A3>
-<07> <03D2>
-<08> <03A6>
-<0B> <2191>
-<0C> <2193>
-<0D> <0027>
-<0E> <00A1>
-<0F> <00BF>
-<10> <0131>
-<11> <0237>
-<12> <0060>
-<13> <00B4>
-<14> <02C7>
-<15> <02D8>
-<16> <00AF>
-<17> <02DA>
-<18> <00B8>
-<19> <00DF>
-<1A> <00E6>
-<1B> <0153>
-<1C> <00F8>
-<1D> <00C6>
-<1E> <0152>
-<1F> <00D8>
-<20> <2423>
-<27> <2019>
-<60> <2018>
-<7F> <00A8>
-endbfchar
-endcmap
-CMapName currentdict /CMap defineresource pop
-end
-end
-%%EndResource
-%%EOF
- }\endgroup
- \expandafter\edef\csname cmapOT1TT\endcsname#1{%
- \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
- }%
-\fi\fi
-
-
% Set the font macro #1 to the font named #2, adding on the
% specified font prefix (normally `cm').
-% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
-% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass
-% empty to omit).
-\def\setfont#1#2#3#4#5{%
- \font#1=\fontprefix#2#3 scaled #4
- \csname cmap#5\endcsname#1%
-}
-% This is what gets called when #5 of \setfont is empty.
-\let\cmap\gobble
-% emacs-page end of cmaps
+% #3 is the font's design size, #4 is a scale factor
+\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
% Use cm as the default font prefix.
% To specify the font prefix, you must define \fontprefix
@@ -1939,298 +1530,119 @@
\def\scshape{csc}
\def\scbshape{csc}
-% Definitions for a main text size of 11pt. This is the default in
-% Texinfo.
-%
-\def\definetextfontsizexi{%
% Text fonts (11.2pt, magstep1).
\def\textnominalsize{11pt}
\edef\mainmagstep{\magstephalf}
-\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
-\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
-\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
-\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
-\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
-\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
-\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
-\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\setfont\textrm\rmshape{10}{\mainmagstep}
+\setfont\texttt\ttshape{10}{\mainmagstep}
+\setfont\textbf\bfshape{10}{\mainmagstep}
+\setfont\textit\itshape{10}{\mainmagstep}
+\setfont\textsl\slshape{10}{\mainmagstep}
+\setfont\textsf\sfshape{10}{\mainmagstep}
+\setfont\textsc\scshape{10}{\mainmagstep}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}
\font\texti=cmmi10 scaled \mainmagstep
\font\textsy=cmsy10 scaled \mainmagstep
-\def\textecsize{1095}
% A few fonts for @defun names and args.
-\setfont\defbf\bfshape{10}{\magstep1}{OT1}
-\setfont\deftt\ttshape{10}{\magstep1}{OT1TT}
-\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT}
+\setfont\defbf\bfshape{10}{\magstep1}
+\setfont\deftt\ttshape{10}{\magstep1}
+\setfont\defttsl\ttslshape{10}{\magstep1}
\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
% Fonts for indices, footnotes, small examples (9pt).
\def\smallnominalsize{9pt}
-\setfont\smallrm\rmshape{9}{1000}{OT1}
-\setfont\smalltt\ttshape{9}{1000}{OT1TT}
-\setfont\smallbf\bfshape{10}{900}{OT1}
-\setfont\smallit\itshape{9}{1000}{OT1IT}
-\setfont\smallsl\slshape{9}{1000}{OT1}
-\setfont\smallsf\sfshape{9}{1000}{OT1}
-\setfont\smallsc\scshape{10}{900}{OT1}
-\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\setfont\smallrm\rmshape{9}{1000}
+\setfont\smalltt\ttshape{9}{1000}
+\setfont\smallbf\bfshape{10}{900}
+\setfont\smallit\itshape{9}{1000}
+\setfont\smallsl\slshape{9}{1000}
+\setfont\smallsf\sfshape{9}{1000}
+\setfont\smallsc\scshape{10}{900}
+\setfont\smallttsl\ttslshape{10}{900}
\font\smalli=cmmi9
\font\smallsy=cmsy9
-\def\smallecsize{0900}
% Fonts for small examples (8pt).
\def\smallernominalsize{8pt}
-\setfont\smallerrm\rmshape{8}{1000}{OT1}
-\setfont\smallertt\ttshape{8}{1000}{OT1TT}
-\setfont\smallerbf\bfshape{10}{800}{OT1}
-\setfont\smallerit\itshape{8}{1000}{OT1IT}
-\setfont\smallersl\slshape{8}{1000}{OT1}
-\setfont\smallersf\sfshape{8}{1000}{OT1}
-\setfont\smallersc\scshape{10}{800}{OT1}
-\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\setfont\smallerrm\rmshape{8}{1000}
+\setfont\smallertt\ttshape{8}{1000}
+\setfont\smallerbf\bfshape{10}{800}
+\setfont\smallerit\itshape{8}{1000}
+\setfont\smallersl\slshape{8}{1000}
+\setfont\smallersf\sfshape{8}{1000}
+\setfont\smallersc\scshape{10}{800}
+\setfont\smallerttsl\ttslshape{10}{800}
\font\smalleri=cmmi8
\font\smallersy=cmsy8
-\def\smallerecsize{0800}
% Fonts for title page (20.4pt):
\def\titlenominalsize{20pt}
-\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
-\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
-\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
-\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
-\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
-\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\setfont\titlerm\rmbshape{12}{\magstep3}
+\setfont\titleit\itbshape{10}{\magstep4}
+\setfont\titlesl\slbshape{10}{\magstep4}
+\setfont\titlett\ttbshape{12}{\magstep3}
+\setfont\titlettsl\ttslshape{10}{\magstep4}
+\setfont\titlesf\sfbshape{17}{\magstep1}
\let\titlebf=\titlerm
-\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\setfont\titlesc\scbshape{10}{\magstep4}
\font\titlei=cmmi12 scaled \magstep3
\font\titlesy=cmsy10 scaled \magstep4
\def\authorrm{\secrm}
\def\authortt{\sectt}
-\def\titleecsize{2074}
% Chapter (and unnumbered) fonts (17.28pt).
\def\chapnominalsize{17pt}
-\setfont\chaprm\rmbshape{12}{\magstep2}{OT1}
-\setfont\chapit\itbshape{10}{\magstep3}{OT1IT}
-\setfont\chapsl\slbshape{10}{\magstep3}{OT1}
-\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT}
-\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT}
-\setfont\chapsf\sfbshape{17}{1000}{OT1}
+\setfont\chaprm\rmbshape{12}{\magstep2}
+\setfont\chapit\itbshape{10}{\magstep3}
+\setfont\chapsl\slbshape{10}{\magstep3}
+\setfont\chaptt\ttbshape{12}{\magstep2}
+\setfont\chapttsl\ttslshape{10}{\magstep3}
+\setfont\chapsf\sfbshape{17}{1000}
\let\chapbf=\chaprm
-\setfont\chapsc\scbshape{10}{\magstep3}{OT1}
+\setfont\chapsc\scbshape{10}{\magstep3}
\font\chapi=cmmi12 scaled \magstep2
\font\chapsy=cmsy10 scaled \magstep3
-\def\chapecsize{1728}
% Section fonts (14.4pt).
\def\secnominalsize{14pt}
-\setfont\secrm\rmbshape{12}{\magstep1}{OT1}
-\setfont\secit\itbshape{10}{\magstep2}{OT1IT}
-\setfont\secsl\slbshape{10}{\magstep2}{OT1}
-\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT}
-\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT}
-\setfont\secsf\sfbshape{12}{\magstep1}{OT1}
+\setfont\secrm\rmbshape{12}{\magstep1}
+\setfont\secit\itbshape{10}{\magstep2}
+\setfont\secsl\slbshape{10}{\magstep2}
+\setfont\sectt\ttbshape{12}{\magstep1}
+\setfont\secttsl\ttslshape{10}{\magstep2}
+\setfont\secsf\sfbshape{12}{\magstep1}
\let\secbf\secrm
-\setfont\secsc\scbshape{10}{\magstep2}{OT1}
+\setfont\secsc\scbshape{10}{\magstep2}
\font\seci=cmmi12 scaled \magstep1
\font\secsy=cmsy10 scaled \magstep2
-\def\sececsize{1440}
% Subsection fonts (13.15pt).
\def\ssecnominalsize{13pt}
-\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1}
-\setfont\ssecit\itbshape{10}{1315}{OT1IT}
-\setfont\ssecsl\slbshape{10}{1315}{OT1}
-\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT}
-\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT}
-\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}
+\setfont\ssecit\itbshape{10}{1315}
+\setfont\ssecsl\slbshape{10}{1315}
+\setfont\ssectt\ttbshape{12}{\magstephalf}
+\setfont\ssecttsl\ttslshape{10}{1315}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}
\let\ssecbf\ssecrm
-\setfont\ssecsc\scbshape{10}{1315}{OT1}
+\setfont\ssecsc\scbshape{10}{1315}
\font\sseci=cmmi12 scaled \magstephalf
\font\ssecsy=cmsy10 scaled 1315
-\def\ssececsize{1200}
% Reduced fonts for @acro in text (10pt).
\def\reducednominalsize{10pt}
-\setfont\reducedrm\rmshape{10}{1000}{OT1}
-\setfont\reducedtt\ttshape{10}{1000}{OT1TT}
-\setfont\reducedbf\bfshape{10}{1000}{OT1}
-\setfont\reducedit\itshape{10}{1000}{OT1IT}
-\setfont\reducedsl\slshape{10}{1000}{OT1}
-\setfont\reducedsf\sfshape{10}{1000}{OT1}
-\setfont\reducedsc\scshape{10}{1000}{OT1}
-\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT}
+\setfont\reducedrm\rmshape{10}{1000}
+\setfont\reducedtt\ttshape{10}{1000}
+\setfont\reducedbf\bfshape{10}{1000}
+\setfont\reducedit\itshape{10}{1000}
+\setfont\reducedsl\slshape{10}{1000}
+\setfont\reducedsf\sfshape{10}{1000}
+\setfont\reducedsc\scshape{10}{1000}
+\setfont\reducedttsl\ttslshape{10}{1000}
\font\reducedi=cmmi10
\font\reducedsy=cmsy10
-\def\reducedecsize{1000}
-% reset the current fonts
-\textfonts
-\rm
-} % end of 11pt text font size definitions
-
-
-% Definitions to make the main text be 10pt Computer Modern, with
-% section, chapter, etc., sizes following suit. This is for the GNU
-% Press printing of the Emacs 22 manual. Maybe other manuals in the
-% future. Used with @smallbook, which sets the leading to 12pt.
-%
-\def\definetextfontsizex{%
-% Text fonts (10pt).
-\def\textnominalsize{10pt}
-\edef\mainmagstep{1000}
-\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
-\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
-\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
-\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
-\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
-\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
-\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
-\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
-\font\texti=cmmi10 scaled \mainmagstep
-\font\textsy=cmsy10 scaled \mainmagstep
-\def\textecsize{1000}
-
-% A few fonts for @defun names and args.
-\setfont\defbf\bfshape{10}{\magstephalf}{OT1}
-\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT}
-\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT}
-\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
-
-% Fonts for indices, footnotes, small examples (9pt).
-\def\smallnominalsize{9pt}
-\setfont\smallrm\rmshape{9}{1000}{OT1}
-\setfont\smalltt\ttshape{9}{1000}{OT1TT}
-\setfont\smallbf\bfshape{10}{900}{OT1}
-\setfont\smallit\itshape{9}{1000}{OT1IT}
-\setfont\smallsl\slshape{9}{1000}{OT1}
-\setfont\smallsf\sfshape{9}{1000}{OT1}
-\setfont\smallsc\scshape{10}{900}{OT1}
-\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
-\font\smalli=cmmi9
-\font\smallsy=cmsy9
-\def\smallecsize{0900}
-
-% Fonts for small examples (8pt).
-\def\smallernominalsize{8pt}
-\setfont\smallerrm\rmshape{8}{1000}{OT1}
-\setfont\smallertt\ttshape{8}{1000}{OT1TT}
-\setfont\smallerbf\bfshape{10}{800}{OT1}
-\setfont\smallerit\itshape{8}{1000}{OT1IT}
-\setfont\smallersl\slshape{8}{1000}{OT1}
-\setfont\smallersf\sfshape{8}{1000}{OT1}
-\setfont\smallersc\scshape{10}{800}{OT1}
-\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
-\font\smalleri=cmmi8
-\font\smallersy=cmsy8
-\def\smallerecsize{0800}
-
-% Fonts for title page (20.4pt):
-\def\titlenominalsize{20pt}
-\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
-\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
-\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
-\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
-\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
-\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
-\let\titlebf=\titlerm
-\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
-\font\titlei=cmmi12 scaled \magstep3
-\font\titlesy=cmsy10 scaled \magstep4
-\def\authorrm{\secrm}
-\def\authortt{\sectt}
-\def\titleecsize{2074}
-
-% Chapter fonts (14.4pt).
-\def\chapnominalsize{14pt}
-\setfont\chaprm\rmbshape{12}{\magstep1}{OT1}
-\setfont\chapit\itbshape{10}{\magstep2}{OT1IT}
-\setfont\chapsl\slbshape{10}{\magstep2}{OT1}
-\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT}
-\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT}
-\setfont\chapsf\sfbshape{12}{\magstep1}{OT1}
-\let\chapbf\chaprm
-\setfont\chapsc\scbshape{10}{\magstep2}{OT1}
-\font\chapi=cmmi12 scaled \magstep1
-\font\chapsy=cmsy10 scaled \magstep2
-\def\chapecsize{1440}
-
-% Section fonts (12pt).
-\def\secnominalsize{12pt}
-\setfont\secrm\rmbshape{12}{1000}{OT1}
-\setfont\secit\itbshape{10}{\magstep1}{OT1IT}
-\setfont\secsl\slbshape{10}{\magstep1}{OT1}
-\setfont\sectt\ttbshape{12}{1000}{OT1TT}
-\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT}
-\setfont\secsf\sfbshape{12}{1000}{OT1}
-\let\secbf\secrm
-\setfont\secsc\scbshape{10}{\magstep1}{OT1}
-\font\seci=cmmi12
-\font\secsy=cmsy10 scaled \magstep1
-\def\sececsize{1200}
-
-% Subsection fonts (10pt).
-\def\ssecnominalsize{10pt}
-\setfont\ssecrm\rmbshape{10}{1000}{OT1}
-\setfont\ssecit\itbshape{10}{1000}{OT1IT}
-\setfont\ssecsl\slbshape{10}{1000}{OT1}
-\setfont\ssectt\ttbshape{10}{1000}{OT1TT}
-\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT}
-\setfont\ssecsf\sfbshape{10}{1000}{OT1}
-\let\ssecbf\ssecrm
-\setfont\ssecsc\scbshape{10}{1000}{OT1}
-\font\sseci=cmmi10
-\font\ssecsy=cmsy10
-\def\ssececsize{1000}
-
-% Reduced fonts for @acro in text (9pt).
-\def\reducednominalsize{9pt}
-\setfont\reducedrm\rmshape{9}{1000}{OT1}
-\setfont\reducedtt\ttshape{9}{1000}{OT1TT}
-\setfont\reducedbf\bfshape{10}{900}{OT1}
-\setfont\reducedit\itshape{9}{1000}{OT1IT}
-\setfont\reducedsl\slshape{9}{1000}{OT1}
-\setfont\reducedsf\sfshape{9}{1000}{OT1}
-\setfont\reducedsc\scshape{10}{900}{OT1}
-\setfont\reducedttsl\ttslshape{10}{900}{OT1TT}
-\font\reducedi=cmmi9
-\font\reducedsy=cmsy9
-\def\reducedecsize{0900}
-
-% reduce space between paragraphs
-\divide\parskip by 2
-
-% reset the current fonts
-\textfonts
-\rm
-} % end of 10pt text font size definitions
-
-
-% We provide the user-level command
-% @fonttextsize 10
-% (or 11) to redefine the text font size. pt is assumed.
-%
-\def\xword{10}
-\def\xiword{11}
-%
-\parseargdef\fonttextsize{%
- \def\textsizearg{#1}%
- \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.
- %
- \begingroup \globaldefs=1
- \ifx\textsizearg\xword \definetextfontsizex
- \else \ifx\textsizearg\xiword \definetextfontsizexi
- \else
- \errhelp=\EMsimple
- address@hidden only supports `10' or `11', not `\textsizearg'}
- \fi\fi
- \endgroup
-}
-
-
% In order for the font changes to affect most math symbols and letters,
% we have to define the \textfont of the standard families. Since
% texinfo doesn't allow for producing subscripts and superscripts except
@@ -2341,7 +1753,7 @@
% Set up the default fonts, so we can use them for creating boxes.
%
-\definetextfontsizexi
+\textfonts \rm
% Define these so they can be easily changed for other fonts.
\def\angleleft{$\langle$}
@@ -2351,10 +1763,10 @@
\newcount\fontdepth \fontdepth=0
% Fonts for short table of contents.
-\setfont\shortcontrm\rmshape{12}{1000}{OT1}
-\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12
-\setfont\shortcontsl\slshape{12}{1000}{OT1}
-\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
+\setfont\shortcontrm\rmshape{12}{1000}
+\setfont\shortcontbf\bfshape{10}{\magstep1} % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}
+\setfont\shortconttt\ttshape{12}{1000}
%% Add scribe-like font environments, plus @l for inline lisp (usually sans
%% serif) and @ii for TeX italic
@@ -2417,7 +1829,7 @@
\null
}
\def\samp#1{`\tclose{#1}'\null}
-\setfont\keyrm\rmshape{8}{1000}{OT1}
+\setfont\keyrm\rmshape{8}{1000}
\font\keysy=cmsy9
\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
\raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
@@ -2425,7 +1837,6 @@
\hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
\kern-0.4pt\hrule}%
\kern-.06em\raise0.4pt\hbox{\angleright}}}}
-\def\key #1{{\nohyphenation \uppercase{#1}}\null}
% The old definition, with no lozenge:
%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
\def\ctrl #1{{\tt \rawbackslash \hat}#1}
@@ -2467,14 +1878,11 @@
% and arrange explicitly to hyphenate at a dash.
% -- rms.
{
- \catcode`\-=\active \catcode`\_=\active
- \catcode`\'=\active \catcode`\`=\active
+ \catcode`\-=\active
+ \catcode`\_=\active
%
\global\def\code{\begingroup
- \catcode\rquoteChar=\active \catcode\lquoteChar=\active
- \let'\codequoteright \let`\codequoteleft
- %
- \catcode\dashChar=\active \catcode\underChar=\active
+ \catcode`\-=\active \catcode`\_=\active
\ifallowcodebreaks
\let-\codedash
\let_\codeunder
@@ -2710,35 +2118,6 @@
\thiseurofont
}
-% Hacks for glyphs from the EC fonts similar to \euro. We don't
-% use \let for the aliases, because sometimes we redefine the original
-% macro, and the alias should reflect the redefinition.
-\def\guillemetleft{{\ecfont \char"13}}
-\def\guillemotleft{\guillemetleft}
-\def\guillemetright{{\ecfont \char"14}}
-\def\guillemotright{\guillemetright}
-\def\guilsinglleft{{\ecfont \char"0E}}
-\def\guilsinglright{{\ecfont \char"0F}}
-\def\quotedblbase{{\ecfont \char"12}}
-\def\quotesinglbase{{\ecfont \char"0D}}
-%
-\def\ecfont{%
- % We can't distinguish serif/sanserif and italic/slanted, but this
- % is used for crude hacks anyway (like adding French and German
- % quotes to documents typeset with CM, where we lose kerning), so
- % hopefully nobody will notice/care.
- \edef\ecsize{\csname\curfontsize ecsize\endcsname}%
- \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
- \ifx\curfontstyle\bfstylename
- % bold:
- \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
- \else
- % regular:
- \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
- \fi
- \thisecfont
-}
-
% @registeredsymbol - R in a circle. The font for the R should really
% be smaller yet, but lllsize is the best we can do for now.
% Adapted from the plain.tex definition of \copyright.
@@ -2749,10 +2128,6 @@
}$%
}
-% @textdegree - the normal degrees sign.
-%
-\def\textdegree{$^\circ$}
-
% Laurent Siebenmann reports \Orb undefined with:
% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38
% so we'll define it if necessary.
@@ -2761,13 +2136,7 @@
\def\Orb{\mathhexbox20D}
\fi
-% Quotes.
-\chardef\quotedblleft="5C
-\chardef\quotedblright=`\"
-\chardef\quoteleft=`\`
-\chardef\quoteright=`\'
-
\message{page headings,}
\newskip\titlepagetopglue \titlepagetopglue = 1.5in
@@ -2930,40 +2299,13 @@
%
% Leave some space for the footline. Hopefully ok to assume
% @evenfooting will not be used by itself.
- \global\advance\pageheight by -12pt
- \global\advance\vsize by -12pt
+ \global\advance\pageheight by -\baselineskip
+ \global\advance\vsize by -\baselineskip
}
\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
-% @evenheadingmarks top \thischapter <- chapter at the top of a page
-% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page
-%
-% The same set of arguments for:
-%
-% @oddheadingmarks
-% @evenfootingmarks
-% @oddfootingmarks
-% @everyheadingmarks
-% @everyfootingmarks
-\def\evenheadingmarks{\headingmarks{even}{heading}}
-\def\oddheadingmarks{\headingmarks{odd}{heading}}
-\def\evenfootingmarks{\headingmarks{even}{footing}}
-\def\oddfootingmarks{\headingmarks{odd}{footing}}
-\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1}
- \headingmarks{odd}{heading}{#1} }
-\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1}
- \headingmarks{odd}{footing}{#1} }
-% #1 = even/odd, #2 = heading/footing, #3 = top/bottom.
-\def\headingmarks#1#2#3 {%
- \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname
- \global\expandafter\let\csname get#1#2marks\endcsname \temp
-}
-
-\everyheadingmarks bottom
-\everyfootingmarks bottom
-
% @headings double turns headings on for double-sided printing.
% @headings single turns headings on for single-sided printing.
% @headings off turns them off.
@@ -3617,7 +2959,6 @@
\def\doignore#1{\begingroup
% Scan in ``verbatim'' mode:
- \obeylines
\catcode`\@ = \other
\catcode`\{ = \other
\catcode`\} = \other
@@ -3638,16 +2979,16 @@
\gdef\dodoignore#1{%
% #1 contains the command name as a string, e.g., `ifinfo'.
%
- % Define a command to find the next address@hidden #1'.
- address@hidden #1{%
- address@hidden
- %
+ % Define a command to find the next address@hidden #1', which must be on a
line
+ % by itself.
+ address@hidden address@hidden
% And this command to find another #1 command, at the beginning of a
% line. (Otherwise, we would consider a line address@hidden @ifset', for
% example, to count as an @ifset for nesting.)
address@hidden
%
% And now expand that command.
+ \obeylines %
\doignoretext ^^M%
}%
}
@@ -3677,12 +3018,7 @@
}
% Finish off ignored text.
-{ \obeylines%
- % Ignore anything after the last address@hidden #1'; this matters in verbatim
- % environments, where otherwise the newline after an ignored conditional
- % would result in a blank line in the output.
- \gdef\enddoignore#1^^M{\endgroup\ignorespaces}%
-}
+\def\enddoignore{\endgroup\ignorespaces}
% @set VAR sets the variable VAR to an empty value.
@@ -3885,39 +3221,12 @@
\escapechar = `\\ % use backslash in output files.
address@hidden@}% 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
%
- % I don't entirely understand this, but when an index entry is
- % generated from a macro call, the \endinput which \scanmacro inserts
- % causes processing to be prematurely terminated. This is,
- % apparently, because \indexsorttmp is fully expanded, and \endinput
- % is an expandable command. The redefinition below makes \endinput
- % disappear altogether for that purpose -- although logging shows that
- % processing continues to some further point. On the other hand, it
- % seems \endinput does not hurt in the printed index arg, since that
- % is still getting written without apparent harm.
- %
- % Sample source (mac-idx3.tex, reported by Graham Percival to
- % help-texinfo, 22may06):
- % @macro funindex {WORD}
- % @findex xyz
- % @end macro
- % ...
- % @funindex commtest
- %
- % The above is not enough to reproduce the bug, but it gives the flavor.
- %
- % Sample whatsit resulting:
- % address@hidden@folio address@hidden address@hidden }}}
- %
- % So:
- \let\endinput = \empty
- %
% Do the redefinitions.
\commondummies
}
@@ -3935,7 +3244,6 @@
%
% Do the redefinitions.
\commondummies
- \otherbackslash
}
% Called from \indexdummies and \atdummies.
@@ -4003,23 +3311,12 @@
\definedummyword\equiv
\definedummyword\error
\definedummyword\euro
- \definedummyword\guillemetleft
- \definedummyword\guillemetright
- \definedummyword\guilsinglleft
- \definedummyword\guilsinglright
\definedummyword\expansion
\definedummyword\minus
\definedummyword\pounds
\definedummyword\point
\definedummyword\print
- \definedummyword\quotedblbase
- \definedummyword\quotedblleft
- \definedummyword\quotedblright
- \definedummyword\quoteleft
- \definedummyword\quoteright
- \definedummyword\quotesinglbase
\definedummyword\result
- \definedummyword\textdegree
%
% We want to disable all macros so that they are not expanded by \write.
\macrolist
@@ -4033,62 +3330,63 @@
% \commondummiesnofonts: common to \commondummies and \indexnofonts.
%
-\def\commondummiesnofonts{%
- % Control letters and accents.
- \definedummyletter\!%
- \definedummyaccent\"%
- \definedummyaccent\'%
- \definedummyletter\*%
- \definedummyaccent\,%
- \definedummyletter\.%
- \definedummyletter\/%
- \definedummyletter\:%
- \definedummyaccent\=%
- \definedummyletter\?%
- \definedummyaccent\^%
- \definedummyaccent\`%
- \definedummyaccent\~%
- \definedummyword\u
- \definedummyword\v
- \definedummyword\H
- \definedummyword\dotaccent
- \definedummyword\ringaccent
- \definedummyword\tieaccent
- \definedummyword\ubaraccent
- \definedummyword\udotaccent
- \definedummyword\dotless
- %
- % Texinfo font commands.
- \definedummyword\b
- \definedummyword\i
- \definedummyword\r
- \definedummyword\sc
- \definedummyword\t
- %
- % Commands that take arguments.
- \definedummyword\acronym
- \definedummyword\cite
- \definedummyword\code
- \definedummyword\command
- \definedummyword\dfn
- \definedummyword\emph
- \definedummyword\env
- \definedummyword\file
- \definedummyword\kbd
- \definedummyword\key
- \definedummyword\math
- \definedummyword\option
- \definedummyword\pxref
- \definedummyword\ref
- \definedummyword\samp
- \definedummyword\strong
- \definedummyword\tie
- \definedummyword\uref
- \definedummyword\url
- \definedummyword\var
- \definedummyword\verb
- \definedummyword\w
- \definedummyword\xref
+% Better have this without active chars.
+{
+ \catcode`\~=\other
+ \gdef\commondummiesnofonts{%
+ % Control letters and accents.
+ \definedummyletter\!%
+ \definedummyaccent\"%
+ \definedummyaccent\'%
+ \definedummyletter\*%
+ \definedummyaccent\,%
+ \definedummyletter\.%
+ \definedummyletter\/%
+ \definedummyletter\:%
+ \definedummyaccent\=%
+ \definedummyletter\?%
+ \definedummyaccent\^%
+ \definedummyaccent\`%
+ \definedummyaccent\~%
+ \definedummyword\u
+ \definedummyword\v
+ \definedummyword\H
+ \definedummyword\dotaccent
+ \definedummyword\ringaccent
+ \definedummyword\tieaccent
+ \definedummyword\ubaraccent
+ \definedummyword\udotaccent
+ \definedummyword\dotless
+ %
+ % Texinfo font commands.
+ \definedummyword\b
+ \definedummyword\i
+ \definedummyword\r
+ \definedummyword\sc
+ \definedummyword\t
+ %
+ % Commands that take arguments.
+ \definedummyword\acronym
+ \definedummyword\cite
+ \definedummyword\code
+ \definedummyword\command
+ \definedummyword\dfn
+ \definedummyword\emph
+ \definedummyword\env
+ \definedummyword\file
+ \definedummyword\kbd
+ \definedummyword\key
+ \definedummyword\math
+ \definedummyword\option
+ \definedummyword\samp
+ \definedummyword\strong
+ \definedummyword\tie
+ \definedummyword\uref
+ \definedummyword\url
+ \definedummyword\var
+ \definedummyword\verb
+ \definedummyword\w
+ }
}
% \indexnofonts is used when outputting the strings to sort the index
@@ -4147,23 +3445,12 @@
\def\equiv{==}%
\def\error{error}%
\def\euro{euro}%
- \def\guillemetleft{<<}%
- \def\guillemetright{>>}%
- \def\guilsinglleft{<}%
- \def\guilsinglright{>}%
\def\expansion{==>}%
\def\minus{-}%
\def\pounds{pounds}%
\def\point{.}%
\def\print{-|}%
- \def\quotedblbase{"}%
- \def\quotedblleft{"}%
- \def\quotedblright{"}%
- \def\quoteleft{`}%
- \def\quoteright{'}%
- \def\quotesinglbase{,}%
\def\result{=>}%
- \def\textdegree{degrees}%
%
% 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.
@@ -4203,7 +3490,11 @@
%
\edef\writeto{\csname#1indfile\endcsname}%
%
- \safewhatsit\dosubindwrite
+ \ifvmode
+ \dosubindsanitize
+ \else
+ \dosubindwrite
+ \fi
}%
\fi
}
@@ -4240,13 +3531,13 @@
\temp
}
-% Take care of unwanted page breaks/skips around a whatsit:
+% Take care of unwanted page breaks:
%
% If a skip is the last thing on the list now, preserve it
% by backing up by \lastskip, doing the \write, then inserting
% the skip again. Otherwise, the whatsit generated by the
-% \write or \pdfdest will make \lastskip zero. The result is that
-% sequences like this:
+% \write will make \lastskip zero. The result is that sequences
+% like this:
% @end defun
% @tindex whatever
% @defun ...
@@ -4270,31 +3561,25 @@
%
\edef\zeroskipmacro{\expandafter\the\csname address@hidden
%
-\newskip\whatsitskip
-\newcount\whatsitpenalty
-%
% ..., ready, GO:
%
-\def\safewhatsit#1{%
-\ifhmode
- #1%
-\else
+\def\dosubindsanitize{%
% \lastskip and \lastpenalty cannot both be nonzero simultaneously.
- \whatsitskip = \lastskip
+ \skip0 = \lastskip
\edef\lastskipmacro{\the\lastskip}%
- \whatsitpenalty = \lastpenalty
+ \count255 = \lastpenalty
%
% If \lastskip is nonzero, that means the last item was a
% skip. And since a skip is discardable, that means this
- % -\whatsitskip glue we're inserting is preceded by a
+ % -\skip0 glue we're inserting is preceded by a
% non-discardable item, therefore it is not a potential
% breakpoint, therefore no \nobreak needed.
\ifx\lastskipmacro\zeroskipmacro
\else
- \vskip-\whatsitskip
+ \vskip-\skip0
\fi
%
- #1%
+ \dosubindwrite
%
\ifx\lastskipmacro\zeroskipmacro
% If \lastskip was zero, perhaps the last item was a penalty, and
@@ -4308,14 +3593,13 @@
% Description.
% would allow a break between the index-whatever whatsit
% and the "Description." paragraph.
- \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi
+ \ifnum\count255>9999 \penalty\count255 \fi
\else
% On the other hand, if we had a nonzero \lastskip,
% this make-up glue would be preceded by a non-discardable item
% (the whatsit from the \write), so we must insert a \nobreak.
- \nobreak\vskip\whatsitskip
+ \nobreak\vskip\skip0
\fi
-\fi
}
% The index entry written in the file actually looks like
@@ -4358,7 +3642,6 @@
%
\smallfonts \rm
\tolerance = 9500
- \plainfrenchspacing
\everypar = {}% don't want the \kern\-parindent from indentation suppression.
%
% See if the index file exists and is nonempty.
@@ -4488,8 +3771,11 @@
% The following is kludged to not output a line of dots in the index if
% there are no page numbers. The next person who breaks this will be
% cursed by a Unix daemon.
- \setbox\boxA = \hbox{#1}%
- \ifdim\wd\boxA = 0pt
+ \def\tempa{{\rm }}%
+ \def\tempb{#1}%
+ \edef\tempc{\tempa}%
+ \edef\tempd{\tempb}%
+ \ifx\tempc\tempd
\ %
\else
%
@@ -4513,9 +3799,9 @@
\endgroup
}
-% Like plain.tex's \dotfill, except uses up at least 1 em.
+% Like \dotfill except takes at least 1 em.
\def\indexdotfill{\cleaders
- \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill}
+ \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus
1fill}
\def\primary #1{\line{#1\hfil}}
@@ -4625,34 +3911,6 @@
%
% All done with double columns.
\def\enddoublecolumns{%
- % The following penalty ensures that the page builder is exercised
- % _before_ we change the output routine. This is necessary in the
- % following situation:
- %
- % The last section of the index consists only of a single entry.
- % Before this section, \pagetotal is less than \pagegoal, so no
- % break occurs before the last section starts. However, the last
- % section, consisting of \initial and the single \entry, does not
- % fit on the page and has to be broken off. Without the following
- % penalty the page builder will not be exercised until \eject
- % below, and by that time we'll already have changed the output
- % routine to the \balancecolumns version, so the next-to-last
- % double-column page will be processed with \balancecolumns, which
- % is wrong: The two columns will go to the main vertical list, with
- % the broken-off section in the recent contributions. As soon as
- % the output routine finishes, TeX starts reconsidering the page
- % break. The two columns and the broken-off section both fit on the
- % page, because the two columns now take up only half of the page
- % goal. When TeX sees \eject from below which follows the final
- % section, it invokes the new output routine that we've set after
- % \balancecolumns below; \onepageout will try to fit the two columns
- % and the final section into the vbox of \pageheight (see
- % \pagebody), causing an overfull box.
- %
- % Note that glue won't work here, because glue does not exercise the
- % page builder, unlike penalties (see The TeXbook, pp. 280-281).
- \penalty0
- %
\output = {%
% Split the last of the double-column material. Leave it on the
% current page, no automatic page break.
@@ -4762,15 +4020,11 @@
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
-% Each @chapter defines these (using marks) as the number+name, number
-% and name of the chapter. Page headings and footings can use
-% these. @section does likewise.
+% Each @chapter defines this as the name of the chapter.
+% page headings and footings can use it. @section does likewise.
+% However, they are not reliable, because we don't use marks.
\def\thischapter{}
-\def\thischapternum{}
-\def\thischaptername{}
\def\thissection{}
-\def\thissectionnum{}
-\def\thissectionname{}
\newcount\absseclevel % used to calculate proper heading level
\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
@@ -5071,20 +4325,7 @@
\def\chapbreak{\dobreak \chapheadingskip {-4000}}
\def\chappager{\par\vfill\supereject}
-% Because \domark is called before \chapoddpage, the filler page will
-% get the headings for the next chapter, which is wrong. But we don't
-% care -- we just disable all headings on the filler page.
-\def\chapoddpage{%
- \chappager
- \ifodd\pageno \else
- \begingroup
- \evenheadline={\hfil}\evenfootline={\hfil}%
- \oddheadline={\hfil}\oddfootline={\hfil}%
- \hbox to 0pt{}%
- \chappager
- \endgroup
- \fi
-}
+\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
@@ -5118,72 +4359,41 @@
\def\Yappendixkeyword{Yappendix}
%
\def\chapmacro#1#2#3{%
- % Insert the first mark before the heading break (see notes for \domark).
- \let\prevchapterdefs=\lastchapterdefs
- \let\prevsectiondefs=\lastsectiondefs
- \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}%
- \gdef\thissection{}}%
- %
- \def\temptype{#2}%
- \ifx\temptype\Ynothingkeyword
- \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
- \gdef\thischapter{\thischaptername}}%
- \else\ifx\temptype\Yomitfromtockeyword
- \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
- \gdef\thischapter{}}%
- \else\ifx\temptype\Yappendixkeyword
- \toks0={#1}%
- \xdef\lastchapterdefs{%
- \gdef\noexpand\thischaptername{\the\toks0}%
- \gdef\noexpand\thischapternum{\appendixletter}%
- \gdef\noexpand\thischapter{\putwordAppendix{} \noexpand\thischapternum:
- \noexpand\thischaptername}%
- }%
- \else
- \toks0={#1}%
- \xdef\lastchapterdefs{%
- \gdef\noexpand\thischaptername{\the\toks0}%
- \gdef\noexpand\thischapternum{\the\chapno}%
- \gdef\noexpand\thischapter{\putwordChapter{} \noexpand\thischapternum:
- \noexpand\thischaptername}%
- }%
- \fi\fi\fi
- %
- % Output the mark. Pass it through \safewhatsit, to take care of
- % the preceding space.
- \safewhatsit\domark
- %
- % Insert the chapter heading break.
\pchapsepmacro
- %
- % Now the second mark, after the heading break. No break points
- % between here and the heading.
- \let\prevchapterdefs=\lastchapterdefs
- \let\prevsectiondefs=\lastsectiondefs
- \domark
- %
{%
\chapfonts \rm
%
- % Have to define \lastsection before calling \donoderef, because the
+ % Have to define \thissection before calling \donoderef, because the
% xref code eventually uses it. On the other hand, it has to be called
% after \pchapsepmacro, or the headline will change too soon.
- \gdef\lastsection{#1}%
+ \gdef\thissection{#1}%
+ \gdef\thischaptername{#1}%
%
% Only insert the separating space if we have a chapter/appendix
% number, and don't print the unnumbered ``number''.
+ \def\temptype{#2}%
\ifx\temptype\Ynothingkeyword
\setbox0 = \hbox{}%
\def\toctype{unnchap}%
+ \gdef\thischapter{#1}%
\else\ifx\temptype\Yomitfromtockeyword
\setbox0 = \hbox{}% contents like unnumbered, but no toc entry
\def\toctype{omit}%
+ \gdef\thischapter{}%
\else\ifx\temptype\Yappendixkeyword
\setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
\def\toctype{app}%
+ % We don't substitute the actual chapter name into \thischapter
+ % because we don't want its macros evaluated now. And we don't
+ % use \thissection because that changes with each section.
+ %
+ \xdef\thischapter{\putwordAppendix{} \appendixletter:
+ \noexpand\thischaptername}%
\else
\setbox0 = \hbox{#3\enspace}%
\def\toctype{numchap}%
+ \xdef\thischapter{\putwordChapter{} \the\chapno:
+ \noexpand\thischaptername}%
\fi\fi\fi
%
% Write the toc entry for this chapter. Must come before the
@@ -5199,7 +4409,6 @@
\donoderef{#2}%
%
% Typeset the actual heading.
- \nobreak % Avoid page breaks at the interline glue.
\vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
\hangindent=\wd0 \centerparametersmaybe
\unhbox0 #1\par}%
@@ -5262,95 +4471,45 @@
% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
% section number.
%
-\def\seckeyword{sec}
-%
\def\sectionheading#1#2#3#4{%
{%
% Switch to the right set of fonts.
\csname #2fonts\endcsname \rm
%
- \def\sectionlevel{#2}%
- \def\temptype{#3}%
- %
- % Insert first mark before the heading break (see notes for \domark).
- \let\prevsectiondefs=\lastsectiondefs
- \ifx\temptype\Ynothingkeyword
- \ifx\sectionlevel\seckeyword
- \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}%
- \gdef\thissection{\thissectionname}}%
- \fi
- \else\ifx\temptype\Yomitfromtockeyword
- % Don't redefine \thissection.
- \else\ifx\temptype\Yappendixkeyword
- \ifx\sectionlevel\seckeyword
- \toks0={#1}%
- \xdef\lastsectiondefs{%
- \gdef\noexpand\thissectionname{\the\toks0}%
- \gdef\noexpand\thissectionnum{#4}%
- \gdef\noexpand\thissection{\putwordSection{}
\noexpand\thissectionnum:
- \noexpand\thissectionname}%
- }%
- \fi
- \else
- \ifx\sectionlevel\seckeyword
- \toks0={#1}%
- \xdef\lastsectiondefs{%
- \gdef\noexpand\thissectionname{\the\toks0}%
- \gdef\noexpand\thissectionnum{#4}%
- \gdef\noexpand\thissection{\putwordSection{}
\noexpand\thissectionnum:
- \noexpand\thissectionname}%
- }%
- \fi
- \fi\fi\fi
- %
- % Output the mark. Pass it through \safewhatsit, to take care of
- % the preceding space.
- \safewhatsit\domark
- %
% Insert space above the heading.
\csname #2headingbreak\endcsname
%
- % Now the second mark, after the heading break. No break points
- % between here and the heading.
- \let\prevsectiondefs=\lastsectiondefs
- \domark
- %
% Only insert the space after the number if we have a section number.
+ \def\sectionlevel{#2}%
+ \def\temptype{#3}%
+ %
\ifx\temptype\Ynothingkeyword
\setbox0 = \hbox{}%
\def\toctype{unn}%
- \gdef\lastsection{#1}%
+ \gdef\thissection{#1}%
\else\ifx\temptype\Yomitfromtockeyword
% for @headings -- no section number, don't include in toc,
- % and don't redefine \lastsection.
+ % and don't redefine \thissection.
\setbox0 = \hbox{}%
\def\toctype{omit}%
\let\sectionlevel=\empty
\else\ifx\temptype\Yappendixkeyword
\setbox0 = \hbox{#4\enspace}%
\def\toctype{app}%
- \gdef\lastsection{#1}%
+ \gdef\thissection{#1}%
\else
\setbox0 = \hbox{#4\enspace}%
\def\toctype{num}%
- \gdef\lastsection{#1}%
+ \gdef\thissection{#1}%
\fi\fi\fi
%
- % Write the toc entry (before \donoderef). See comments in \chapmacro.
+ % Write the toc entry (before \donoderef). See comments in \chfplain.
\writetocentry{\toctype\sectionlevel}{#1}{#4}%
%
% Write the node reference (= pdf destination for pdftex).
- % Again, see comments in \chapmacro.
+ % Again, see comments in \chfplain.
\donoderef{#3}%
%
- % Interline glue will be inserted when the vbox is completed.
- % That glue will be a valid breakpoint for the page, since it'll be
- % preceded by a whatsit (usually from the \donoderef, or from the
- % \writetocentry if there was no node). We don't want to allow that
- % break, since then the whatsits could end up on page n while the
- % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000.
- \nobreak
- %
% Output the actual section heading.
\vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
\hangindent=\wd0 % zero if no section number
@@ -5413,7 +4572,7 @@
\edef\temp{%
address@hidden
\temp
- }%
+ }
\fi
\fi
%
@@ -5448,7 +4607,7 @@
\def\readtocfile{%
\setupdatafile
\activecatcodes
- \input \tocreadfilename
+ \input \jobname.toc
}
\newskip\contentsrightmargin \contentsrightmargin=1in
@@ -5467,6 +4626,7 @@
%
% Don't need to put `Contents' or `Short Contents' in the headline.
% It is abundantly clear what they are.
+ \def\thischapter{}%
\chapmacro{#1}{Yomitfromtoc}{}%
%
\savepageno = \pageno
@@ -5478,16 +4638,11 @@
\ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
}
-% redefined for the two-volume lispref. We always output on
-% \jobname.toc even if this is redefined.
-%
-\def\tocreadfilename{\jobname.toc}
% Normal (long) toc.
-%
\def\contents{%
\startcontents{\putwordTOC}%
- \openin 1 \tocreadfilename\space
+ \openin 1 \jobname.toc
\ifeof 1 \else
\readtocfile
\fi
@@ -5525,7 +4680,7 @@
\let\numsubsubsecentry = \numsecentry
\let\appsubsubsecentry = \numsecentry
\let\unnsubsubsecentry = \numsecentry
- \openin 1 \tocreadfilename\space
+ \openin 1 \jobname.toc
\ifeof 1 \else
\readtocfile
\fi
@@ -5669,7 +4824,7 @@
{\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 \tensf error\kern-1.5pt}
%
\setbox\errorbox=\hbox to \dimen0{\hfil
\hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
@@ -5860,18 +5015,12 @@
\let\SETdispenvsize\relax
\def\setnormaldispenv{%
\ifx\SETdispenvsize\smallword
- % end paragraph for sake of leading, in case document has no blank
- % line. This is redundant with what happens in \aboveenvbreak, but
- % we need to do it before changing the fonts, and it's inconvenient
- % to change the fonts afterward.
- \ifnum \lastpenalty=10000 \else \endgraf \fi
\smallexamplefonts \rm
\fi
}
\def\setsmalldispenv{%
\ifx\SETdispenvsize\nosmallword
\else
- \ifnum \lastpenalty=10000 \else \endgraf \fi
\smallexamplefonts \rm
\fi
}
@@ -5898,10 +5047,11 @@
%
\maketwodispenvs {lisp}{example}{%
\nonfillstart
- \tt\quoteexpand
+ \tt
\let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
\gobble % eat return
}
+
% @display/@smalldisplay: same as @lisp except keep current font.
%
\makedispenv {display}{%
@@ -6029,34 +5179,6 @@
\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
%
\def\starttabbox{\setbox0=\hbox\bgroup}
-
-% 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.
-%
-\def\codequoteright{%
- \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
- \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
- '%
- \else \char'15 \fi
- \else \char'15 \fi
-}
-%
-% and a similar option for the left quote char vs. a grave accent.
-% Modern fonts display ASCII 0x60 as a grave accent, so some people like
-% the code environments to do likewise.
-%
-\def\codequoteleft{%
- \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
- \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
- `%
- \else \char'22 \fi
- \else \char'22 \fi
-}
-%
\begingroup
\catcode`\^^I=\active
\gdef\tabexpand{%
@@ -6069,16 +5191,7 @@
\wd0=\dimen0 \box0 \starttabbox
}%
}
- \catcode`\'=\active
- \gdef\rquoteexpand{\catcode\rquoteChar=\active \def'{\codequoteright}}%
- %
- \catcode`\`=\active
- \gdef\lquoteexpand{\catcode\lquoteChar=\active \def`{\codequoteleft}}%
- %
- \gdef\quoteexpand{\rquoteexpand \lquoteexpand}%
\endgroup
-
-% start the verbatim environment.
\def\setupverbatim{%
\let\nonarrowing = t%
\nonfillstart
@@ -6087,7 +5200,6 @@
\def\par{\leavevmode\egroup\box0\endgraf}%
\catcode`\`=\active
\tabexpand
- \quoteexpand
% Respect line breaks,
% print special symbols as themselves, and
% make each space count
@@ -6172,36 +5284,28 @@
\endgroup
}
-
\message{defuns,}
% @defun etc.
\newskip\defbodyindent \defbodyindent=.4in
\newskip\defargsindent \defargsindent=50pt
\newskip\deflastargmargin \deflastargmargin=18pt
-\newcount\defunpenalty
% Start the processing of @deffn:
\def\startdefun{%
\ifnum\lastpenalty<10000
\medbreak
- \defunpenalty=10003 % Will keep this @deffn together with the
- % following @def command, see below.
\else
% If there are two @def commands in a row, we'll have a \nobreak,
% which is there to keep the function description together with its
% header. But if there's nothing but headers, we need to allow a
% break somewhere. Check specifically for penalty 10002, inserted
- % by \printdefunline, instead of 10000, since the sectioning
+ % by \defargscommonending, instead of 10000, since the sectioning
% commands also insert a nobreak penalty, and we don't want to allow
% a break between a section heading and a defun.
+ %
+ \ifnum\lastpenalty=10002 \penalty2000 \fi
%
- % As a minor 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.
- \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi
- %
% Similarly, after a section heading, do not allow a break.
% But do insert the glue.
\medskip % preceded by discardable penalty, so not a breakpoint
@@ -6218,7 +5322,7 @@
%
% As above, allow line break if we have multiple x headers in a row.
% It's not a great place, though.
- \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi
+ \ifnum\lastpenalty=10002 \penalty3000 \fi
%
% And now, it's time to reuse the body of the original defun:
\expandafter\gobbledefun#1%
@@ -6236,7 +5340,7 @@
\advance\rightskip by 0pt plus 1fil
\endgraf
\nobreak\vskip -\parskip
- \penalty\defunpenalty % signal to \startdefun and \dodefunx
+ \penalty 10002 % signal to \startdefun and \dodefunx
% Some of the @defun-type tags do not enable magic parentheses,
% rendering the following check redundant. But we don't optimize.
\checkparencounts
@@ -6505,14 +5609,12 @@
\ifnum\parencount=0 \else \badparencount \fi
\ifnum\brackcount=0 \else \badbrackcount \fi
}
-% these should not use \errmessage; the glibc manual, at least, actually
-% has such constructs (when documenting function pointers).
\def\badparencount{%
- \message{Warning: unbalanced parentheses in @def...}%
+ \errmessage{Unbalanced parentheses in @def}%
\global\parencount=0
}
\def\badbrackcount{%
- \message{Warning: unbalanced square brackets in @def...}%
+ \errmessage{Unbalanced square braces in @def}%
\global\brackcount=0
}
@@ -6547,6 +5649,7 @@
\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}%
@@ -6607,10 +5710,6 @@
% all characters are catcode 10, 11 or 12, except \ which is active
% (as in normal texinfo). It is necessary to change the definition of \.
-% 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
% body, and then making it the \newlinechar in \scanmacro.
@@ -6625,7 +5724,6 @@
\catcode`\_=\other
\catcode`\|=\other
\catcode`\~=\other
- \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi
}
\def\scanargctxt{%
@@ -6818,11 +5916,11 @@
% {. 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)
-\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx}
\def\braceorlinexxx{%
\ifx\nchar\bgroup\else
\expandafter\parsearg
- \fi \macnamexxx}
+ \fi \next}
% @alias.
@@ -6843,6 +5941,7 @@
\message{cross references,}
\newwrite\auxfile
+
\newif\ifhavexrefs % True if xref values are known.
\newif\ifwarnedxrefs % True if we warned once that they aren't known.
@@ -6887,7 +5986,7 @@
% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
% anchor), which consists of three parts:
-% 1) NAME-title - the current sectioning name taken from \lastsection,
+% 1) NAME-title - the current sectioning name taken from \thissection,
% or the anchor name.
% 2) NAME-snt - section number and type, passed as the SNT arg, or
% empty for anchors.
@@ -6906,10 +6005,10 @@
address@hidden #1 of \setref, expanded by the \edef
##1}{##2}}% these are parameters of \writexrdef
}%
- \toks0 = \expandafter{\lastsection}%
+ \toks0 = \expandafter{\thissection}%
\immediate \writexrdef{title}{\the\toks0 }%
\immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
- \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, during
\shipout
+ \writexrdef{pg}{\folio}% will be written later, during \shipout
}%
\fi
}
@@ -6955,8 +6054,7 @@
\ifpdf
\leavevmode
\getfilename{#4}%
- {\indexnofonts
- \turnoffactive
+ {\turnoffactive
% See comments at \activebackslashdouble.
{\activebackslashdouble \xdef\pdfxrefdest{#1}%
\backslashparens\pdfxrefdest}%
@@ -6969,7 +6067,7 @@
goto name{\pdfmkpgn{\pdfxrefdest}}%
\fi
}%
- \setcolor{\linkcolor}%
+ \linkcolor
\fi
%
% Float references are printed completely differently: "Figure 1.2"
@@ -6987,7 +6085,7 @@
% If the user specified the print name (third arg) to the ref,
% print it instead of our usual "Figure 1.2".
\ifdim\wd0 = 0pt
- \refx{#1-snt}{}%
+ \refx{#1-snt}%
\else
\printedrefname
\fi
@@ -7007,7 +6105,7 @@
% 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}%
+ \putwordsection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
\else
% _ (for example) has to be the character _ for the purposes of the
% control sequence corresponding to the node, but it has to expand
@@ -7103,18 +6201,10 @@
% collisions). But if this is a float type, we have more work to do.
%
\def\xrdef#1#2{%
- {% The node name might contain 8-bit characters, which in our current
- % implementation are changed to commands like @'e. Don't let these
- % mess up the control sequence name.
- \indexnofonts
- \turnoffactive
- \xdef\safexrefname{#1}%
- }%
+ \expandafter\gdef\csname XR#1\endcsname{#2}% remember this xref value.
%
- \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref
- %
% Was that xref control sequence that we just defined for a float?
- \expandafter\iffloat\csname XR\safexrefname\endcsname
+ \expandafter\iffloat\csname XR#1\endcsname
% it was a float, and we have the (safe) float type in \iffloattype.
\expandafter\let\expandafter\floatlist
\csname floatlist\iffloattype\endcsname
@@ -7129,8 +6219,7 @@
%
% Remember this xref in the control sequence \floatlistFLOATTYPE,
% for later use in \listoffloats.
- \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
- {\safexrefname}}%
+ \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0{#1}}%
\fi
}
@@ -7234,7 +6323,6 @@
\input\jobname.#1
\endgroup}
-
\message{insertions,}
% including footnotes.
@@ -7427,7 +6515,7 @@
% above and below.
\nobreak\vskip\parskip
\nobreak
- \line\bgroup
+ \line\bgroup\hss
\fi
%
% Output the image.
@@ -7440,7 +6528,7 @@
\epsfbox{#1.eps}%
\fi
%
- \ifimagevmode \egroup \bigbreak \fi % space after the image
+ \ifimagevmode \hss \egroup \bigbreak \fi % space after the image
\endgroup}
@@ -7507,13 +6595,13 @@
\global\advance\floatno by 1
%
{%
- % This magic value for \lastsection is output by \setref as the
+ % This magic value for \thissection is output by \setref as the
% XREFLABEL-title value. \xrefX uses it to distinguish float
% labels (which have a completely different output format) from
% node and anchor labels. And \xrdef uses it to construct the
% lists of floats.
%
- \edef\lastsection{\floatmagic=\safefloattype}%
+ \edef\thissection{\floatmagic=\safefloattype}%
\setref{\floatlabel}{Yfloat}%
}%
\fi
@@ -7581,7 +6669,6 @@
% caption if specified, else the full caption if specified, else nothing.
{%
\atdummies
- %
% since we read the caption text in the macro world, where ^^M
% is turned into a normal character, we have to scan it back, so
% we don't write the literal three characters "^^M" into the aux file.
@@ -7602,9 +6689,8 @@
%
% place the captured inserts
%
- % BEWARE: when the floats start floating, we have to issue warning
- % whenever an insert appears inside a float which could possibly
- % float. --kasal, 26may04
+ % BEWARE: when the floats start float, we have to issue warning whenever an
+ % insert appears inside a float which could possibly float. --kasal, 26may04
%
\checkinserts
}
@@ -7648,7 +6734,7 @@
% #1 is the control sequence we are passed; we expand into a conditional
% which is true if #1 represents a float ref. That is, the magic
-% \lastsection value which we \setref above.
+% \thissection value which we \setref above.
%
\def\iffloat#1{\expandafter\doiffloat#1==\finish}
%
@@ -7709,871 +6795,39 @@
\writeentry
}}
-
\message{localization,}
+% and i18n.
% @documentlanguage is usually given very early, just after
% @setfilename. If done too late, it may not override everything
-% properly. Single argument is the language (de) or locale (de_DE)
-% abbreviation. It would be nice if we could set up a hyphenation file.
+% properly. Single argument is the language abbreviation.
+% It would be nice if we could set up a hyphenation file here.
%
-{
- \catcode`\_ = \active
- \globaldefs=1
-\parseargdef\documentlanguage{\begingroup
- \let_=\normalunderscore % normal _ character for filenames
+\parseargdef\documentlanguage{%
\tex % read txi-??.tex file in plain TeX.
- % Read the file by the name they passed if it exists.
+ % Read the file if it exists.
\openin 1 txi-#1.tex
\ifeof 1
- \documentlanguagetrywithoutunderscore{#1_\finish}%
+ \errhelp = \nolanghelp
+ \errmessage{Cannot read language file txi-#1.tex}%
\else
\input txi-#1.tex
\fi
\closein 1
\endgroup
-\endgroup}
}
-%
-% If they passed de_DE, and txi-de_DE.tex doesn't exist,
-% try txi-de.tex.
-%
-\def\documentlanguagetrywithoutunderscore#1_#2\finish{%
- \openin 1 txi-#1.tex
- \ifeof 1
- \errhelp = \nolanghelp
- \errmessage{Cannot read language file txi-#1.tex}%
- \else
- \input txi-#1.tex
- \fi
- \closein 1
-}
-%
\newhelp\nolanghelp{The given language definition file cannot be found or
is empty. Maybe you need to install it? In the current directory
should work if nowhere else does.}
-% Set the catcode of characters 128 through 255 to the specified number.
-%
-\def\setnonasciicharscatcode#1{%
- \count255=128
- \loop\ifnum\count255<256
- \global\catcode\count255=#1\relax
- \advance\count255 by 1
- \repeat
-}
-\def\setnonasciicharscatcodenonglobal#1{%
- \count255=128
- \loop\ifnum\count255<256
- \catcode\count255=#1\relax
- \advance\count255 by 1
- \repeat
-}
+% @documentencoding should change something in TeX eventually, most
+% likely, but for now just recognize it.
+\let\documentencoding = \comment
-% @documentencoding sets the definition of non-ASCII characters
-% according to the specified encoding.
-%
-\parseargdef\documentencoding{%
- % Encoding being declared for the document.
- \def\declaredencoding{\csname #1.enc\endcsname}%
- %
- % Supported encodings: names converted to tokens in order to be able
- % to compare them with \ifx.
- \def\ascii{\csname US-ASCII.enc\endcsname}%
- \def\latnine{\csname ISO-8859-15.enc\endcsname}%
- \def\latone{\csname ISO-8859-1.enc\endcsname}%
- \def\lattwo{\csname ISO-8859-2.enc\endcsname}%
- \def\utfeight{\csname UTF-8.enc\endcsname}%
- %
- \ifx \declaredencoding \ascii
- \asciichardefs
- %
- \else \ifx \declaredencoding \lattwo
- \setnonasciicharscatcode\active
- \lattwochardefs
- %
- \else \ifx \declaredencoding \latone
- \setnonasciicharscatcode\active
- \latonechardefs
- %
- \else \ifx \declaredencoding \latnine
- \setnonasciicharscatcode\active
- \latninechardefs
- %
- \else \ifx \declaredencoding \utfeight
- \setnonasciicharscatcode\active
- \utfeightchardefs
- %
- \else
- \message{Unknown document encoding #1, ignoring.}%
- %
- \fi % utfeight
- \fi % latnine
- \fi % latone
- \fi % lattwo
- \fi % ascii
-}
-% A message to be logged when using a character that isn't available
-% the default font encoding (OT1).
-%
-\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
-
-% Take account of \c (plain) vs. \, (Texinfo) difference.
-\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi}
-
-% First, make active non-ASCII characters in order for them to be
-% correctly categorized when TeX reads the replacement text of
-% macros containing the character definitions.
-\setnonasciicharscatcode\active
+% Page size parameters.
%
-% Latin1 (ISO-8859-1) character definitions.
-\def\latonechardefs{%
- \gdef^^a0{~}
- \gdef^^a1{\exclamdown}
- \gdef^^a2{\missingcharmsg{CENT SIGN}}
- \gdef^^a3{{\pounds}}
- \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
- \gdef^^a5{\missingcharmsg{YEN SIGN}}
- \gdef^^a6{\missingcharmsg{BROKEN BAR}}
- \gdef^^a7{\S}
- \gdef^^a8{\"{}}
- \gdef^^a9{\copyright}
- \gdef^^aa{\ordf}
- \gdef^^ab{\missingcharmsg{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}}
- \gdef^^ac{$\lnot$}
- \gdef^^ad{\-}
- \gdef^^ae{\registeredsymbol}
- \gdef^^af{\={}}
- %
- \gdef^^b0{\textdegree}
- \gdef^^b1{$\pm$}
- \gdef^^b2{$^2$}
- \gdef^^b3{$^3$}
- \gdef^^b4{\'{}}
- \gdef^^b5{$\mu$}
- \gdef^^b6{\P}
- %
- \gdef^^b7{$^.$}
- \gdef^^b8{\cedilla\ }
- \gdef^^b9{$^1$}
- \gdef^^ba{\ordm}
- %
- \gdef^^bb{\missingcharmsg{RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK}}
- \gdef^^bc{$1\over4$}
- \gdef^^bd{$1\over2$}
- \gdef^^be{$3\over4$}
- \gdef^^bf{\questiondown}
- %
- \gdef^^c0{\`A}
- \gdef^^c1{\'A}
- \gdef^^c2{\^A}
- \gdef^^c3{\~A}
- \gdef^^c4{\"A}
- \gdef^^c5{\ringaccent A}
- \gdef^^c6{\AE}
- \gdef^^c7{\cedilla C}
- \gdef^^c8{\`E}
- \gdef^^c9{\'E}
- \gdef^^ca{\^E}
- \gdef^^cb{\"E}
- \gdef^^cc{\`I}
- \gdef^^cd{\'I}
- \gdef^^ce{\^I}
- \gdef^^cf{\"I}
- %
- \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER ETH}}
- \gdef^^d1{\~N}
- \gdef^^d2{\`O}
- \gdef^^d3{\'O}
- \gdef^^d4{\^O}
- \gdef^^d5{\~O}
- \gdef^^d6{\"O}
- \gdef^^d7{$\times$}
- \gdef^^d8{\O}
- \gdef^^d9{\`U}
- \gdef^^da{\'U}
- \gdef^^db{\^U}
- \gdef^^dc{\"U}
- \gdef^^dd{\'Y}
- \gdef^^de{\missingcharmsg{LATIN CAPITAL LETTER THORN}}
- \gdef^^df{\ss}
- %
- \gdef^^e0{\`a}
- \gdef^^e1{\'a}
- \gdef^^e2{\^a}
- \gdef^^e3{\~a}
- \gdef^^e4{\"a}
- \gdef^^e5{\ringaccent a}
- \gdef^^e6{\ae}
- \gdef^^e7{\cedilla c}
- \gdef^^e8{\`e}
- \gdef^^e9{\'e}
- \gdef^^ea{\^e}
- \gdef^^eb{\"e}
- \gdef^^ec{\`{\dotless i}}
- \gdef^^ed{\'{\dotless i}}
- \gdef^^ee{\^{\dotless i}}
- \gdef^^ef{\"{\dotless i}}
- %
- \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER ETH}}
- \gdef^^f1{\~n}
- \gdef^^f2{\`o}
- \gdef^^f3{\'o}
- \gdef^^f4{\^o}
- \gdef^^f5{\~o}
- \gdef^^f6{\"o}
- \gdef^^f7{$\div$}
- \gdef^^f8{\o}
- \gdef^^f9{\`u}
- \gdef^^fa{\'u}
- \gdef^^fb{\^u}
- \gdef^^fc{\"u}
- \gdef^^fd{\'y}
- \gdef^^fe{\missingcharmsg{LATIN SMALL LETTER THORN}}
- \gdef^^ff{\"y}
-}
-
-% Latin9 (ISO-8859-15) encoding character definitions.
-\def\latninechardefs{%
- % Encoding is almost identical to Latin1.
- \latonechardefs
- %
- \gdef^^a4{\euro}
- \gdef^^a6{\v S}
- \gdef^^a8{\v s}
- \gdef^^b4{\v Z}
- \gdef^^b8{\v z}
- \gdef^^bc{\OE}
- \gdef^^bd{\oe}
- \gdef^^be{\"Y}
-}
-
-% Latin2 (ISO-8859-2) character definitions.
-\def\lattwochardefs{%
- \gdef^^a0{~}
- \gdef^^a1{\missingcharmsg{LATIN CAPITAL LETTER A WITH OGONEK}}
- \gdef^^a2{\u{}}
- \gdef^^a3{\L}
- \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
- \gdef^^a5{\v L}
- \gdef^^a6{\'S}
- \gdef^^a7{\S}
- \gdef^^a8{\"{}}
- \gdef^^a9{\v S}
- \gdef^^aa{\cedilla S}
- \gdef^^ab{\v T}
- \gdef^^ac{\'Z}
- \gdef^^ad{\-}
- \gdef^^ae{\v Z}
- \gdef^^af{\dotaccent Z}
- %
- \gdef^^b0{\textdegree}
- \gdef^^b1{\missingcharmsg{LATIN SMALL LETTER A WITH OGONEK}}
- \gdef^^b2{\missingcharmsg{OGONEK}}
- \gdef^^b3{\l}
- \gdef^^b4{\'{}}
- \gdef^^b5{\v l}
- \gdef^^b6{\'s}
- \gdef^^b7{\v{}}
- \gdef^^b8{\cedilla\ }
- \gdef^^b9{\v s}
- \gdef^^ba{\cedilla s}
- \gdef^^bb{\v t}
- \gdef^^bc{\'z}
- \gdef^^bd{\H{}}
- \gdef^^be{\v z}
- \gdef^^bf{\dotaccent z}
- %
- \gdef^^c0{\'R}
- \gdef^^c1{\'A}
- \gdef^^c2{\^A}
- \gdef^^c3{\u A}
- \gdef^^c4{\"A}
- \gdef^^c5{\'L}
- \gdef^^c6{\'C}
- \gdef^^c7{\cedilla C}
- \gdef^^c8{\v C}
- \gdef^^c9{\'E}
- \gdef^^ca{\missingcharmsg{LATIN CAPITAL LETTER E WITH OGONEK}}
- \gdef^^cb{\"E}
- \gdef^^cc{\v E}
- \gdef^^cd{\'I}
- \gdef^^ce{\^I}
- \gdef^^cf{\v D}
- %
- \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER D WITH STROKE}}
- \gdef^^d1{\'N}
- \gdef^^d2{\v N}
- \gdef^^d3{\'O}
- \gdef^^d4{\^O}
- \gdef^^d5{\H O}
- \gdef^^d6{\"O}
- \gdef^^d7{$\times$}
- \gdef^^d8{\v R}
- \gdef^^d9{\ringaccent U}
- \gdef^^da{\'U}
- \gdef^^db{\H U}
- \gdef^^dc{\"U}
- \gdef^^dd{\'Y}
- \gdef^^de{\cedilla T}
- \gdef^^df{\ss}
- %
- \gdef^^e0{\'r}
- \gdef^^e1{\'a}
- \gdef^^e2{\^a}
- \gdef^^e3{\u a}
- \gdef^^e4{\"a}
- \gdef^^e5{\'l}
- \gdef^^e6{\'c}
- \gdef^^e7{\cedilla c}
- \gdef^^e8{\v c}
- \gdef^^e9{\'e}
- \gdef^^ea{\missingcharmsg{LATIN SMALL LETTER E WITH OGONEK}}
- \gdef^^eb{\"e}
- \gdef^^ec{\v e}
- \gdef^^ed{\'\i}
- \gdef^^ee{\^\i}
- \gdef^^ef{\v d}
- %
- \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER D WITH STROKE}}
- \gdef^^f1{\'n}
- \gdef^^f2{\v n}
- \gdef^^f3{\'o}
- \gdef^^f4{\^o}
- \gdef^^f5{\H o}
- \gdef^^f6{\"o}
- \gdef^^f7{$\div$}
- \gdef^^f8{\v r}
- \gdef^^f9{\ringaccent u}
- \gdef^^fa{\'u}
- \gdef^^fb{\H u}
- \gdef^^fc{\"u}
- \gdef^^fd{\'y}
- \gdef^^fe{\cedilla t}
- \gdef^^ff{\dotaccent{}}
-}
-
-% UTF-8 character definitions.
-%
-% This code to support UTF-8 is based on LaTeX's utf8.def, with some
-% changes for Texinfo conventions. It is included here under the GPL by
-% permission from Frank Mittelbach and the LaTeX team.
-%
-\newcount\countUTFx
-\newcount\countUTFy
-\newcount\countUTFz
-
-\gdef\UTFviiiTwoOctets#1#2{\expandafter
- \UTFviiiDefined\csname u8:#1\string #2\endcsname}
-%
-\gdef\UTFviiiThreeOctets#1#2#3{\expandafter
- \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
-%
-\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter
- \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
-
-\gdef\UTFviiiDefined#1{%
- \ifx #1\relax
- \message{\linenumber Unicode char \string #1 not defined for Texinfo}%
- \else
- \expandafter #1%
- \fi
-}
-
-\begingroup
- \catcode`\~13
- \catcode`\"12
-
- \def\UTFviiiLoop{%
- \global\catcode\countUTFx\active
- \uccode`\~\countUTFx
- \uppercase\expandafter{\UTFviiiTmp}%
- \advance\countUTFx by 1
- \ifnum\countUTFx < \countUTFy
- \expandafter\UTFviiiLoop
- \fi}
-
- \countUTFx = "C2
- \countUTFy = "E0
- \def\UTFviiiTmp{%
- \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
- \UTFviiiLoop
-
- \countUTFx = "E0
- \countUTFy = "F0
- \def\UTFviiiTmp{%
- \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
- \UTFviiiLoop
-
- \countUTFx = "F0
- \countUTFy = "F4
- \def\UTFviiiTmp{%
- \xdef~{\noexpand\UTFviiiFourOctets\string~}}
- \UTFviiiLoop
-\endgroup
-
-\begingroup
- \catcode`\"=12
- \catcode`\<=12
- \catcode`\.=12
- \catcode`\,=12
- \catcode`\;=12
- \catcode`\!=12
- \catcode`\~=13
-
- \gdef\DeclareUnicodeCharacter#1#2{%
- \countUTFz = "#1\relax
- \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
- \begingroup
- \parseXMLCharref
- \def\UTFviiiTwoOctets##1##2{%
- \csname u8:##1\string ##2\endcsname}%
- \def\UTFviiiThreeOctets##1##2##3{%
- \csname u8:##1\string ##2\string ##3\endcsname}%
- \def\UTFviiiFourOctets##1##2##3##4{%
- \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
- \expandafter\expandafter\expandafter\expandafter
- \expandafter\expandafter\expandafter
- \gdef\UTFviiiTmp{#2}%
- \endgroup}
-
- \gdef\parseXMLCharref{%
- \ifnum\countUTFz < "A0\relax
- \errhelp = \EMsimple
- \errmessage{Cannot define Unicode char value < 00A0}%
- \else\ifnum\countUTFz < "800\relax
- \parseUTFviiiA,%
- \parseUTFviiiB C\UTFviiiTwoOctets.,%
- \else\ifnum\countUTFz < "10000\relax
- \parseUTFviiiA;%
- \parseUTFviiiA,%
- \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
- \else
- \parseUTFviiiA;%
- \parseUTFviiiA,%
- \parseUTFviiiA!%
- \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
- \fi\fi\fi
- }
-
- \gdef\parseUTFviiiA#1{%
- \countUTFx = \countUTFz
- \divide\countUTFz by 64
- \countUTFy = \countUTFz
- \multiply\countUTFz by 64
- \advance\countUTFx by -\countUTFz
- \advance\countUTFx by 128
- \uccode `#1\countUTFx
- \countUTFz = \countUTFy}
-
- \gdef\parseUTFviiiB#1#2#3#4{%
- \advance\countUTFz by "#10\relax
- \uccode `#3\countUTFz
- \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
-\endgroup
-
-\def\utfeightchardefs{%
- \DeclareUnicodeCharacter{00A0}{\tie}
- \DeclareUnicodeCharacter{00A1}{\exclamdown}
- \DeclareUnicodeCharacter{00A3}{\pounds}
- \DeclareUnicodeCharacter{00A8}{\"{ }}
- \DeclareUnicodeCharacter{00A9}{\copyright}
- \DeclareUnicodeCharacter{00AA}{\ordf}
- \DeclareUnicodeCharacter{00AB}{\guillemetleft}
- \DeclareUnicodeCharacter{00AD}{\-}
- \DeclareUnicodeCharacter{00AE}{\registeredsymbol}
- \DeclareUnicodeCharacter{00AF}{\={ }}
-
- \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}
- \DeclareUnicodeCharacter{00B4}{\'{ }}
- \DeclareUnicodeCharacter{00B8}{\cedilla{ }}
- \DeclareUnicodeCharacter{00BA}{\ordm}
- \DeclareUnicodeCharacter{00BB}{\guillemetright}
- \DeclareUnicodeCharacter{00BF}{\questiondown}
-
- \DeclareUnicodeCharacter{00C0}{\`A}
- \DeclareUnicodeCharacter{00C1}{\'A}
- \DeclareUnicodeCharacter{00C2}{\^A}
- \DeclareUnicodeCharacter{00C3}{\~A}
- \DeclareUnicodeCharacter{00C4}{\"A}
- \DeclareUnicodeCharacter{00C5}{\AA}
- \DeclareUnicodeCharacter{00C6}{\AE}
- \DeclareUnicodeCharacter{00C7}{\cedilla{C}}
- \DeclareUnicodeCharacter{00C8}{\`E}
- \DeclareUnicodeCharacter{00C9}{\'E}
- \DeclareUnicodeCharacter{00CA}{\^E}
- \DeclareUnicodeCharacter{00CB}{\"E}
- \DeclareUnicodeCharacter{00CC}{\`I}
- \DeclareUnicodeCharacter{00CD}{\'I}
- \DeclareUnicodeCharacter{00CE}{\^I}
- \DeclareUnicodeCharacter{00CF}{\"I}
-
- \DeclareUnicodeCharacter{00D1}{\~N}
- \DeclareUnicodeCharacter{00D2}{\`O}
- \DeclareUnicodeCharacter{00D3}{\'O}
- \DeclareUnicodeCharacter{00D4}{\^O}
- \DeclareUnicodeCharacter{00D5}{\~O}
- \DeclareUnicodeCharacter{00D6}{\"O}
- \DeclareUnicodeCharacter{00D8}{\O}
- \DeclareUnicodeCharacter{00D9}{\`U}
- \DeclareUnicodeCharacter{00DA}{\'U}
- \DeclareUnicodeCharacter{00DB}{\^U}
- \DeclareUnicodeCharacter{00DC}{\"U}
- \DeclareUnicodeCharacter{00DD}{\'Y}
- \DeclareUnicodeCharacter{00DF}{\ss}
-
- \DeclareUnicodeCharacter{00E0}{\`a}
- \DeclareUnicodeCharacter{00E1}{\'a}
- \DeclareUnicodeCharacter{00E2}{\^a}
- \DeclareUnicodeCharacter{00E3}{\~a}
- \DeclareUnicodeCharacter{00E4}{\"a}
- \DeclareUnicodeCharacter{00E5}{\aa}
- \DeclareUnicodeCharacter{00E6}{\ae}
- \DeclareUnicodeCharacter{00E7}{\cedilla{c}}
- \DeclareUnicodeCharacter{00E8}{\`e}
- \DeclareUnicodeCharacter{00E9}{\'e}
- \DeclareUnicodeCharacter{00EA}{\^e}
- \DeclareUnicodeCharacter{00EB}{\"e}
- \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}
- \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}
- \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
- \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
-
- \DeclareUnicodeCharacter{00F1}{\~n}
- \DeclareUnicodeCharacter{00F2}{\`o}
- \DeclareUnicodeCharacter{00F3}{\'o}
- \DeclareUnicodeCharacter{00F4}{\^o}
- \DeclareUnicodeCharacter{00F5}{\~o}
- \DeclareUnicodeCharacter{00F6}{\"o}
- \DeclareUnicodeCharacter{00F8}{\o}
- \DeclareUnicodeCharacter{00F9}{\`u}
- \DeclareUnicodeCharacter{00FA}{\'u}
- \DeclareUnicodeCharacter{00FB}{\^u}
- \DeclareUnicodeCharacter{00FC}{\"u}
- \DeclareUnicodeCharacter{00FD}{\'y}
- \DeclareUnicodeCharacter{00FF}{\"y}
-
- \DeclareUnicodeCharacter{0100}{\=A}
- \DeclareUnicodeCharacter{0101}{\=a}
- \DeclareUnicodeCharacter{0102}{\u{A}}
- \DeclareUnicodeCharacter{0103}{\u{a}}
- \DeclareUnicodeCharacter{0106}{\'C}
- \DeclareUnicodeCharacter{0107}{\'c}
- \DeclareUnicodeCharacter{0108}{\^C}
- \DeclareUnicodeCharacter{0109}{\^c}
- \DeclareUnicodeCharacter{010A}{\dotaccent{C}}
- \DeclareUnicodeCharacter{010B}{\dotaccent{c}}
- \DeclareUnicodeCharacter{010C}{\v{C}}
- \DeclareUnicodeCharacter{010D}{\v{c}}
- \DeclareUnicodeCharacter{010E}{\v{D}}
-
- \DeclareUnicodeCharacter{0112}{\=E}
- \DeclareUnicodeCharacter{0113}{\=e}
- \DeclareUnicodeCharacter{0114}{\u{E}}
- \DeclareUnicodeCharacter{0115}{\u{e}}
- \DeclareUnicodeCharacter{0116}{\dotaccent{E}}
- \DeclareUnicodeCharacter{0117}{\dotaccent{e}}
- \DeclareUnicodeCharacter{011A}{\v{E}}
- \DeclareUnicodeCharacter{011B}{\v{e}}
- \DeclareUnicodeCharacter{011C}{\^G}
- \DeclareUnicodeCharacter{011D}{\^g}
- \DeclareUnicodeCharacter{011E}{\u{G}}
- \DeclareUnicodeCharacter{011F}{\u{g}}
-
- \DeclareUnicodeCharacter{0120}{\dotaccent{G}}
- \DeclareUnicodeCharacter{0121}{\dotaccent{g}}
- \DeclareUnicodeCharacter{0124}{\^H}
- \DeclareUnicodeCharacter{0125}{\^h}
- \DeclareUnicodeCharacter{0128}{\~I}
- \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}
- \DeclareUnicodeCharacter{012A}{\=I}
- \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}
- \DeclareUnicodeCharacter{012C}{\u{I}}
- \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}
-
- \DeclareUnicodeCharacter{0130}{\dotaccent{I}}
- \DeclareUnicodeCharacter{0131}{\dotless{i}}
- \DeclareUnicodeCharacter{0132}{IJ}
- \DeclareUnicodeCharacter{0133}{ij}
- \DeclareUnicodeCharacter{0134}{\^J}
- \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}
- \DeclareUnicodeCharacter{0139}{\'L}
- \DeclareUnicodeCharacter{013A}{\'l}
-
- \DeclareUnicodeCharacter{0141}{\L}
- \DeclareUnicodeCharacter{0142}{\l}
- \DeclareUnicodeCharacter{0143}{\'N}
- \DeclareUnicodeCharacter{0144}{\'n}
- \DeclareUnicodeCharacter{0147}{\v{N}}
- \DeclareUnicodeCharacter{0148}{\v{n}}
- \DeclareUnicodeCharacter{014C}{\=O}
- \DeclareUnicodeCharacter{014D}{\=o}
- \DeclareUnicodeCharacter{014E}{\u{O}}
- \DeclareUnicodeCharacter{014F}{\u{o}}
-
- \DeclareUnicodeCharacter{0150}{\H{O}}
- \DeclareUnicodeCharacter{0151}{\H{o}}
- \DeclareUnicodeCharacter{0152}{\OE}
- \DeclareUnicodeCharacter{0153}{\oe}
- \DeclareUnicodeCharacter{0154}{\'R}
- \DeclareUnicodeCharacter{0155}{\'r}
- \DeclareUnicodeCharacter{0158}{\v{R}}
- \DeclareUnicodeCharacter{0159}{\v{r}}
- \DeclareUnicodeCharacter{015A}{\'S}
- \DeclareUnicodeCharacter{015B}{\'s}
- \DeclareUnicodeCharacter{015C}{\^S}
- \DeclareUnicodeCharacter{015D}{\^s}
- \DeclareUnicodeCharacter{015E}{\cedilla{S}}
- \DeclareUnicodeCharacter{015F}{\cedilla{s}}
-
- \DeclareUnicodeCharacter{0160}{\v{S}}
- \DeclareUnicodeCharacter{0161}{\v{s}}
- \DeclareUnicodeCharacter{0162}{\cedilla{t}}
- \DeclareUnicodeCharacter{0163}{\cedilla{T}}
- \DeclareUnicodeCharacter{0164}{\v{T}}
-
- \DeclareUnicodeCharacter{0168}{\~U}
- \DeclareUnicodeCharacter{0169}{\~u}
- \DeclareUnicodeCharacter{016A}{\=U}
- \DeclareUnicodeCharacter{016B}{\=u}
- \DeclareUnicodeCharacter{016C}{\u{U}}
- \DeclareUnicodeCharacter{016D}{\u{u}}
- \DeclareUnicodeCharacter{016E}{\ringaccent{U}}
- \DeclareUnicodeCharacter{016F}{\ringaccent{u}}
-
- \DeclareUnicodeCharacter{0170}{\H{U}}
- \DeclareUnicodeCharacter{0171}{\H{u}}
- \DeclareUnicodeCharacter{0174}{\^W}
- \DeclareUnicodeCharacter{0175}{\^w}
- \DeclareUnicodeCharacter{0176}{\^Y}
- \DeclareUnicodeCharacter{0177}{\^y}
- \DeclareUnicodeCharacter{0178}{\"Y}
- \DeclareUnicodeCharacter{0179}{\'Z}
- \DeclareUnicodeCharacter{017A}{\'z}
- \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}
- \DeclareUnicodeCharacter{017C}{\dotaccent{z}}
- \DeclareUnicodeCharacter{017D}{\v{Z}}
- \DeclareUnicodeCharacter{017E}{\v{z}}
-
- \DeclareUnicodeCharacter{01C4}{D\v{Z}}
- \DeclareUnicodeCharacter{01C5}{D\v{z}}
- \DeclareUnicodeCharacter{01C6}{d\v{z}}
- \DeclareUnicodeCharacter{01C7}{LJ}
- \DeclareUnicodeCharacter{01C8}{Lj}
- \DeclareUnicodeCharacter{01C9}{lj}
- \DeclareUnicodeCharacter{01CA}{NJ}
- \DeclareUnicodeCharacter{01CB}{Nj}
- \DeclareUnicodeCharacter{01CC}{nj}
- \DeclareUnicodeCharacter{01CD}{\v{A}}
- \DeclareUnicodeCharacter{01CE}{\v{a}}
- \DeclareUnicodeCharacter{01CF}{\v{I}}
-
- \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}
- \DeclareUnicodeCharacter{01D1}{\v{O}}
- \DeclareUnicodeCharacter{01D2}{\v{o}}
- \DeclareUnicodeCharacter{01D3}{\v{U}}
- \DeclareUnicodeCharacter{01D4}{\v{u}}
-
- \DeclareUnicodeCharacter{01E2}{\={\AE}}
- \DeclareUnicodeCharacter{01E3}{\={\ae}}
- \DeclareUnicodeCharacter{01E6}{\v{G}}
- \DeclareUnicodeCharacter{01E7}{\v{g}}
- \DeclareUnicodeCharacter{01E8}{\v{K}}
- \DeclareUnicodeCharacter{01E9}{\v{k}}
-
- \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}
- \DeclareUnicodeCharacter{01F1}{DZ}
- \DeclareUnicodeCharacter{01F2}{Dz}
- \DeclareUnicodeCharacter{01F3}{dz}
- \DeclareUnicodeCharacter{01F4}{\'G}
- \DeclareUnicodeCharacter{01F5}{\'g}
- \DeclareUnicodeCharacter{01F8}{\`N}
- \DeclareUnicodeCharacter{01F9}{\`n}
- \DeclareUnicodeCharacter{01FC}{\'{\AE}}
- \DeclareUnicodeCharacter{01FD}{\'{\ae}}
- \DeclareUnicodeCharacter{01FE}{\'{\O}}
- \DeclareUnicodeCharacter{01FF}{\'{\o}}
-
- \DeclareUnicodeCharacter{021E}{\v{H}}
- \DeclareUnicodeCharacter{021F}{\v{h}}
-
- \DeclareUnicodeCharacter{0226}{\dotaccent{A}}
- \DeclareUnicodeCharacter{0227}{\dotaccent{a}}
- \DeclareUnicodeCharacter{0228}{\cedilla{E}}
- \DeclareUnicodeCharacter{0229}{\cedilla{e}}
- \DeclareUnicodeCharacter{022E}{\dotaccent{O}}
- \DeclareUnicodeCharacter{022F}{\dotaccent{o}}
-
- \DeclareUnicodeCharacter{0232}{\=Y}
- \DeclareUnicodeCharacter{0233}{\=y}
- \DeclareUnicodeCharacter{0237}{\dotless{j}}
-
- \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
- \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
- \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
- \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}
- \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}
- \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}
- \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}
- \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}
- \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}
- \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}
- \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}
- \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}
-
- \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}
- \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}
-
- \DeclareUnicodeCharacter{1E20}{\=G}
- \DeclareUnicodeCharacter{1E21}{\=g}
- \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}
- \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}
- \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}
- \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}
- \DeclareUnicodeCharacter{1E26}{\"H}
- \DeclareUnicodeCharacter{1E27}{\"h}
-
- \DeclareUnicodeCharacter{1E30}{\'K}
- \DeclareUnicodeCharacter{1E31}{\'k}
- \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}
- \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}
- \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}
- \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}
- \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}
- \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}
- \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}
- \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}
- \DeclareUnicodeCharacter{1E3E}{\'M}
- \DeclareUnicodeCharacter{1E3F}{\'m}
-
- \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}
- \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}
- \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}
- \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}
- \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}
- \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}
- \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}
- \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}
- \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}
- \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}
-
- \DeclareUnicodeCharacter{1E54}{\'P}
- \DeclareUnicodeCharacter{1E55}{\'p}
- \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}
- \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}
- \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}
- \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}
- \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}
- \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}
- \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}
- \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}
-
- \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}
- \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}
- \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}
- \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}
- \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}
- \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}
- \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}
- \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}
- \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}
- \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}
-
- \DeclareUnicodeCharacter{1E7C}{\~V}
- \DeclareUnicodeCharacter{1E7D}{\~v}
- \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}
- \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}
-
- \DeclareUnicodeCharacter{1E80}{\`W}
- \DeclareUnicodeCharacter{1E81}{\`w}
- \DeclareUnicodeCharacter{1E82}{\'W}
- \DeclareUnicodeCharacter{1E83}{\'w}
- \DeclareUnicodeCharacter{1E84}{\"W}
- \DeclareUnicodeCharacter{1E85}{\"w}
- \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}
- \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}
- \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}
- \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}
- \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}
- \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}
- \DeclareUnicodeCharacter{1E8C}{\"X}
- \DeclareUnicodeCharacter{1E8D}{\"x}
- \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}
- \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}
-
- \DeclareUnicodeCharacter{1E90}{\^Z}
- \DeclareUnicodeCharacter{1E91}{\^z}
- \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}
- \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}
- \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}
- \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}
- \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}
- \DeclareUnicodeCharacter{1E97}{\"t}
- \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}
- \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}
-
- \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}
- \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}
-
- \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}
- \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}
- \DeclareUnicodeCharacter{1EBC}{\~E}
- \DeclareUnicodeCharacter{1EBD}{\~e}
-
- \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}
- \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}
- \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}
- \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}
-
- \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}
- \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}
-
- \DeclareUnicodeCharacter{1EF2}{\`Y}
- \DeclareUnicodeCharacter{1EF3}{\`y}
- \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}
-
- \DeclareUnicodeCharacter{1EF8}{\~Y}
- \DeclareUnicodeCharacter{1EF9}{\~y}
-
- \DeclareUnicodeCharacter{2013}{--}
- \DeclareUnicodeCharacter{2014}{---}
- \DeclareUnicodeCharacter{2018}{\quoteleft}
- \DeclareUnicodeCharacter{2019}{\quoteright}
- \DeclareUnicodeCharacter{201A}{\quotesinglbase}
- \DeclareUnicodeCharacter{201C}{\quotedblleft}
- \DeclareUnicodeCharacter{201D}{\quotedblright}
- \DeclareUnicodeCharacter{201E}{\quotedblbase}
- \DeclareUnicodeCharacter{2022}{\bullet}
- \DeclareUnicodeCharacter{2026}{\dots}
- \DeclareUnicodeCharacter{2039}{\guilsinglleft}
- \DeclareUnicodeCharacter{203A}{\guilsinglright}
- \DeclareUnicodeCharacter{20AC}{\euro}
-
- \DeclareUnicodeCharacter{2192}{\expansion}
- \DeclareUnicodeCharacter{21D2}{\result}
-
- \DeclareUnicodeCharacter{2212}{\minus}
- \DeclareUnicodeCharacter{2217}{\point}
- \DeclareUnicodeCharacter{2261}{\equiv}
-}% end of \utfeightchardefs
-
-
-% US-ASCII character definitions.
-\def\asciichardefs{% nothing need be done
- \relax
-}
-
-% Make non-ASCII characters printable again for compatibility with
-% existing Texinfo documents that may use them, even without declaring a
-% document encoding.
-%
-\setnonasciicharscatcode \other
-
-
-\message{formatting,}
-
\newdimen\defaultparindent \defaultparindent = 15pt
\chapheadingskip = 15pt plus 4pt minus 2pt
@@ -8586,7 +6840,7 @@
% Don't be so finicky about underfull hboxes, either.
\hbadness = 2000
-% Following George Bush, get rid of widows and orphans.
+% Following George Bush, just get rid of widows and orphans.
\widowpenalty=10000
\clubpenalty=10000
@@ -8633,10 +6887,6 @@
\ifpdf
\pdfpageheight #7\relax
\pdfpagewidth #8\relax
- % if we don't reset these, they will remain at "1 true in" of
- % whatever layout pdftex was dumped with.
- \pdfhorigin = 1 true in
- \pdfvorigin = 1 true in
\fi
%
\setleading{\textleading}
@@ -8651,7 +6901,7 @@
\textleading = 13.2pt
%
% If page is nothing but text, make it come out even.
- \internalpagesizes{607.2pt}{6in}% that's 46 lines
+ \internalpagesizes{46\baselineskip}{6in}%
{\voffset}{.25in}%
{\bindingoffset}{36pt}%
{11in}{8.5in}%
@@ -8663,7 +6913,7 @@
\textleading = 12pt
%
\internalpagesizes{7.5in}{5in}%
- {-.2in}{0in}%
+ {\voffset}{.25in}%
{\bindingoffset}{16pt}%
{9.25in}{7in}%
%
@@ -8707,7 +6957,7 @@
% \global\normaloffset = -6mm
% \global\bindingoffset = 10mm
% @end tex
- \internalpagesizes{673.2pt}{160mm}% that's 51 lines
+ \internalpagesizes{51\baselineskip}{160mm}
{\voffset}{\hoffset}%
{\bindingoffset}{44pt}%
{297mm}{210mm}%
@@ -8772,7 +7022,7 @@
\parskip = 3pt plus 2pt minus 1pt
\setleading{\textleading}%
%
- \dimen0 = #1\relax
+ \dimen0 = #1
\advance\dimen0 by \voffset
%
\dimen2 = \hsize
@@ -8867,13 +7117,6 @@
% \otherifyactive is called near the end of this file.
\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
-% Used sometimes to turn off (effectively) the active characters even after
-% parsing them.
-\def\turnoffactive{%
- \normalturnoffactive
- \otherbackslash
-}
-
address@hidden
% \backslashcurfont outputs one backslash character in current font,
@@ -8881,29 +7124,28 @@
\global\chardef\backslashcurfont=`\\
\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other.
+{\catcode`\\=\active
+ @address@hidden@address@hidden
+ @address@hidden@address@hidden
+}
+
% \realbackslash is an actual character `\' with catcode other, and
% \doublebackslash is two of them (for the pdf outlines).
{\catcode`\\=\other @address@hidden @address@hidden
-% In texinfo, backslash is an active character; it prints the backslash
-% in fixed width font.
+% \normalbackslash outputs one backslash in fixed width font.
+\def\normalbackslash{{\tt\backslashcurfont}}
+
\catcode`\\=\active
address@hidden@address@hidden@backslashcurfont}}
-% 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.
address@hidden@address@hidden@backslashcurfont}
address@hidden@address@hidden@realbackslash}
-
-% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
-% the literal character `\'.
-%
address@hidden@normalturnoffactive{%
- @address@hidden
+% Used sometimes to turn off (effectively) the active characters
+% even after parsing them.
address@hidden@turnoffactive{%
@let"address@hidden
+ @address@hidden
@address@hidden
@address@hidden
@address@hidden
@@ -8915,6 +7157,12 @@
@unsepspaces
}
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'. (Thus, \ is not expandable when this is in
+% effect.)
+%
address@hidden@address@hidden @address@hidden
+
% Make _ and + \other characters, temporarily.
% This is canceled by @fixbackslash.
@otherifyactive
@@ -8927,7 +7175,7 @@
@address@hidden = @eatinput
% On the other hand, perhaps the file did not have a `\input texinfo'. Then
-% the first `\' in the file would cause an error. This macro tries to fix
+% the first `\{ in the file would cause an error. This macro tries to fix
% that, assuming it is called before the first `\' could plausibly occur.
% Also turn back on active characters that might appear in the input
% file name, in case not using a pre-dumped format.
Modified: libmicrohttpd/doc/tutorial.texi
===================================================================
--- libmicrohttpd/doc/tutorial.texi 2008-08-28 06:51:01 UTC (rev 7636)
+++ libmicrohttpd/doc/tutorial.texi 2008-08-28 19:29:47 UTC (rev 7637)
@@ -45,32 +45,32 @@
@node Introduction
@chapter Introduction
address@hidden introduction.inc
address@hidden chapters/introduction.inc
@node Hello browser example
@chapter Hello browser example
address@hidden hellobrowser.inc
address@hidden chapters/hellobrowser.inc
@node Exploring requests
@chapter Exploring requests
address@hidden exploringrequests.inc
address@hidden chapters/exploringrequests.inc
@node Response headers
@chapter Response headers
address@hidden responseheaders.inc
address@hidden chapters/responseheaders.inc
@node Supporting basic authentication
@chapter Supporting basic authentication
address@hidden basicauthentication.inc
address@hidden chapters/basicauthentication.inc
@node Processing POST data
@chapter Processing POST data
address@hidden processingpost.inc
address@hidden chapters/processingpost.inc
@node Bibliography
@appendix Bibliography
address@hidden bibliography.inc
address@hidden chapters/bibliography.inc
@node License text
@appendix GNU Free Documentation License
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r7637 - in libmicrohttpd/doc: . chapters,
gnunet <=