From: Chet Ramey Date: Tue, 3 Mar 2026 16:14:10 +0000 (-0500) Subject: fix cosmetic error when printing if commands containing here-documents in the body... X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=d0b41c2c5fa67d670aac1a5eb1509b650bdc2e4e;p=thirdparty%2Fbash.git fix cosmetic error when printing if commands containing here-documents in the body; compiling -DSTRICT_POSIX now forces posix-mode shells to expand redirections before assignment statements preceding simple commands --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 47862e7e0..9e9b8d39c 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -12721,3 +12721,39 @@ subst.c,subst.h - expand_words: call expand_assignment_statements instead of do_assignment_statements, remove some duplicate code + 2/25 + ---- +print_cmd.c + - print_if_command: if we have just printed the `action' command, + and it ends with a here-document, fix indentation amount + Report and fix from Weixie Cui <523516579@qq.com> + + 2/27 + ---- +subst.c + - WEXP_DEFERVARS: new word expansion flag, means to defer assignment + statements until after other word expansions and redirections + - WEXP_POSIX: new flag set for expand_word_list_internal, means to + separate out the assignment statements but leave them in + SUBST_ASSIGN_VARLIST + - if STRICT_POSIX is defined, expand_words calls expand_word_list_internal + with WEXP_POSIX when in posix mode + - expand_word_list_internal: only call expand_assignment_statements if + WEXP_DEFERVARS is not set in EFLAGS. It can only be set if the shell + is compiled -DSTRICT_POSIX and in posix mode + +execute_cmd.c + - execute_null_command: if compiled -DSTRICT_POSIX and in posix mode, + expand assignment statements after performing redirections and only + if the redirections complete without errors + - execute_subshell_builtin_or_function,execute_builtin_or_function: + if compiled -DSTRICT_POSIX and in posix mode, expand assignment + statements after performing redirections and only if the + redirections complete without errors + - execute_simple_command: if compiled -DSTRICT_POSIX and in posix mode, + expand assignment statements after performing redirections and only + if the redirections complete without errors, and defer environment + creation until after calling expand_assignment_statements() + + + diff --git a/MANIFEST b/MANIFEST index e33e075f3..75706f96e 100644 --- a/MANIFEST +++ b/MANIFEST @@ -533,6 +533,7 @@ m4/bison.m4 f m4/c-bool.m4 f m4/codeset.m4 f m4/d-type.m4 f +m4/environ.m4 f m4/extern-inline.m4 f m4/fcntl-o.m4 f m4/flexmember.m4 f diff --git a/POSIX b/POSIX index baf127539..feb8ad6ca 100644 --- a/POSIX +++ b/POSIX @@ -387,7 +387,13 @@ default even when in POSIX mode. Specifically: entries if ‘FCEDIT’ is unset, rather than defaulting directly to ‘ed’. ‘fc’ uses ‘ed’ if ‘EDITOR’ is unset. - 3. As noted above, Bash requires the ‘xpg_echo’ option to be enabled + 3. Bash does not perform redirections before expanding variable + assignments preceding a simple command; it does not allow the + redirections access to the results of the variable assignments, but + any side effects of expanding the redirections take place first. + If compiled in strict posix mode, Bash performs redirections first. + + 4. As noted above, Bash requires the ‘xpg_echo’ option to be enabled for the ‘echo’ builtin to be fully conformant. Bash can be configured to be POSIX-conformant by default, by specifying diff --git a/assoc.c b/assoc.c index 5a8e81800..94cdf97ad 100644 --- a/assoc.c +++ b/assoc.c @@ -278,6 +278,58 @@ assoc_subrange (HASH_TABLE *hash, arrayind_t start, arrayind_t nelem, int starsu return (ret); } +/* + * Return a string whose elements are the members of array H beginning at + * the element with key START and ending with key END. + * Order is non-deterministic and determined by walking the hash table + * from beginning to end (assoc_to_word_list()). + * If START isn't found, this starts at the beginning of the list created + * from the hash table. + * If END isn't found, this returns START. + * If neither START nor END is found, this returns the first entry in the list. + * These semantics are compatible with the ksh93 ${assoc[k1..k2]} expansion. + */ +char * +assoc_subslice (HASH_TABLE *hash, char *start, char *end, int starsub, int quoted, int pflags) +{ + WORD_LIST *l, *save, *h, *t; + int i, j; + char *ret; + + if (assoc_empty (hash)) + return ((char *)NULL); + + save = l = assoc_to_word_list (hash); + if (save == 0) + return ((char *)NULL); + + for (h = l; h; h = h->next) + if (STREQ (start, h->word->word)) + break; + + if (h == 0) /* XXX could return NULL here */ + h = l; + + for (t = h; t; t = t->next) + if (STREQ (end, t->word->word)) + break; + + /* XXX could leave it set to the last element by leaving t = 0 and not + messing around with t->next below */ + if (t == 0) + t = h; + + l = t->next; + t->next = (WORD_LIST *)NULL; + + ret = string_list_pos_params (starsub ? '*' : '@', h, quoted, pflags); + + t->next = l; + + dispose_words (save); + return (ret); +} + /* Substitute REP for each match of PAT in each element of hash table H, qualified by FLAGS to say what kind of quoting to do. */ char * diff --git a/assoc.h b/assoc.h index 46dc0aef6..beaea6843 100644 --- a/assoc.h +++ b/assoc.h @@ -46,6 +46,7 @@ extern void assoc_remove (HASH_TABLE *, const char *); extern char *assoc_reference (HASH_TABLE *, const char *); extern char *assoc_subrange (HASH_TABLE *, arrayind_t, arrayind_t, int, int, int); +extern char *assoc_subslice (HASH_TABLE *, char *, char *, int, int, int); extern char *assoc_patsub (HASH_TABLE *, char *, char *, int); extern char *assoc_modcase (HASH_TABLE *, char *, int, int); diff --git a/builtins/common.c b/builtins/common.c index 6f85c5184..15a3b1560 100644 --- a/builtins/common.c +++ b/builtins/common.c @@ -1052,7 +1052,7 @@ builtin_arrayref_flags (WORD_DESC *w, int baseflags) # if 0 /* This is a little sketchier but handles quoted arguments. */ - if (array_expand_once && (t = strchr (w->word, '[')) && t[strlen(t) - 1] == ']') + if (array_expand_once && (t = strchr (w->word, '[')) && t[strlen(t) - 1] == ']') vflags |= VA_ONEWORD|VA_NOEXPAND; # endif diff --git a/builtins/source.def b/builtins/source.def index 5668951c2..4e292a902 100644 --- a/builtins/source.def +++ b/builtins/source.def @@ -29,8 +29,8 @@ Read and execute commands from FILENAME in the current shell. If the -p option is supplied, the PATH argument is treated as a colon- separated list of directories to search for FILENAME. If -p is not supplied, and the sourcepath shell option is enabled, 'source' searches -$PATH to find FILENAME. If any ARGUMENTS are supplied, they become the -positional parameters when FILENAME is executed. +the directories in $PATH to find FILENAME. If any ARGUMENTS are supplied, +they become the positional parameters when FILENAME is executed. Exit Status: Returns the status of the last command executed in FILENAME; fails if @@ -47,8 +47,8 @@ Read and execute commands from FILENAME in the current shell. If the -p option is supplied, the PATH argument is treated as a colon- separated list of directories to search for FILENAME. If -p is not supplied, and the sourcepath shell option is enabled, '.' searches -$PATH to find FILENAME. If any ARGUMENTS are supplied, they become the -positional parameters when FILENAME is executed. +the directories in $PATH to find FILENAME. If any ARGUMENTS are supplied, +they become the positional parameters when FILENAME is executed. Exit Status: Returns the status of the last command executed in FILENAME; fails if diff --git a/configure b/configure index 89b882e43..e6d2d741e 100755 --- a/configure +++ b/configure @@ -7116,6 +7116,16 @@ fi +# environ.m4 +# serial 8 + + + +# Check if a variable is properly declared. +# gt_CHECK_VAR_DECL(includes,variable) + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 printf %s "checking for an ANSI C-conforming const... " >&6; } if test ${ac_cv_c_const+y} @@ -9415,8 +9425,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$save_LIBS test $gl_pthread_api = yes && break done - echo "$as_me:9418: gl_pthread_api=$gl_pthread_api" >&5 - echo "$as_me:9419: LIBPTHREAD=$LIBPTHREAD" >&5 + echo "$as_me:9428: gl_pthread_api=$gl_pthread_api" >&5 + echo "$as_me:9429: LIBPTHREAD=$LIBPTHREAD" >&5 gl_pthread_in_glibc=no # On Linux with glibc >= 2.34, libc contains the fully functional @@ -9442,7 +9452,7 @@ rm -rf conftest* ;; esac - echo "$as_me:9445: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5 + echo "$as_me:9455: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5 # Test for libpthread by looking for pthread_kill. (Not pthread_self, # since it is defined as a macro on OSF/1.) @@ -9620,7 +9630,7 @@ fi fi fi - echo "$as_me:9623: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5 + echo "$as_me:9633: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5 printf %s "checking whether POSIX threads API is available... " >&6; } @@ -9867,8 +9877,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ LIBS=$save_LIBS test $gl_pthread_api = yes && break done - echo "$as_me:9870: gl_pthread_api=$gl_pthread_api" >&5 - echo "$as_me:9871: LIBPTHREAD=$LIBPTHREAD" >&5 + echo "$as_me:9880: gl_pthread_api=$gl_pthread_api" >&5 + echo "$as_me:9881: LIBPTHREAD=$LIBPTHREAD" >&5 gl_pthread_in_glibc=no # On Linux with glibc >= 2.34, libc contains the fully functional @@ -9894,7 +9904,7 @@ rm -rf conftest* ;; esac - echo "$as_me:9897: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5 + echo "$as_me:9907: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5 # Test for libpthread by looking for pthread_kill. (Not pthread_self, # since it is defined as a macro on OSF/1.) @@ -10072,7 +10082,7 @@ fi fi fi - echo "$as_me:10075: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5 + echo "$as_me:10085: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5 printf %s "checking whether POSIX threads API is available... " >&6; } diff --git a/configure.ac b/configure.ac index 5bee338af..c3f0d42d1 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ dnl report bugs to chet.ramey@case.edu dnl dnl Process this file with autoconf to produce a configure script. -# Copyright (C) 1987-2025 Free Software Foundation, Inc. +# Copyright (C) 1987-2026 Free Software Foundation, Inc. # # This program is free software: you can redistribute it and/or modify @@ -783,6 +783,8 @@ m4_include([m4/host-cpu-c-abi.m4]) m4_include([m4/c-bool.m4]) m4_include([m4/d-type.m4]) +m4_include([m4/environ.m4]) + dnl C compiler characteristics AC_C_CONST AC_C_INLINE diff --git a/doc/bash.info b/doc/bash.info index df5767c5d..baf9c7408 100644 --- a/doc/bash.info +++ b/doc/bash.info @@ -1,9 +1,9 @@ This is bash.info, produced by makeinfo version 7.2 from bashref.texi. This text is a brief description of the features that are present in the -Bash shell (version 5.3, 14 January 2026). +Bash shell (version 5.3, 27 February 2026). - This is Edition 5.3, last updated 14 January 2026, of ‘The GNU Bash + This is Edition 5.3, last updated 27 February 2026, of ‘The GNU Bash Reference Manual’, for ‘Bash’, Version 5.3. Copyright © 1988-2026 Free Software Foundation, Inc. @@ -26,10 +26,10 @@ Bash Features ************* This text is a brief description of the features that are present in the -Bash shell (version 5.3, 14 January 2026). The Bash home page is +Bash shell (version 5.3, 27 February 2026). The Bash home page is . - This is Edition 5.3, last updated 14 January 2026, of ‘The GNU Bash + This is Edition 5.3, last updated 27 February 2026, of ‘The GNU Bash Reference Manual’, for ‘Bash’, Version 5.3. Bash contains features that appear in other popular shells, and some @@ -7774,7 +7774,8 @@ startup files. builtins. 12. Tilde expansion is only performed on assignments preceding a - command name, rather than on all assignment statements on the line. + command name, rather than on all assignment statements on the line, + unless the command is a declaration command. 13. While variable indirection is available, it may not be applied to the ‘#’ and ‘?’ special parameters. @@ -8062,7 +8063,13 @@ default even when in POSIX mode. Specifically: entries if ‘FCEDIT’ is unset, rather than defaulting directly to ‘ed’. ‘fc’ uses ‘ed’ if ‘EDITOR’ is unset. - 3. As noted above, Bash requires the ‘xpg_echo’ option to be enabled + 3. Bash does not perform redirections before expanding variable + assignments preceding a simple command; it does not allow the + redirections access to the results of the variable assignments, but + any side effects of expanding the redirections take place first. + If compiled in strict posix mode, Bash performs redirections first. + + 4. As noted above, Bash requires the ‘xpg_echo’ option to be enabled for the ‘echo’ builtin to be fully conformant. Bash can be configured to be POSIX-conformant by default, by @@ -13728,138 +13735,138 @@ D.5 Concept Index  Tag Table: -Node: Top899 -Node: Introduction2838 -Node: What is Bash?3051 -Node: What is a shell?4184 -Node: Definitions6794 -Node: Basic Shell Features10121 -Node: Shell Syntax11345 -Node: Shell Operation12372 -Node: Quoting13663 -Node: Escape Character15001 -Node: Single Quotes15536 -Node: Double Quotes15885 -Node: ANSI-C Quoting17230 -Node: Locale Translation18624 -Node: Creating Internationalized Scripts20027 -Node: Comments24225 -Node: Shell Commands24992 -Node: Reserved Words25931 -Node: Simple Commands27074 -Node: Pipelines27736 -Node: Lists30992 -Node: Compound Commands32941 -Node: Looping Constructs33950 -Node: Conditional Constructs36499 -Node: Command Grouping51636 -Node: Coprocesses53128 -Node: GNU Parallel55814 -Node: Shell Functions56732 -Node: Shell Parameters65180 -Node: Positional Parameters70081 -Node: Special Parameters71171 -Node: Shell Expansions74632 -Node: Brace Expansion76821 -Node: Tilde Expansion80157 -Node: Shell Parameter Expansion83112 -Node: Command Substitution103759 -Node: Arithmetic Expansion107610 -Node: Process Substitution108786 -Node: Word Splitting109894 -Node: Filename Expansion112338 -Node: Pattern Matching115562 -Node: Quote Removal121328 -Node: Redirections121632 -Node: Executing Commands131888 -Node: Simple Command Expansion132555 -Node: Command Search and Execution134663 -Node: Command Execution Environment137107 -Node: Environment140633 -Node: Exit Status142536 -Node: Signals144595 -Node: Shell Scripts149543 -Node: Shell Builtin Commands152841 -Node: Bourne Shell Builtins155182 -Node: Bash Builtins181901 -Node: Modifying Shell Behavior219637 -Node: The Set Builtin219979 -Node: The Shopt Builtin231973 -Node: Special Builtins249026 -Node: Shell Variables250015 -Node: Bourne Shell Variables250449 -Node: Bash Variables252957 -Node: Bash Features292241 -Node: Invoking Bash293255 -Node: Bash Startup Files299839 -Node: Interactive Shells305081 -Node: What is an Interactive Shell?305489 -Node: Is this Shell Interactive?306151 -Node: Interactive Shell Behavior306975 -Node: Bash Conditional Expressions310736 -Node: Shell Arithmetic316153 -Node: Aliases319480 -Node: Arrays322614 -Node: The Directory Stack330317 -Node: Directory Stack Builtins331114 -Node: Controlling the Prompt335559 -Node: The Restricted Shell338443 -Node: Bash POSIX Mode341536 -Node: Shell Compatibility Mode360952 -Node: Job Control369959 -Node: Job Control Basics370416 -Node: Job Control Builtins376784 -Node: Job Control Variables383572 -Node: Command Line Editing384803 -Node: Introduction and Notation386506 -Node: Readline Interaction388858 -Node: Readline Bare Essentials390046 -Node: Readline Movement Commands391854 -Node: Readline Killing Commands392850 -Node: Readline Arguments394873 -Node: Searching395963 -Node: Readline Init File398206 -Node: Readline Init File Syntax399509 -Node: Conditional Init Constructs426460 -Node: Sample Init File430845 -Node: Bindable Readline Commands433965 -Node: Commands For Moving435503 -Node: Commands For History437967 -Node: Commands For Text443358 -Node: Commands For Killing447483 -Node: Numeric Arguments450271 -Node: Commands For Completion451423 -Node: Keyboard Macros457119 -Node: Miscellaneous Commands457820 -Node: Readline vi Mode465363 -Node: Programmable Completion466340 -Node: Programmable Completion Builtins476076 -Node: A Programmable Completion Example487813 -Node: Using History Interactively493158 -Node: Bash History Facilities493839 -Node: Bash History Builtins497574 -Node: History Interaction505169 -Node: Event Designators510119 -Node: Word Designators511697 -Node: Modifiers514089 -Node: Installing Bash516026 -Node: Basic Installation517142 -Node: Compilers and Options521018 -Node: Compiling For Multiple Architectures521768 -Node: Installation Names523521 -Node: Specifying the System Type525755 -Node: Sharing Defaults526501 -Node: Operation Controls527215 -Node: Optional Features528234 -Node: Reporting Bugs540957 -Node: Major Differences From The Bourne Shell542314 -Node: GNU Free Documentation License563741 -Node: Indexes588918 -Node: Builtin Index589369 -Node: Reserved Word Index596467 -Node: Variable Index598912 -Node: Function Index616325 -Node: Concept Index630458 +Node: Top901 +Node: Introduction2842 +Node: What is Bash?3055 +Node: What is a shell?4188 +Node: Definitions6798 +Node: Basic Shell Features10125 +Node: Shell Syntax11349 +Node: Shell Operation12376 +Node: Quoting13667 +Node: Escape Character15005 +Node: Single Quotes15540 +Node: Double Quotes15889 +Node: ANSI-C Quoting17234 +Node: Locale Translation18628 +Node: Creating Internationalized Scripts20031 +Node: Comments24229 +Node: Shell Commands24996 +Node: Reserved Words25935 +Node: Simple Commands27078 +Node: Pipelines27740 +Node: Lists30996 +Node: Compound Commands32945 +Node: Looping Constructs33954 +Node: Conditional Constructs36503 +Node: Command Grouping51640 +Node: Coprocesses53132 +Node: GNU Parallel55818 +Node: Shell Functions56736 +Node: Shell Parameters65184 +Node: Positional Parameters70085 +Node: Special Parameters71175 +Node: Shell Expansions74636 +Node: Brace Expansion76825 +Node: Tilde Expansion80161 +Node: Shell Parameter Expansion83116 +Node: Command Substitution103763 +Node: Arithmetic Expansion107614 +Node: Process Substitution108790 +Node: Word Splitting109898 +Node: Filename Expansion112342 +Node: Pattern Matching115566 +Node: Quote Removal121332 +Node: Redirections121636 +Node: Executing Commands131892 +Node: Simple Command Expansion132559 +Node: Command Search and Execution134667 +Node: Command Execution Environment137111 +Node: Environment140637 +Node: Exit Status142540 +Node: Signals144599 +Node: Shell Scripts149547 +Node: Shell Builtin Commands152845 +Node: Bourne Shell Builtins155186 +Node: Bash Builtins181905 +Node: Modifying Shell Behavior219641 +Node: The Set Builtin219983 +Node: The Shopt Builtin231977 +Node: Special Builtins249030 +Node: Shell Variables250019 +Node: Bourne Shell Variables250453 +Node: Bash Variables252961 +Node: Bash Features292245 +Node: Invoking Bash293259 +Node: Bash Startup Files299843 +Node: Interactive Shells305085 +Node: What is an Interactive Shell?305493 +Node: Is this Shell Interactive?306155 +Node: Interactive Shell Behavior306979 +Node: Bash Conditional Expressions310740 +Node: Shell Arithmetic316157 +Node: Aliases319484 +Node: Arrays322618 +Node: The Directory Stack330321 +Node: Directory Stack Builtins331118 +Node: Controlling the Prompt335563 +Node: The Restricted Shell338447 +Node: Bash POSIX Mode341540 +Node: Shell Compatibility Mode361356 +Node: Job Control370363 +Node: Job Control Basics370820 +Node: Job Control Builtins377188 +Node: Job Control Variables383976 +Node: Command Line Editing385207 +Node: Introduction and Notation386910 +Node: Readline Interaction389262 +Node: Readline Bare Essentials390450 +Node: Readline Movement Commands392258 +Node: Readline Killing Commands393254 +Node: Readline Arguments395277 +Node: Searching396367 +Node: Readline Init File398610 +Node: Readline Init File Syntax399913 +Node: Conditional Init Constructs426864 +Node: Sample Init File431249 +Node: Bindable Readline Commands434369 +Node: Commands For Moving435907 +Node: Commands For History438371 +Node: Commands For Text443762 +Node: Commands For Killing447887 +Node: Numeric Arguments450675 +Node: Commands For Completion451827 +Node: Keyboard Macros457523 +Node: Miscellaneous Commands458224 +Node: Readline vi Mode465767 +Node: Programmable Completion466744 +Node: Programmable Completion Builtins476480 +Node: A Programmable Completion Example488217 +Node: Using History Interactively493562 +Node: Bash History Facilities494243 +Node: Bash History Builtins497978 +Node: History Interaction505573 +Node: Event Designators510523 +Node: Word Designators512101 +Node: Modifiers514493 +Node: Installing Bash516430 +Node: Basic Installation517546 +Node: Compilers and Options521422 +Node: Compiling For Multiple Architectures522172 +Node: Installation Names523925 +Node: Specifying the System Type526159 +Node: Sharing Defaults526905 +Node: Operation Controls527619 +Node: Optional Features528638 +Node: Reporting Bugs541361 +Node: Major Differences From The Bourne Shell542718 +Node: GNU Free Documentation License564145 +Node: Indexes589322 +Node: Builtin Index589773 +Node: Reserved Word Index596871 +Node: Variable Index599316 +Node: Function Index616729 +Node: Concept Index630862  End Tag Table diff --git a/doc/bashref.info b/doc/bashref.info index c3af797c6..6d97d8e9c 100644 --- a/doc/bashref.info +++ b/doc/bashref.info @@ -2,9 +2,9 @@ This is bashref.info, produced by makeinfo version 7.2 from bashref.texi. This text is a brief description of the features that are present in the -Bash shell (version 5.3, 14 January 2026). +Bash shell (version 5.3, 27 February 2026). - This is Edition 5.3, last updated 14 January 2026, of ‘The GNU Bash + This is Edition 5.3, last updated 27 February 2026, of ‘The GNU Bash Reference Manual’, for ‘Bash’, Version 5.3. Copyright © 1988-2026 Free Software Foundation, Inc. @@ -27,10 +27,10 @@ Bash Features ************* This text is a brief description of the features that are present in the -Bash shell (version 5.3, 14 January 2026). The Bash home page is +Bash shell (version 5.3, 27 February 2026). The Bash home page is . - This is Edition 5.3, last updated 14 January 2026, of ‘The GNU Bash + This is Edition 5.3, last updated 27 February 2026, of ‘The GNU Bash Reference Manual’, for ‘Bash’, Version 5.3. Bash contains features that appear in other popular shells, and some @@ -7775,7 +7775,8 @@ startup files. builtins. 12. Tilde expansion is only performed on assignments preceding a - command name, rather than on all assignment statements on the line. + command name, rather than on all assignment statements on the line, + unless the command is a declaration command. 13. While variable indirection is available, it may not be applied to the ‘#’ and ‘?’ special parameters. @@ -8063,7 +8064,13 @@ default even when in POSIX mode. Specifically: entries if ‘FCEDIT’ is unset, rather than defaulting directly to ‘ed’. ‘fc’ uses ‘ed’ if ‘EDITOR’ is unset. - 3. As noted above, Bash requires the ‘xpg_echo’ option to be enabled + 3. Bash does not perform redirections before expanding variable + assignments preceding a simple command; it does not allow the + redirections access to the results of the variable assignments, but + any side effects of expanding the redirections take place first. + If compiled in strict posix mode, Bash performs redirections first. + + 4. As noted above, Bash requires the ‘xpg_echo’ option to be enabled for the ‘echo’ builtin to be fully conformant. Bash can be configured to be POSIX-conformant by default, by @@ -13729,138 +13736,138 @@ D.5 Concept Index  Tag Table: -Node: Top902 -Node: Introduction2844 -Node: What is Bash?3060 -Node: What is a shell?4196 -Node: Definitions6809 -Node: Basic Shell Features10139 -Node: Shell Syntax11366 -Node: Shell Operation12396 -Node: Quoting13690 -Node: Escape Character15031 -Node: Single Quotes15569 -Node: Double Quotes15921 -Node: ANSI-C Quoting17269 -Node: Locale Translation18666 -Node: Creating Internationalized Scripts20072 -Node: Comments24273 -Node: Shell Commands25043 -Node: Reserved Words25985 -Node: Simple Commands27131 -Node: Pipelines27796 -Node: Lists31055 -Node: Compound Commands33007 -Node: Looping Constructs34019 -Node: Conditional Constructs36571 -Node: Command Grouping51711 -Node: Coprocesses53206 -Node: GNU Parallel55895 -Node: Shell Functions56816 -Node: Shell Parameters65267 -Node: Positional Parameters70171 -Node: Special Parameters71264 -Node: Shell Expansions74728 -Node: Brace Expansion76920 -Node: Tilde Expansion80259 -Node: Shell Parameter Expansion83217 -Node: Command Substitution103867 -Node: Arithmetic Expansion107721 -Node: Process Substitution108900 -Node: Word Splitting110011 -Node: Filename Expansion112458 -Node: Pattern Matching115685 -Node: Quote Removal121454 -Node: Redirections121761 -Node: Executing Commands132020 -Node: Simple Command Expansion132690 -Node: Command Search and Execution134801 -Node: Command Execution Environment137248 -Node: Environment140777 -Node: Exit Status142683 -Node: Signals144745 -Node: Shell Scripts149696 -Node: Shell Builtin Commands152997 -Node: Bourne Shell Builtins155341 -Node: Bash Builtins182063 -Node: Modifying Shell Behavior219802 -Node: The Set Builtin220147 -Node: The Shopt Builtin232144 -Node: Special Builtins249200 -Node: Shell Variables250192 -Node: Bourne Shell Variables250629 -Node: Bash Variables253140 -Node: Bash Features292427 -Node: Invoking Bash293444 -Node: Bash Startup Files300031 -Node: Interactive Shells305276 -Node: What is an Interactive Shell?305687 -Node: Is this Shell Interactive?306352 -Node: Interactive Shell Behavior307179 -Node: Bash Conditional Expressions310943 -Node: Shell Arithmetic316363 -Node: Aliases319693 -Node: Arrays322830 -Node: The Directory Stack330536 -Node: Directory Stack Builtins331336 -Node: Controlling the Prompt335784 -Node: The Restricted Shell338671 -Node: Bash POSIX Mode341767 -Node: Shell Compatibility Mode361186 -Node: Job Control370196 -Node: Job Control Basics370656 -Node: Job Control Builtins377027 -Node: Job Control Variables383818 -Node: Command Line Editing385052 -Node: Introduction and Notation386758 -Node: Readline Interaction389113 -Node: Readline Bare Essentials390304 -Node: Readline Movement Commands392115 -Node: Readline Killing Commands393114 -Node: Readline Arguments395140 -Node: Searching396233 -Node: Readline Init File398479 -Node: Readline Init File Syntax399785 -Node: Conditional Init Constructs426739 -Node: Sample Init File431127 -Node: Bindable Readline Commands434250 -Node: Commands For Moving435791 -Node: Commands For History438258 -Node: Commands For Text443652 -Node: Commands For Killing447780 -Node: Numeric Arguments450571 -Node: Commands For Completion451726 -Node: Keyboard Macros457425 -Node: Miscellaneous Commands458129 -Node: Readline vi Mode465675 -Node: Programmable Completion466655 -Node: Programmable Completion Builtins476394 -Node: A Programmable Completion Example488134 -Node: Using History Interactively493482 -Node: Bash History Facilities494166 -Node: Bash History Builtins497904 -Node: History Interaction505502 -Node: Event Designators510455 -Node: Word Designators512036 -Node: Modifiers514431 -Node: Installing Bash516371 -Node: Basic Installation517490 -Node: Compilers and Options521369 -Node: Compiling For Multiple Architectures522122 -Node: Installation Names523878 -Node: Specifying the System Type526115 -Node: Sharing Defaults526864 -Node: Operation Controls527581 -Node: Optional Features528603 -Node: Reporting Bugs541329 -Node: Major Differences From The Bourne Shell542689 -Node: GNU Free Documentation License564119 -Node: Indexes589299 -Node: Builtin Index589753 -Node: Reserved Word Index596854 -Node: Variable Index599302 -Node: Function Index616718 -Node: Concept Index630854 +Node: Top904 +Node: Introduction2848 +Node: What is Bash?3064 +Node: What is a shell?4200 +Node: Definitions6813 +Node: Basic Shell Features10143 +Node: Shell Syntax11370 +Node: Shell Operation12400 +Node: Quoting13694 +Node: Escape Character15035 +Node: Single Quotes15573 +Node: Double Quotes15925 +Node: ANSI-C Quoting17273 +Node: Locale Translation18670 +Node: Creating Internationalized Scripts20076 +Node: Comments24277 +Node: Shell Commands25047 +Node: Reserved Words25989 +Node: Simple Commands27135 +Node: Pipelines27800 +Node: Lists31059 +Node: Compound Commands33011 +Node: Looping Constructs34023 +Node: Conditional Constructs36575 +Node: Command Grouping51715 +Node: Coprocesses53210 +Node: GNU Parallel55899 +Node: Shell Functions56820 +Node: Shell Parameters65271 +Node: Positional Parameters70175 +Node: Special Parameters71268 +Node: Shell Expansions74732 +Node: Brace Expansion76924 +Node: Tilde Expansion80263 +Node: Shell Parameter Expansion83221 +Node: Command Substitution103871 +Node: Arithmetic Expansion107725 +Node: Process Substitution108904 +Node: Word Splitting110015 +Node: Filename Expansion112462 +Node: Pattern Matching115689 +Node: Quote Removal121458 +Node: Redirections121765 +Node: Executing Commands132024 +Node: Simple Command Expansion132694 +Node: Command Search and Execution134805 +Node: Command Execution Environment137252 +Node: Environment140781 +Node: Exit Status142687 +Node: Signals144749 +Node: Shell Scripts149700 +Node: Shell Builtin Commands153001 +Node: Bourne Shell Builtins155345 +Node: Bash Builtins182067 +Node: Modifying Shell Behavior219806 +Node: The Set Builtin220151 +Node: The Shopt Builtin232148 +Node: Special Builtins249204 +Node: Shell Variables250196 +Node: Bourne Shell Variables250633 +Node: Bash Variables253144 +Node: Bash Features292431 +Node: Invoking Bash293448 +Node: Bash Startup Files300035 +Node: Interactive Shells305280 +Node: What is an Interactive Shell?305691 +Node: Is this Shell Interactive?306356 +Node: Interactive Shell Behavior307183 +Node: Bash Conditional Expressions310947 +Node: Shell Arithmetic316367 +Node: Aliases319697 +Node: Arrays322834 +Node: The Directory Stack330540 +Node: Directory Stack Builtins331340 +Node: Controlling the Prompt335788 +Node: The Restricted Shell338675 +Node: Bash POSIX Mode341771 +Node: Shell Compatibility Mode361590 +Node: Job Control370600 +Node: Job Control Basics371060 +Node: Job Control Builtins377431 +Node: Job Control Variables384222 +Node: Command Line Editing385456 +Node: Introduction and Notation387162 +Node: Readline Interaction389517 +Node: Readline Bare Essentials390708 +Node: Readline Movement Commands392519 +Node: Readline Killing Commands393518 +Node: Readline Arguments395544 +Node: Searching396637 +Node: Readline Init File398883 +Node: Readline Init File Syntax400189 +Node: Conditional Init Constructs427143 +Node: Sample Init File431531 +Node: Bindable Readline Commands434654 +Node: Commands For Moving436195 +Node: Commands For History438662 +Node: Commands For Text444056 +Node: Commands For Killing448184 +Node: Numeric Arguments450975 +Node: Commands For Completion452130 +Node: Keyboard Macros457829 +Node: Miscellaneous Commands458533 +Node: Readline vi Mode466079 +Node: Programmable Completion467059 +Node: Programmable Completion Builtins476798 +Node: A Programmable Completion Example488538 +Node: Using History Interactively493886 +Node: Bash History Facilities494570 +Node: Bash History Builtins498308 +Node: History Interaction505906 +Node: Event Designators510859 +Node: Word Designators512440 +Node: Modifiers514835 +Node: Installing Bash516775 +Node: Basic Installation517894 +Node: Compilers and Options521773 +Node: Compiling For Multiple Architectures522526 +Node: Installation Names524282 +Node: Specifying the System Type526519 +Node: Sharing Defaults527268 +Node: Operation Controls527985 +Node: Optional Features529007 +Node: Reporting Bugs541733 +Node: Major Differences From The Bourne Shell543093 +Node: GNU Free Documentation License564523 +Node: Indexes589703 +Node: Builtin Index590157 +Node: Reserved Word Index597258 +Node: Variable Index599706 +Node: Function Index617122 +Node: Concept Index631258  End Tag Table diff --git a/doc/bashref.texi b/doc/bashref.texi index 20671707d..903fef258 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -9707,6 +9707,13 @@ the @code{command} builtin or another non-special builtin fails. There is ambiguity in @sc{posix} about this. @end ignore +@item +Bash does not perform redirections before expanding variable assignments +preceding a simple command; it does not allow the redirections access to +the results of the variable assignments, but any side effects of expanding +the redirections take place first. +If compiled in @i{strict posix} mode, Bash performs redirections first. + @item As noted above, Bash requires the @code{xpg_echo} option to be enabled for the @code{echo} builtin to be fully conformant. diff --git a/doc/version.texi b/doc/version.texi index c3a5142a8..67d46a641 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -2,10 +2,10 @@ Copyright (C) 1988-2026 Free Software Foundation, Inc. @end ignore -@set LASTCHANGE Wed Jan 14 15:46:16 EST 2026 +@set LASTCHANGE Fri Feb 27 12:23:35 EST 2026 @set EDITION 5.3 @set VERSION 5.3 -@set UPDATED 14 January 2026 -@set UPDATED-MONTH January 2026 +@set UPDATED 27 February 2026 +@set UPDATED-MONTH February 2026 diff --git a/execute_cmd.c b/execute_cmd.c index f7fbd71f1..2e3df00f4 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -106,6 +106,7 @@ extern int errno; # include /* mbschr */ #endif +extern WORD_LIST *subst_assign_varlist; extern int command_string_index; extern char *the_printed_command; extern time_t shell_start_time; @@ -4272,10 +4273,15 @@ execute_null_command (REDIRECT *redirects, int pipe_in, int pipe_out, int async) if (code) exit (EXECUTION_FAILURE); - if (do_redirections (redirects, RX_ACTIVE) == 0) - exit (EXECUTION_SUCCESS); - else + if (do_redirections (redirects, RX_ACTIVE) != 0) exit (EXECUTION_FAILURE); + +#if defined (STRICT_POSIX) + if (posixly_correct) + exit (subst_assign_varlist ? expand_assignment_statements ((char *)NULL, 1) : EXECUTION_SUCCESS); + else +#endif + exit (EXECUTION_SUCCESS); } else { @@ -4300,6 +4306,11 @@ execute_null_command (REDIRECT *redirects, int pipe_in, int pipe_out, int async) cleanup_redirects (redirection_undo_list); redirection_undo_list = (REDIRECT *)NULL; +#if defined (STRICT_POSIX) + if (r == 0 && posixly_correct && subst_assign_varlist) + expand_assignment_statements ((char *)NULL, 1); +#endif + if (r != 0) return (EXECUTION_FAILURE); else if (last_command_subst_pid != NO_PID) @@ -5608,6 +5619,11 @@ execute_subshell_builtin_or_function (WORD_LIST *words, REDIRECT *redirects, add_unwind_protect (uw_cleanup_redirects, (char *)saved_undo_list); } +#if defined (STRICT_POSIX) + if (posixly_correct && subst_assign_varlist) + expand_assignment_statements (this_command_name, 0); +#endif + if (builtin) { int subshell_exit_value; @@ -5743,6 +5759,11 @@ execute_builtin_or_function (WORD_LIST *words, add_unwind_protect (uw_cleanup_redirects, (char *)saved_undo_list); } +#if defined (STRICT_POSIX) + if (posixly_correct && subst_assign_varlist) + expand_assignment_statements (this_command_name, 0); +#endif + if (builtin) result = execute_builtin (builtin, words, flags, 0); else @@ -5920,8 +5941,13 @@ execute_disk_command (WORD_LIST *words, REDIRECT *redirects, char *command_line, if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE && (subshell_environment & SUBSHELL_PIPE) == 0) adjust_shell_level (-1); - maybe_make_export_env (); - put_command_name_into_env (command); +#if defined (STRICT_POSIX) + if (posixly_correct == 0 || subst_assign_varlist == 0) /* Done below. */ +#endif + { + maybe_make_export_env (); + put_command_name_into_env (command); + } } else if (command == 0 && notfound_str == 0) /* make sure */ init_notfound_str (); @@ -6001,9 +6027,20 @@ execute_disk_command (WORD_LIST *words, REDIRECT *redirects, char *command_line, exit (EXECUTION_FAILURE); } +#if defined (STRICT_POSIX) + if (posixly_correct && subst_assign_varlist) + { + expand_assignment_statements (command, 0); + + maybe_make_export_env (); + put_command_name_into_env (command); + } +#endif + #if defined (PROCESS_SUBSTITUTION) && !defined (HAVE_DEV_FD) /* This should only contain FIFOs created as part of redirection - expansion. */ + expansion and expanding the rhs of assignment statements in + posix mode. */ unlink_all_fifos (); #endif diff --git a/m4/environ.m4 b/m4/environ.m4 new file mode 100644 index 000000000..5c0644ab9 --- /dev/null +++ b/m4/environ.m4 @@ -0,0 +1,48 @@ +# environ.m4 +# serial 8 +dnl Copyright (C) 2001-2004, 2006-2026 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl This file is offered as-is, without any warranty. + +AC_DEFUN_ONCE([gl_ENVIRON], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + dnl Persuade glibc to declare environ. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_HEADERS_ONCE([unistd.h]) + gt_CHECK_VAR_DECL( + [#if HAVE_UNISTD_H + #include + #endif + /* mingw, BeOS, Haiku declare environ in , not in . */ + #include + ], + [environ]) + if test $gt_cv_var_environ_declaration != yes; then + HAVE_DECL_ENVIRON=0 + fi +]) + +# Check if a variable is properly declared. +# gt_CHECK_VAR_DECL(includes,variable) +AC_DEFUN([gt_CHECK_VAR_DECL], +[ + define([gt_cv_var], [gt_cv_var_]$2[_declaration]) + AC_CACHE_CHECK([if $2 is properly declared], [gt_cv_var], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[$1 + typedef struct { int foo; } foo_t; + extern foo_t $2;]], + [[$2.foo = 1;]])], + [gt_cv_var=no], + [gt_cv_var=yes])]) + if test $gt_cv_var = yes; then + AC_DEFINE([HAVE_]m4_translit($2, [a-z], [A-Z])[_DECL], 1, + [Define if you have the declaration of $2.]) + fi + undefine([gt_cv_var]) +]) diff --git a/print_cmd.c b/print_cmd.c index 17b058e47..d6adc37cb 100644 --- a/print_cmd.c +++ b/print_cmd.c @@ -843,7 +843,7 @@ print_if_command (IF_COM *if_command) semicolon (); if (was_heredoc) { - indent (indentation_amount); + indent (indentation); cprintf ("then\n"); was_heredoc = 0; } diff --git a/subst.c b/subst.c index 87637e690..67677d338 100644 --- a/subst.c +++ b/subst.c @@ -12722,10 +12722,12 @@ separate_out_assignments (WORD_LIST *tlist) #define WEXP_TILDEEXP 0x004 #define WEXP_PARAMEXP 0x008 #define WEXP_PATHEXP 0x010 +#define WEXP_DEFERVARS 0x020 /* All of the expansions, including variable assignments at the start of the list. */ #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP) +#define WEXP_POSIX (WEXP_ALL|WEXP_DEFERVARS) /* All of the expansions except variable assignments at the start of the list. */ @@ -12739,11 +12741,16 @@ separate_out_assignments (WORD_LIST *tlist) /* Take the list of words in LIST and do the various substitutions. Return a new list of words which is the expanded list, and without things like variable assignments. */ - +/* This is only called to expand the words of a simple command, so it can + pay attention to posix mode treatment of variable assignments. */ WORD_LIST * expand_words (WORD_LIST *list) { +#if defined (STRICT_POSIX) + return (expand_word_list_internal (list, posixly_correct ? WEXP_POSIX : WEXP_ALL)); +#else return (expand_word_list_internal (list, WEXP_ALL)); +#endif } /* Same as expand_words (), but doesn't hack variable or environment @@ -13404,7 +13411,7 @@ expand_word_list_internal (WORD_LIST *list, int eflags) garglist = new_list = separate_out_assignments (new_list); if (new_list == 0) { - if (subst_assign_varlist) + if (subst_assign_varlist && (eflags & WEXP_DEFERVARS) == 0) expand_assignment_statements ((char *)NULL, 1); return ((WORD_LIST *)NULL); @@ -13438,7 +13445,7 @@ expand_word_list_internal (WORD_LIST *list, int eflags) new_list = dequote_list (new_list); } - if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist) + if (((eflags & (WEXP_VARASSIGN|WEXP_DEFERVARS)) == WEXP_VARASSIGN) && subst_assign_varlist) expand_assignment_statements ((new_list && new_list->word) ? new_list->word->word : (char *)NULL, new_list == 0); return (new_list); diff --git a/subst.h b/subst.h index e7fdfe964..69f966e92 100644 --- a/subst.h +++ b/subst.h @@ -1,6 +1,6 @@ /* subst.h -- Names of externally visible functions in subst.c. */ -/* Copyright (C) 1993-2024 Free Software Foundation, Inc. +/* Copyright (C) 1993-2026 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. diff --git a/support/savedir/texi2html.debug b/support/savedir/texi2html.debug deleted file mode 100755 index dbe15cd2d..000000000 --- a/support/savedir/texi2html.debug +++ /dev/null @@ -1,5439 +0,0 @@ -#! /usr/bin/perl -'di '; -'ig 00 '; -#+############################################################################## -# -# texi2html: Program to transform Texinfo documents to HTML -# -# Copyright (C) 1999, 2000 Free Software Foundation, Inc. -# -# This program 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 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -#-############################################################################## - -# This requires perl version 5 or higher -require 5.0; - -#++############################################################################## -# -# NOTE FOR DEBUGGING THIS SCRIPT: -# You can run 'perl texi2html.pl' directly, provided you have -# the environment variable T2H_HOME set to the directory containing -# the texi2html.init file -# -#--############################################################################## - -# CVS version: -# $Id: texi2html.pl,v 1.55 2000/07/27 14:39:41 obachman Exp $ - -# Homepage: -$T2H_HOMEPAGE = < (original author) - Karl Berry - Olaf Bachmann - and many others. -Maintained by: Olaf Bachmann -Send bugs and suggestions to -EOT - -# Version: set in configure.in -$THISVERSION = '1.64'; -$THISPROG = "texi2html $THISVERSION"; # program name and version - -# The man page for this program is included at the end of this file and can be -# viewed using the command 'nroff -man texi2html'. - -# Identity: - -$T2H_TODAY = &pretty_date; # like "20 September 1993" -# the eval prevents this from breaking on system which do not have -# a proper getpwuid implemented -eval { ($T2H_USER = (getpwuid ($<))[6]) =~ s/,.*//;}; # Who am i - -#+++############################################################################ -# # -# Initialization # -# Pasted content of File $(srcdir)/texi2html.init: Default initializations # -# # -#---############################################################################ - -# leave this within comments, and keep the require statement -# This way, you can directly run texi2html.pl, if $ENV{T2H_HOME}/texi2html.init -# exists. - -# -# -*-perl-*- -###################################################################### -# File: texi2html.init -# -# Sets default values for command-line arguments and for various customizable -# procedures -# -# A copy of this file is pasted into the beginning of texi2html by -# 'make texi2html' -# -# Copy this file and make changes to it, if you like. -# Afterwards, either, load it with command-line option -init_file -# -# $Id: texi2html.init,v 1.34 2000/07/27 14:09:02 obachman Exp $ - -###################################################################### -# stuff which can also be set by command-line options -# -# -# Note: values set here, overwrite values set by the command-line -# options before -init_file and might still be overwritten by -# command-line arguments following the -init_file option -# - -# T2H_OPTIONS is a hash whose keys are the (long) names of valid -# command-line options and whose values are a hash with the following keys: -# type ==> one of !|=i|:i|=s|:s (see GetOpt::Long for more info) -# linkage ==> ref to scalar, array, or subroutine (see GetOpt::Long for more info) -# verbose ==> short description of option (displayed by -h) -# noHelp ==> if 1 -> for "not so important options": only print description on -h 1 -# 2 -> for obsolete options: only print description on -h 2 - -$T2H_DEBUG = 0; -$T2H_OPTIONS -> {debug} = -{ - type => '=i', - linkage => \$main::T2H_DEBUG, - verbose => 'output HTML with debuging information', -}; - -$T2H_DOCTYPE = ''; -$T2H_OPTIONS -> {doctype} = -{ - type => '=s', - linkage => \$main::T2H_DOCTYPE, - verbose => 'document type which is output in header of HTML files', - noHelp => 1 -}; - -$T2H_CHECK = 0; -$T2H_OPTIONS -> {check} = -{ - type => '!', - linkage => \$main::T2H_CHECK, - verbose => 'if set, only check files and output all things that may be Texinfo commands', - noHelp => 1 -}; - -# -expand -# if set to "tex" (or, "info") expand @iftex and @tex (or, @ifinfo) sections -# else, neither expand @iftex, @tex, nor @ifinfo sections -$T2H_EXPAND = "info"; -$T2H_OPTIONS -> {expand} = -{ - type => '=s', - linkage => \$T2H_EXPAND, - verbose => 'Expand info|tex|none section of texinfo source', -}; - -# - glossary -#if set, uses section named `Footnotes' for glossary -$T2H_USE_GLOSSARY = 0; -T2H_OPTIONS -> {glossary} = -{ - type => '!', - linkage => \$T2H_USE_GLOSSARY, - verbose => "if set, uses section named `Footnotes' for glossary", - noHelp => 1, -}; - - -# -invisible -# $T2H_INVISIBLE_MARK is the text used to create invisible destination -# anchors for index links (you can for instance use the invisible.xbm -# file shipped with this program). This is a workaround for a known -# bug of many WWW browsers, including netscape. -# For me, it works fine without it -- on the contrary: if there, it -# inserts space between headers and start of text (obachman 3/99) -$T2H_INVISIBLE_MARK = ''; -# $T2H_INVISIBLE_MARK = ' '; -$T2H_OPTIONS -> {invisible} = -{ - type => '=s', - linkage => \$T2H_INVISIBLE_MARK, - verbose => 'use text in invisble anchot', - noHelp => 1, -}; - -# -iso -# if set, ISO8879 characters are used for special symbols (like copyright, etc) -$T2H_USE_ISO = 0; -$T2H_OPTIONS -> {iso} = -{ - type => 'iso', - linkage => \$T2H_USE_ISO, - verbose => 'if set, ISO8879 characters are used for special symbols (like copyright, etc)', - noHelp => 1, -}; - -# -I -# list directories where @include files are searched for (besides the -# directory of the doc file) additional '-I' args add to this list -@T2H_INCLUDE_DIRS = ("."); -$T2H_OPTIONS -> {I} = -{ - type => '=s', - linkage => \@T2H_INCLUDE_DIRS, - verbose => 'append $s to the @include search path', -}; - -# -top_file -# uses file of this name for top-level file -# extension is manipulated appropriately, if necessary. -# If empty, .html is used -# Typically, you would set this to "index.html". -$T2H_TOP_FILE = ''; -$T2H_OPTIONS -> {top_file} = -{ - type => '=s', - linkage => \$T2H_TOP_FILE, - verbose => 'use $s as top file, instead of .html', -}; - - -# -toc_file -# uses file of this name for table of contents file -# extension is manipulated appropriately, if necessary. -# If empty, _toc.html is used -$T2H_TOC_FILE = ''; -$T2H_OPTIONS -> {toc_file} = -{ - type => '=s', - linkage => \$T2H_TOC_FILE, - verbose => 'use $s as ToC file, instead of _toc.html', -}; - -# -frames -# if set, output two additional files which use HTML 4.0 "frames". -$T2H_FRAMES = 0; -$T2H_OPTIONS -> {frames} = -{ - type => '!', - linkage => \$T2H_FRAMES, - verbose => 'output files which use HTML 4.0 frames (experimental)', - noHelp => 1, -}; - - -# -menu | -nomenu -# if set, show the Texinfo menus -$T2H_SHOW_MENU = 1; -$T2H_OPTIONS -> {menu} = -{ - type => '!', - linkage => \$T2H_SHOW_MENU, - verbose => 'ouput Texinfo menus', -}; - -# -number | -nonumber -# if set, number sections and show section names and numbers in references -# and menus -$T2H_NUMBER_SECTIONS = 1; -$T2H_OPTIONS -> {number} = -{ - type => '!', - linkage => \$T2H_NUMBER_SECTIONS, - verbose => 'use numbered sections' -}; - -# if set, and T2H_NUMBER_SECTIONS is set, then use node names in menu -# entries, instead of section names -$T2H_NODE_NAME_IN_MENU = 0; - -# if set and menu entry equals menu descr, then do not print menu descr. -# Likewise, if node name equals entry name, do not print entry name. -$T2H_AVOID_MENU_REDUNDANCY = 1; - -# -split section|chapter|none -# if set to 'section' (resp. 'chapter') create one html file per (sub)section -# (resp. chapter) and separate pages for Top, ToC, Overview, Index, -# Glossary, About. -# otherwise, create monolithic html file which contains whole document -#$T2H_SPLIT = 'section'; -$T2H_SPLIT = ''; -$T2H_OPTIONS -> {split} = -{ - type => '=s', - linkage => \$T2H_SPLIT, - verbose => 'split document on section|chapter else no splitting', -}; - -# -section_navigation|-no-section_navigation -# if set, then navigation panels are printed at the beginning of each section -# and, possibly at the end (depending on whether or not there were more than -# $T2H_WORDS_IN_PAGE words on page -# This is most useful if you do not want to have section navigation -# on -split chapter -$T2H_SECTION_NAVIGATION = 1; -$T2H_OPTIONS -> {sec_nav} = -{ - type => '!', - linkage => \$T2H_SECTION_NAVIGATION, - verbose => 'output navigation panels for each section', -}; - -# -subdir -# if set put result files in this directory -# if not set result files are put into current directory -#$T2H_SUBDIR = 'html'; -$T2H_SUBDIR = ''; -$T2H_OPTIONS -> {subdir} = -{ - type => '=s', - linkage => \$T2H_SUBDIR, - verbose => 'put HTML files in directory $s, instead of $cwd', -}; - -# -short_extn -# If this is set all HTML file will have extension ".htm" instead of -# ".html". This is helpful when shipping the document to PC systems. -$T2H_SHORTEXTN = 0; -$T2H_OPTIONS -> {short_ext} = -{ - type => '!', - linkage => \$T2H_SHORTEXTN, - verbose => 'use "htm" extension for output HTML files', -}; - - -# -prefix -# Set the output file prefix, prepended to all .html, .gif and .pl files. -# By default, this is the basename of the document -$T2H_PREFIX = ''; -$T2H_OPTIONS -> {prefix} = -{ - type => '=s', - linkage => \$T2H_PREFIX, - verbose => 'use as prefix for output files, instead of ', -}; - -# -o filename -# If set, generate monolithic document output html into $filename -$T2H_OUT = ''; -$T2H_OPTIONS -> {out_file} = -{ - type => '=s', - linkage => sub {$main::T2H_OUT = @_[1]; $T2H_SPLIT = '';}, - verbose => 'if set, all HTML output goes into file $s', -}; - -# -short_ref -#if set cross-references are given without section numbers -$T2H_SHORT_REF = ''; -$T2H_OPTIONS -> {short_ref} = -{ - type => '!', - linkage => \$T2H_SHORT_REF, - verbose => 'if set, references are without section numbers', -}; - -# -idx_sum -# if value is set, then for each @prinindex $what -# $docu_name_$what.idx is created which contains lines of the form -# $key\t$ref sorted alphabetically (case matters) -$T2H_IDX_SUMMARY = 0; -$T2H_OPTIONS -> {idx_sum} = -{ - type => '!', - linkage => \$T2H_IDX_SUMMARY, - verbose => 'if set, also output index summary', - noHelp => 1, -}; - -# -verbose -# if set, chatter about what we are doing -$T2H_VERBOSE = ''; -$T2H_OPTIONS -> {Verbose} = -{ - type => '!', - linkage => \$T2H_VERBOSE, - verbose => 'print progress info to stdout', -}; - -# -lang -# For page titles use $T2H_WORDS->{$T2H_LANG}->{...} as title. -# To add a new language, supply list of titles (see $T2H_WORDS below). -# and use ISO 639 language codes (see e.g. perl module Locale-Codes-1.02 -# for definitions) -# Default's to 'en' if not set or no @documentlanguage is specified -$T2H_LANG = ''; -$T2H_OPTIONS -> {lang} = -{ - type => '=s', - linkage => sub {SetDocumentLanguage($_[1])}, - verbose => 'use $s as document language (ISO 639 encoding)', -}; - -# -l2h -# if set, uses latex2html for generation of math content -$T2H_L2H = ''; -$T2H_OPTIONS -> {l2h} = -{ - type => '!', - linkage => \$T2H_L2H, - verbose => 'if set, uses latex2html for @math and @tex', -}; - -###################### -# The following options are only relevant if $T2H_L2H is set -# -# -l2h_l2h -# name/location of latex2html progam -$T2H_L2H_L2H = "latex2html"; -$T2H_OPTIONS -> {l2h_l2h} = -{ - type => '=s', - linkage => \$T2H_L2H_L2H, - verbose => 'program to use for latex2html translation', - noHelp => 1, -}; - -# -l2h_skip -# if set, skips actual call to latex2html tries to reuse previously generated -# content, instead -$T2H_L2H_SKIP = ''; -$T2H_OPTIONS -> {l2h_skip} = -{ - type => '!', - linkage => \$T2H_L2H_SKIP, - verbose => 'if set, tries to reuse previously latex2html output', - noHelp => 1, -}; - -# -l2h_tmp -# if set, l2h uses this directory for temporarary files. The path -# leading to this directory may not contain a dot (i.e., a "."), -# otherwise, l2h will fail -$T2H_L2H_TMP = ''; -$T2H_OPTIONS -> {l2h_tmp} = -{ - type => '=s', - linkage => \$T2H_L2H_TMP, - verbose => 'if set, uses $s as temporary latex2html directory', - noHelp => 1, -}; - -# if set, cleans intermediate files (they all have the prefix $doc_l2h_) -# of l2h -$T2H_L2H_CLEAN = 1; -$T2H_OPTIONS -> {l2h_clean} = -{ - type => '!', - linkage => \$T2H_L2H_CLEAN, - verbose => 'if set, do not keep intermediate latex2html files for later reuse', - noHelp => 1, -}; - -$T2H_OPTIONS -> {D} = -{ - type => '=s', - linkage => sub {$main::value{@_[1]} = 1;}, - verbose => 'equivalent to Texinfo "@set $s 1"', - noHelp => 1, -}; - -$T2H_OPTIONS -> {init_file} = -{ - type => '=s', - linkage => \&LoadInitFile, - verbose => 'load init file $s' -}; - - -############################################################################## -# -# The following can only be set in the init file -# -############################################################################## - -# if set, center @image by default -# otherwise, do not center by default -$T2H_CENTER_IMAGE = 1; - -# used as identation for block enclosing command @example, etc -# If not empty, must be enclosed in -$T2H_EXAMPLE_INDENT_CELL = ' '; -# same as above, only for @small -$T2H_SMALL_EXAMPLE_INDENT_CELL = ' '; -# font size for @small -$T2H_SMALL_FONT_SIZE = '-1'; - -# if non-empty, and no @..heading appeared in Top node, then -# use this as header for top node/section, otherwise use value of -# @settitle or @shorttitle (in that order) -$T2H_TOP_HEADING = ''; - -# if set, use this chapter for 'Index' button, else -# use first chapter whose name matches 'index' (case insensitive) -$T2H_INDEX_CHAPTER = ''; - -# if set and $T2H_SPLIT is set, then split index pages at the next letter -# after they have more than that many entries -$T2H_SPLIT_INDEX = 100; - -# if set (e.g., to index.html) replace hrefs to this file -# (i.e., to index.html) by ./ -$T2H_HREF_DIR_INSTEAD_FILE = ''; - -######################################################################## -# Language dependencies: -# To add a new language extend T2H_WORDS hash and create $T2H_<...>_WORDS hash -# To redefine one word, simply do: -# $T2H_WORDS->{}->{} = 'whatever' in your personal init file. -# -$T2H_WORDS_EN = -{ - # titles of pages - 'ToC_Title' => 'Table of Contents', - 'Overview_Title' => 'Short Table of Contents', - 'Index_Title' => 'Index', - 'About_Title' => 'About this document', - 'Footnotes_Title' => 'Footnotes', - 'See' => 'See', - 'see' => 'see', - 'section' => 'section', -# If necessary, we could extend this as follows: -# # text for buttons -# 'Top_Button' => 'Top', -# 'ToC_Button' => 'Contents', -# 'Overview_Button' => 'Overview', -# 'Index_button' => 'Index', -# 'Back_Button' => 'Back', -# 'FastBack_Button' => 'FastBack', -# 'Prev_Button' => 'Prev', -# 'Up_Button' => 'Up', -# 'Next_Button' => 'Next', -# 'Forward_Button' =>'Forward', -# 'FastWorward_Button' => 'FastForward', -# 'First_Button' => 'First', -# 'Last_Button' => 'Last', -# 'About_Button' => 'About' -}; - -$T2H_WORD_DE = -{ - 'ToC_Title' => 'Inhaltsverzeichniss', - 'Overview_Title' => 'Kurzes Inhaltsverzeichniss', - 'Index_Title' => 'Index', - 'About_Title' => 'Über dieses Dokument', - 'Footnotes_Title' => 'Fußnoten', - 'See' => 'Siehe', - 'see' => 'siehe', - 'section' => 'Abschnitt', -}; - -$T2H_WORD_NL = -{ - 'ToC_Title' => 'Inhoudsopgave', - 'Overview_Title' => 'Korte inhoudsopgave', - 'Index_Title' => 'Index', #Not sure ;-) - 'About_Title' => 'No translation available!', #No translation available! - 'Footnotes_Title' => 'No translation available!', #No translation available! - 'See' => 'Zie', - 'see' => 'zie', - 'section' => 'sectie', -}; - -$T2H_WORD_ES = -{ - 'ToC_Title' => 'índice General', - 'Overview_Title' => 'Resumen del Contenido', - 'Index_Title' => 'Index', #Not sure ;-) - 'About_Title' => 'No translation available!', #No translation available! - 'Footnotes_Title' => 'Fußnoten', - 'See' => 'Véase', - 'see' => 'véase', - 'section' => 'sección', -}; - -$T2H_WORD_NO = -{ - 'ToC_Title' => 'Innholdsfortegnelse', - 'Overview_Title' => 'Kort innholdsfortegnelse', - 'Index_Title' => 'Indeks', #Not sure ;-) - 'About_Title' => 'No translation available!', #No translation available! - 'Footnotes_Title' => 'No translation available!', - 'See' => 'Se', - 'see' => 'se', - 'section' => 'avsnitt', -}; - -$T2H_WORD_PT = -{ - 'ToC_Title' => 'Sumário', - 'Overview_Title' => 'Breve Sumário', - 'Index_Title' => 'Índice', #Not sure ;-) - 'About_Title' => 'No translation available!', #No translation available! - 'Footnotes_Title' => 'No translation available!', - 'See' => 'Veja', - 'see' => 'veja', - 'section' => 'Seção', -}; - -$T2H_WORDS = -{ - 'en' => $T2H_WORDS_EN, - 'de' => $T2H_WORDS_DE, - 'nl' => $T2H_WORDS_NL, - 'es' => $T2H_WORDS_ES, - 'no' => $T2H_WORDS_NO, - 'pt' => $T2H_WORDS_PT -}; - -@MONTH_NAMES_EN = -( - 'January', 'February', 'March', 'April', 'May', - 'June', 'July', 'August', 'September', 'October', - 'November', 'December' -); - -@MONTH_NAMES_DE = -( - 'Januar', 'Februar', 'März', 'April', 'Mai', - 'Juni', 'Juli', 'August', 'September', 'Oktober', - 'November', 'Dezember' -); - -@MONTH_NAMES_NL = -( - 'Januari', 'Februari', 'Maart', 'April', 'Mei', - 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', - 'November', 'December' -); - -@MONTH_NAMES_ES = -( - 'enero', 'febrero', 'marzo', 'abril', 'mayo', - 'junio', 'julio', 'agosto', 'septiembre', 'octubre', - 'noviembre', 'diciembre' -); - -@MONTH_NAMES_NO = -( - - 'januar', 'februar', 'mars', 'april', 'mai', - 'juni', 'juli', 'august', 'september', 'oktober', - 'november', 'desember' -); - -@MONTH_NAMES_PT = -( - 'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', - 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', - 'Novembro', 'Dezembro' -); - - -$MONTH_NAMES = -{ - 'en' => \@MONTH_NAMES_EN, - 'de' => \@MONTH_NAMES_DE, - 'es' => \@MONTH_NAMES_ES, - 'nl' => \@MONTH_NAMES_NL, - 'no' => \@MONTH_NAMES_NO, - 'pt' => \@MONTH_NAMES_PT -}; -######################################################################## -# Control of Page layout: -# You can make changes of the Page layout at two levels: -# 1.) For small changes, it is often enough to change the value of -# some global string/hash/array variables -# 2.) For larger changes, reimplement one of the T2H_DEFAULT_* routines, -# give them another name, and assign them to the respective -# $T2H_ variable. - -# As a general interface, the hashes T2H_HREF, T2H_NAME, T2H_NODE hold -# href, html-name, node-name of -# This -- current section (resp. html page) -# Top -- top page ($T2H_TOP_FILE) -# Contents -- Table of contents -# Overview -- Short table of contents -# Index -- Index page -# About -- page which explain "navigation buttons" -# First -- first node -# Last -- last node -# -# Whether or not the following hash values are set, depends on the context -# (all values are w.r.t. 'This' section) -# Next -- next node of texinfo -# Prev -- previous node of texinfo -# Up -- up node of texinfo -# Forward -- next node in reading order -# Back -- previous node in reading order -# FastForward -- if leave node, up and next, else next node -# FastBackward-- if leave node, up and prev, else prev node -# -# Furthermore, the following global variabels are set: -# $T2H_THISDOC{title} -- title as set by @setttile -# $T2H_THISDOC{fulltitle} -- full title as set by @title... -# $T2H_THISDOC{subtitle} -- subtitle as set by @subtitle -# $T2H_THISDOC{author} -- author as set by @author -# -# and pointer to arrays of lines which need to be printed by t2h_print_lines -# $T2H_OVERVIEW -- lines of short table of contents -# $T2H_TOC -- lines of table of contents -# $T2H_TOP -- lines of Top texinfo node -# $T2H_THIS_SECTION -- lines of 'This' section - -# -# There are the following subs which control the layout: -# -$T2H_print_section = \&T2H_DEFAULT_print_section; -$T2H_print_Top_header = \&T2H_DEFAULT_print_Top_header; -$T2H_print_Top_footer = \&T2H_DEFAULT_print_Top_footer; -$T2H_print_Top = \&T2H_DEFAULT_print_Top; -$T2H_print_Toc = \&T2H_DEFAULT_print_Toc; -$T2H_print_Overview = \&T2H_DEFAULT_print_Overview; -$T2H_print_Footnotes = \&T2H_DEFAULT_print_Footnotes; -$T2H_print_About = \&T2H_DEFAULT_print_About; -$T2H_print_misc_header = \&T2H_DEFAULT_print_misc_header; -$T2H_print_misc_footer = \&T2H_DEFAULT_print_misc_footer; -$T2H_print_misc = \&T2H_DEFAULT_print_misc; -$T2H_print_chapter_header = \&T2H_DEFAULT_print_chapter_header; -$T2H_print_chapter_footer = \&T2H_DEFAULT_print_chapter_footer; -$T2H_print_page_head = \&T2H_DEFAULT_print_page_head; -$T2H_print_page_foot = \&T2H_DEFAULT_print_page_foot; -$T2H_print_head_navigation = \&T2H_DEFAULT_print_head_navigation; -$T2H_print_foot_navigation = \&T2H_DEFAULT_print_foot_navigation; -$T2H_button_icon_img = \&T2H_DEFAULT_button_icon_img; -$T2H_print_navigation = \&T2H_DEFAULT_print_navigation; -$T2H_about_body = \&T2H_DEFAULT_about_body; -$T2H_print_frame = \&T2H_DEFAULT_print_frame; -$T2H_print_toc_frame = \&T2H_DEFAULT_print_toc_frame; - -######################################################################## -# Layout for html for every sections -# -sub T2H_DEFAULT_print_section -{ - my $fh = shift; - local $T2H_BUTTONS = \@T2H_SECTION_BUTTONS; - &$T2H_print_head_navigation($fh) if $T2H_SECTION_NAVIGATION; - my $nw = t2h_print_lines($fh); - if ($T2H_SPLIT eq 'section' && $T2H_SECTION_NAVIGATION) - { - &$T2H_print_foot_navigation($fh, $nw); - } - else - { - print $fh '
' . "\n"; - } -} - -################################################################### -# Layout of top-page I recommend that you use @ifnothtml, @ifhtml, -# @html within the Top texinfo node to specify content of top-level -# page. -# -# If you enclose everything in @ifnothtml, then title, subtitle, -# author and overview is printed -# T2H_HREF of Next, Prev, Up, Forward, Back are not defined -# if $T2H_SPLIT then Top page is in its own html file -sub T2H_DEFAULT_print_Top_header -{ - &$T2H_print_page_head(@_) if $T2H_SPLIT; - t2h_print_label(@_); # this needs to be called, otherwise no label set - &$T2H_print_head_navigation(@_); -} -sub T2H_DEFAULT_print_Top_footer -{ - &$T2H_print_foot_navigation(@_); - &$T2H_print_page_foot(@_) if $T2H_SPLIT; -} -sub T2H_DEFAULT_print_Top -{ - my $fh = shift; - - # for redefining navigation buttons use: - # local $T2H_BUTTONS = [...]; - # as it is, 'Top', 'Contents', 'Index', 'About' are printed - local $T2H_BUTTONS = \@T2H_MISC_BUTTONS; - &$T2H_print_Top_header($fh); - if ($T2H_THIS_SECTION) - { - # if top-level node has content, then print it with extra header - print $fh "

$T2H_NAME{Top}

" - unless ($T2H_HAS_TOP_HEADING); - t2h_print_lines($fh, $T2H_THIS_SECTION) - } - else - { - # top-level node is fully enclosed in @ifnothtml - # print fulltitle, subtitle, author, Overview - print $fh - "
\n

" . - join("

\n

", split(/\n/, $T2H_THISDOC{fulltitle})) . - "

\n"; - print $fh "

$T2H_THISDOC{subtitle}

\n" if $T2H_THISDOC{subtitle}; - print $fh "$T2H_THISDOC{author}\n" if $T2H_THISDOC{author}; - print $fh < -
-

-

Overview:

-
-EOT - t2h_print_lines($fh, $T2H_OVERVIEW); - print $fh "
\n"; - } - &$T2H_print_Top_footer($fh); -} - -################################################################### -# Layout of Toc, Overview, and Footnotes pages -# By default, we use "normal" layout -# T2H_HREF of Next, Prev, Up, Forward, Back, etc are not defined -# use: local $T2H_BUTTONS = [...] to redefine navigation buttons -sub T2H_DEFAULT_print_Toc -{ - return &$T2H_print_misc(@_); -} -sub T2H_DEFAULT_print_Overview -{ - return &$T2H_print_misc(@_); -} -sub T2H_DEFAULT_print_Footnotes -{ - return &$T2H_print_misc(@_); -} -sub T2H_DEFAULT_print_About -{ - return &$T2H_print_misc(@_); -} - -sub T2H_DEFAULT_print_misc_header -{ - &$T2H_print_page_head(@_) if $T2H_SPLIT; - # this needs to be called, otherwise, no labels are set - t2h_print_label(@_); - &$T2H_print_head_navigation(@_); -} -sub T2H_DEFAULT_print_misc_footer -{ - &$T2H_print_foot_navigation(@_); - &$T2H_print_page_foot(@_) if $T2H_SPLIT; -} -sub T2H_DEFAULT_print_misc -{ - my $fh = shift; - local $T2H_BUTTONS = \@T2H_MISC_BUTTONS; - &$T2H_print_misc_header($fh); - print $fh "

$T2H_NAME{This}

\n"; - t2h_print_lines($fh); - &$T2H_print_misc_footer($fh); -} - -################################################################### -# chapter_header and chapter_footer are only called if -# T2H_SPLIT eq 'chapter' -# chapter_header: after print_page_header, before print_section -# chapter_footer: after print_section of last section, before print_page_footer -# -# If you want to get rid of navigation stuff after each section, -# redefine print_section such that it does not call print_navigation, -# and put print_navigation into print_chapter_header -@T2H_CHAPTER_BUTTONS = - ( - 'FastBack', 'FastForward', ' ', - ' ', ' ', ' ', ' ', - 'Top', 'Contents', 'Index', 'About', - ); - -sub T2H_DEFAULT_print_chapter_header -{ - # nothing to do there, by default - if (! $T2H_SECTION_NAVIGATION) - { - my $fh = shift; - local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS; - &$T2H_print_navigation($fh); - print $fh "\n
\n"; - } -} - -sub T2H_DEFAULT_print_chapter_footer -{ - local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS; - &$T2H_print_navigation(@_); -} -################################################################### -$T2H_TODAY = &pretty_date; # like "20 September 1993" - -sub pretty_date { - local($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst); - - ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); - $year += ($year < 70) ? 2000 : 1900; - # obachman: Let's do it as the Americans do - return($MONTH_NAMES->{$T2H_LANG}[$mon] . ", " . $mday . " " . $year); -} - - -################################################################### -# Layout of standard header and footer -# - -# Set the default body text, inserted between -###$T2H_BODYTEXT = 'LANG="EN" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"'; -$T2H_BODYTEXT = 'LANG="' . $T2H_LANG . '" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"'; -# text inserted after -$T2H_AFTER_BODY_OPEN = ''; -#text inserted before -$T2H_PRE_BODY_CLOSE = ''; -# this is used in footer -$T2H_ADDRESS = "by $T2H_USER " if $T2H_USER; -$T2H_ADDRESS .= "on $T2H_TODAY"; -# this is added inside after and some META NAME stuff -# can be used for <style> <script>, <meta> tags -$T2H_EXTRA_HEAD = ''; - -sub T2H_DEFAULT_print_page_head -{ - my $fh = shift; - my $longtitle = "$T2H_THISDOC{title}: $T2H_NAME{This}"; - print $fh <<EOT; -<HTML> -$T2H_DOCTYPE -<!-- Created on $T2H_TODAY by $THISPROG --> -<!-- -$T2H_AUTHORS ---> -<HEAD> -<TITLE>$longtitle - - - - - - -$T2H_EXTRA_HEAD - - - -$T2H_AFTER_BODY_OPEN -EOT -} - -sub T2H_DEFAULT_print_page_foot -{ - my $fh = shift; - print $fh < - -This document was generated -$T2H_ADDRESS -using texi2html -$T2H_PRE_BODY_CLOSE - - -EOT -} - -################################################################### -# Layout of navigation panel - -# if this is set, then a vertical navigation panel is used -$T2H_VERTICAL_HEAD_NAVIGATION = 0; -sub T2H_DEFAULT_print_head_navigation -{ - my $fh = shift; - if ($T2H_VERTICAL_HEAD_NAVIGATION) - { - print $fh < - - -EOT - } - &$T2H_print_navigation($fh, $T2H_VERTICAL_HEAD_NAVIGATION); - if ($T2H_VERTICAL_HEAD_NAVIGATION) - { - print $fh < - -EOT - } - elsif ($T2H_SPLIT eq 'section') - { - print $fh "
\n"; - } -} - -# Specifies the minimum page length required before a navigation panel -# is placed at the bottom of a page (the default is that of latex2html) -# T2H_THIS_WORDS_IN_PAGE holds number of words of current page -$T2H_WORDS_IN_PAGE = 300; -sub T2H_DEFAULT_print_foot_navigation -{ - my $fh = shift; - my $nwords = shift; - if ($T2H_VERTICAL_HEAD_NAVIGATION) - { - print $fh < - - -EOT - } - print $fh "
\n"; - &$T2H_print_navigation($fh) if ($nwords >= $T2H_WORDS_IN_PAGE) -} - -###################################################################### -# navigation panel -# -# specify in this array which "buttons" should appear in which order -# in the navigation panel for sections; use ' ' for empty buttons (space) -@T2H_SECTION_BUTTONS = - ( - 'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward', - ' ', ' ', ' ', ' ', - 'Top', 'Contents', 'Index', 'About', - ); - -# buttons for misc stuff -@T2H_MISC_BUTTONS = ('Top', 'Contents', 'Index', 'About'); - -# insert here name of icon images for buttons -# Icons are used, if $T2H_ICONS and resp. value are set -%T2H_ACTIVE_ICONS = - ( - 'Top', '', - 'Contents', '', - 'Overview', '', - 'Index', '', - 'Back', '', - 'FastBack', '', - 'Prev', '', - 'Up', '', - 'Next', '', - 'Forward', '', - 'FastForward', '', - 'About' , '', - 'First', '', - 'Last', '', - ' ', '' - ); - -# insert here name of icon images for these, if button is inactive -%T2H_PASSIVE_ICONS = - ( - 'Top', '', - 'Contents', '', - 'Overview', '', - 'Index', '', - 'Back', '', - 'FastBack', '', - 'Prev', '', - 'Up', '', - 'Next', '', - 'Forward', '', - 'FastForward', '', - 'About', '', - 'First', '', - 'Last', '', - ); - -# how to create IMG tag -sub T2H_DEFAULT_button_icon_img -{ - my $button = shift; - my $icon = shift; - my $name = shift; - return qq{$button: $name}; -} - -# Names of text as alternative for icons -%T2H_NAVIGATION_TEXT = - ( - 'Top', 'Top', - 'Contents', 'Contents', - 'Overview', 'Overview', - 'Index', 'Index', - ' ', '   ', - 'Back', ' < ', - 'FastBack', ' << ', - 'Prev', 'Prev', - 'Up', ' Up ', - 'Next', 'Next', - 'Forward', ' > ', - 'FastForward', ' >> ', - 'About', ' ? ', - 'First', ' |< ', - 'Last', ' >| ' - ); - -sub T2H_DEFAULT_print_navigation -{ - my $fh = shift; - my $vertical = shift; - my $spacing = 1; - print $fh "\n"; - - print $fh "" unless $vertical; - for $button (@$T2H_BUTTONS) - { - print $fh qq{\n} if $vertical; - print $fh qq{\n"; - print $fh "\n" if $vertical; - } - print $fh "" unless $vertical; - print $fh "
}; - - if (ref($button) eq 'CODE') - { - &$button($fh, $vertical); - } - elsif ($button eq ' ') - { # handle space button - print $fh - $T2H_ICONS && $T2H_ACTIVE_ICONS{' '} ? - &$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{' '}) : - $T2H_NAVIGATION_TEXT{' '}; - next; - } - elsif ($T2H_HREF{$button}) - { # button is active - print $fh - $T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ? # use icon ? - t2h_anchor('', $T2H_HREF{$button}, # yes - &$T2H_button_icon_img($button, - $T2H_ACTIVE_ICONS{$button}, - $T2H_NAME{$button})) - : # use text - "[" . - t2h_anchor('', $T2H_HREF{$button}, $T2H_NAVIGATION_TEXT{$button}) . - "]"; - } - else - { # button is passive - print $fh - $T2H_ICONS && $T2H_PASSIVE_ICONS{$button} ? - &$T2H_button_icon_img($button, - $T2H_PASSIVE_ICONS{$button}, - $T2H_NAME{$button}) : - - "[" . $T2H_NAVIGATION_TEXT{$button} . "]"; - } - print $fh "
\n"; -} - -###################################################################### -# Frames: this is from "Richard Y. Kim" -# Should be improved to be more conforming to other _print* functions - -sub T2H_DEFAULT_print_frame -{ - my $fh = shift; - print $fh < -$T2H_THISDOC{title} - - - - - -EOT -} - -sub T2H_DEFAULT_print_toc_frame -{ - my $fh = shift; - &$T2H_print_page_head($fh); - print $fh <Content -EOT - print $fh map {s/HREF=/target=\"main\" HREF=/; $_;} @stoc_lines; - print $fh "\n"; -} - -###################################################################### -# About page -# - -# T2H_PRE_ABOUT might be a function -$T2H_PRE_ABOUT = <texi2html -

-EOT -$T2H_AFTER_ABOUT = ''; - -sub T2H_DEFAULT_about_body -{ - my $about; - if (ref($T2H_PRE_ABOUT) eq 'CODE') - { - $about = &$T2H_PRE_ABOUT(); - } - else - { - $about = $T2H_PRE_ABOUT; - } - $about .= <

- - - - - - - -EOT - - for $button (@T2H_SECTION_BUTTONS) - { - next if $button eq ' ' || ref($button) eq 'CODE'; - $about .= < - - - - -EOT - } - - $about .= < -

-where the Example assumes that the current position -is at Subsubsection One-Two-Three of a document of -the following structure: -
    -
  • 1. Section One
  • -
      -
    • 1.1 Subsection One-One
    • -
        -
      • ...
      • -
      -
    • 1.2 Subsection One-Two
    • -
        -
      • 1.2.1 Subsubsection One-Two-One -
      • 1.2.2 Subsubsection One-Two-Two -
      • 1.2.3 Subsubsection One-Two-Three     -<== Current Position -
      • 1.2.4 Subsubsection One-Two-Four -
      -
    • 1.3 Subsection One-Three
    • -
        -
      • ...
      • -
      -
    • 1.4 Subsection One-Four
    • -
    -
-$T2H_AFTER_ABOUT -EOT - return $about; -} - - -%T2H_BUTTONS_GOTO = - ( - 'Top', 'cover (top) of document', - 'Contents', 'table of contents', - 'Overview', 'short table of contents', - 'Index', 'concept index', - 'Back', 'previous section in reading order', - 'FastBack', 'previous or up-and-previous section ', - 'Prev', 'previous section same level', - 'Up', 'up section', - 'Next', 'next section same level', - 'Forward', 'next section in reading order', - 'FastForward', 'next or up-and-next section', - 'About' , 'this page', - 'First', 'first section in reading order', - 'Last', 'last section in reading order', - ); - -%T2H_BUTTONS_EXAMPLE = -( - 'Top', '   ', - 'Contents', '   ', - 'Overview', '   ', - 'Index', '   ', - 'Back', '1.2.2', - 'FastBack', '1.1', - 'Prev', '1.2.2', - 'Up', '1.2', - 'Next', '1.2.4', - 'Forward', '1.2.4', - 'FastForward', '1.3', - 'About', '   ', - 'First', '1.', - 'Last', '1.2.4', -); - - -###################################################################### -# from here on, its l2h init stuff -# - -## initialization for latex2html as for Singular manual generation -## obachman 3/99 - -# -# Options controlling Titles, File-Names, Tracing and Sectioning -# -$TITLE = ''; - -$SHORTEXTN = 0; - -$LONG_TITLES = 0; - -$DESTDIR = ''; # should be overwritten by cmd-line argument - -$NO_SUBDIR = 0;# should be overwritten by cmd-line argument - -$PREFIX = ''; # should be overwritten by cmd-line argument - -$AUTO_PREFIX = 0; # this is needed, so that prefix settings are used - -$AUTO_LINK = 0; - -$SPLIT = 0; - -$MAX_LINK_DEPTH = 0; - -$TMP = ''; # should be overwritten by cmd-line argument - -$DEBUG = 0; - -$VERBOSE = 1; - -# -# Options controlling Extensions and Special Features -# -$HTML_VERSION = "3.2"; - -$TEXDEFS = 1; # we absolutely need that - -$EXTERNAL_FILE = ''; - -$SCALABLE_FONTS = 1; - -$NO_SIMPLE_MATH = 1; - -$LOCAL_ICONS = 1; - -$SHORT_INDEX = 0; - -$NO_FOOTNODE = 1; - -$ADDRESS = ''; - -$INFO = ''; - -# -# Switches controlling Image Generation -# -$ASCII_MODE = 0; - -$NOLATEX = 0; - -$EXTERNAL_IMAGES = 0; - -$PS_IMAGES = 0; - -$NO_IMAGES = 0; - -$IMAGES_ONLY = 0; - -$REUSE = 2; - -$ANTI_ALIAS = 1; - -$ANTI_ALIAS_TEXT = 1; - -# -#Switches controlling Navigation Panels -# -$NO_NAVIGATION = 1; -$ADDRESS = ''; -$INFO = 0; # 0 = do not make a "About this document..." section - -# -#Switches for Linking to other documents -# -# actuall -- we don't care - -$MAX_SPLIT_DEPTH = 0; # Stop making separate files at this depth - -$MAX_LINK_DEPTH = 0; # Stop showing child nodes at this depth - -$NOLATEX = 0; # 1 = do not pass unknown environments to Latex - -$EXTERNAL_IMAGES = 0; # 1 = leave the images outside the document - -$ASCII_MODE = 0; # 1 = do not use any icons or internal images - -# 1 = use links to external postscript images rather than inlined bitmap -# images. -$PS_IMAGES = 0; -$SHOW_SECTION_NUMBERS = 0; - -### Other global variables ############################################### -$CHILDLINE = ""; - -# This is the line width measured in pixels and it is used to right justify -# equations and equation arrays; -$LINE_WIDTH = 500; - -# Used in conjunction with AUTO_NAVIGATION -$WORDS_IN_PAGE = 300; - -# Affects ONLY the way accents are processed -$default_language = 'english'; - -# The value of this variable determines how many words to use in each -# title that is added to the navigation panel (see below) -# -$WORDS_IN_NAVIGATION_PANEL_TITLES = 0; - -# This number will determine the size of the equations, special characters, -# and anything which will be converted into an inlined image -# *except* "image generating environments" such as "figure", "table" -# or "minipage". -# Effective values are those greater than 0. -# Sensible values are between 0.1 - 4. -$MATH_SCALE_FACTOR = 1.5; - -# This number will determine the size of -# image generating environments such as "figure", "table" or "minipage". -# Effective values are those greater than 0. -# Sensible values are between 0.1 - 4. -$FIGURE_SCALE_FACTOR = 1.6; - - -# If both of the following two variables are set then the "Up" button -# of the navigation panel in the first node/page of a converted document -# will point to $EXTERNAL_UP_LINK. $EXTERNAL_UP_TITLE should be set -# to some text which describes this external link. -$EXTERNAL_UP_LINK = ""; -$EXTERNAL_UP_TITLE = ""; - -# If this is set then the resulting HTML will look marginally better if viewed -# with Netscape. -$NETSCAPE_HTML = 1; - -# Valid paper sizes are "letter", "legal", "a4","a3","a2" and "a0" -# Paper sizes has no effect other than in the time it takes to create inlined -# images and in whether large images can be created at all ie -# - larger paper sizes *MAY* help with large image problems -# - smaller paper sizes are quicker to handle -$PAPERSIZE = "a4"; - -# Replace "english" with another language in order to tell LaTeX2HTML that you -# want some generated section titles (eg "Table of Contents" or "References") -# to appear in a different language. Currently only "english" and "french" -# is supported but it is very easy to add your own. See the example in the -# file "latex2html.config" -$TITLES_LANGUAGE = "english"; - -1; # This must be the last non-comment line - -# End File texi2html.init -###################################################################### - - -require "$ENV{T2H_HOME}/texi2html.init" - if ($0 =~ /\.pl$/ && - -e "$ENV{T2H_HOME}/texi2html.init" && -r "$ENV{T2H_HOME}/texi2html.init"); - -#+++############################################################################ -# # -# Initialization # -# Pasted content of File $(srcdir)/MySimple.pm: Command-line processing # -# # -#---############################################################################ - -# leave this within comments, and keep the require statement -# This way, you can directly run texi2html.pl, if $ENV{T2H_HOME}/texi2html.init -# exists. - -# -package Getopt::MySimple; - -# Name: -# Getopt::MySimple. -# -# Documentation: -# POD-style (incomplete) documentation is in file MySimple.pod -# -# Tabs: -# 4 spaces || die. -# -# Author: -# Ron Savage rpsavage@ozemail.com.au. -# 1.00 19-Aug-97 Initial version. -# 1.10 13-Oct-97 Add arrays of switches (eg '=s@'). -# 1.20 3-Dec-97 Add 'Help' on a per-switch basis. -# 1.30 11-Dec-97 Change 'Help' to 'verbose'. Make all hash keys lowercase. -# 1.40 10-Nov-98 Change width of help report. Restructure tests. -# 1-Jul-00 Modifications for Texi2html - -# -------------------------------------------------------------------------- -# Locally modified by obachman (Display type instead of env, order by cmp) -# $Id: MySimple.pm,v 1.1 2000/07/03 08:44:13 obachman Exp $ - -# use strict; -# no strict 'refs'; - -use vars qw(@EXPORT @EXPORT_OK @ISA); -use vars qw($fieldWidth $opt $VERSION); - -use Exporter(); -use Getopt::Long; - -@ISA = qw(Exporter); -@EXPORT = qw(); -@EXPORT_OK = qw($opt); # An alias for $self -> {'opt'}. - -# -------------------------------------------------------------------------- - -$fieldWidth = 20; -$VERSION = '1.41'; - -# -------------------------------------------------------------------------- - -sub byOrder -{ - my($self) = @_; - - return uc($a) cmp (uc($b)); -} - -# -------------------------------------------------------------------------- - -sub dumpOptions -{ - my($self) = @_; - - print 'Option', ' ' x ($fieldWidth - length('Option') ), "Value\n"; - - for (sort byOrder keys(%{$self -> {'opt'} }) ) - { - print "-$_", ' ' x ($fieldWidth - (1 + length) ), "${$self->{'opt'} }{$_}\n"; - } - - print "\n"; - -} # End of dumpOptions. - -# -------------------------------------------------------------------------- -# Return: -# 0 -> Error. -# 1 -> Ok. - -sub getOptions -{ - push(@_, 0) if ($#_ == 2); # Default for $ignoreCase is 0. - push(@_, 1) if ($#_ == 3); # Default for $helpThenExit is 1. - - my($self, $default, $helpText, $versionText, - $helpThenExit, $versionThenExit, $ignoreCase) = @_; - - $helpThenExit = 1 unless (defined($helpThenExit)); - $versionThenExit = 1 unless (defined($versionThenExit)); - $ignoreCase = 0 unless (defined($ignoreCase)); - - $self -> {'default'} = $default; - $self -> {'helpText'} = $helpText; - $self -> {'versionText'} = $versionText; - $Getopt::Long::ignorecase = $ignoreCase; - - unless (defined($self -> {'default'}{'help'})) - { - $self -> {'default'}{'help'} = - { - type => ':i', - default => '', - linkage => sub {$self->helpOptions($_[1]); exit (0) if $helpThenExit;}, - verbose => "print help and exit" - }; - } - - unless (defined($self -> {'default'}{'version'})) - { - $self -> {'default'}{'version'} = - { - type => '', - default => '', - linkage => sub {print $self->{'versionText'}; exit (0) if versionTheExit;}, - verbose => "print version and exit" - }; - } - - for (keys(%{$self -> {'default'} }) ) - { - my $type = ${$self -> {'default'} }{$_}{'type'}; - push(@{$self -> {'type'} }, "$_$type"); - $self->{'opt'}->{$_} = ${$self -> {'default'} }{$_}{'linkage'} - if ${$self -> {'default'} }{$_}{'linkage'}; - } - - my($result) = &GetOptions($self -> {'opt'}, @{$self -> {'type'} }); - - return $result unless $result; - - for (keys(%{$self -> {'default'} }) ) - { - if (! defined(${$self -> {'opt'} }{$_})) #{ - { - ${$self -> {'opt'} }{$_} = ${$self -> {'default'} }{$_}{'default'}; - } - } - - $result; -} # End of getOptions. - -# -------------------------------------------------------------------------- - -sub helpOptions -{ - my($self) = shift; - my($noHelp) = shift; - $noHelp = 0 unless $noHelp; - my($optwidth, $typewidth, $defaultwidth, $maxlinewidth, $valind, $valwidth) - = (10, 5, 9, 78, 4, 11); - - print "$self->{'helpText'}" if ($self -> {'helpText'}); - - print ' Option', ' ' x ($optwidth - length('Option') -1 ), - 'Type', ' ' x ($typewidth - length('Type') + 1), - 'Default', ' ' x ($defaultwidth - length('Default') ), - "Description\n"; - - for (sort byOrder keys(%{$self -> {'default'} }) ) - { - my($line, $help, $option, $val); - $option = $_; - next if ${$self->{'default'} }{$_}{'noHelp'} && ${$self->{'default'} }{$_}{'noHelp'} > $noHelp; - $line = " -$_ " . ' ' x ($optwidth - (2 + length) ) . - "${$self->{'default'} }{$_}{'type'} ". - ' ' x ($typewidth - (1+length(${$self -> {'default'} }{$_}{'type'}) )); - - $val = ${$self->{'default'} }{$_}{'linkage'}; - if ($val) - { - if (ref($val) eq 'SCALAR') - { - $val = $$val; - } - else - { - $val = ''; - } - } - else - { - $val = ${$self->{'default'} }{$_}{'default'}; - } - $line .= "$val "; - $line .= ' ' x ($optwidth + $typewidth + $defaultwidth + 1 - length($line)); - - if (defined(${$self -> {'default'} }{$_}{'verbose'}) && - ${$self -> {'default'} }{$_}{'verbose'} ne '') - { - $help = "${$self->{'default'} }{$_}{'verbose'}"; - } - else - { - $help = ' '; - } - if ((length("$line") + length($help)) < $maxlinewidth) - { - print $line , $help, "\n"; - } - else - { - print $line, "\n", ' ' x $valind, $help, "\n"; - } - for $val (sort byOrder keys(%{${$self->{'default'}}{$option}{'values'}})) - { - print ' ' x ($valind + 2); - print $val, ' ', ' ' x ($valwidth - length($val) - 2); - print ${$self->{'default'}}{$option}{'values'}{$val}, "\n"; - } - } - - print <| ! no argument: variable is set to 1 on -foo (or, to 0 on -nofoo) - =s | :s mandatory (or, optional) string argument - =i | :i mandatory (or, optional) integer argument -EOT -} # End of helpOptions. - -#------------------------------------------------------------------- - -sub new -{ - my($class) = @_; - my($self) = {}; - $self -> {'default'} = {}; - $self -> {'helpText'} = ''; - $self -> {'opt'} = {}; - $opt = $self -> {'opt'}; # An alias for $self -> {'opt'}. - $self -> {'type'} = (); - - return bless $self, $class; - -} # End of new. - -# -------------------------------------------------------------------------- - -1; - -# End MySimple.pm - -require "$ENV{T2H_HOME}/MySimple.pm" - if ($0 =~ /\.pl$/ && - -e "$ENV{T2H_HOME}/texi2html.init" && -r "$ENV{T2H_HOME}/texi2html.init"); - -package main; - -#+++############################################################################ -# # -# Constants # -# # -#---############################################################################ - -$DEBUG_TOC = 1; -$DEBUG_INDEX = 2; -$DEBUG_BIB = 4; -$DEBUG_GLOSS = 8; -$DEBUG_DEF = 16; -$DEBUG_HTML = 32; -$DEBUG_USER = 64; -$DEBUG_L2H = 128; - - -$BIBRE = '\[[\w\/-]+\]'; # RE for a bibliography reference -$FILERE = '[\/\w.+-]+'; # RE for a file name -$VARRE = '[^\s\{\}]+'; # RE for a variable name -$NODERE = '[^,:]+'; # RE for a node name -$NODESRE = '[^:]+'; # RE for a list of node names - -$ERROR = "***"; # prefix for errors -$WARN = "**"; # prefix for warnings - - # program home page -$PROTECTTAG = "_ThisIsProtected_"; # tag to recognize protected sections - -$CHAPTEREND = "\n"; # to know where a chpater ends -$SECTIONEND = "\n"; # to know where section ends -$TOPEND = "\n"; # to know where top ends - - - -# -# pre-defined indices -# -$index_properties = -{ - 'c' => { name => 'cp'}, - 'f' => { name => 'fn', code => 1}, - 'v' => { name => 'vr', code => 1}, - 'k' => { name => 'ky', code => 1}, - 'p' => { name => 'pg', code => 1}, - 't' => { name => 'tp', code => 1} -}; - - -%predefined_index = ( - 'cp', 'c', - 'fn', 'f', - 'vr', 'v', - 'ky', 'k', - 'pg', 'p', - 'tp', 't', - ); - -# -# valid indices -# -%valid_index = ( - 'c', 1, - 'f', 1, - 'v', 1, - 'k', 1, - 'p', 1, - 't', 1, - ); - -# -# texinfo section names to level -# -%sec2level = ( - 'top', 0, - 'chapter', 1, - 'unnumbered', 1, - 'majorheading', 1, - 'chapheading', 1, - 'appendix', 1, - 'section', 2, - 'unnumberedsec', 2, - 'heading', 2, - 'appendixsec', 2, - 'appendixsection', 2, - 'subsection', 3, - 'unnumberedsubsec', 3, - 'subheading', 3, - 'appendixsubsec', 3, - 'subsubsection', 4, - 'unnumberedsubsubsec', 4, - 'subsubheading', 4, - 'appendixsubsubsec', 4, - ); - -# -# accent map, TeX command to ISO name -# -%accent_map = ( - '"', 'uml', - '~', 'tilde', - '^', 'circ', - '`', 'grave', - '\'', 'acute', - ); - -# -# texinfo "simple things" (@foo) to HTML ones -# -%simple_map = ( - # cf. makeinfo.c - "*", "
", # HTML+ - " ", " ", - "\t", " ", - "-", "­", # soft hyphen - "\n", "\n", - "|", "", - 'tab', '<\/TD>
Button Name Go to From 1.2.3 go to
-EOT - $about .= - ($T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ? - &$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{$button}) : - " [" . $T2H_NAVIGATION_TEXT{$button} . "] "); - $about .= < - -$button - -$T2H_BUTTONS_GOTO{$button} - -$T2H_BUTTONS_EXAMPLE{$button} -
', - # spacing commands - ":", "", - "!", "!", - "?", "?", - ".", ".", - "-", "", - ); - -# -# texinfo "things" (@foo{}) to HTML ones -# -%things_map = ( - 'TeX', 'TeX', - 'br', '

', # paragraph break - 'bullet', '*', - 'copyright', '(C)', - 'dots', '...<\/small>', - 'enddots', '....<\/small>', - 'equiv', '==', - 'error', 'error-->', - 'expansion', '==>', - 'minus', '-', - 'point', '-!-', - 'print', '-|', - 'result', '=>', - 'today', $T2H_TODAY, - 'aa', 'å', - 'AA', 'Å', - 'ae', 'æ', - 'oe', 'œ', - 'AE', 'Æ', - 'OE', 'Œ', - 'o', 'ø', - 'O', 'Ø', - 'ss', 'ß', - 'l', '\/l', - 'L', '\/L', - 'exclamdown', '¡', - 'questiondown', '¿', - 'pounds', '£' - ); - -# -# texinfo styles (@foo{bar}) to HTML ones -# -%style_map = ( - 'acronym', '&do_acronym', - 'asis', '', - 'b', 'B', - 'cite', 'CITE', - 'code', 'CODE', - 'command', 'CODE', - 'ctrl', '&do_ctrl', # special case - 'dfn', 'EM', # DFN tag is illegal in the standard - 'dmn', '', # useless - 'email', '&do_email', # insert a clickable email address - 'emph', 'EM', - 'env', 'CODE', - 'file', '"TT', # will put quotes, cf. &apply_style - 'i', 'I', - 'kbd', 'KBD', - 'key', 'KBD', - 'math', '&do_math', - 'option', '"SAMP', # will put quotes, cf. &apply_style - 'r', '', # unsupported - 'samp', '"SAMP', # will put quotes, cf. &apply_style - 'sc', '&do_sc', # special case - 'strong', 'STRONG', - 't', 'TT', - 'titlefont', '', # useless - 'uref', '&do_uref', # insert a clickable URL - 'url', '&do_url', # insert a clickable URL - 'var', 'VAR', - 'w', '', # unsupported - 'H', '&do_accent', - 'dotaccent', '&do_accent', - 'ringaccent','&do_accent', - 'tieaccent', '&do_accent', - 'u','&do_accent', - 'ubaraccent','&do_accent', - 'udotaccent','&do_accent', - 'v', '&do_accent', - ',', '&do_accent', - 'dotless', '&do_accent' - ); - -# -# texinfo format (@foo/@end foo) to HTML ones -# -%format_map = ( - 'quotation', 'BLOCKQUOTE', - # lists - 'itemize', 'UL', - 'enumerate', 'OL', - # poorly supported - 'flushleft', 'PRE', - 'flushright', 'PRE', - ); - -# -# an eval of these $complex_format_map->{what}->[0] yields beginning -# an eval of these $complex_format_map->{what}->[1] yieleds end -$complex_format_map = -{ - example => - [ - q{"$T2H_EXAMPLE_INDENT_CELL
"},
-  q{'
'} - ], - smallexample => - [ - q{"$T2H_SMALL_EXAMPLE_INDENT_CELL
"},
-  q{'
'} - ], - display => - [ - q{"$T2H_EXAMPLE_INDENT_CELL
'},
-  q{'
'} - ], - smalldisplay => - [ - q{"$T2H_SMALL_EXAMPLE_INDENT_CELL
'},
-  q{'
'} - ] -}; - -$complex_format_map->{lisp} = $complex_format_map->{example}; -$complex_format_map->{smalllisp} = $complex_format_map->{smallexample}; -$complex_format_map->{format} = $complex_format_map->{display}; -$complex_format_map->{smallformat} = $complex_format_map->{smalldisplay}; - -# -# texinfo definition shortcuts to real ones -# -%def_map = ( - # basic commands - 'deffn', 0, - 'defvr', 0, - 'deftypefn', 0, - 'deftypevr', 0, - 'defcv', 0, - 'defop', 0, - 'deftp', 0, - # basic x commands - 'deffnx', 0, - 'defvrx', 0, - 'deftypefnx', 0, - 'deftypevrx', 0, - 'defcvx', 0, - 'defopx', 0, - 'deftpx', 0, - # shortcuts - 'defun', 'deffn Function', - 'defmac', 'deffn Macro', - 'defspec', 'deffn {Special Form}', - 'defvar', 'defvr Variable', - 'defopt', 'defvr {User Option}', - 'deftypefun', 'deftypefn Function', - 'deftypevar', 'deftypevr Variable', - 'defivar', 'defcv {Instance Variable}', - 'deftypeivar', 'defcv {Instance Variable}', # NEW: FIXME - 'defmethod', 'defop Method', - 'deftypemethod', 'defop Method', # NEW:FIXME - # x shortcuts - 'defunx', 'deffnx Function', - 'defmacx', 'deffnx Macro', - 'defspecx', 'deffnx {Special Form}', - 'defvarx', 'defvrx Variable', - 'defoptx', 'defvrx {User Option}', - 'deftypefunx', 'deftypefnx Function', - 'deftypevarx', 'deftypevrx Variable', - 'defivarx', 'defcvx {Instance Variable}', - 'defmethodx', 'defopx Method', - ); - -# -# things to skip -# -%to_skip = ( - # comments - 'c', 1, - 'comment', 1, - 'ifnotinfo', 1, - 'ifnottex', 1, - 'ifhtml', 1, - 'end ifhtml', 1, - 'end ifnotinfo', 1, - 'end ifnottex', 1, - # useless - 'detailmenu', 1, - 'direntry', 1, - 'contents', 1, - 'shortcontents', 1, - 'summarycontents', 1, - 'footnotestyle', 1, - 'end ifclear', 1, - 'end ifset', 1, - 'titlepage', 1, - 'end titlepage', 1, - # unsupported commands (formatting) - 'afourpaper', 1, - 'cropmarks', 1, - 'finalout', 1, - 'headings', 1, - 'sp', 1, - 'need', 1, - 'page', 1, - 'setchapternewpage', 1, - 'everyheading', 1, - 'everyfooting', 1, - 'evenheading', 1, - 'evenfooting', 1, - 'oddheading', 1, - 'oddfooting', 1, - 'smallbook', 1, - 'vskip', 1, - 'filbreak', 1, - 'paragraphindent', 1, - # unsupported formats - 'cartouche', 1, - 'end cartouche', 1, - 'group', 1, - 'end group', 1, - ); - -#+++############################################################################ -# # -# Argument parsing, initialisation # -# # -#---############################################################################ - -# -# flush stdout and stderr after every write -# -select(STDERR); -$| = 1; -select(STDOUT); -$| = 1; - - -%value = (); # hold texinfo variables, see also -D -$use_bibliography = 1; -$use_acc = 1; - -# -# called on -init-file -sub LoadInitFile -{ - my $init_file = shift; - # second argument is value of options - $init_file = shift; - if (-f $init_file) - { - print "# reading initialization file from $init_file\n" - if ($T2H_VERBOSE); - require($init_file); - } - else - { - print "$ERROR Error: can't read init file $int_file\n"; - $init_file = ''; - } -} - -# -# called on -lang -sub SetDocumentLanguage -{ - my $lang = shift; - if (! exists($T2H_WORDS->{$lang})) - { - warn "$ERROR: Language specs for '$lang' do not exists. Reverting to '" . - ($T2H_LANG ? T2H_LANG : "en") . "'\n"; - } - else - { - print "# using '$lang' as document language\n" if ($T2H_VERBOSE); - $T2H_LANG = $lang; - } -} - -## -## obsolete cmd line options -## -$T2H_OBSOLETE_OPTIONS -> {'no-section_navigation'} = -{ - type => '!', - linkage => sub {$main::T2H_SECTION_NAVIGATION = 0;}, - verbose => 'obsolete, use -nosec_nav', - noHelp => 2, -}; -$T2H_OBSOLETE_OPTIONS -> {use_acc} = -{ - type => '!', - linkage => \$use_acc, - verbose => 'obsolete', - noHelp => 2 -}; -$T2H_OBSOLETE_OPTIONS -> {expandinfo} = -{ - type => '!', - linkage => sub {$main::T2H_EXPAND = 'info';}, - verbose => 'obsolete, use "-expand info" instead', - noHelp => 2, -}; -$T2H_OBSOLETE_OPTIONS -> {expandtex} = -{ - type => '!', - linkage => sub {$main::T2H_EXPAND = 'tex';}, - verbose => 'obsolete, use "-expand tex" instead', - noHelp => 2, -}; -$T2H_OBSOLETE_OPTIONS -> {monolithic} = -{ - type => '!', - linkage => sub {$main::T2H_SPLIT = '';}, - verbose => 'obsolete, use "-split no" instead', - noHelp => 2 -}; -$T2H_OBSOLETE_OPTIONS -> {split_node} = -{ - type => '!', - linkage => sub{$main::T2H_SPLIT = 'section';}, - verbose => 'obsolete, use "-split section" instead', - noHelp => 2, -}; -$T2H_OBSOLETE_OPTIONS -> {split_chapter} = -{ - type => '!', - linkage => sub{$main::T2H_SPLIT = 'chapter';}, - verbose => 'obsolete, use "-split chapter" instead', - noHelp => 2, -}; -$T2H_OBSOLETE_OPTIONS -> {no_verbose} = -{ - type => '!', - linkage => sub {$main::T2H_VERBOSE = 0;}, - verbose => 'obsolete, use -noverbose instead', - noHelp => 2, -}; -$T2H_OBSOLETE_OPTIONS -> {output_file} = -{ - type => '=s', - linkage => sub {$main::T2H_OUT = @_[1]; $T2H_SPLIT = '';}, - verbose => 'obsolete, use -out_file instead', - noHelp => 2 -}; - -$T2H_OBSOLETE_OPTIONS -> {section_navigation} = -{ - type => '!', - linkage => \$T2H_SECTION_NAVIGATION, - verbose => 'obsolete, use -sec_nav instead', - noHelp => 2, -}; - -$T2H_OBSOLETE_OPTIONS -> {verbose} = -{ - type => '!', - linkage => \$T2H_VERBOSE, - verbose => 'obsolete, use -Verbose instead', - noHelp => 2 -}; - -# read initialzation from $sysconfdir/texi2htmlrc or $HOME/.texi2htmlrc -my $home = $ENV{HOME}; -defined($home) or $home = ''; -foreach $i ('/usr/local/etc/texi2htmlrc', "$home/.texi2htmlrc") { - if (-f $i) { - print "# reading initialization file from $i\n" - if ($T2H_VERBOSE); - require($i); - } -} - - -#+++############################################################################ -# # -# parse command-line options -# # -#---############################################################################ -$T2H_USAGE_TEXT = <getOptions($T2H_OPTIONS, $T2H_USAGE_TEXT, "$THISVERSION\n")) -{ - print $Configure_failed if $Configure_failed; - die $T2H_FAILURE_TEXT; -} - -if (@ARGV > 1) -{ - eval {Getopt::Long::Configure("no_pass_through");}; - if (! $options->getOptions($T2H_OBSOLETE_OPTIONS, $T2H_USAGE_TEXT, "$THISVERSION\n")) - { - print $Configure_failed if $Configure_failed; - die $T2H_FAILURE_TEXT; - } -} - -if ($T2H_CHECK) { - die "Need file to check\n$T2H_FAILURE_TEXT" unless @ARGV > 0; - ✓ - exit; -} - -#+++############################################################################ -# # -# evaluation of cmd line options -# # -#---############################################################################ - -if ($T2H_EXPAND eq 'info') -{ - $to_skip{'ifinfo'} = 1; - $to_skip{'end ifinfo'} = 1; -} -elsif ($T2H_EXPAND eq 'tex') -{ - $to_skip{'iftex'} = 1; - $to_skip{'end iftex'} = 1; - -} - -$T2H_INVISIBLE_MARK = '' if $T2H_INVISIBLE_MARK eq 'xbm'; - -# -# file name buisness -# -die "Need exactly one file to translate\n$T2H_FAILURE_TEXT" unless @ARGV == 1; -$docu = shift(@ARGV); -if ($docu =~ /.*\//) { - chop($docu_dir = $&); - $docu_name = $'; -} else { - $docu_dir = '.'; - $docu_name = $docu; -} -unshift(@T2H_INCLUDE_DIRS, $docu_dir); -$docu_name =~ s/\.te?x(i|info)?$//; # basename of the document -$docu_name = $T2H_PREFIX if ($T2H_PREFIX); - -# subdir -if ($T2H_SUBDIR && ! $T2H_OUT) -{ - $T2H_SUBDIR =~ s|/*$||; - unless (-d "$T2H_SUBDIR" && -w "$T2H_SUBDIR") - { - if ( mkdir($T2H_SUBDIR, oct(755))) - { - print "# created directory $T2H_SUBDIR\n" if ($T2H_VERBOSE); - } - else - { - warn "$ERROR can't create directory $T2H_SUBDIR. Put results into current directory\n"; - $T2H_SUBDIR = ''; - } - } -} - -if ($T2H_SUBDIR && ! $T2H_OUT) -{ - $docu_rdir = "$T2H_SUBDIR/"; - print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE); -} -else -{ - if ($T2H_OUT && $T2H_OUT =~ m|(.*)/|) - { - $docu_rdir = "$1/"; - print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE); - } - else - { - print "# putting result files into current directory \n" if ($T2H_VERBOSE); - $docu_rdir = ''; - } -} - -# extension -if ($T2H_SHORTEXTN) -{ - $docu_ext = "htm"; -} -else -{ - $docu_ext = "html"; -} -if ($T2H_TOP_FILE =~ /\..*$/) -{ - $T2H_TOP_FILE = $`.".$docu_ext"; -} - -# result files -if (! $T2H_OUT && ($T2H_SPLIT =~ /section/i || $T2H_SPLIT =~ /node/i)) -{ - $T2H_SPLIT = 'section'; -} -elsif (! $T2H_OUT && $T2H_SPLIT =~ /chapter/i) -{ - $T2H_SPLIT = 'chapter' -} -else -{ - undef $T2H_SPLIT; -} - -$docu_doc = "$docu_name.$docu_ext"; # document's contents -$docu_doc_file = "$docu_rdir$docu_doc"; -if ($T2H_SPLIT) -{ - $docu_toc = $T2H_TOC_FILE || "${docu_name}_toc.$docu_ext"; # document's table of contents - $docu_stoc = "${docu_name}_ovr.$docu_ext"; # document's short toc - $docu_foot = "${docu_name}_fot.$docu_ext"; # document's footnotes - $docu_about = "${docu_name}_abt.$docu_ext"; # about this document - $docu_top = $T2H_TOP_FILE || $docu_doc; -} -else -{ - if ($T2H_OUT) - { - $docu_doc = $T2H_OUT; - $docu_doc =~ s|.*/||; - } - $docu_toc = $docu_foot = $docu_stoc = $docu_about = $docu_top = $docu_doc; -} - -$docu_toc_file = "$docu_rdir$docu_toc"; -$docu_stoc_file = "$docu_rdir$docu_stoc"; -$docu_foot_file = "$docu_rdir$docu_foot"; -$docu_about_file = "$docu_rdir$docu_about"; -$docu_top_file = "$docu_rdir$docu_top"; - -$docu_frame_file = "$docu_rdir${docu_name}_frame.$docu_ext"; -$docu_toc_frame_file = "$docu_rdir${docu_name}_toc_frame.$docu_ext"; - -# -# variables -# -$value{'html'} = 1; # predefine html (the output format) -$value{'texi2html'} = $THISVERSION; # predefine texi2html (the translator) -# _foo: internal to track @foo -foreach ('_author', '_title', '_subtitle', - '_settitle', '_setfilename', '_shorttitle') { - $value{$_} = ''; # prevent -w warnings -} -%node2sec = (); # node to section name -%sec2node = (); # section to node name -%sec2number = (); # section to number -%number2sec = (); # number to section -%idx2node = (); # index keys to node -%node2href = (); # node to HREF -%node2next = (); # node to next -%node2prev = (); # node to prev -%node2up = (); # node to up -%bib2href = (); # bibliography reference to HREF -%gloss2href = (); # glossary term to HREF -@sections = (); # list of sections -%tag2pro = (); # protected sections - -# -# initial indexes -# -$bib_num = 0; -$foot_num = 0; -$gloss_num = 0; -$idx_num = 0; -$sec_num = 0; -$doc_num = 0; -$html_num = 0; - -# -# can I use ISO8879 characters? (HTML+) -# -if ($T2H_USE_ISO) { - $things_map{'bullet'} = "•"; - $things_map{'copyright'} = "©"; - $things_map{'dots'} = "…"; - $things_map{'equiv'} = "≡"; - $things_map{'expansion'} = "→"; - $things_map{'point'} = "∗"; - $things_map{'result'} = "⇒"; -} - -# -# read texi2html extensions (if any) -# -$extensions = 'texi2html.ext'; # extensions in working directory -if (-f $extensions) { - print "# reading extensions from $extensions\n" if $T2H_VERBOSE; - require($extensions); -} -($progdir = $0) =~ s/[^\/]+$//; -if ($progdir && ($progdir ne './')) { - $extensions = "${progdir}texi2html.ext"; # extensions in texi2html directory - if (-f $extensions) { - print "# reading extensions from $extensions\n" if $T2H_VERBOSE; - require($extensions); - } -} - - -print "# reading from $docu\n" if $T2H_VERBOSE; - -######################################################################### -# -# latex2html stuff -# -# latex2html conversions consist of three stages: -# 1) ToLatex: Put "latex" code into a latex file -# 2) ToHtml: Use latex2html to generate corresponding html code and images -# 3) FromHtml: Extract generated code and images from latex2html run -# - -########################## -# default settings -# - -# defaults for files and names - -sub l2h_Init -{ - local($root) = @_; - - return 0 unless ($root); - - $l2h_name = "${root}_l2h"; - - $l2h_latex_file = "$docu_rdir${l2h_name}.tex"; - $l2h_cache_file = "${docu_rdir}l2h_cache.pm"; - $T2H_L2H_L2H = "latex2html" unless ($T2H_L2H_L2H); - - # destination dir -- generated images are put there, should be the same - # as dir of enclosing html document -- - $l2h_html_file = "$docu_rdir${l2h_name}.html"; - $l2h_prefix = "${l2h_name}_"; - return 1; -} - - -########################## -# -# First stage: Generation of Latex file -# Initialize with: l2h_InitToLatex -# Add content with: l2h_ToLatex($text) --> HTML placeholder comment -# Finish with: l2h_FinishToLatex -# - -$l2h_latex_preample = <$l2h_latex_file")) - { - warn "$ERROR Error l2h: Can't open latex file '$latex_file' for writing\n"; - return 0; - } - print "# l2h: use ${l2h_latex_file} as latex file\n" if ($T2H_VERBOSE); - print L2H_LATEX $l2h_latex_preample; - } - # open database for caching - l2h_InitCache(); - $l2h_latex_count = 0; - $l2h_to_latex_count = 0; - $l2h_cached_count = 0; - return 1; -} - -# print text (1st arg) into latex file (if not already there), return -# HTML commentary which can be later on replaced by the latex2html -# generated text -sub l2h_ToLatex -{ - my($text) = @_; - my($count); - - $l2h_to_latex_count++; - $text =~ s/(\s*)$//; - - # try whether we can cache it - my $cached_text = l2h_FromCache($text); - if ($cached_text) - { - $l2h_cached_count++; - return $cached_text; - } - - # try whether we have text already on things to do - unless ($count = $l2h_to_latex{$text}) - { - $count = $l2h_latex_count; - $l2h_latex_count++; - $l2h_to_latex{$text} = $count; - $l2h_to_latex[$count] = $text; - unless ($T2H_L2H_SKIP) - { - print L2H_LATEX "\\begin{rawhtml}\n"; - print L2H_LATEX "\n"; - print L2H_LATEX "\\end{rawhtml}\n"; - - print L2H_LATEX "$text\n"; - - print L2H_LATEX "\\begin{rawhtml}\n"; - print L2H_LATEX "\n"; - print L2H_LATEX "\\end{rawhtml}\n"; - } - } - return ""; -} - -# print closing into latex file and close it -sub l2h_FinishToLatex -{ - local ($reused); - - $reused = $l2h_to_latex_count - $l2h_latex_count - $l2h_cached_count; - unless ($T2H_L2H_SKIP) - { - print L2H_LATEX $l2h_latex_closing; - close(L2H_LATEX); - } - print "# l2h: finished to latex ($l2h_cached_count cached, $reused reused, $l2h_latex_count contents)\n" if ($T2H_VERBOSE); - unless ($l2h_latex_count) - { - l2h_Finish(); - return 0; - } - return 1; -} - -################################### -# Second stage: Use latex2html to generate corresponding html code and images -# -# l2h_ToHtml([$l2h_latex_file, [$l2h_html_dir]]): -# Call latex2html on $l2h_latex_file -# Put images (prefixed with $l2h_name."_") and html file(s) in $l2h_html_dir -# Return 1, on success -# 0, otherwise -# -sub l2h_ToHtml -{ - local($call, $ext, $root, $dotbug); - - if ($T2H_L2H_SKIP) - { - print "# l2h: skipping latex2html run\n" if ($T2H_VERBOSE); - return 1; - } - - # Check for dot in directory where dvips will work - if ($T2H_L2H_TMP) - { - if ($T2H_L2H_TMP =~ /\./) - { - warn "$ERROR Warning l2h: l2h_tmp dir contains a dot. Use /tmp, instead\n"; - $dotbug = 1; - } - } - else - { - if (&getcwd =~ /\./) - { - warn "$ERROR Warning l2h: current dir contains a dot. Use /tmp as l2h_tmp dir \n"; - $dotbug = 1; - } - } - # fix it, if necessary and hope that it works - $T2H_L2H_TMP = "/tmp" if ($dotbug); - - $call = $T2H_L2H_L2H; - # use init file, if specified - $call = $call . " -init_file " . $init_file if ($init_file && -f $init_file); - # set output dir - $call .= ($docu_rdir ? " -dir $docu_rdir" : " -no_subdir"); - # use l2h_tmp, if specified - $call = $call . " -tmp $T2H_L2H_TMP" if ($T2H_L2H_TMP); - # options we want to be sure of - $call = $call ." -address 0 -info 0 -split 0 -no_navigation -no_auto_link"; - $call = $call ." -prefix ${l2h_prefix} $l2h_latex_file"; - - print "# l2h: executing '$call'\n" if ($T2H_VERBOSE); - if (system($call)) - { - warn "l2h ***Error: '${call}' did not succeed\n"; - return 0; - } - else - { - print "# l2h: latex2html finished successfully\n" if ($T2H_VERBOSE); - return 1; - } -} - -# this is directly pasted over from latex2html -sub getcwd { - local($_) = `pwd`; - - die "'pwd' failed (out of memory?)\n" - unless length; - chop; - $_; -} - - -########################## -# Third stage: Extract generated contents from latex2html run -# Initialize with: l2h_InitFromHtml -# open $l2h_html_file for reading -# reads in contents into array indexed by numbers -# return 1, on success -- 0, otherwise -# Extract Html code with: l2h_FromHtml($text) -# replaces in $text all previosuly inserted comments by generated html code -# returns (possibly changed) $text -# Finish with: l2h_FinishFromHtml -# closes $l2h_html_dir/$l2h_name.".$docu_ext" - -sub l2h_InitFromHtml -{ - local($h_line, $h_content, $count, %l2h_img); - - if (! open(L2H_HTML, "<${l2h_html_file}")) - { - print "$ERROR Error l2h: Can't open ${l2h_html_file} for reading\n"; - return 0; - } - print "# l2h: use ${l2h_html_file} as html file\n" if ($T2H_VERBOSE); - - $l2h_html_count = 0; - - while ($h_line = ) - { - if ($h_line =~ /^/) - { - $count = $1; - $h_content = ""; - while ($h_line = ) - { - if ($h_line =~ /^/) - { - chomp $h_content; - chomp $h_content; - $l2h_html_count++; - $h_content = l2h_ToCache($count, $h_content); - $l2h_from_html[$count] = $h_content; - $h_content = ''; - last; - } - $h_content = $h_content.$h_line; - } - if ($hcontent) - { - print "$ERROR Warning l2h: l2h_end $l2h_name $count not found\n" - if ($T2H_VERBOSE); - close(L2H_HTML); - return 0; - } - } - } - print "# l2h: Got $l2h_html_count of $l2h_latex_count html contents\n" - if ($T2H_VERBOSE); - - close(L2H_HTML); - return 1; -} - -sub l2h_FromHtml -{ - local($text) = @_; - local($done, $to_do, $count); - - $to_do = $text; - - while ($to_do =~ /([^\000]*)([^\000]*)/) - { - $to_do = $1; - $count = $2; - $done = $3.$done; - - $done = "".$done - if ($T2H_DEBUG & $DEBUG_L2H); - - $done = &l2h_ExtractFromHtml($count) . $done; - - $done = "".$done - if ($T2H_DEBUG & $DEBUG_L2H); - } - return $to_do.$done; -} - - -sub l2h_ExtractFromHtml -{ - local($count) = @_; - - return $l2h_from_html[$count] if ($l2h_from_html[$count]); - - if ($count >= 0 && $count < $l2h_latex_count) - { - # now we are in trouble - local($l_l2h, $_); - - $l2h_extract_error++; - print "$ERROR l2h: can't extract content $count from html\n" - if ($T2H_VERBOSE); - # try simple (ordinary) substition (without l2h) - $l_l2h = $T2H_L2H; - $T2H_L2H = 0; - $_ = $l2h_to_latex{$count}; - $_ = &substitute_style($_); - &unprotect_texi; - $_ = "" . $_ - if ($T2H_DEBUG & $DEBUG_L2H); - $T2H_L2H = $l_l2h; - return $_; - } - else - { - # now we have been incorrectly called - $l2h_range_error++; - print "$ERROR l2h: Request of $count content which is out of valide range [0,$l2h_latex_count)\n"; - return "" - if ($T2H_DEBUG & $DEBUG_L2H); - return ""; - } -} - -sub l2h_FinishFromHtml -{ - if ($T2H_VERBOSE) - { - if ($l2h_extract_error + $l2h_range_error) - { - print "# l2h: finished from html ($l2h_extract_error extract and $l2h_range_error errors)\n"; - } - else - { - print "# l2h: finished from html (no errors)\n"; - } - } -} - -sub l2h_Finish -{ - l2h_StoreCache(); - if ($T2H_L2H_CLEAN) - { - print "# l2h: removing temporary files generated by l2h extension\n" - if $T2H_VERBOSE; - while (<"$docu_rdir$l2h_name"*>) - { - unlink $_; - } - } - print "# l2h: Finished\n" if $T2H_VERBOSE; - return 1; -} - -############################## -# stuff for l2h caching -# - -# I tried doing this with a dbm data base, but it did not store all -# keys/values. Hence, I did as latex2html does it -sub l2h_InitCache -{ - if (-r "$l2h_cache_file") - { - my $rdo = do "$l2h_cache_file"; - warn("$ERROR l2h Error: could not load $docu_rdir$l2h_cache_file: $@\n") - unless ($rdo); - } -} - -sub l2h_StoreCache -{ - return unless $l2h_latex_count; - - my ($key, $value); - open(FH, ">$l2h_cache_file") || return warn"$ERROR l2h Error: could not open $docu_rdir$l2h_cache_file for writing: $!\n"; - - - while (($key, $value) = each %l2h_cache) - { - # escape stuff - $key =~ s|/|\\/|g; - $key =~ s|\\\\/|\\/|g; - # weird, a \ at the end of the key results in an error - # maybe this also broke the dbm database stuff - $key =~ s|\\$|\\\\|; - $value =~ s/\|/\\\|/g; - $value =~ s/\\\\\|/\\\|/g; - $value =~ s|\\\\|\\\\\\\\|g; - print FH "\n\$l2h_cache_key = q/$key/;\n"; - print FH "\$l2h_cache{\$l2h_cache_key} = q|$value|;\n"; - } - print FH "1;"; - close(FH); -} - -# return cached html, if it exists for text, and if all pictures -# are there, as well -sub l2h_FromCache -{ - my $text = shift; - my $cached = $l2h_cache{$text}; - if ($cached) - { - while ($cached =~ m/SRC="(.*?)"/g) - { - unless (-e "$docu_rdir$1") - { - return undef; - } - } - return $cached; - } - return undef; -} - -# insert generated html into cache, move away images, -# return transformed html -$maximage = 1; -sub l2h_ToCache -{ - my $count = shift; - my $content = shift; - my @images = ($content =~ /SRC="(.*?)"/g); - my ($src, $dest); - - for $src (@images) - { - $dest = $l2h_img{$src}; - unless ($dest) - { - my $ext; - if ($src =~ /.*\.(.*)$/ && $1 ne $docu_ext) - { - $ext = $1; - } - else - { - warn "$ERROR: L2h image $src has invalid extension\n"; - next; - } - while (-e "$docu_rdir${docu_name}_$maximage.$ext") { $maximage++;} - $dest = "${docu_name}_$maximage.$ext"; - system("cp -f $docu_rdir$src $docu_rdir$dest"); - $l2h_img{$src} = $dest; - unlink "$docu_rdir$src" unless ($DEBUG & DEBUG_L2H); - } - $content =~ s/$src/$dest/g; - } - $l2h_cache{$l2h_to_latex[$count]} = $content; - return $content; -} - - -#+++############################################################################ -# # -# Pass 1: read source, handle command, variable, simple substitution # -# # -#---############################################################################ - -@lines = (); # whole document -@toc_lines = (); # table of contents -@stoc_lines = (); # table of contents -$curlevel = 0; # current level in TOC -$node = ''; # current node name -$node_next = ''; # current node next name -$node_prev = ''; # current node prev name -$node_up = ''; # current node up name -$in_table = 0; # am I inside a table -$table_type = ''; # type of table ('', 'f', 'v', 'multi') -@tables = (); # nested table support -$in_bibliography = 0; # am I inside a bibliography -$in_glossary = 0; # am I inside a glossary -$in_top = 0; # am I inside the top node -$has_top = 0; # did I see a top node? -$has_top_command = 0; # did I see @top for automatic pointers? -$in_pre = 0; # am I inside a preformatted section -$in_list = 0; # am I inside a list -$in_html = 0; # am I inside an HTML section -$first_line = 1; # is it the first line -$dont_html = 0; # don't protect HTML on this line -$deferred_ref = ''; # deferred reference for indexes -@html_stack = (); # HTML elements stack -$html_element = ''; # current HTML element -&html_reset; -%macros = (); # macros - -# init l2h -$T2H_L2H = &l2h_Init($docu_name) if ($T2H_L2H); -$T2H_L2H = &l2h_InitToLatex if ($T2H_L2H); - -# build code for simple substitutions -# the maps used (%simple_map and %things_map) MUST be aware of this -# watch out for regexps, / and escaped characters! -$subst_code = ''; -foreach (keys(%simple_map)) { - ($re = $_) =~ s/(\W)/\\$1/g; # protect regexp chars - $subst_code .= "s/\\\@$re/$simple_map{$_}/g;\n"; -} -foreach (keys(%things_map)) { - $subst_code .= "s/\\\@$_\\{\\}/$things_map{$_}/g;\n"; -} -if ($use_acc) { - # accentuated characters - foreach (keys(%accent_map)) { - if ($_ eq "`") { - $subst_code .= "s/$;3"; - } elsif ($_ eq "'") { - $subst_code .= "s/$;4"; - } else { - $subst_code .= "s/\\\@\\$_"; - } - $subst_code .= "([a-z])/&\${1}$accent_map{$_};/gi;\n"; - } -} -eval("sub simple_substitutions { $subst_code }"); - -&init_input; -INPUT_LINE: while ($_ = &next_line) { - # - # remove \input on the first lines only - # - if ($first_line) { - next if /^\\input/; - $first_line = 0; - } - # non-@ substitutions cf. texinfmt.el - # - # parse texinfo tags - # - $tag = ''; - $end_tag = ''; - if (/^\s*\@end\s+(\w+)\b/) { - $end_tag = $1; - } elsif (/^\s*\@(\w+)\b/) { - $tag = $1; - } - # - # handle @html / @end html - # - if ($in_html) { - if ($end_tag eq 'html') { - $in_html = 0; - } else { - $tag2pro{$in_html} .= $_; - } - next; - } elsif ($tag eq 'html') { - $in_html = $PROTECTTAG . ++$html_num; - push(@lines, $in_html); - next; - } - - # - # try to remove inlined comments - # syntax from tex-mode.el comment-start-skip - # - s/((^|[^\@])(\@\@)*)\@c(omment | |\{|$).*/$1/; - -# Sometimes I use @c right at the end of a line ( to suppress the line feed ) -# s/((^|[^\@])(\@\@)*)\@c(omment)?$/$1/; -# s/((^|[^\@])(\@\@)*)\@c(omment)? .*/$1/; -# s/(.*)\@c{.*?}(.*)/$1$2/; -# s/(.*)\@comment{.*?}(.*)/$1$2/; -# s/^(.*)\@c /$1/; -# s/^(.*)\@comment /$1/; - - ############################################################# - # value substitution before macro expansion, so that - # it works in macro arguments - s/\@value{($VARRE)}/$value{$1}/eg; - - ############################################################# - # macro substitution - while (/\@(\w+)/g) - { - if (exists($macros->{$1})) - { - my $before = $`; - my $name = $1; - my $after = $'; - my @args; - my $args; - if ($after =~ /^\s*{(.*?[^\\])}(.*)/) - { - $args = $1; - $after = $2; - } - elsif (@{$macros->{$name}->{Args}} == 1) - { - $args = $after; - $args =~ s/^\s*//; - $args =~ s/\s*$//; - $after = ''; - } - $args =~ s|\\\\|\\|g; - $args =~ s|\\{|{|g; - $args =~ s|\\}|}|g; - if (@{$macros->{$name}->{Args}} > 1) - { - $args =~ s/(^|[^\\]),/$1$;/g ; - $args =~ s|\\,|,|g; - @args = split(/$;\s*/, $args) if (@{$macros->{$name}->{Args}} > 1); - } - else - { - $args =~ s|\\,|,|g; - @args = ($args); - } - my $macrobody = $macros->{$name}->{Body}; - for ($i=0; $i<=$#args; $i++) - { - $macrobody =~ s|\\$macros->{$name}->{Args}->[$i]\\|$args[$i]|g; - } - $macrobody =~ s|\\\\|\\|g; - $_ = $before . $macrobody . $after; - unshift @input_spool, map {$_ = $_."\n"} split(/\n/, $_); - next INPUT_LINE; - } - } # - - - # - # try to skip the line - # - if ($end_tag) { - $in_titlepage = 0 if $end_tag eq 'titlepage'; - next if $to_skip{"end $end_tag"}; - } elsif ($tag) { - $in_titlepage = 1 if $tag eq 'titlepage'; - next if $to_skip{$tag}; - last if $tag eq 'bye'; - } - if ($in_top) { - # parsing the top node - if ($tag eq 'node' || - ($sec2level{$tag} && $tag !~ /unnumbered/ && $tag !~ /heading/)) - { - # no more in top - $in_top = 0; - push(@lines, $TOPEND); - } - } - unless ($in_pre) { - s/``/\"/g; - s/''/\"/g; - s/([\w ])---([\w ])/$1--$2/g; - } - # - # analyze the tag - # - if ($tag) { - # skip lines - &skip_until($tag), next if $tag eq 'ignore'; - &skip_until($tag), next if $tag eq 'ifnothtml'; - if ($tag eq 'ifinfo') - { - &skip_until($tag), next unless $T2H_EXPAND eq 'info'; - } - if ($tag eq 'iftex') - { - &skip_until($tag), next unless $T2H_EXPAND eq 'tex'; - } - if ($tag eq 'tex') - { - # add to latex2html file - if ($T2H_EXPAND eq 'tex' && $T2H_L2H && ! $in_pre) - { - # add space to the end -- tex(i2dvi) does this, as well - push(@lines, &l2h_ToLatex(&string_until($tag) . " ")); - } - else - { - &skip_until($tag); - } - next; - } - if ($tag eq 'titlepage') - { - next; - } - # handle special tables - if ($tag =~ /^(|f|v|multi)table$/) { - $table_type = $1; - $tag = 'table'; - } - # special cases - if ($tag eq 'top' || ($tag eq 'node' && /^\@node\s+top\s*,/i)) { - $in_top = 1; - $has_top = 1; - $has_top_command = 1 if $tag eq 'top'; - @lines = (); # ignore all lines before top (title page garbage) - next; - } elsif ($tag eq 'node') { - if ($in_top) - { - $in_top = 0; - push(@lines, $TOPEND); - } - warn "$ERROR Bad node line: $_" unless $_ =~ /^\@node\s$NODESRE$/o; - # request of "Richard Y. Kim" - s/^\@node\s+//; - $_ = &protect_html($_); # if node contains '&' for instance - ($node, $node_next, $node_prev, $node_up) = split(/,/); - &normalise_node($node); - &normalise_node($node_next); - &normalise_node($node_prev); - &normalise_node($node_up); - $node =~ /\"/ ? - push @lines, &html_debug("\n", __LINE__) : - push @lines, &html_debug("\n", __LINE__); - next; - } elsif ($tag eq 'include') { - if (/^\@include\s+($FILERE)\s*$/o) { - $file = LocateIncludeFile($1); - if ($file && -e $file) { - &open($file); - print "# including $file\n" if $T2H_VERBOSE; - } else { - warn "$ERROR Can't find $1, skipping"; - } - } else { - warn "$ERROR Bad include line: $_"; - } - next; - } elsif ($tag eq 'ifclear') { - if (/^\@ifclear\s+($VARRE)\s*$/o) { - next unless defined($value{$1}); - &skip_until($tag); - } else { - warn "$ERROR Bad ifclear line: $_"; - } - next; - } elsif ($tag eq 'ifset') { - if (/^\@ifset\s+($VARRE)\s*$/o) { - next if defined($value{$1}); - &skip_until($tag); - } else { - warn "$ERROR Bad ifset line: $_"; - } - next; - } elsif ($tag eq 'menu') { - unless ($T2H_SHOW_MENU) { - &skip_until($tag); - next; - } - &html_push_if($tag); - push(@lines, &html_debug('', __LINE__)); - } elsif ($format_map{$tag}) { - $in_pre = 1 if $format_map{$tag} eq 'PRE'; - &html_push_if($format_map{$tag}); - push(@lines, &html_debug('', __LINE__)); - $in_list++ if $format_map{$tag} eq 'UL' || $format_map{$tag} eq 'OL' ; -# push(@lines, &debug("

\n", __LINE__)) -# if $tag =~ /example/i; - # sunshine@sunshineco.com:
bla
looks better than - #
\nbla
(at least on NeXTstep browser - push(@lines, &debug("<$format_map{$tag}>" . - ($in_pre ? '' : "\n"), __LINE__)); - next; - } - elsif (exists $complex_format_map->{$tag}) - { - my $start = eval $complex_format_map->{$tag}->[0]; - if ($@) - { - print "$ERROR: eval of complex_format_map->{$tag}->[0] $complex_format_map->{$tag}->[0]: $@"; - $start = '
'
-	  }
-	  $in_pre = 1 if $start =~ /
\n", __LINE__));
-		    &html_push_if('TABLE');
-		} else {
-		    push(@lines, &debug("
\n", __LINE__)); - &html_push_if('DL'); - } - push(@lines, &html_debug('', __LINE__)); - } else { - warn "$ERROR Bad table line: $_"; - } - next; - } - elsif ($tag eq 'synindex' || $tag eq 'syncodeindex') - { - if (/^\@$tag\s+(\w+)\s+(\w+)\s*$/) - { - my $from = $1; - my $to = $2; - my $prefix_from = IndexName2Prefix($from); - my $prefix_to = IndexName2Prefix($to); - - warn("$ERROR unknown from index name $from ind syn*index line: $_"), next - unless $prefix_from; - warn("$ERROR unknown to index name $to ind syn*index line: $_"), next - unless $prefix_to; - - if ($tag eq 'syncodeindex') - { - $index_properties->{$prefix_to}->{'from_code'}->{$prefix_from} = 1; - } - else - { - $index_properties->{$prefix_to}->{'from'}->{$prefix_from} = 1; - } - } - else - { - warn "$ERROR Bad syn*index line: $_"; - } - next; - } - elsif ($tag eq 'defindex' || $tag eq 'defcodeindex') - { - if (/^\@$tag\s+(\w+)\s*$/) - { - my $name = $1; - $index_properties->{$name}->{name} = $name; - $index_properties->{$name}->{code} = 1 if $tag eq 'defcodeindex'; - } - else - { - warn "$ERROR Bad defindex line: $_"; - } - next; - } - elsif (/^\@printindex/) - { - push (@lines, "$_"); - next; - } - elsif ($tag eq 'sp') { - push(@lines, &debug("

\n", __LINE__)); - next; - } elsif ($tag eq 'center') { - push(@lines, &debug("

\n", __LINE__)); - s/\@center//; - } elsif ($tag eq 'setref') { - &protect_html; # if setref contains '&' for instance - if (/^\@$tag\s*{($NODERE)}\s*$/) { - $setref = $1; - $setref =~ s/\s+/ /g; # normalize - $setref =~ s/ $//; - $node2sec{$setref} = $name; - $sec2node{$name} = $setref; - $node2href{$setref} = "$docu_doc#$docid"; - } else { - warn "$ERROR Bad setref line: $_"; - } - next; - } elsif ($tag eq 'lowersections') { - local ($sec, $level); - while (($sec, $level) = each %sec2level) { - $sec2level{$sec} = $level + 1; - } - next; - } elsif ($tag eq 'raisesections') { - local ($sec, $level); - while (($sec, $level) = each %sec2level) { - $sec2level{$sec} = $level - 1; - } - next; - } - elsif ($tag eq 'macro' || $tag eq 'rmacro') - { - if (/^\@$tag\s*(\w+)\s*(.*)/) - { - my $name = $1; - my @args; - @args = split(/\s*,\s*/ , $1) - if ($2 =~ /^\s*{(.*)}\s*/); - - $macros->{$name}->{Args} = \@args; - $macros->{$name}->{Body} = ''; - while (($_ = &next_line) && $_ !~ /\@end $tag/) - { - $macros->{$name}->{Body} .= $_; - } - die "ERROR: No closing '\@end $tag' found for macro definition of '$name'\n" - unless (/\@end $tag/); - chomp $macros->{$name}->{Body}; - } - else - { - warn "$ERROR: Bad macro defintion $_" - } - next; - } - elsif ($tag eq 'unmacro') - { - delete $macros->{$1} if (/^\@unmacro\s*(\w+)/); - next; - } - elsif ($tag eq 'documentlanguage') - { - SetDocumentLanguage($1) if (!$T2H_LANG && /documentlanguage\s*(\w+)/); - } - elsif (defined($def_map{$tag})) { - if ($def_map{$tag}) { - s/^\@$tag\s+//; - $tag = $def_map{$tag}; - $_ = "\@$tag $_"; - $tag =~ s/\s.*//; - } - } elsif (defined($user_sub{$tag})) { - s/^\@$tag\s+//; - $sub = $user_sub{$tag}; - print "# user $tag = $sub, arg: $_" if $T2H_DEBUG & $DEBUG_USER; - if (defined(&$sub)) { - chop($_); - &$sub($_); - } else { - warn "$ERROR Bad user sub for $tag: $sub\n"; - } - next; - } - if (defined($def_map{$tag})) { - s/^\@$tag\s+//; - if ($tag =~ /x$/) { - # extra definition line - $tag = $`; - $is_extra = 1; - } else { - $is_extra = 0; - } - while (/\{([^\{\}]*)\}/) { - # this is a {} construct - ($before, $contents, $after) = ($`, $1, $'); - # protect spaces - $contents =~ s/\s+/$;9/g; - # restore $_ protecting {} - $_ = "$before$;7$contents$;8$after"; - } - @args = split(/\s+/, &protect_html($_)); - foreach (@args) { - s/$;9/ /g; # unprotect spaces - s/$;7/\{/g; # ... { - s/$;8/\}/g; # ... } - } - $type = shift(@args); - $type =~ s/^\{(.*)\}$/$1/; - print "# def ($tag): {$type} ", join(', ', @args), "\n" - if $T2H_DEBUG & $DEBUG_DEF; - $type .= ':'; # it's nicer like this - my $name = shift(@args); - $name =~ s/^\{(.*)\}$/$1/; - if ($is_extra) { - $_ = &debug("
", __LINE__); - } else { - $_ = &debug("
\n
", __LINE__); - } - if ($tag eq 'deffn' || $tag eq 'defvr' || $tag eq 'deftp') { - $_ .= "$type $name"; - $_ .= " @args" if @args; - } elsif ($tag eq 'deftypefn' || $tag eq 'deftypevr' - || $tag eq 'defcv' || $tag eq 'defop') { - $ftype = $name; - $name = shift(@args); - $name =~ s/^\{(.*)\}$/$1/; - $_ .= "$type $ftype $name"; - $_ .= " @args" if @args; - } else { - warn "$ERROR Unknown definition type: $tag\n"; - $_ .= "$type $name"; - $_ .= " @args" if @args; - } - $_ .= &debug("\n
", __LINE__); - $name = &unprotect_html($name); - if ($tag eq 'deffn' || $tag eq 'deftypefn') { - EnterIndexEntry('f', $name, $docu_doc, $section, \@lines); -# unshift(@input_spool, "\@findex $name\n"); - } elsif ($tag eq 'defop') { - EnterIndexEntry('f', "$name on $ftype", $docu_doc, $section, \@lines); -# unshift(@input_spool, "\@findex $name on $ftype\n"); - } elsif ($tag eq 'defvr' || $tag eq 'deftypevr' || $tag eq 'defcv') { - EnterIndexEntry('v', $name, $docu_doc, $section, \@lines); -# unshift(@input_spool, "\@vindex $name\n"); - } else { - EnterIndexEntry('t', $name, $docu_doc, $section, \@lines); -# unshift(@input_spool, "\@tindex $name\n"); - } - $dont_html = 1; - } - } elsif ($end_tag) { - if ($format_map{$end_tag}) { - $in_pre = 0 if $format_map{$end_tag} eq 'PRE'; - $in_list-- if $format_map{$end_tag} eq 'UL' || $format_map{$end_tag} eq 'OL' ; - &html_pop_if('P'); - &html_pop_if('LI'); - &html_pop_if(); - push(@lines, &debug("\n", __LINE__)); - push(@lines, &html_debug('', __LINE__)); - } - elsif (exists $complex_format_map->{$end_tag}) - { - my $end = eval $complex_format_map->{$end_tag}->[1]; - if ($@) - { - print "$ERROR: eval of complex_format_map->{$end_tag}->[1] $complex_format_map->{$end_tag}->[0]: $@"; - $end = '
' - } - $in_pre = 0 if $end =~ m|
|; - push(@lines, html_debug($end, __LINE__)); - } elsif ($end_tag =~ /^(|f|v|multi)table$/) { - unless (@tables) { - warn "$ERROR \@end $end_tag without \@*table\n"; - next; - } - &html_pop_if('P'); - ($table_type, $in_table) = split($;, shift(@tables)); - unless ($1 eq $table_type) { - warn "$ERROR \@end $end_tag without matching \@$end_tag\n"; - next; - } - if ($table_type eq "multi") { - push(@lines, "
\n"); - &html_pop_if('TR'); - } else { - push(@lines, "\n"); - &html_pop_if('DD'); - } - &html_pop_if(); - if (@tables) { - ($table_type, $in_table) = split($;, $tables[0]); - } else { - $in_table = 0; - } - } elsif (defined($def_map{$end_tag})) { - push(@lines, &debug("\n", __LINE__)); - } elsif ($end_tag eq 'menu') { - &html_pop_if(); - push(@lines, $_); # must keep it for pass 2 - } - next; - } - ############################################################# - # anchor insertion - while (/\@anchor\s*\{(.*?)\}/) - { - $_ = $`.$'; - my $anchor = $1; - $anchor = &normalise_node($anchor); - push @lines, &html_debug("\n"); - $node2href{$anchor} = "$docu_doc#$anchor"; - next INPUT_LINE if $_ =~ /^\s*$/; - } - - ############################################################# - # index entry generation, after value substitutions - if (/^\@(\w+?)index\s+/) - { - EnterIndexEntry($1, $', $docu_doc, $section, \@lines); - next; - } - # - # protect texi and HTML things - &protect_texi; - $_ = &protect_html($_) unless $dont_html; - $dont_html = 0; - # substitution (unsupported things) - s/^\@exdent\s+//g; - s/\@noindent\s+//g; - s/\@refill\s+//g; - # other substitutions - &simple_substitutions; - s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4 - # - # analyze the tag again - # - if ($tag) { - if (defined($sec2level{$tag}) && $sec2level{$tag} > 0) { - if (/^\@$tag\s+(.+)$/) { - $name = $1; - $name = &normalise_node($name); - $level = $sec2level{$tag}; - # check for index -# $first_index_chapter = $name - $first_index_chapter = $node - if ($level == 1 && !$first_index_chapter && - $name =~ /index/i); -if ($level == 1 && $name =~ /index/i) { - print "# at level 1 found '" . $name . "' as matching index name (node = '" . $node . "')\n"; - print "# first index chapter = '" . $first_index_chapter . "' \n"; -} - if ($in_top && /heading/){ - $T2H_HAS_TOP_HEADING = 1; - $_ = &debug("$name\n", __LINE__); - &html_push_if('body'); - print "# top heading, section $name, level $level\n" - if $T2H_DEBUG & $DEBUG_TOC; - } - else - { - unless (/^\@\w*heading/) - { - unless (/^\@unnumbered/) - { - my $number = &update_sec_num($tag, $level); - $name = $number. ' ' . $name if $T2H_NUMBER_SECTIONS; - $sec2number{$name} = $number; - $number2sec{$number} = $name; - } - if (defined($toplevel)) - { - push @lines, ($level==$toplevel ? $CHAPTEREND : $SECTIONEND); - } - else - { - # first time we see a "section" - unless ($level == 1) - { - warn "$WARN The first section found is not of level 1: $_"; - } - $toplevel = $level; - } - push(@sections, $name); - next_doc() if ($T2H_SPLIT eq 'section' || - $T2H_SPLIT && $level == $toplevel); - } - $sec_num++; - $docid = "SEC$sec_num"; - $tocid = (/^\@\w*heading/ ? undef : "TOC$sec_num"); - # check biblio and glossary - $in_bibliography = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*bibliography$/i); - $in_glossary = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*glossary$/i); - # check node - if ($node) - { - warn "$ERROR Duplicate node found: $node\n" - if ($node2sec{$node}); - } - else - { - $name .= ' ' while ($node2sec{$name}); - $node = $name; - } - $name .= ' ' while ($sec2node{$name}); - $section = $name; - $node2sec{$node} = $name; - $sec2node{$name} = $node; - $node2href{$node} = "$docu_doc#$docid"; -print "# set node2href for '" . $node . "' (" . $name . ") to '" . $node2href{$node} . "'\n" - if ($node =~ /index/i); - $node2next{$node} = $node_next; - $node2prev{$node} = $node_prev; - $node2up{$node} = $node_up; - print "# node $node, section $name, level $level\n" - if $T2H_DEBUG & $DEBUG_TOC; - - $node = ''; - $node_next = ''; - $node_prev = ''; - $node_next = ''; - if ($tocid) - { - # update TOC - while ($level > $curlevel) { - $curlevel++; - push(@toc_lines, "
    \n"); - } - while ($level < $curlevel) { - $curlevel--; - push(@toc_lines, "
\n"); - } - $_ = &t2h_anchor($tocid, "$docu_doc#$docid", $name, 1); - $_ = &substitute_style($_); - push(@stoc_lines, "$_
\n") if ($level == 1); - if ($T2H_NUMBER_SECTIONS) - { - push(@toc_lines, $_ . "
\n") - } - else - { - push(@toc_lines, "
  • " . $_ ."
  • "); - } - } - else - { - push(@lines, &html_debug("\n", - __LINE__)); - } - # update DOC - push(@lines, &html_debug('', __LINE__)); - &html_reset; - $_ = " $name \n\n"; - $_ = &debug($_, __LINE__); - push(@lines, &html_debug('', __LINE__)); - } - # update DOC - foreach $line (split(/\n+/, $_)) { - push(@lines, "$line\n"); - } - next; - } else { - warn "$ERROR Bad section line: $_"; - } - } else { - # track variables - $value{$1} = Unprotect_texi($2), next if /^\@set\s+($VARRE)\s+(.*)$/o; - delete $value{$1}, next if /^\@clear\s+($VARRE)\s*$/o; - # store things - $value{'_shorttitle'} = Unprotect_texi($1), next if /^\@shorttitle\s+(.*)$/; - $value{'_setfilename'} = Unprotect_texi($1), next if /^\@setfilename\s+(.*)$/; - $value{'_settitle'} = Unprotect_texi($1), next if /^\@settitle\s+(.*)$/; - $value{'_author'} .= Unprotect_texi($1)."\n", next if /^\@author\s+(.*)$/; - $value{'_subtitle'} .= Unprotect_texi($1)."\n", next if /^\@subtitle\s+(.*)$/; - $value{'_title'} .= Unprotect_texi($1)."\n", next if /^\@title\s+(.*)$/; - - # list item - if (/^\s*\@itemx?\s+/) { - $what = $'; - $what =~ s/\s+$//; - if ($in_bibliography && $use_bibliography) { - if ($what =~ /^$BIBRE$/o) { - $id = 'BIB' . ++$bib_num; - $bib2href{$what} = "$docu_doc#$id"; - print "# found bibliography for '$what' id $id\n" - if $T2H_DEBUG & $DEBUG_BIB; - $what = &t2h_anchor($id, '', $what); - } - } elsif ($in_glossary && $T2H_USE_GLOSSARY) { - $id = 'GLOSS' . ++$gloss_num; - $entry = $what; - $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/; - $gloss2href{$entry} = "$docu_doc#$id"; - print "# found glossary for '$entry' id $id\n" - if $T2H_DEBUG & $DEBUG_GLOSS; - $what = &t2h_anchor($id, '', $what); - } - elsif ($in_table && ($table_type eq 'f' || $table_type eq 'v')) - { - EnterIndexEntry($table_type, $what, $docu_doc, $section, \@lines); - } - &html_pop_if('P'); - if ($html_element eq 'DL' || $html_element eq 'DD') { - if ($things_map{$in_table} && !$what) { - # special case to allow @table @bullet for instance - push(@lines, &debug("
    $things_map{$in_table}\n", __LINE__)); - } else { - push(@lines, &debug("
    \@$in_table\{$what\}\n", __LINE__)); - } - push(@lines, "
    "); - &html_push('DD') unless $html_element eq 'DD'; - if ($table_type) { # add also an index - unshift(@input_spool, "\@${table_type}index $what\n"); - } - } elsif ($html_element eq 'TABLE') { - push(@lines, &debug("$what\n", __LINE__)); - &html_push('TR'); - } elsif ($html_element eq 'TR') { - push(@lines, &debug("\n", __LINE__)); - push(@lines, &debug("$what\n", __LINE__)); - } else { - push(@lines, &debug("
  • $what\n", __LINE__)); - &html_push('LI') unless $html_element eq 'LI'; - } - push(@lines, &html_debug('', __LINE__)); - if ($deferred_ref) { - push(@lines, &debug("$deferred_ref\n", __LINE__)); - $deferred_ref = ''; - } - next; - } elsif (/^\@tab\s+(.*)$/) { - push(@lines, "$1\n"); - next; - } - } - } - # paragraph separator - if ($_ eq "\n" && ! $in_pre) { - next if $#lines >= 0 && $lines[$#lines] eq "\n"; - if ($html_element eq 'P') { - push (@lines, &debug("

    \n", __LINE__)); - } -# else -# { -# push(@lines, "

    \n"); -# $_ = &debug("

    \n", __LINE__); -# } - elsif ($html_element eq 'body' || $html_element eq 'BLOCKQUOTE' || $html_element eq 'DD' || $html_element eq 'LI') - { - &html_push('P'); - push(@lines, &debug("

    \n", __LINE__)); - } - } - # otherwise - push(@lines, $_) unless $in_titlepage; - push(@lines, &debug("

  • \n", __LINE__)) if ($tag eq 'center'); -} - -# finish TOC -$level = 0; -while ($level < $curlevel) { - $curlevel--; - push(@toc_lines, "\n"); -} - -print "# end of pass 1\n" if $T2H_VERBOSE; - -SetDocumentLanguage('en') unless ($T2H_LANG); -#+++############################################################################ -# # -# Stuff related to Index generation # -# # -#---############################################################################ - -sub EnterIndexEntry -{ - my $prefix = shift; - my $key = shift; - my $docu_doc = shift; - my $section = shift; - my $lines = shift; - local $_; - - warn "$ERROR Undefined index command: $_", next - unless (exists ($index_properties->{$prefix})); - $key =~ s/\s+$//; - $_ = $key; - &protect_texi; - $key = $_; - $_ = &protect_html($_); - my $html_key = substitute_style($_); - my $id; - $key = remove_style($key); - $key = remove_things($key); - $_ = $key; - &unprotect_texi; - $key = $_; - while (exists $index->{$prefix}->{$key}) {$key .= ' '}; - if ($lines->[$#lines] =~ /^$/) - { - $id = $1; - } - else - { - $id = 'IDX' . ++$idx_num; - push(@$lines, &t2h_anchor($id, '', $T2H_INVISIBLE_MARK, !$in_pre)); - } - $index->{$prefix}->{$key}->{html_key} = $html_key; - $index->{$prefix}->{$key}->{section} = $section; - $index->{$prefix}->{$key}->{href} = "$docu_doc#$id"; - print "# found ${prefix}index for '$key' with id $id\n" - if $T2H_DEBUG & $DEBUG_INDEX; -} - -sub IndexName2Prefix -{ - my $name = shift; - my $prefix; - - for $prefix (keys %$index_properties) - { - return $prefix if ($index_properties->{$prefix}->{name} eq $name); - } - return undef; -} - -sub GetIndexEntries -{ - my $normal = shift; - my $code = shift; - my ($entries, $prefix, $key) = ({}); - - for $prefix (keys %$normal) - { - for $key (keys %{$index->{$prefix}}) - { - $entries->{$key} = {%{$index->{$prefix}->{$key}}}; - } - } - - if (defined($code)) - { - for $prefix (keys %$code) - { - unless (exists $normal->{$keys}) - { - for $key (keys %{$index->{$prefix}}) - { - $entries->{$key} = {%{$index->{$prefix}->{$key}}}; - $entries->{$key}->{html_key} = "$entries->{$key}->{html_key}"; - } - } - } - } - return $entries; -} - -sub byAlpha -{ - if ($a =~ /^[A-Za-z]/) - { - if ($b =~ /^[A-Za-z]/) - { - return lc($a) cmp lc($b); - } - else - { - return 1; - } - } - elsif ($b =~ /^[A-Za-z]/) - { - return -1; - } - else - { - return lc($a) cmp lc($b); - } -} - -sub GetIndexPages -{ - my $entries = shift; - my (@Letters, $key); - my ($EntriesByLetter, $Pages, $page) = ({}, [], {}); - my @keys = sort byAlpha keys %$entries; - - for $key (@keys) - { - push @{$EntriesByLetter->{uc(substr($key,0, 1))}} , $entries->{$key}; - } - @Letters = sort byAlpha keys %$EntriesByLetter; - - $T2H_SPLIT_INDEX = 0 unless ($T2H_SPLIT); - - unless ($T2H_SPLIT_INDEX) - { - $page->{First} = $Letters[0]; - $page->{Last} = $Letters[$#Letters]; - $page->{Letters} = \@Letters; - $page->{EntriesByLetter} = $EntriesByLetter; - push @$Pages, $page; - return $Pages; - } - - if ($T2H_SPLIT_INDEX =~ /^\d+$/) - { - my $i = 0; - my ($prev_letter, $letter); - $page->{First} = $Letters[0]; - for $letter (@Letters) - { - if ($i > $T2H_SPLIT_INDEX) - { - $page->{Last} = $prev_letter; - push @$Pages, {%$page}; - $page->{Letters} = []; - $page->{EntriesByLetter} = {}; - $page->{First} = $letter; - $i=0; - } - push @{$page->{Letters}}, $letter; - $page->{EntriesByLetter}->{$letter} = [@{$EntriesByLetter->{$letter}}]; - $i += scalar(@{$EntriesByLetter->{$letter}}); - $prev_letter = $letter; - } - $page->{Last} = $Letters[$#Letters]; - push @$Pages, {%$page}; - } - return $Pages; -} - -sub GetIndexSummary -{ - my $first_page = shift; - my $Pages = shift; - my $name = shift; - my ($page, $letter, $summary, $i, $l1, $l2, $l); - - $i = 0; - $summary = '
    Jump to:   '; - - for $page ($first_page, @$Pages) - { - for $letter (@{$page->{Letters}}) - { - $l = t2h_anchor('', "$page->{href}#${name}_$letter", "$letter", - 0, 'style="text-decoration:none"') . "\n   \n"; - - if ($letter =~ /^[A-Za-z]/) - { - $l2 .= $l; - } - else - { - $l1 .= $l; - } - } - } - $summary .= $l1 . "
    \n" if ($l1); - $summary .= $l2 . '

    '; - return $summary; -} - -sub PrintIndexPage -{ - my $lines = shift; - my $summary = shift; - my $page = shift; - my $name = shift; - - push @$lines, $summary; - - push @$lines , <

    - - - -EOT - - for $letter (@{$page->{Letters}}) - { - push @$lines, "\n"; - for $entry (@{$page->{EntriesByLetter}->{$letter}}) - { - push @$lines, - "\n"; - } - push @$lines, "\n"; - } - push @$lines, "
    Index Entry Section

    $letter
    " . - t2h_anchor('', $entry->{href}, $entry->{html_key}) . - "" . - t2h_anchor('', sec_href($entry->{section}), clean_name($entry->{section})) . - "

    "; - push @$lines, $summary; -} - -sub PrintIndex -{ - my $lines = shift; - my $name = shift; - my $section = shift; - $section = 'Top' unless $section; - my $prefix = IndexName2Prefix($name); - - warn ("$ERROR printindex: bad index name: $name"), return - unless $prefix; - - if ($index_properties->{$prefix}->{code}) - { - $index_properties->{$prefix}->{from_code}->{$prefix} = 1; - } - else - { - $index_properties->{$prefix}->{from}->{$prefix}= 1; - } - - my $Entries = GetIndexEntries($index_properties->{$prefix}->{from}, - $index_properties->{$prefix}->{from_code}); - return unless %$Entries; - - if ($T2H_IDX_SUMMARY) - { - my $key; - open(FHIDX, ">$docu_rdir$docu_name" . "_$name.idx") - || die "Can't open > $docu_rdir$docu_name" . "_$name.idx for writing: $!\n"; - print "# writing $name index summary in $docu_rdir$docu_name" . "_$name.idx...\n" if $T2H_VERBOSE; - - for $key (sort keys %$Entries) - { - print FHIDX "$key\t$Entries->{$key}->{href}\n"; - } - } - - my $Pages = GetIndexPages($Entries); - my $page; - my $first_page = shift @$Pages; - my $sec_name = $section; - # remove section number - $sec_name =~ s/.*? // if $sec_name =~ /^([A-Z]|\d+)\./; - - ($first_page->{href} = sec_href($section)) =~ s/\#.*$//; - # Update tree structure of document - if (@$Pages) - { - my $sec; - my @after; - - while (@sections && $sections[$#sections] ne $section) - { - unshift @after, pop @sections; - } - - for $page (@$Pages) - { - my $node = ($page->{First} ne $page->{Last} ? - "$sec_name: $page->{First} -- $page->{Last}" : - "$sec_name: $page->{First}"); - push @sections, $node; - $node2sec{$node} = $node; - $sec2node{$node} = $node; - $node2up{$node} = $section; - $page->{href} = next_doc(); - $page->{name} = $node; - $node2href{$node} = $page->{href}; - if ($prev_node) - { - $node2next{$prev_node} = $node; - $node2prev{$node} = $prev_node; - } - $prev_node = $node; - } - push @sections, @after; - } - - my $summary = GetIndexSummary($first_page, $Pages, $name); - PrintIndexPage($lines, $summary, $first_page, $name); - for $page (@$Pages) - { - push @$lines, ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND); - push @$lines, "

    $page->{name}

    \n"; - PrintIndexPage($lines, $summary, $page, $name); - } -} - - -#+++############################################################################ -# # -# Pass 2/3: handle style, menu, index, cross-reference # -# # -#---############################################################################ - -@lines2 = (); # whole document (2nd pass) -@lines3 = (); # whole document (3rd pass) -$in_menu = 0; # am I inside a menu - -while (@lines) { - $_ = shift(@lines); - # - # special case (protected sections) - # - if (/^$PROTECTTAG/o) { - push(@lines2, $_); - next; - } - # - # menu - # - if (/^\@menu\b/) - { - $in_menu = 1; - $in_menu_listing = 1; - push(@lines2, &debug("
    \n", __LINE__)); - next; - } - if (/^\@end\s+menu\b/) - { - if ($in_menu_listing) - { - push(@lines2, &debug("
    \n", __LINE__)); - } - else - { - push(@lines2, &debug("\n", __LINE__)); - } - $in_menu = 0; - $in_menu_listing = 0; - next; - } - if ($in_menu) - { - my ($node, $name, $descr); - if (/^\*\s+($NODERE)::/o) - { - $node = $1; - $descr = $'; - } - elsif (/^\*\s+(.+):\s+([^\t,\.\n]+)[\t,\.\n]/) - { - $name = $1; - $node = $2; - $descr = $'; - } - elsif (/^\*/) - { - warn "$ERROR Bad menu line: $_"; - } - else - { - if ($in_menu_listing) - { - $in_menu_listing = 0; - push(@lines2, &debug("\n", __LINE__)); - } - # should be like verbatim -- preseve spaces, etc - s/ /\ /g; - $_ .= "
    \n"; - push(@lines2, $_); - } - if ($node) - { - if (! $in_menu_listing) - { - $in_menu_listing = 1; - push(@lines2, &debug("\n", __LINE__)); - } - # look for continuation - while ($lines[0] =~ /^\s+\w+/) - { - $descr .= shift(@lines); - } - &menu_entry($node, $name, $descr); - } - next; - } - # - # printindex - # - PrintIndex(\@lines2, $2, $1), next - if (/^\@printindex\s+(\w+)/); - # - # simple style substitutions - # - $_ = &substitute_style($_); - # - # xref - # - while (/\@(x|px|info|)ref{([^{}]+)(}?)/) { - # note: Texinfo may accept other characters - ($type, $nodes, $full) = ($1, $2, $3); - ($before, $after) = ($`, $'); - if (! $full && $after) { - warn "$ERROR Bad xref (no ending } on line): $_"; - $_ = "$before$;0${type}ref\{$nodes$after"; - next; # while xref - } - if ($type eq 'x') { - $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} "; - } elsif ($type eq 'px') { - $type = "$T2H_WORDS->{$T2H_LANG}->{'see'} "; - } elsif ($type eq 'info') { - $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} Info"; - } else { - $type = ''; - } - unless ($full) { - $next = shift(@lines); - $next = &substitute_style($next); - chop($nodes); # remove final newline - if ($next =~ /\}/) { # split on 2 lines - $nodes .= " $`"; - $after = $'; - } else { - $nodes .= " $next"; - $next = shift(@lines); - $next = &substitute_style($next); - chop($nodes); - if ($next =~ /\}/) { # split on 3 lines - $nodes .= " $`"; - $after = $'; - } else { - warn "$ERROR Bad xref (no ending }): $_"; - $_ = "$before$;0xref\{$nodes$after"; - unshift(@lines, $next); - next; # while xref - } - } - } - $nodes =~ s/\s+/ /g; # remove useless spaces - @args = split(/\s*,\s*/, $nodes); - $node = $args[0]; # the node is always the first arg - $node = &normalise_node($node); - $sec = $args[2] || $args[1] || $node2sec{$node}; - $href = $node2href{$node}; - if (@args == 5) { # reference to another manual - $sec = $args[2] || $node; - $man = $args[4] || $args[3]; - $_ = "${before}${type}$T2H_WORDS->{$T2H_LANG}->{'section'} `$sec' in \@cite{$man}$after"; - } elsif ($type =~ /Info/) { # inforef - warn "$ERROR Wrong number of arguments: $_" unless @args == 3; - ($nn, $_, $in) = @args; - $_ = "${before}${type} file `$in', node `$nn'$after"; - } elsif ($sec && $href && ! $T2H_SHORT_REF) { - $_ = "${before}${type}"; - $_ .= "$T2H_WORDS->{$T2H_LANG}->{'section'} " if ${type}; - $_ .= &t2h_anchor('', $href, $sec) . $after; - } - elsif ($href) - { - $_ = "${before}${type} " . - &t2h_anchor('', $href, $args[2] || $args[1] || $node) . - $after; - } - else { - warn "$ERROR Undefined node ($node): $_"; - $_ = "$before$;0xref{$nodes}$after"; - } - } - - # replace images - s[\@image\s*{(.+?)}] - { - my @args = split (/\s*,\s*/, $1); - my $base = $args[0]; - my $image = - LocateIncludeFile("$base.png") || - LocateIncludeFile("$base.jpg") || - LocateIncludeFile("$base.gif"); - warn "$ERROR no image file for $base: $_" unless ($image && -e $image); - "\"$base\""; - ($T2H_CENTER_IMAGE ? - "
    \"$base\"
    " : - "\"$base\""); - }eg; - - # - # try to guess bibliography references or glossary terms - # - unless (/^/) { - $done .= $pre . &t2h_anchor('', $href, $what); - } else { - $done .= "$pre$what"; - } - $_ = $post; - } - $_ = $done . $_; - } - if ($T2H_USE_GLOSSARY) { - $done = ''; - while (/\b\w+\b/) { - ($pre, $what, $post) = ($`, $&, $'); - $entry = $what; - $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/; - $href = $gloss2href{$entry}; - if (defined($href) && $post !~ /^[^<]*<\/A>/) { - $done .= $pre . &t2h_anchor('', $href, $what); - } else { - $done .= "$pre$what"; - } - $_ = $post; - } - $_ = $done . $_; - } - } - # otherwise - push(@lines2, $_); -} -print "# end of pass 2\n" if $T2H_VERBOSE; - -# -# split style substitutions -# -while (@lines2) { - $_ = shift(@lines2); - # - # special case (protected sections) - # - if (/^$PROTECTTAG/o) { - push(@lines3, $_); - next; - } - # - # split style substitutions - # - $old = ''; - while ($old ne $_) { - $old = $_; - if (/\@(\w+)\{/) { - ($before, $style, $after) = ($`, $1, $'); - if (defined($style_map{$style})) { - $_ = $after; - $text = ''; - $after = ''; - $failed = 1; - while (@lines2) { - if (/\}/) { - $text .= $`; - $after = $'; - $failed = 0; - last; - } else { - $text .= $_; - $_ = shift(@lines2); - } - } - if ($failed) { - die "* Bad syntax (\@$style) after: $before\n"; - } else { - $text = &apply_style($style, $text); - $_ = "$before$text$after"; - } - } - } - } - # otherwise - push(@lines3, $_); -} -print "# end of pass 3\n" if $T2H_VERBOSE; - -#+++############################################################################ -# # -# Pass 4: foot notes, final cleanup # -# # -#---############################################################################ - -@foot_lines = (); # footnotes -@doc_lines = (); # final document -$end_of_para = 0; # true if last line is

    - -while (@lines3) { - $_ = shift(@lines3); - # - # special case (protected sections) - # - if (/^$PROTECTTAG/o) { - push(@doc_lines, $_); - $end_of_para = 0; - next; - } - # - # footnotes - # - while (/\@footnote([^\{\s]+)\{/) { - ($before, $d, $after) = ($`, $1, $'); - $_ = $after; - $text = ''; - $after = ''; - $failed = 1; - while (@lines3) { - if (/\}/) { - $text .= $`; - $after = $'; - $failed = 0; - last; - } else { - $text .= $_; - $_ = shift(@lines3); - } - } - if ($failed) { - die "* Bad syntax (\@footnote) after: $before\n"; - } else { - $foot_num++; - $docid = "DOCF$foot_num"; - $footid = "FOOT$foot_num"; - $foot = "($foot_num)"; - push(@foot_lines, "

    " . &t2h_anchor($footid, "$d#$docid", $foot) . "

    \n"); - $text = "

    $text" unless $text =~ /^\s*

    /; - push(@foot_lines, "$text\n"); - $_ = $before . &t2h_anchor($docid, "$docu_foot#$footid", $foot) . $after; - } - } - # - # remove unnecessary

    - # - if (/^\s*

    \s*$/) { - next if $end_of_para++; - } else { - $end_of_para = 0; - } - # otherwise - push(@doc_lines, $_); -} - -print "# end of pass 4\n" if $T2H_VERBOSE; - -#+++############################################################################ -# # -# Pass 5: print things # -# # -#---############################################################################ - -$T2H_L2H = &l2h_FinishToLatex if ($T2H_L2H); -$T2H_L2H = &l2h_ToHtml if ($T2H_L2H); -$T2H_L2H = &l2h_InitFromHtml if ($T2H_L2H); - -# fix node2up, node2prev, node2next, if desired -if ($has_top_command) -{ - for $section (keys %sec2number) - { - $node = $sec2node{$section}; - $node2up{$node} = Sec2UpNode($section) unless $node2up{$node}; - $node2prev{$node} = Sec2PrevNode($section) unless $node2prev{$node}; - $node2next{$node} = Sec2NextNode($section) unless $node2next{$node}; - } -} - -# prepare %T2H_THISDOC -$T2H_THISDOC{fulltitle} = $value{'_title'} || $value{'_settitle'} || "Untitled Document"; -$T2H_THISDOC{title} = $value{'_settitle'} || $T2H_THISDOC{fulltitle}; -$T2H_THISDOC{author} = $value{'_author'}; -$T2H_THISDOC{subtitle} = $value{'_subtitle'}; -$T2H_THISDOC{shorttitle} = $value{'_shorttitle'}; -for $key (keys %T2H_THISDOC) -{ - $_ = &substitute_style($T2H_THISDOC{$key}); - &unprotect_texi; - s/\s*$//; - $T2H_THISDOC{$key} = $_; -} - -# if no sections, then simply print document as is -unless (@sections) -{ - print "# Writing content into $docu_top_file \n" if $T2H_VERBOSE; - open(FILE, "> $docu_top_file") - || die "$ERROR: Can't open $docu_top_file for writing: $!\n"; - - &$T2H_print_page_head(\*FILE); - $T2H_THIS_SECTION = \@doc_lines; - t2h_print_lines(\*FILE); - &$T2H_print_foot_navigation(\*FILE); - &$T2H_print_page_foot(\*FILE); - close(FILE); - goto Finish; -} - -# initialize $T2H_HREF, $T2H_NAME -%T2H_HREF = - ( - 'First' , sec_href($sections[0]), - 'Last', sec_href($sections[$#sections]), - 'About', $docu_about. '#SEC_About', - ); - -# prepare TOC, OVERVIEW, TOP -$T2H_TOC = \@toc_lines; -$T2H_OVERVIEW = \@stoc_lines; -if ($has_top) -{ - while (1) - { - $_ = shift @doc_lines; - last if /$TOPEND/; - push @$T2H_TOP, $_; - } - $T2H_HREF{'Top'} = $docu_top . '#SEC_Top'; -} -else -{ - $T2H_HREF{'Top'} = $T2H_HREF{First}; -} - -$node2href{Top} = $T2H_HREF{Top}; -$T2H_HREF{Contents} = $docu_toc.'#SEC_Contents' if @toc_lines; -$T2H_HREF{Overview} = $docu_stoc.'#SEC_OVERVIEW' if @stoc_lines; - -# settle on index -if ($T2H_INDEX_CHAPTER) -{ - $T2H_HREF{Index} = $node2href{normalise_node($T2H_INDEX_CHAPTER)}; - warn "$ERROR T2H_INDEX_CHAPTER '$T2H_INDEX_CHAPTER' not found\n" - unless $T2H_HREF{Index}; -} -if (! $T2H_HREF{Index} && $first_index_chapter) -{ - $T2H_INDEX_CHAPTER = $first_index_chapter; - $T2H_HREF{Index} = $node2href{$T2H_INDEX_CHAPTER}; -print "# Set Index HREF to '" . clean_name($T2H_INDEX_CHAPTER) . "' \n"; -} - -print "# Using '" . clean_name($T2H_INDEX_CHAPTER) . "' as index page\n" - if ($T2H_VERBOSE && $T2H_HREF{Index}); - -print "# Using '" . $T2H_HREF{Index} . "' as index href\n"; - -%T2H_NAME = - ( - 'First', clean_name($sec2node{$sections[0]}), - 'Last', clean_name($sec2node{$sections[$#sections]}), - 'About', $T2H_WORDS->{$T2H_LANG}->{'About_Title'}, - 'Contents', $T2H_WORDS->{$T2H_LANG}->{'ToC_Title'}, - 'Overview', $T2H_WORDS->{$T2H_LANG}->{'Overview_Title'}, - 'Index' , clean_name($T2H_INDEX_CHAPTER), - 'Top', clean_name($T2H_TOP_HEADING || $T2H_THISDOC{'title'} || $T2H_THISDOC{'shorttitle'}), - ); - -############################################################################# -# print frame and frame toc file -# -if ( $T2H_FRAMES ) -{ - open(FILE, "> $docu_frame_file") - || die "$ERROR: Can't open $docu_frame_file for writing: $!\n"; - print "# Creating frame in $docu_frame_file ...\n" if $T2H_VERBOSE; - &$T2H_print_frame(\*FILE); - close(FILE); - - open(FILE, "> $docu_toc_frame_file") - || die "$ERROR: Can't open $docu_toc_frame_file for writing: $!\n"; - print "# Creating toc frame in $docu_frame_file ...\n" if $T2H_VERBOSE; - &$T2H_print_toc_frame(\*FILE); - close(FILE); -} - - -############################################################################# -# print Top -# -open(FILE, "> $docu_top_file") - || die "$ERROR: Can't open $docu_top_file for writing: $!\n"; -&$T2H_print_page_head(\*FILE) unless ($T2H_SPLIT); - -if ($has_top) -{ - print "# Creating Top in $docu_top_file ...\n" if $T2H_VERBOSE; - $T2H_THIS_SECTION = $T2H_TOP; - $T2H_HREF{This} = $T2H_HREF{Top}; - $T2H_NAME{This} = $T2H_NAME{Top}; - &$T2H_print_Top(\*FILE); -} - -close(FILE) if $T2H_SPLIT; - -############################################################################# -# Print sections -# -$T2H_NODE{Forward} = $sec2node{$sections[0]}; -$T2H_NAME{Forward} = &clean_name($sec2node{$sections[0]}); -$T2H_HREF{Forward} = sec_href($sections[0]); -$T2H_NODE{This} = 'Top'; -$T2H_NAME{This} = $T2H_NAME{Top}; -$T2H_HREF{This} = $T2H_HREF{Top}; -if ($T2H_SPLIT) -{ - print "# writing " . scalar(@sections) . - " sections in $docu_rdir$docu_name"."_[1..$doc_num]" - if $T2H_VERBOSE; - $previous = ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND); - undef $FH; - $doc_num = 0; -} -else -{ - print "# writing " . scalar(@sections) . " sections in $docu_top_file ..." - if $T2H_VERBOSE; - $FH = \*FILE; - $previous = ''; -} - -$counter = 0; -# loop through sections -while ($section = shift(@sections)) -{ - if ($T2H_SPLIT && ($T2H_SPLIT eq 'section' || $previous eq $CHAPTEREND)) - { - if ($FH) - { - #close previous page - &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter'; - &$T2H_print_page_foot($FH); - close($FH); - undef $FH; - } - } - $T2H_NAME{Back} = $T2H_NAME{This}; - $T2H_HREF{Back} = $T2H_HREF{This}; - $T2H_NODE{Back} = $T2H_NODE{This}; - $T2H_NAME{This} = $T2H_NAME{Forward}; - $T2H_HREF{This} = $T2H_HREF{Forward}; - $T2H_NODE{This} = $T2H_NODE{Forward}; - if ($sections[0]) - { - $T2H_NODE{Forward} = $sec2node{$sections[0]}; - $T2H_NAME{Forward} = &clean_name($T2H_NODE{Forward}); - $T2H_HREF{Forward} = sec_href($sections[0]); - } - else - { - undef $T2H_HREF{Forward}, $T2H_NODE{Forward}, $T2H_NAME{Forward}; - } - - $node = $node2up{$T2H_NODE{This}}; - $T2H_HREF{Up} = $node2href{$node}; - if ($T2H_HREF{Up} eq $T2H_HREF{This} || ! $T2H_HREF{Up}) - { - $T2H_NAME{Up} = $T2H_NAME{Top}; - $T2H_HREF{Up} = $T2H_HREF{Top}; - $T2H_NODE{Up} = 'Up'; - } - else - { - $T2H_NAME{Up} = &clean_name($node); - $T2H_NODE{Up} = $node; - } - - $node = $T2H_NODE{This}; - $node = $node2prev{$node}; - $T2H_NAME{Prev} = &clean_name($node); - $T2H_HREF{Prev} = $node2href{$node}; - $T2H_NODE{Prev} = $node; - - $node = $T2H_NODE{This}; - if ($node2up{$node} && $node2up{$node} ne 'Top'&& - ($node2prev{$node} eq $T2H_NODE{Back} || ! $node2prev{$node})) - { - $node = $node2up{$node}; - while ($node && $node ne $node2up{$node} && ! $node2prev{$node}) - { - $node = $node2up{$node}; - } - $node = $node2prev{$node} - unless $node2up{$node} eq 'Top' || ! $node2up{$node}; - } - else - { - $node = $node2prev{$node}; - } - $T2H_NAME{FastBack} = &clean_name($node); - $T2H_HREF{FastBack} = $node2href{$node}; - $T2H_NODE{FastBack} = $node; - - $node = $T2H_NODE{This}; - $node = $node2next{$node}; - $T2H_NAME{Next} = &clean_name($node); - $T2H_HREF{Next} = $node2href{$node}; - $T2H_NODE{Next} = $node; - - $node = $T2H_NODE{This}; - if ($node2up{$node} && $node2up{$node} ne 'Top'&& - ($node2next{$node} eq $T2H_NODE{Forward} || ! $node2next{$node})) - { - $node = $node2up{$node}; - while ($node && $node ne $node2up{$node} && ! $node2next{$node}) - { - $node = $node2up{$node}; - } - } - $node = $node2next{$node}; - $T2H_NAME{FastForward} = &clean_name($node); - $T2H_HREF{FastForward} = $node2href{$node}; - $T2H_NODE{FastForward} = $node; - - if (! defined($FH)) - { - my $file = $T2H_HREF{This}; - $file =~ s/\#.*$//; - open(FILE, "> $docu_rdir$file") || - die "$ERROR: Can't open $docu_rdir$file for writing: $!\n"; - $FH = \*FILE; - &$T2H_print_page_head($FH); - t2h_print_label($FH); - &$T2H_print_chapter_header($FH) if $T2H_SPLIT eq 'chapter'; - } - else - { - t2h_print_label($FH); - } - - $T2H_THIS_SECTION = []; - while (@doc_lines) { - $_ = shift(@doc_lines); - last if ($_ eq $SECTIONEND || $_ eq $CHAPTEREND); - push(@$T2H_THIS_SECTION, $_); - } - $previous = $_; - &$T2H_print_section($FH); - - if ($T2H_VERBOSE) - { - $counter++; - print "." if $counter =~ /00$/; - } -} -if ($T2H_SPLIT) -{ - &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter'; - &$T2H_print_page_foot($FH); - close($FH); -} -print "\n" if $T2H_VERBOSE; - -############################################################################# -# Print ToC, Overview, Footnotes -# -undef $T2H_HREF{Prev}; -undef $T2H_HREF{Next}; -undef $T2H_HREF{Back}; -undef $T2H_HREF{Forward}; -undef $T2H_HREF{Up}; - -if (@foot_lines) -{ - print "# writing Footnotes in $docu_foot_file...\n" if $T2H_VERBOSE; - open (FILE, "> $docu_foot_file") || die "$ERROR: Can't open $docu_foot_file for writing: $!\n" - if $T2H_SPLIT; - $T2H_HREF{This} = $docu_foot; - $T2H_NAME{This} = $T2H_WORDS->{$T2H_LANG}->{'Footnotes_Title'}; - $T2H_THIS_SECTION = \@foot_lines; - &$T2H_print_Footnotes(\*FILE); - close(FILE) if $T2H_SPLIT; -} - -if (@toc_lines) -{ - print "# writing Toc in $docu_toc_file...\n" if $T2H_VERBOSE; - open (FILE, "> $docu_toc_file") || die "$ERROR: Can't open $docu_toc_file for writing: $!\n" - if $T2H_SPLIT; - $T2H_HREF{This} = $T2H_HREF{Contents}; - $T2H_NAME{This} = $T2H_NAME{Contents}; - $T2H_THIS_SECTION = \@toc_lines; - &$T2H_print_Toc(\*FILE); - close(FILE) if $T2H_SPLIT; -} - -if (@stoc_lines) -{ - print "# writing Overview in $docu_stoc_file...\n" if $T2H_VERBOSE; - open (FILE, "> $docu_stoc_file") || die "$ERROR: Can't open $docu_stoc_file for writing: $!\n" - if $T2H_SPLIT; - - $T2H_HREF{This} = $T2H_HREF{Overview}; - $T2H_NAME{This} = $T2H_NAME{Overview}; - $T2H_THIS_SECTION = \@stoc_lines; - unshift @$T2H_THIS_SECTION, "

    \n"; - push @$T2H_THIS_SECTION, "\n
    \n"; - &$T2H_print_Overview(\*FILE); - close(FILE) if $T2H_SPLIT; -} - -if ($about_body = &$T2H_about_body()) -{ - print "# writing About in $docu_about_file...\n" if $T2H_VERBOSE; - open (FILE, "> $docu_about_file") || die "$ERROR: Can't open $docu_about_file for writing: $!\n" - if $T2H_SPLIT; - - $T2H_HREF{This} = $T2H_HREF{About}; - $T2H_NAME{This} = $T2H_NAME{About}; - $T2H_THIS_SECTION = [$about_body]; - &$T2H_print_About(\*FILE); - close(FILE) if $T2H_SPLIT; -} - -unless ($T2H_SPLIT) -{ - &$T2H_print_page_foot(\*FILE); - close (FILE); -} - -Finish: -&l2h_FinishFromHtml if ($T2H_L2H); -&l2h_Finish if($T2H_L2H); -print "# that's all folks\n" if $T2H_VERBOSE; - -exit(0); - -#+++############################################################################ -# # -# Low level functions # -# # -#---############################################################################ - -sub LocateIncludeFile -{ - my $file = shift; - my $dir; - - return $file if (-e $file && -r $file); - foreach $dir (@T2H_INCLUDE_DIRS) - { - return "$dir/$file" if (-e "$dir/$file" && -r "$dir/$file"); - } - return undef; -} - -sub clean_name -{ - local ($_); - $_ = &remove_style($_[0]); - &unprotect_texi; - return $_; -} - -sub update_sec_num { - local($name, $level) = @_; - my $ret; - - $level--; # here we start at 0 - if ($name =~ /^appendix/ || defined(@appendix_sec_num)) { - # appendix style - if (defined(@appendix_sec_num)) { - &incr_sec_num($level, @appendix_sec_num); - } else { - @appendix_sec_num = ('A', 0, 0, 0); - } - $ret = join('.', @appendix_sec_num[0..$level]); - } else { - # normal style - if (defined(@normal_sec_num)) - { - &incr_sec_num($level, @normal_sec_num); - } - else - { - @normal_sec_num = (1, 0, 0, 0); - } - $ret = join('.', @normal_sec_num[0..$level]); - } - - $ret .= "." if $level == 0; - return $ret; -} - -sub incr_sec_num { - local($level, $l); - $level = shift(@_); - $_[$level]++; - foreach $l ($level+1 .. 3) { - $_[$l] = 0; - } -} - -sub Sec2UpNode -{ - my $sec = shift; - my $num = $sec2number{$sec}; - - return '' unless $num; - return 'Top' unless $num =~ /\.\d+/; - $num =~ s/\.[^\.]*$//; - $num = $num . '.' unless $num =~ /\./; - return $sec2node{$number2sec{$num}}; -} - -sub Sec2PrevNode -{ - my $sec = shift; - my $num = $sec2number{$sec}; - my ($i, $post); - - if ($num =~ /(\w+)(\.$|$)/) - { - $num = $`; - $i = $1; - $post = $2; - if ($i eq 'A') - { - $i = $normal_sec_num[0]; - } - elsif ($i ne '1') - { - # unfortunately, -- operator is not magical - $i = chr(ord($i) + 1); - } - else - { - return ''; - } - return $sec2node{$number2sec{$num . $i . $post}} - } - return ''; -} - -sub Sec2NextNode -{ - my $sec = shift; - my $num = $sec2number{$sec}; - my $i; - - if ($num =~ /(\w+)(\.$|$)/) - { - $num = $`; - $i = $1; - $post = $2; - if ($post eq '.' && $i eq $normal_sec_num[0]) - { - $i = 'A'; - } - else - { - $i++; - } - return $sec2node{$number2sec{$num . $i . $post}} - } - return ''; -} - -sub check { - local($_, %seen, %context, $before, $match, $after); - - while (<>) { - if (/\@(\*|\.|\:|\@|\{|\})/) { - $seen{$&}++; - $context{$&} .= "> $_" if $T2H_VERBOSE; - $_ = "$`XX$'"; - redo; - } - if (/\@(\w+)/) { - ($before, $match, $after) = ($`, $&, $'); - if ($before =~ /\b[\w-]+$/ && $after =~ /^[\w-.]*\b/) { # e-mail address - $seen{'e-mail address'}++; - $context{'e-mail address'} .= "> $_" if $T2H_VERBOSE; - } else { - $seen{$match}++; - $context{$match} .= "> $_" if $T2H_VERBOSE; - } - $match =~ s/^\@/X/; - $_ = "$before$match$after"; - redo; - } - } - - foreach (sort(keys(%seen))) { - if ($T2H_VERBOSE) { - print "$_\n"; - print $context{$_}; - } else { - print "$_ ($seen{$_})\n"; - } - } -} - -sub open { - local($name) = @_; - - ++$fh_name; - if (open($fh_name, $name)) { - unshift(@fhs, $fh_name); - } else { - warn "$ERROR Can't read file $name: $!\n"; - } -} - -sub init_input { - @fhs = (); # hold the file handles to read - @input_spool = (); # spooled lines to read - $fh_name = 'FH000'; - &open($docu); -} - -sub next_line { - local($fh, $line); - - if (@input_spool) { - $line = shift(@input_spool); - return($line); - } - while (@fhs) { - $fh = $fhs[0]; - $line = <$fh>; - return($line) if $line; - close($fh); - shift(@fhs); - } - return(undef); -} - -# used in pass 1, use &next_line -sub skip_until { - local($tag) = @_; - local($_); - - while ($_ = &next_line) { - return if /^\@end\s+$tag\s*$/; - } - die "* Failed to find '$tag' after: " . $lines[$#lines]; -} - -# used in pass 1 for l2h use &next_line -sub string_until { - local($tag) = @_; - local($_, $string); - - while ($_ = &next_line) { - return $string if /^\@end\s+$tag\s*$/; -# $_ =~ s/hbox/mbox/g; - $string = $string.$_; - } - die "* Failed to find '$tag' after: " . $lines[$#lines]; -} - -# -# HTML stacking to have a better HTML output -# - -sub html_reset { - @html_stack = ('html'); - $html_element = 'body'; -} - -sub html_push { - local($what) = @_; - push(@html_stack, $html_element); - $html_element = $what; -} - -sub html_push_if { - local($what) = @_; - push(@html_stack, $html_element) - if ($html_element && $html_element ne 'P'); - $html_element = $what; -} - -sub html_pop { - $html_element = pop(@html_stack); -} - -sub html_pop_if { - local($elt); - - if (@_) { - foreach $elt (@_) { - if ($elt eq $html_element) { - $html_element = pop(@html_stack) if @html_stack; - last; - } - } - } else { - $html_element = pop(@html_stack) if @html_stack; - } -} - -sub html_debug { - local($what, $line) = @_; - if ($T2H_DEBUG & $DEBUG_HTML) - { - $what = "\n" unless $what; - return("$what") - } - return($what); -} - -# to debug the output... -sub debug { - local($what, $line) = @_; - return("$what") - if $T2H_DEBUG & $DEBUG_HTML; - return($what); -} - -sub SimpleTexi2Html -{ - local $_ = $_[0]; - &protect_texi; - &protect_html; - $_ = substitute_style($_); - $_[0] = $_; -} - -sub normalise_node { - local $_ = $_[0]; - s/\s+/ /g; - s/ $//; - s/^ //; - &protect_texi; - &protect_html; - $_ = substitute_style($_); - $_[0] = $_; -} - -sub menu_entry -{ - my ($node, $name, $descr) = @_; - my ($href, $entry); - - &normalise_node($node); - $href = $node2href{$node}; - if ($href) - { - $descr =~ s/^\s+//; - $descr =~ s/\s*$//; - $descr = SimpleTexi2Html($descr); - if ($T2H_NUMBER_SECTIONS && !$T2H_NODE_NAME_IN_MENU && $node2sec{$node}) - { - $entry = $node2sec{$node}; - $name = ''; - } - else - { - &normalise_node($name); - $entry = ($name && ($name ne $node || ! $T2H_AVOID_MENU_REDUNDANCY) - ? "$name : $node" : $node); - } - - if ($T2H_AVOID_MENU_REDUNDANCY && $descr) - { - my $clean_entry = $entry; - $clean_entry =~ s/^.*? // if ($clean_entry =~ /^([A-Z]|\d+)\.[\d\.]* /); - $clean_entry =~ s/[^\w]//g; - my $clean_descr = $descr; - $clean_descr =~ s/[^\w]//g; - $descr = '' if ($clean_entry eq $clean_descr) - } - push(@lines2,&debug('
    \n", __LINE__)); - } - elsif ($node =~ /^\(.*\)\w+/) - { - push(@lines2,&debug('\n", __LINE__)) - } - else - { - warn "$ERROR Undefined node of menu_entry ($node): $_"; - } -} - -sub do_ctrl { "^$_[0]" } - -sub do_email { - local($addr, $text) = split(/,\s*/, $_[0]); - - $text = $addr unless $text; - &t2h_anchor('', "mailto:$addr", $text); -} - -sub do_sc -{ - # l2h does this much better - return &l2h_ToLatex("{\\sc ".&unprotect_html($_[0])."}") if ($T2H_L2H); - return "\U$_[0]\E"; -} - -sub do_math -{ - return &l2h_ToLatex("\$".&unprotect_html($_[0])."\$") if ($T2H_L2H); - return "".$text.""; -} - -sub do_uref { - local($url, $text, $only_text) = split(/,\s*/, $_[0]); - - $text = $only_text if $only_text; - $text = $url unless $text; - &t2h_anchor('', $url, $text); -} - -sub do_url { &t2h_anchor('', $_[0], $_[0]) } - -sub do_acronym -{ - return '' . $_[0] . ''; -} - -sub do_accent -{ - return "&$_[0]acute;" if $_[1] eq 'H'; - return "$_[0]." if $_[1] eq 'dotaccent'; - return "$_[0]*" if $_[1] eq 'ringaccent'; - return "$_[0]".'[' if $_[1] eq 'tieaccent'; - return "$_[0]".'(' if $_[1] eq 'u'; - return "$_[0]_" if $_[1] eq 'ubaraccent'; - return ".$_[0]" if $_[1] eq 'udotaccent'; - return "$_[0]<" if $_[1] eq 'v'; - return "&$_[0]cedil;" if $_[1] eq ','; - return "$_[0]" if $_[1] eq 'dotless'; - return undef; -} - -sub apply_style { - local($texi_style, $text) = @_; - local($style); - - $style = $style_map{$texi_style}; - if (defined($style)) { # known style - if ($style =~ /^\"/) { # add quotes - $style = $'; - $text = "\`$text\'"; - } - if ($style =~ /^\&/) { # custom - $style = $'; - $text = &$style($text, $texi_style); - } elsif ($style) { # good style - $text = "<$style>$text"; - } else { # no style - } - } else { # unknown style - $text = undef; - } - return($text); -} - -# remove Texinfo styles -sub remove_style { - local($_) = @_; - 1 while(s/\@\w+{([^\{\}]+)}/$1/g); - return($_); -} - -sub remove_things -{ - local ($_) = @_; - s|\@(\w+)\{\}|$1|g; - return $_; -} - -sub substitute_style { - local($_) = @_; - local($changed, $done, $style, $text); - - &simple_substitutions; - $changed = 1; - while ($changed) { - $changed = 0; - $done = ''; - while (/\@(\w+){([^\{\}]+)}/ || /\@(,){([^\{\}]+)}/) { - $text = &apply_style($1, $2); - if ($text) { - $_ = "$`$text$'"; - $changed = 1; - } else { - $done .= "$`\@$1"; - $_ = "{$2}$'"; - } - } - $_ = $done . $_; - } - return($_); -} - -sub t2h_anchor { - local($name, $href, $text, $newline, $extra_attribs) = @_; - local($result); - - $result = " - $what =~ s/\&/\&\#38;/g; - $what =~ s/\/\&\#62;/g; - # restore anything in quotes - # this fixes my problem where I had: - # < IMG SRC="leftarrow.gif" ALT="<--" > but what if I wanted < in my ALT text ?? - # maybe byte stuffing or some other technique should be used. - $what =~ s/\"([^\&]+)\&\#60;(.*)\"/"$1<$2"/g; - $what =~ s/\"([^\&]+)\&\#62;(.*)\"/"$1>$2"/g; - $what =~ s/\"([^\&]+)\&\#38;(.*)\"/"$1&$2"/g; - # but recognize some HTML things - $what =~ s/\&\#60;\/A\&\#62;/<\/A>/g; # - $what =~ s/\&\#60;A ([^\&]+)\&\#62;//g; # - $what =~ s/\&\#60;IMG ([^\&]+)\&\#62;//g; # - return($what); -} - -sub unprotect_texi { - s/$;0/\@/go; - s/$;1/\{/go; - s/$;2/\}/go; - s/$;3/\`/go; - s/$;4/\'/go; -} - -sub Unprotect_texi -{ - local $_ = shift; - &unprotect_texi; - return($_); -} - -sub unprotect_html { - local($what) = @_; - $what =~ s/\&\#38;/\&/g; - $what =~ s/\&\#60;/\/g; - return($what); -} - -sub t2h_print_label -{ - my $fh = shift; - my $href = shift || $T2H_HREF{This}; - $href =~ s/.*#(.*)$/$1/; - print $fh qq{\n}; -} - -############################################################################## - - # These next few lines are legal in both Perl and nroff. - -.00 ; # finish .ig - -'di \" finish diversion--previous line must be blank -.nr nl 0-1 \" fake up transition to first page again -.nr % 0 \" start at page 1 -'; __END__ ############# From here on it's a standard manual page ############ -.so /usr/local/man/man1/texi2html.1 diff --git a/tests/savedir/dev-tcp.tests b/tests/savedir/dev-tcp.tests deleted file mode 100644 index 0f3a2281d..000000000 --- a/tests/savedir/dev-tcp.tests +++ /dev/null @@ -1,16 +0,0 @@ -exec 9<>/dev/tcp/129.22.8.162/25 - -read banner <&9 -echo "$banner" - -echo quit >&9 - -read msg <&9 -echo "$msg" - -exec 9<&- - -# nifty date command that queries the date/time server -cat < /dev/tcp/129.22.8.102/13 - -exit 0 diff --git a/tests/savedir/glob-test b/tests/savedir/glob-test deleted file mode 100644 index d32988bc4..000000000 --- a/tests/savedir/glob-test +++ /dev/null @@ -1,388 +0,0 @@ -export LC_COLLATE=C -# -# test the shell globbing -# -expect() -{ - echo expect "$@" -} - -# First, a test that bash-2.01.1 fails -${THIS_SH} ./glob1.sub - -MYDIR=$PWD # save where we are - -TESTDIR=/tmp/glob-test -mkdir $TESTDIR -builtin cd $TESTDIR || { echo $0: cannot cd to $TESTDIR >&2 ; exit 1; } -rm -rf * - -touch a b c d abc abd abe bb bcd ca cb dd de Beware -mkdir bdir - -# see if `regular' globbing works right -expect ' ' -recho a* X* - -expect ' ' -recho \a* - -# see if null glob expansion works -shopt -s nullglob - -expect ' ' -recho a* X* - -shopt -u nullglob - -# see if the failglob option works - -mkdir tmp -touch tmp/l1 tmp/l2 tmp/l3 -builtin echo tmp/l[12] tmp/*4 tmp/*3 -shopt -s failglob -builtin echo tmp/l[12] tmp/*4 tmp/*3 -rm -r tmp -shopt -u failglob - -# see if the code that expands directories only works -expect '' -recho b*/ - -# Test quoted and unquoted globbing characters -expect '<*>' -recho \* - -expect '' -recho 'a*' - -expect '' -recho a\* - -expect ' <*q*>' -recho c* a\* *q* - -expect '<**>' -recho "*"* - -expect '<**>' -recho \** - -expect '<\.\./*/>' -recho "\.\./*/" - -expect '' -recho 's/\..*//' - -# Pattern from Larry Wall's Configure that caused bash to blow up -expect '' -recho "/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*"'$'"/\1/" - -# Make sure character classes work properly - -expect ' ' -recho [a-c]b* - -expect '
    ' -recho [a-y]*[^c] - -expect ' ' -recho a*[^c] - -touch a-b aXb -expect ' ' -recho a[X-]b - -touch .x .y -expect '
    ' -recho [^a-c]* - -# Make sure that filenames with embedded globbing characters are handled -# properly -mkdir a\*b -> a\*b/ooo - -expect '' -recho a\*b/* - -expect '' -recho a\*?/* - -expect '' -cmd='echo !7' -case "$cmd" in -*\\!*) echo match ;; -*) echo no match ;; -esac - -expect '' -file='r.*' -case $file in -*.\*) echo not there ;; -*) echo there ;; -esac - -# examples from the Posix.2 spec (d11.2, p. 243) -expect '' -recho a[b]c - -expect '' -recho a["b"]c - -expect '' -recho a[\b]c - -expect '' -recho a?c - -expect '' -case abc in -a"b"c) echo 'match 1' ;; -*) echo 'BAD match 1' ;; -esac - -expect '' -case abc in -a*c) echo 'match 2' ;; -*) echo 'BAD match 2' ;; -esac - -expect '' -case abc in -"a?c") echo 'bad 1' ;; -*) echo 'ok 1' ;; -esac - -expect '' -case abc in -a\*c) echo 'bad 2' ;; -*) echo 'ok 2' ;; -esac - -expect '' -case abc in -a\[b]c) echo 'bad 3' ;; -*) echo 'ok 3' ;; -esac - -expect '' -case "$nosuchvar" in -"") echo 'ok 4' ;; -*) echo 'bad 4' ;; -esac - -# This is very odd, but sh and ksh seem to agree -expect '' -case abc in -a["\b"]c) echo 'ok 5' ;; -*) echo 'bad 5' ;; -esac - -mkdir man -mkdir man/man1 -touch man/man1/bash.1 -expect '' -recho */man*/bash.* -expect '' -recho $(echo */man*/bash.*) -expect '' -recho "$(echo */man*/bash.*)" - -# tests with multiple `*'s -case abc in -a***c) echo ok 1;; -esac - -case abc in -a*****?c) echo ok 2;; -esac - -case abc in -?*****??) echo ok 3;; -esac - -case abc in -*****??) echo ok 4;; -esac - -case abc in -*****??c) echo ok 5;; -esac - -case abc in -?*****?c) echo ok 6;; -esac - -case abc in -?***?****c) echo ok 7;; -esac - -case abc in -?***?****?) echo ok 8;; -esac - -case abc in -?***?****) echo ok 9;; -esac - -case abc in -*******c) echo ok 10;; -esac - -case abc in -*******?) echo ok 11;; -esac - -case abcdecdhjk in -a*cd**?**??k) echo ok 20;; -esac - -case abcdecdhjk in -a**?**cd**?**??k) echo ok 21;; -esac - -case abcdecdhjk in -a**?**cd**?**??k***) echo ok 22;; -esac - -case abcdecdhjk in -a**?**cd**?**??***k) echo ok 23;; -esac - -case abcdecdhjk in -a**?**cd**?**??***k**) echo ok 24;; -esac - -case abcdecdhjk in -a****c**?**??*****) echo ok 25;; -esac - -case '-' in -[-abc]) echo ok 26 ;; -esac - -case '-' in -[abc-]) echo ok 27 ;; -esac - -case '\' in -\\) echo ok 28 ;; -esac - -case '\' in -[\\]) echo ok 29 ;; -esac - -case '\' in -'\') echo ok 30 ;; -esac - -case '[' in -[[]) echo ok 31 ;; -esac - -# a `[' without a closing `]' is just another character to match, in the -# bash implementation -case '[' in -[) echo ok 32 ;; -esac - -case '[abc' in -[*) echo 'ok 33';; -esac - -# a right bracket shall lose its special meaning and represent itself in -# a bracket expression if it occurs first in the list. -- POSIX.2 2.8.3.2 -case ']' in -[]]) echo ok 34 ;; -esac - -case '-' in -[]-]) echo ok 35 ;; -esac - -# a backslash should just escape the next character in this context -case p in -[a-\z]) echo ok 36 ;; -esac - -# this was a bug in all versions up to bash-2.04-release -case "/tmp" in -[/\\]*) echo ok 37 ;; -esac - -# none of these should output anything - -case abc in -??**********?****?) echo bad 1;; -esac - -case abc in -??**********?****c) echo bad 2;; -esac - -case abc in -?************c****?****) echo bad 3;; -esac - -case abc in -*c*?**) echo bad 4;; -esac - -case abc in -a*****c*?**) echo bad 5;; -esac - -case abc in -a********???*******) echo bad 6;; -esac - -case 'a' in -[]) echo bad 7 ;; -esac - -case '[' in -[abc) echo bad 8;; -esac - -# let's start testing the case-insensitive globbing code -recho b* - -shopt -s nocaseglob -recho b* - -recho [b]* -shopt -u nocaseglob - -# make sure set -f works right -set -f -recho * -set +f - -# test out the GLOBIGNORE code -GLOBIGNORE='.*:*c:*e:?' -recho * - -GLOBIGNORE='.*:*b:*d:?' -recho * - -# see if GLOBIGNORE can substitute for `set -f' -GLOBIGNORE='.*:*' -recho * - -unset GLOBIGNORE -expect '' -recho */man*/bash.* - -# make sure null values for GLOBIGNORE have no effect -GLOBIGNORE= -expect '' -recho */man*/bash.* - -# this is for the benefit of pure coverage, so it writes the pcv file -# in the right place, and for gprof -builtin cd $MYDIR - -rm -rf $TESTDIR - -exit 0 diff --git a/tests/savedir/ifs-1.right b/tests/savedir/ifs-1.right deleted file mode 100644 index af0abb2c9..000000000 --- a/tests/savedir/ifs-1.right +++ /dev/null @@ -1 +0,0 @@ -a:b:c diff --git a/tests/savedir/ifs-1.test b/tests/savedir/ifs-1.test deleted file mode 100644 index a153ce949..000000000 --- a/tests/savedir/ifs-1.test +++ /dev/null @@ -1,5 +0,0 @@ -OIFS="$IFS" -IFS=":$IFS" -eval foo="a:b:c" -IFS="$OIFS" -echo $foo diff --git a/tests/savedir/ifs-2.right b/tests/savedir/ifs-2.right deleted file mode 100644 index af0abb2c9..000000000 --- a/tests/savedir/ifs-2.right +++ /dev/null @@ -1 +0,0 @@ -a:b:c diff --git a/tests/savedir/ifs-2.test b/tests/savedir/ifs-2.test deleted file mode 100644 index 3249f1bf9..000000000 --- a/tests/savedir/ifs-2.test +++ /dev/null @@ -1,9 +0,0 @@ -OIFS=$IFS -IFS=":$IFS" -foo=$(echo a:b:c) -IFS=$OIFS - -for i in $foo -do - echo $i -done diff --git a/tests/savedir/ifs-3.right b/tests/savedir/ifs-3.right deleted file mode 100644 index af0abb2c9..000000000 --- a/tests/savedir/ifs-3.right +++ /dev/null @@ -1 +0,0 @@ -a:b:c diff --git a/tests/savedir/ifs-3.test b/tests/savedir/ifs-3.test deleted file mode 100644 index 4693792a4..000000000 --- a/tests/savedir/ifs-3.test +++ /dev/null @@ -1,9 +0,0 @@ -OIFS=$IFS -IFS=":$IFS" -foo=`echo a:b:c` -IFS=$OIFS - -for i in $foo -do - echo $i -done diff --git a/tests/savedir/input-line-2.sh b/tests/savedir/input-line-2.sh deleted file mode 100644 index b3e126ec8..000000000 --- a/tests/savedir/input-line-2.sh +++ /dev/null @@ -1,4 +0,0 @@ -echo before calling input-line.sub -${THIS_SH} < ./input-line.sub -this line for input-line.sub -echo finished with input-line.sub diff --git a/tests/savedir/minus-e b/tests/savedir/minus-e deleted file mode 100644 index be67ec58f..000000000 --- a/tests/savedir/minus-e +++ /dev/null @@ -1,6 +0,0 @@ -set -e -if set +e -then - false -fi -echo hi diff --git a/tests/savedir/minus-e.right b/tests/savedir/minus-e.right deleted file mode 100644 index 45b983be3..000000000 --- a/tests/savedir/minus-e.right +++ /dev/null @@ -1 +0,0 @@ -hi diff --git a/tests/savedir/perf-script b/tests/savedir/perf-script deleted file mode 100644 index e1172a9df..000000000 --- a/tests/savedir/perf-script +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/bash - -typeset -i m2 m1 M n2 n1 N m n -typeset -i MM=5 NN=5 - -case $# in - 0) : - ;; - 1) MM=$1; NN=$1 - ;; - 2) MM=$1; NN=$2 - ;; - *) echo 1>&2 "Usage: $0 [m [n]]" - ;; -esac - -EMPTYLINE=: # echo -echo 'a = { ' # mathematica - -let "M=1" # for (M=1; M<=MM; M++) -while let "M <= MM"; do - let "N=1" # for (N=1; N<=NN; N++) - while let "N <= NN"; do - - let "m1 = M - 1" - let "m2 = M + 1" - let "n1 = N - 1" - let "n2 = N + 1" - - - echo -n '{ ' # math - let "m=1" # for(m=1; m<=MM; m++) - while let "m <= MM"; do - let "n=1" # for(n=1; n<=NN; n++) - while let "n <= NN"; do - - let "x = (m-m1)*(m-M)*(m-m2)" - let "y = (n-n1)*(n-N)*(n-n2)" - - if let "(x*x + (n-N)*(n-N)) * ((m-M)*(m-M) + y*y)"; then - echo -n "0," - else # neighbour - echo -n "1," - fi - - let "n=n+1" - done - echo -n " "; let "m=m+1" # ". " - done - echo '},' - - - let "N=N+1" - $EMPTYLINE - done - $EMPTYLINE - let "M=M+1" -done - -echo '}' - - - -echo -n 'o = { ' -let "m=1" -while let "m <= MM"; do - let "n=1" - while let "n <= NN"; do - echo -n "1," - let "n=n+1" - done - let "m=m+1" -done -echo " }" - - -echo 'x = LinearSolve[a,o] ' - -exit 0 - - diff --git a/tests/savedir/perftest b/tests/savedir/perftest deleted file mode 100644 index ee3f2c66a..000000000 --- a/tests/savedir/perftest +++ /dev/null @@ -1,10 +0,0 @@ -# originally from Mike Haertel -foo() { case $1 in a*) ;; *) ;; esac ;} -bar() { case $1 in [abc]*) ;; *);; esac ;} -baz() { case $1 in xyzzy) ;; *) ;; esac ;} -for x in /usr/lib/*/* -do - foo $x - bar $x - baz $x -done diff --git a/tests/savedir/read-nchars-int.tests b/tests/savedir/read-nchars-int.tests deleted file mode 100644 index 40b1f982a..000000000 --- a/tests/savedir/read-nchars-int.tests +++ /dev/null @@ -1,11 +0,0 @@ -# interactive - -# from tty -read -n 3 -p 'enter three chars: ' xyz -echo -echo $xyz - -# using readline -read -p 'enter 3 chars: ' -e -n 3 abc -# readline outputs a newline for us, so we don't need the extra echo -echo $abc diff --git a/tests/savedir/read-nchars.tests b/tests/savedir/read-nchars.tests deleted file mode 100644 index 40b1f982a..000000000 --- a/tests/savedir/read-nchars.tests +++ /dev/null @@ -1,11 +0,0 @@ -# interactive - -# from tty -read -n 3 -p 'enter three chars: ' xyz -echo -echo $xyz - -# using readline -read -p 'enter 3 chars: ' -e -n 3 abc -# readline outputs a newline for us, so we don't need the extra echo -echo $abc diff --git a/tests/savedir/redir-t2.sh b/tests/savedir/redir-t2.sh deleted file mode 100644 index 44b2624ee..000000000 --- a/tests/savedir/redir-t2.sh +++ /dev/null @@ -1,17 +0,0 @@ -read line1 - -echo read line 1 \"$line1\" - -exec 4<&0 - -exec 0 <920725204@umunk.GUN.de> - <9207260813.30@rmkhome.UUCP> <1992Jul27.200244.2456@acme.gen.nz> - <9207291604.00@rmkhome.UUCP> - <9208011403.38@rmkhome.UUCP> - -I've reevaluated the allegedly-sh-compatible shells I have on hand (sh, -bash, ash, zsh and a redistributable ksh). bash seems to have improved -since I last looked at it and seems to run inews and subordinates -correctly, and passes the diagnostic tests I extracted from inews and -anne.jones. ash, zsh and redistributable ksh each fail three of the six -tests. This saddens me, as ash is an elegant and relatively small piece -of work, whereas bash is bloated and complicated. - -I've enclosed the test scripts (shx?), driver script (shx) and results -(log) below. A couple caveats: shx4 (a quoting test) uses the C News -getdate command; there may be newer versions of the shells tested - this -evaluation is decidedly informal. Here's a quick summary: sh and bash -passed all tests; ash can't parse "<&$fd" and doesn't understand quoting; -redistributable ksh dumps core on a newline inside backquotes, doesn't -understand quoting, and botches waiting on background processes; zsh -doesn't understand sh quoting (in particular, it sees ! as a job control -character, even inside quotes), and botches waiting for background -processes. - - -# To unbundle, sh this file -echo log 1>&2 -sed 's/^X//' >log <<'!' -X:; ./shx - -sh: -X<&$fd ok -nlbq Mon Aug 3 02:45:00 EDT 1992 -bang geoff -quote 712824302 -setbq defmsgid=<1992Aug3.024502.6176@host> -bgwait sleep done... wait 6187 - - -bash: -X<&$fd ok -nlbq Mon Aug 3 02:45:09 EDT 1992 -bang geoff -quote 712824311 -setbq defmsgid=<1992Aug3.024512.6212@host> -bgwait sleep done... wait 6223 - - -ash: -X<&$fd shx1: 4: Syntax error: Bad fd number -nlbq Mon Aug 3 02:45:19 EDT 1992 -bang geoff -quote getdate: `"now"' not a valid date - -setbq defmsgid=<1992Aug3.` echo 024521 -bgwait sleep done... wait 6241 - - -ksh: -X<&$fd ok -nlbq ./shx: 6248 Memory fault - core dumped -bang geoff -quote getdate: `"now"' not a valid date - -setbq defmsgid=<1992Aug3.024530.6257@host> -bgwait no such job: 6265 -wait 6265 -sleep done... - -zsh: -X<&$fd ok -nlbq Mon Aug 3 02:45:36 EDT 1992 -bang shx3: event not found: /s/ [4] -quote 712824337 -setbq defmsgid=<..6290@host> -bgwait shx7: unmatched " [9] -sleep done... -X:; -! -echo shx 1>&2 -sed 's/^X//' >shx <<'!' -X#! /bin/sh -for cmd in sh bash ash ksh zsh -do -X echo -X echo $cmd: -X for demo in shx? -X do -X $cmd $demo -X done -done -! -echo shx1 1>&2 -sed 's/^X//' >shx1 <<'!' -X# ash fails this one -echo -n '<&$fd ' -fd=3 -echo ok <&$fd -! -echo shx2 1>&2 -sed 's/^X//' >shx2 <<'!' -X# pd ksh fails this one -echo -n "nlbq " -date=` -date` -echo "$date" -! -echo shx3 1>&2 -sed 's/^X//' >shx3 <<'!' -X# zsh fails this one -echo -n 'bang ' -echo 'geoff tty?? Aug 3 02:35' | -X sed -e 's/[ ].*//' -e '/!/s/^.*!//' -! -echo shx4 1>&2 -sed 's/^X//' >shx4 <<'!' -X# ash, pd ksh fail this one -echo -n "quote " -expiry="now" -timet="` getdate \"$expiry\" `" -echo "$timet" -! -echo shx5 1>&2 -sed 's/^X//' >shx5 <<'!' -X# ash, zsh fail this one -echo -n "setbq " -host=host -date="`date`" -echo defmsgid="`set $date; echo \<$6$2$3.\` echo $4 | tr -d : \`.$$@$host\>`" -! -echo shx7 1>&2 -sed 's/^X//' >shx7 <<'!' -X# pd ksh and zsh fail this one -echo -n "bgwait " -X( -X sleep 2 -X echo -n "sleep done... " -X) & -waitcmd="wait $!" -eval $waitcmd -echo "$waitcmd" -! -echo shx8 1>&2 -sed 's/^X//' >shx8 <<'!' -X# in case gcx7 is really breaks this shell -sleep 3 -echo -! -exit 0 diff --git a/tests/savedir/regress/getdate.mk b/tests/savedir/regress/getdate.mk deleted file mode 100644 index 543242e84..000000000 --- a/tests/savedir/regress/getdate.mk +++ /dev/null @@ -1,9 +0,0 @@ -all: getdate - -getdate.c: getdate.y - yacc getdate.y - mv y.tab.c getdate.c - -getdate: getdate.c - $(CC) -o $@ getdate.c - rm -f getdate.c getdate.o diff --git a/tests/savedir/regress/getdate.y b/tests/savedir/regress/getdate.y deleted file mode 100644 index 1df37738d..000000000 --- a/tests/savedir/regress/getdate.y +++ /dev/null @@ -1,553 +0,0 @@ -%token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO -%{ - /* Steven M. Bellovin (unc!smb) */ - /* Dept. of Computer Science */ - /* University of North Carolina at Chapel Hill */ - /* @(#)getdate.y 2.13 9/16/86 */ - -#include -#include -#include -#include -#define timezone tmzn /* ugly hack for obscure name clash */ -#include - -#define daysec (24L*60L*60L) - - static int timeflag, zoneflag, dateflag, dayflag, relflag; - static time_t relsec, relmonth; - static int hh, mm, ss, merid, daylight; - static int dayord, dayreq; - static int month, day, year; - static int ourzone; - -#define AM 1 -#define PM 2 -#define DAYLIGHT 1 -#define STANDARD 2 -#define MAYBE 3 -%} - -%% -timedate: /* empty */ - | timedate item; - -item: tspec = - {timeflag++;} - | zone = - {zoneflag++;} - | dtspec = - {dateflag++;} - | dyspec = - {dayflag++;} - | rspec = - {relflag++;} - | nspec; - -nspec: NUMBER = - {if (timeflag && dateflag && !relflag) year = $1; - else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}}; - -tspec: NUMBER MERIDIAN = - {hh = $1; mm = 0; ss = 0; merid = $2;} - | NUMBER ':' NUMBER = - {hh = $1; mm = $3; merid = 24;} - | NUMBER ':' NUMBER MERIDIAN = - {hh = $1; mm = $3; merid = $4;} - | NUMBER ':' NUMBER NUMBER = - {hh = $1; mm = $3; merid = 24; - daylight = STANDARD; ourzone = $4%100 + 60*$4/100;} - | NUMBER ':' NUMBER ':' NUMBER = - {hh = $1; mm = $3; ss = $5; merid = 24;} - | NUMBER ':' NUMBER ':' NUMBER MERIDIAN = - {hh = $1; mm = $3; ss = $5; merid = $6;} - | NUMBER ':' NUMBER ':' NUMBER NUMBER = - {hh = $1; mm = $3; ss = $5; merid = 24; - daylight = STANDARD; ourzone = $6%100 + 60*$6/100;}; - -zone: ZONE = - {ourzone = $1; daylight = STANDARD;} - | DAYZONE = - {ourzone = $1; daylight = DAYLIGHT;}; - -dyspec: DAY = - {dayord = 1; dayreq = $1;} - | DAY ',' = - {dayord = 1; dayreq = $1;} - | NUMBER DAY = - {dayord = $1; dayreq = $2;}; - -dtspec: NUMBER '/' NUMBER = - {month = $1; day = $3;} - | NUMBER '/' NUMBER '/' NUMBER = - {month = $1; day = $3; year = $5;} - | MONTH NUMBER = - {month = $1; day = $2;} - | MONTH NUMBER ',' NUMBER = - {month = $1; day = $2; year = $4;} - | NUMBER MONTH = - {month = $2; day = $1;} - | NUMBER MONTH NUMBER = - {month = $2; day = $1; year = $3;}; - - -rspec: NUMBER UNIT = - {relsec += 60L * $1 * $2;} - | NUMBER MUNIT = - {relmonth += $1 * $2;} - | NUMBER SUNIT = - {relsec += $1;} - | UNIT = - {relsec += 60L * $1;} - | MUNIT = - {relmonth += $1;} - | SUNIT = - {relsec++;} - | rspec AGO = - {relsec = -relsec; relmonth = -relmonth;}; -%% - -static int mdays[12] = - {31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; -#define epoch 1970 - -extern struct tm *localtime(); - -static time_t -dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag) -int mm, dd, yy, h, m, s, mer, zone, dayflag; -{ - time_t tod, jdate; - register int i; - time_t timeconv(); - - if (yy < 0) yy = -yy; - if (yy < 100) yy += 1900; - mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0)); - if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 || - dd < 1 || dd > mdays[--mm]) return (-1); - jdate = dd-1; - for (i=0; itm_isdst)) - jdate += -1*60*60; - return (jdate); -} - -static time_t -dayconv(ord, day, now) -int ord, day; time_t now; -{ - register struct tm *loctime; - time_t tod; - time_t daylcorr(); - - tod = now; - loctime = localtime(&tod); - tod += daysec * ((day - loctime->tm_wday + 7) % 7); - tod += 7*daysec*(ord<=0?ord:ord-1); - return daylcorr(tod, now); -} - -static time_t -timeconv(hh, mm, ss, mer) -register int hh, mm, ss, mer; -{ - if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1); - switch (mer) { - case AM: if (hh < 1 || hh > 12) return(-1); - return (60L * ((hh%12)*60L + mm)+ss); - case PM: if (hh < 1 || hh > 12) return(-1); - return (60L * ((hh%12 +12)*60L + mm)+ss); - case 24: if (hh < 0 || hh > 23) return (-1); - return (60L * (hh*60L + mm)+ss); - default: return (-1); - } -} - -static time_t -monthadd(sdate, relmonth) -time_t sdate, relmonth; -{ - struct tm *ltime; - time_t dateconv(); - time_t daylcorr(); - int mm, yy; - - if (relmonth == 0) return 0; - ltime = localtime(&sdate); - mm = 12*ltime->tm_year + ltime->tm_mon + relmonth; - yy = mm/12; - mm = mm%12 + 1; - return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour, - ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate); -} - -static time_t -daylcorr(future, now) -time_t future, now; -{ - int fdayl, nowdayl; - - nowdayl = (localtime(&now)->tm_hour+1) % 24; - fdayl = (localtime(&future)->tm_hour+1) % 24; - return (future-now) + 60L*60L*(nowdayl-fdayl); -} - -static char *lptr; - -yylex() -{ - extern int yylval; - int sign; - register char c; - register char *p; - char idbuf[20]; - int pcnt; - - for (;;) { - while (isspace(*lptr)) lptr++; - - if (isdigit(c = *lptr) || c == '-' || c == '+') { - if (c== '-' || c == '+') { - if (c=='-') sign = -1; - else sign = 1; - if (!isdigit(*++lptr)) { - /* yylval = sign; return (NUMBER); */ - return yylex(); /* skip the '-' sign */ - } - } else sign = 1; - yylval = 0; - while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0'; - yylval *= sign; - lptr--; - return (NUMBER); - - } else if (isalpha(c)) { - p = idbuf; - while (isalpha(c = *lptr++) || c=='.') - if (p < &idbuf[sizeof(idbuf)-1]) - *p++ = c; - *p = '\0'; - lptr--; - return (lookup(idbuf)); - } - - else if (c == '(') { - pcnt = 0; - do { - c = *lptr++; - if (c == '\0') return(c); - else if (c == '(') pcnt++; - else if (c == ')') pcnt--; - } while (pcnt > 0); - } - - else return (*lptr++); - } -} - -struct table { - char *name; - int type, value; -}; - -static struct table mdtab[] = { - {"January", MONTH, 1}, - {"February", MONTH, 2}, - {"March", MONTH, 3}, - {"April", MONTH, 4}, - {"May", MONTH, 5}, - {"June", MONTH, 6}, - {"July", MONTH, 7}, - {"August", MONTH, 8}, - {"September", MONTH, 9}, - {"Sept", MONTH, 9}, - {"October", MONTH, 10}, - {"November", MONTH, 11}, - {"December", MONTH, 12}, - - {"Sunday", DAY, 0}, - {"Monday", DAY, 1}, - {"Tuesday", DAY, 2}, - {"Tues", DAY, 2}, - {"Wednesday", DAY, 3}, - {"Wednes", DAY, 3}, - {"Thursday", DAY, 4}, - {"Thur", DAY, 4}, - {"Thurs", DAY, 4}, - {"Friday", DAY, 5}, - {"Saturday", DAY, 6}, - {0, 0, 0}}; - -#define HRS *60 -#define HALFHR 30 -static struct table mztab[] = { - {"a.m.", MERIDIAN, AM}, - {"am", MERIDIAN, AM}, - {"p.m.", MERIDIAN, PM}, - {"pm", MERIDIAN, PM}, - {"nst", ZONE, 3 HRS + HALFHR}, /* Newfoundland */ - {"n.s.t.", ZONE, 3 HRS + HALFHR}, - {"ast", ZONE, 4 HRS}, /* Atlantic */ - {"a.s.t.", ZONE, 4 HRS}, - {"adt", DAYZONE, 4 HRS}, - {"a.d.t.", DAYZONE, 4 HRS}, - {"est", ZONE, 5 HRS}, /* Eastern */ - {"e.s.t.", ZONE, 5 HRS}, - {"edt", DAYZONE, 5 HRS}, - {"e.d.t.", DAYZONE, 5 HRS}, - {"cst", ZONE, 6 HRS}, /* Central */ - {"c.s.t.", ZONE, 6 HRS}, - {"cdt", DAYZONE, 6 HRS}, - {"c.d.t.", DAYZONE, 6 HRS}, - {"mst", ZONE, 7 HRS}, /* Mountain */ - {"m.s.t.", ZONE, 7 HRS}, - {"mdt", DAYZONE, 7 HRS}, - {"m.d.t.", DAYZONE, 7 HRS}, - {"pst", ZONE, 8 HRS}, /* Pacific */ - {"p.s.t.", ZONE, 8 HRS}, - {"pdt", DAYZONE, 8 HRS}, - {"p.d.t.", DAYZONE, 8 HRS}, - {"yst", ZONE, 9 HRS}, /* Yukon */ - {"y.s.t.", ZONE, 9 HRS}, - {"ydt", DAYZONE, 9 HRS}, - {"y.d.t.", DAYZONE, 9 HRS}, - {"hst", ZONE, 10 HRS}, /* Hawaii */ - {"h.s.t.", ZONE, 10 HRS}, - {"hdt", DAYZONE, 10 HRS}, - {"h.d.t.", DAYZONE, 10 HRS}, - - {"gmt", ZONE, 0 HRS}, - {"g.m.t.", ZONE, 0 HRS}, - {"ut", ZONE, 0 HRS}, - {"u.t.", ZONE, 0 HRS}, - {"bst", DAYZONE, 0 HRS}, /* British Summer Time */ - {"b.s.t.", DAYZONE, 0 HRS}, - {"eet", ZONE, 0 HRS}, /* European Eastern Time */ - {"e.e.t.", ZONE, 0 HRS}, - {"eest", DAYZONE, 0 HRS}, /* European Eastern Summer Time */ - {"e.e.s.t.", DAYZONE, 0 HRS}, - {"met", ZONE, -1 HRS}, /* Middle European Time */ - {"m.e.t.", ZONE, -1 HRS}, - {"mest", DAYZONE, -1 HRS}, /* Middle European Summer Time */ - {"m.e.s.t.", DAYZONE, -1 HRS}, - {"wet", ZONE, -2 HRS }, /* Western European Time */ - {"w.e.t.", ZONE, -2 HRS }, - {"west", DAYZONE, -2 HRS}, /* Western European Summer Time */ - {"w.e.s.t.", DAYZONE, -2 HRS}, - - {"jst", ZONE, -9 HRS}, /* Japan Standard Time */ - {"j.s.t.", ZONE, -9 HRS}, /* Japan Standard Time */ - /* No daylight savings time */ - - {"aest", ZONE, -10 HRS}, /* Australian Eastern Time */ - {"a.e.s.t.", ZONE, -10 HRS}, - {"aesst", DAYZONE, -10 HRS}, /* Australian Eastern Summer Time */ - {"a.e.s.s.t.", DAYZONE, -10 HRS}, - {"acst", ZONE, -(9 HRS + HALFHR)}, /* Australian Central Time */ - {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)}, - {"acsst", DAYZONE, -(9 HRS + HALFHR)}, /* Australian Central Summer */ - {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)}, - {"awst", ZONE, -8 HRS}, /* Australian Western Time */ - {"a.w.s.t.", ZONE, -8 HRS}, /* (no daylight time there, I'm told */ - {0, 0, 0}}; - -static struct table unittb[] = { - {"year", MUNIT, 12}, - {"month", MUNIT, 1}, - {"fortnight", UNIT, 14*24*60}, - {"week", UNIT, 7*24*60}, - {"day", UNIT, 1*24*60}, - {"hour", UNIT, 60}, - {"minute", UNIT, 1}, - {"min", UNIT, 1}, - {"second", SUNIT, 1}, - {"sec", SUNIT, 1}, - {0, 0, 0}}; - -static struct table othertb[] = { - {"tomorrow", UNIT, 1*24*60}, - {"yesterday", UNIT, -1*24*60}, - {"today", UNIT, 0}, - {"now", UNIT, 0}, - {"last", NUMBER, -1}, - {"this", UNIT, 0}, - {"next", NUMBER, 2}, - {"first", NUMBER, 1}, - /* {"second", NUMBER, 2}, */ - {"third", NUMBER, 3}, - {"fourth", NUMBER, 4}, - {"fifth", NUMBER, 5}, - {"sixth", NUMBER, 6}, - {"seventh", NUMBER, 7}, - {"eigth", NUMBER, 8}, - {"ninth", NUMBER, 9}, - {"tenth", NUMBER, 10}, - {"eleventh", NUMBER, 11}, - {"twelfth", NUMBER, 12}, - {"ago", AGO, 1}, - {0, 0, 0}}; - -static struct table milzone[] = { - {"a", ZONE, 1 HRS}, - {"b", ZONE, 2 HRS}, - {"c", ZONE, 3 HRS}, - {"d", ZONE, 4 HRS}, - {"e", ZONE, 5 HRS}, - {"f", ZONE, 6 HRS}, - {"g", ZONE, 7 HRS}, - {"h", ZONE, 8 HRS}, - {"i", ZONE, 9 HRS}, - {"k", ZONE, 10 HRS}, - {"l", ZONE, 11 HRS}, - {"m", ZONE, 12 HRS}, - {"n", ZONE, -1 HRS}, - {"o", ZONE, -2 HRS}, - {"p", ZONE, -3 HRS}, - {"q", ZONE, -4 HRS}, - {"r", ZONE, -5 HRS}, - {"s", ZONE, -6 HRS}, - {"t", ZONE, -7 HRS}, - {"u", ZONE, -8 HRS}, - {"v", ZONE, -9 HRS}, - {"w", ZONE, -10 HRS}, - {"x", ZONE, -11 HRS}, - {"y", ZONE, -12 HRS}, - {"z", ZONE, 0 HRS}, - {0, 0, 0}}; - -static -lookup(id) -char *id; -{ -#define gotit (yylval=i->value, i->type) -#define getid for(j=idvar, k=id; *j++ = *k++; ) - - char idvar[20]; - register char *j, *k; - register struct table *i; - int abbrev; - - getid; - if (strlen(idvar) == 3) abbrev = 1; - else if (strlen(idvar) == 4 && idvar[3] == '.') { - abbrev = 1; - idvar[3] = '\0'; - } - else abbrev = 0; - - if (islower(*idvar)) *idvar = toupper(*idvar); - - for (i = mdtab; i->name; i++) { - k = idvar; - for (j = i->name; *j++ == *k++;) { - if (abbrev && j==i->name+3) return gotit; - if (j[-1] == 0) return gotit; - } - } - - getid; - for (i = mztab; i->name; i++) - if (strcmp(i->name, idvar) == 0) return gotit; - - for (j = idvar; *j; j++) - if (isupper(*j)) *j = tolower(*j); - for (i=mztab; i->name; i++) - if (strcmp(i->name, idvar) == 0) return gotit; - - getid; - for (i=unittb; i->name; i++) - if (strcmp(i->name, idvar) == 0) return gotit; - - if (idvar[strlen(idvar)-1] == 's') - idvar[strlen(idvar)-1] = '\0'; - for (i=unittb; i->name; i++) - if (strcmp(i->name, idvar) == 0) return gotit; - - getid; - for (i = othertb; i->name; i++) - if (strcmp(i->name, idvar) == 0) return gotit; - - getid; - if (strlen(idvar) == 1 && isalpha(*idvar)) { - if (isupper(*idvar)) *idvar = tolower(*idvar); - for (i = milzone; i->name; i++) - if (strcmp(i->name, idvar) == 0) return gotit; - } - - return(ID); -} - -time_t -getdate(p, now) -char *p; -struct timeb *now; -{ -#define mcheck(f) if (f>1) err++ - time_t monthadd(); - int err; - struct tm *lt; - struct timeb ftz; - - time_t sdate, tod; - - lptr = p; - if (now == ((struct timeb *) NULL)) { - now = &ftz; - ftime(&ftz); - } - lt = localtime(&now->time); - year = lt->tm_year; - month = lt->tm_mon+1; - day = lt->tm_mday; - relsec = 0; relmonth = 0; - timeflag=zoneflag=dateflag=dayflag=relflag=0; - ourzone = now->timezone; - daylight = MAYBE; - hh = mm = ss = 0; - merid = 24; - - if (err = yyparse()) return (-1); - - mcheck(timeflag); - mcheck(zoneflag); - mcheck(dateflag); - mcheck(dayflag); - - if (err) return (-1); - if (dateflag || timeflag || dayflag) { - sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylight); - if (sdate < 0) return -1; - } - else { - sdate = now->time; - if (relflag == 0) - sdate -= (lt->tm_sec + lt->tm_min*60 + - lt->tm_hour*(60L*60L)); - } - - sdate += relsec; - sdate += monthadd(sdate, relmonth); - - if (dayflag && !dateflag) { - tod = dayconv(dayord, dayreq, sdate); - sdate += tod; - } - - return sdate; -} - -yyerror(s) char *s; -{} - -main(c, v) -int c; -char **v; -{ - printf("%d\n", getdate(v[1], (struct timeb *)0)); -} diff --git a/tests/savedir/regress/shx b/tests/savedir/regress/shx deleted file mode 100644 index feb2bc8f1..000000000 --- a/tests/savedir/regress/shx +++ /dev/null @@ -1,15 +0,0 @@ -#! /bin/sh - -if ksh -c 'echo ""' >/dev/null 2>&1; then - ksh=ksh -fi - -for cmd in sh ../../bash $ksh -do - echo - echo $cmd: - for demo in shx[0-9] - do - $cmd $demo - done -done diff --git a/tests/savedir/regress/shx1 b/tests/savedir/regress/shx1 deleted file mode 100644 index 73c5e8a4b..000000000 --- a/tests/savedir/regress/shx1 +++ /dev/null @@ -1,4 +0,0 @@ -# ash fails this one -echo -n '<&$fd ' -fd=3 -echo ok <&$fd diff --git a/tests/savedir/regress/shx2 b/tests/savedir/regress/shx2 deleted file mode 100644 index 03cff5bbb..000000000 --- a/tests/savedir/regress/shx2 +++ /dev/null @@ -1,5 +0,0 @@ -# pd ksh fails this one -echo -n "nlbq " -date=` -date` -echo "$date" diff --git a/tests/savedir/regress/shx3 b/tests/savedir/regress/shx3 deleted file mode 100644 index 1fbbb3700..000000000 --- a/tests/savedir/regress/shx3 +++ /dev/null @@ -1,4 +0,0 @@ -# zsh fails this one -echo -n 'bang ' -echo 'geoff tty?? Aug 3 02:35' | - sed -e 's/[ ].*//' -e '/!/s/^.*!//' diff --git a/tests/savedir/regress/shx4 b/tests/savedir/regress/shx4 deleted file mode 100644 index 9ae77817d..000000000 --- a/tests/savedir/regress/shx4 +++ /dev/null @@ -1,5 +0,0 @@ -# ash, pd ksh fail this one -echo -n "quote " -expiry="now" -timet="` getdate \"$expiry\" `" -echo "$timet" diff --git a/tests/savedir/regress/shx5 b/tests/savedir/regress/shx5 deleted file mode 100644 index bd7ad0e2d..000000000 --- a/tests/savedir/regress/shx5 +++ /dev/null @@ -1,5 +0,0 @@ -# ash, zsh fail this one -echo -n "setbq " -host=host -date="`date`" -echo defmsgid="`set $date; echo \<$6$2$3.\` echo $4 | tr -d : \`.$$@$host\>`" diff --git a/tests/savedir/regress/shx7 b/tests/savedir/regress/shx7 deleted file mode 100644 index 12ba1ec15..000000000 --- a/tests/savedir/regress/shx7 +++ /dev/null @@ -1,9 +0,0 @@ -# pd ksh and zsh fail this one -echo -n "bgwait " -( - sleep 2 - echo -n "sleep done... " -) & -waitcmd="wait $!" -eval $waitcmd -echo "$waitcmd" diff --git a/tests/savedir/regress/shx8 b/tests/savedir/regress/shx8 deleted file mode 100644 index b466ec1ef..000000000 --- a/tests/savedir/regress/shx8 +++ /dev/null @@ -1,3 +0,0 @@ -# in case gcx7 is really breaks this shell -sleep 3 -echo diff --git a/tests/savedir/run-ifs-tests b/tests/savedir/run-ifs-tests deleted file mode 100644 index a1c6149b8..000000000 --- a/tests/savedir/run-ifs-tests +++ /dev/null @@ -1,13 +0,0 @@ -# -# show that IFS is only applied to the result of expansions -# -${THIS_SH} ifs-1.test > /tmp/xx -diff /tmp/xx ./ifs-1.right - -${THIS_SH} ifs-2.test > /tmp/xx -diff /tmp/xx ./ifs-2.right - -${THIS_SH} ifs-3.test > /tmp/xx -diff /tmp/xx ./ifs-3.right - -rm -f /tmp/xx diff --git a/tests/savedir/run-input-test-2 b/tests/savedir/run-input-test-2 deleted file mode 100644 index ffbac4c65..000000000 --- a/tests/savedir/run-input-test-2 +++ /dev/null @@ -1,2 +0,0 @@ -cat ./input-line-2.sh | ${THIS_SH} > /tmp/xx -diff /tmp/xx input.right && rm -f /tmp/xx diff --git a/tests/savedir/run-minus-e b/tests/savedir/run-minus-e deleted file mode 100644 index 2a91a3d22..000000000 --- a/tests/savedir/run-minus-e +++ /dev/null @@ -1,2 +0,0 @@ -${THIS_SH} ./minus-e > /tmp/xx -diff /tmp/xx minus-e.right && rm -f /tmp/xx diff --git a/tests/savedir/run-r2.sh b/tests/savedir/run-r2.sh deleted file mode 100755 index 0321a1bdd..000000000 --- a/tests/savedir/run-r2.sh +++ /dev/null @@ -1 +0,0 @@ -../../bash ./redir-t2.sh < /etc/passwd diff --git a/tests/savedir/sigint-1.sh b/tests/savedir/sigint-1.sh deleted file mode 100755 index 7b74c3073..000000000 --- a/tests/savedir/sigint-1.sh +++ /dev/null @@ -1,9 +0,0 @@ -echo before trap -trap 'echo caught sigint' 2 -echo after trap - -for i in 1 2 3 -do - echo $i - sleep 5 -done diff --git a/tests/savedir/sigint-2.sh b/tests/savedir/sigint-2.sh deleted file mode 100755 index 69eaf56a0..000000000 --- a/tests/savedir/sigint-2.sh +++ /dev/null @@ -1,7 +0,0 @@ -echo before loop - -for i in 1 2 3 -do - echo $i - sleep 5 -done diff --git a/tests/savedir/sigint-3.sh b/tests/savedir/sigint-3.sh deleted file mode 100755 index 2627fe6cb..000000000 --- a/tests/savedir/sigint-3.sh +++ /dev/null @@ -1,11 +0,0 @@ -sleep 5 & -sleep 5 & -sleep 5 & - -echo wait 1 -wait - -echo wait 2 -wait - -exit diff --git a/tests/savedir/sigint-4.sh b/tests/savedir/sigint-4.sh deleted file mode 100755 index 587dd2651..000000000 --- a/tests/savedir/sigint-4.sh +++ /dev/null @@ -1,13 +0,0 @@ -trap 'echo sigint' 2 - -sleep 5 & -sleep 5 & -sleep 5 & - -echo wait 1 -wait - -echo wait 2 -wait - -exit diff --git a/tests/savedir/test-minus-e.1 b/tests/savedir/test-minus-e.1 deleted file mode 100644 index 77cc3f26c..000000000 --- a/tests/savedir/test-minus-e.1 +++ /dev/null @@ -1,9 +0,0 @@ -touch .file -while set -e ; test -r .file ; do - echo -n "stop loop? " - read reply - case "$reply" in - y*) rm .file non-dash-file ;; - esac - set +e -done diff --git a/tests/savedir/test-minus-e.2 b/tests/savedir/test-minus-e.2 deleted file mode 100644 index f66966eba..000000000 --- a/tests/savedir/test-minus-e.2 +++ /dev/null @@ -1,11 +0,0 @@ -touch .file -set -e -while set +e ; test -r .file ; do - echo -n "stop loop? [yes to quit] " - read reply - if [ "$reply" = yes ] ; then - rm .file non-dash-file - fi - set -e -done -rm -f .file diff --git a/tests/savedir/test.patmatch b/tests/savedir/test.patmatch deleted file mode 100644 index 88b563167..000000000 --- a/tests/savedir/test.patmatch +++ /dev/null @@ -1,15 +0,0 @@ -# these will work only if test.c has been compiled with -DPATTERN_MATCHING -# to get =~ and !~ - -[ a =\~ a ] && echo OK || echo BAD -[ a !~ b ] && echo OK || echo BAD - -[ a =\~ \* ] && echo OK || echo BAD -[ a =\~ \? ] && echo OK || echo BAD -[ abc !~ \? ] && echo OK || echo BAD - -[ '' =\~ \* ] && echo OK || echo BAD -[ '' !~ \?\* ] && echo OK || echo BAD - -[ a =\~ \[abc] ] && echo OK || echo BAD -[ x !~ \[abc] ] && echo OK || echo BAD diff --git a/tests/savedir/time.tests b/tests/savedir/time.tests deleted file mode 100644 index 9c4e4a34d..000000000 --- a/tests/savedir/time.tests +++ /dev/null @@ -1,50 +0,0 @@ -# This program 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. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU 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 . -# -: ${THIS_SH:=./bash} - -printf "time -c : :\n" -time ${THIS_SH} -c : - -printf "time /dev/null:\n" -time ${THIS_SH} /dev/null - -printf "\nPOSIX: time -p /dev/null:\n" -time -p ${THIS_SH} /dev/null - -printf "\nBSD time /dev/null:\n" -TIMEFORMAT=$'\t%1R real\t%1U user\t%1S sys' -time ${THIS_SH} /dev/null - -printf "\nSYSV time /dev/null:\n" -TIMEFORMAT=$'\nreal\t%1R\nuser\t%1U\nsys\t%1S' -time ${THIS_SH} /dev/null - -printf "\nksh time /dev/null:\n" -TIMEFORMAT=$'\nreal\t%2lR\nuser\t%2lU\nsys\t%2lS' -time ${THIS_SH} < /dev/null - -time (:) -(time :) - -times -x - -printf "\ntimes:\n" -times -echo -times -- - -printf "\ntime standalone:\n" -{ time ; echo after; } |& wc -l - -exit 0 diff --git a/tests/savedir/wait-bg.tests b/tests/savedir/wait-bg.tests deleted file mode 100644 index 95c98b087..000000000 --- a/tests/savedir/wait-bg.tests +++ /dev/null @@ -1,25 +0,0 @@ -#! /bin/bash - -i=0 -while [ $i -lt $1 ] -do - /bin/sh -c "sleep 4; exit 0" & - rv=$? - pid=$! - eval bg_pid_$i=$pid - echo $$: Job $i: pid is $pid rv=$rv - i=$((i + 1)) -done - - - -i=0 -while [ $i -lt $1 ] -do - eval wpid=\$bg_pid_$i - echo Waiting for job $i '('pid $wpid')' - wait $wpid - rv=$? - echo Return value is $rv - i=$((i + 1)) -done
    ' . - &t2h_anchor('', $href, $entry) . - '  ' . - $descr . - "
    ' . - $entry . - '' . $descr . - "