summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2015-03-18 20:41:52 -0400
committerLuke Shumaker <lukeshu@sbcglobal.net>2015-03-18 20:41:52 -0400
commitc02fbeff112e0172d0ad12bf7709099784305396 (patch)
tree9bf774537966e3533b9fe5e2f63a315ebf8b7a9a
parent5b8264b872e0f45a021ad814499468da2c9e43c7 (diff)
Hey, I built Bash 1.14 on a modern box!
-rw-r--r--public/bash-1.14.7-gcc4-stdarg.patch284
-rw-r--r--public/bash-1.14.7-machines-config.patch21
-rw-r--r--public/bash-arrays.md9
-rw-r--r--public/build-bash-1.md87
4 files changed, 397 insertions, 4 deletions
diff --git a/public/bash-1.14.7-gcc4-stdarg.patch b/public/bash-1.14.7-gcc4-stdarg.patch
new file mode 100644
index 0000000..28d7c07
--- /dev/null
+++ b/public/bash-1.14.7-gcc4-stdarg.patch
@@ -0,0 +1,284 @@
+diff -ru bash-1.14.7/builtins/common.c bash-1.14.7.new2/builtins/common.c
+--- bash-1.14.7/builtins/common.c 1995-01-30 13:02:37.000000000 -0500
++++ bash-1.14.7.new2/builtins/common.c 2015-03-17 02:38:18.479744668 -0400
+@@ -20,7 +20,7 @@
+ #include <sys/types.h>
+ #include "../posixstat.h"
+ #if defined (HAVE_VFPRINTF)
+-#include <varargs.h>
++#include <stdarg.h>
+ #endif /* VFPRINTF */
+
+ #if defined (HAVE_STRING_H)
+@@ -114,17 +114,14 @@
+ shell. */
+ #if defined (HAVE_VFPRINTF)
+ void
+-builtin_error (va_alist)
+- va_dcl
++builtin_error (char *format, ...)
+ {
+- char *format;
+ va_list args;
+
+ if (this_command_name && *this_command_name)
+ fprintf (stderr, "%s: ", this_command_name);
+
+- va_start (args);
+- format = va_arg (args, char *);
++ va_start (args, format);
+ vfprintf (stderr, format, args);
+ va_end (args);
+ fprintf (stderr, "\n");
+diff -ru bash-1.14.7/builtins/common.h bash-1.14.7.new2/builtins/common.h
+--- bash-1.14.7/builtins/common.h 1994-04-18 19:39:46.000000000 -0500
++++ bash-1.14.7.new2/builtins/common.h 2015-03-17 02:38:18.479744668 -0400
+@@ -23,7 +23,7 @@
+
+ #define ISOPTION(s, c) (s[0] == '-' && !s[2] && s[1] == c)
+
+-extern void builtin_error ();
++extern void builtin_error (char *, ...);
+ extern void bad_option ();
+
+ extern int get_numeric_arg ();
+diff -ru bash-1.14.7/error.c bash-1.14.7.new2/error.c
+--- bash-1.14.7/error.c 1994-12-05 13:39:31.000000000 -0500
++++ bash-1.14.7.new2/error.c 2015-03-17 02:38:18.479744668 -0400
+@@ -22,7 +22,7 @@
+ #include <fcntl.h>
+
+ #if defined (HAVE_VFPRINTF)
+-#include <varargs.h>
++#include <stdarg.h>
+ #endif
+
+ #include <errno.h>
+@@ -121,18 +121,15 @@
+ #else /* We have VARARGS support, so use it. */
+
+ void
+-programming_error (va_alist)
+- va_dcl
++programming_error (char *format, ...)
+ {
+ va_list args;
+- char *format;
+
+ #if defined (JOB_CONTROL)
+ give_terminal_to (shell_pgrp);
+ #endif /* JOB_CONTROL */
+
+- va_start (args);
+- format = va_arg (args, char *);
++ va_start (args, format);
+ vfprintf (stderr, format, args);
+ fprintf (stderr, "\n");
+ va_end (args);
+@@ -144,15 +141,12 @@
+ }
+
+ void
+-report_error (va_alist)
+- va_dcl
++report_error (char *format, ...)
+ {
+ va_list args;
+- char *format;
+
+ fprintf (stderr, "%s: ", get_name_for_error ());
+- va_start (args);
+- format = va_arg (args, char *);
++ va_start (args, format);
+ vfprintf (stderr, format, args);
+ fprintf (stderr, "\n");
+
+@@ -162,15 +156,12 @@
+ }
+
+ void
+-fatal_error (va_alist)
+- va_dcl
++fatal_error (char *format, ...)
+ {
+ va_list args;
+- char *format;
+
+ fprintf (stderr, "%s: ", get_name_for_error ());
+- va_start (args);
+- format = va_arg (args, char *);
++ va_start (args, format);
+ vfprintf (stderr, format, args);
+ fprintf (stderr, "\n");
+
+@@ -179,30 +170,24 @@
+ }
+
+ void
+-internal_error (va_alist)
+- va_dcl
++internal_error (char *format, ...)
+ {
+ va_list args;
+- char *format;
+
+ fprintf (stderr, "%s: ", get_name_for_error ());
+- va_start (args);
+- format = va_arg (args, char *);
++ va_start (args, format);
+ vfprintf (stderr, format, args);
+ fprintf (stderr, "\n");
+
+ va_end (args);
+ }
+
+-itrace (va_alist)
+- va_dcl
++itrace (char *format, ...)
+ {
+ va_list args;
+- char *format;
+
+ fprintf(stderr, "TRACE: pid %d: ", getpid());
+- va_start (args);
+- format = va_arg (args, char *);
++ va_start (args, format);
+ vfprintf (stderr, format, args);
+ fprintf (stderr, "\n");
+
+@@ -214,11 +199,9 @@
+ #if 0
+ /* A trace function for silent debugging -- doesn't require a control
+ terminal. */
+-trace (va_alist)
+- va_dcl
++trace (char *format, ...)
+ {
+ va_list args;
+- char *format;
+ static FILE *tracefp = (FILE *)NULL;
+
+ if (tracefp == NULL)
+@@ -231,8 +214,7 @@
+
+ fprintf(tracefp, "TRACE: pid %d: ", getpid());
+
+- va_start (args);
+- format = va_arg (args, char *);
++ va_start (args, format);
+ vfprintf (tracefp, format, args);
+ fprintf (tracefp, "\n");
+
+diff -ru bash-1.14.7/error.h bash-1.14.7.new2/error.h
+--- bash-1.14.7/error.h 1994-01-26 14:31:10.000000000 -0500
++++ bash-1.14.7.new2/error.h 2015-03-17 02:38:18.479744668 -0400
+@@ -25,10 +25,10 @@
+ extern void file_error ();
+
+ /* Report a programmer's error, and abort. Pass REASON, and ARG1 ... ARG5. */
+-extern void programming_error ();
++extern void programming_error (char *, ...);
+
+ /* General error reporting. Pass FORMAT and ARG1 ... ARG5. */
+-extern void report_error ();
++extern void report_error (char *, ...);
+
+ /* Report an unrecoverable error and exit. Pass FORMAT and ARG1 ... ARG5. */
+-extern void fatal_error ();
++extern void fatal_error (char *, ...);
+diff -ru bash-1.14.7/lib/readline/display.c bash-1.14.7.new2/lib/readline/display.c
+--- bash-1.14.7/lib/readline/display.c 1995-05-01 09:18:02.000000000 -0500
++++ bash-1.14.7.new2/lib/readline/display.c 2015-03-17 02:46:02.243878132 -0400
+@@ -1020,14 +1020,11 @@
+ mini-modeline. */
+
+ #if defined (HAVE_VARARGS_H)
+-rl_message (va_alist)
+- va_dcl
++rl_message (char *format, ...)
+ {
+- char *format;
+ va_list args;
+
+- va_start (args);
+- format = va_arg (args, char *);
++ va_start (args, format);
+ vsprintf (msg_buf, format, args);
+ va_end (args);
+
+diff -ru bash-1.14.7/lib/readline/readline.h bash-1.14.7.new2/lib/readline/readline.h
+--- bash-1.14.7/lib/readline/readline.h 1994-07-26 14:35:40.000000000 -0500
++++ bash-1.14.7.new2/lib/readline/readline.h 2015-03-17 02:46:34.466572077 -0400
+@@ -271,7 +271,7 @@
+
+ /* Functions in display.c */
+ extern void rl_redisplay ();
+-extern int rl_message (), rl_clear_message ();
++extern int rl_message (char *, ...), rl_clear_message ();
+ extern int rl_reset_line_state ();
+ extern int rl_character_len ();
+ extern int rl_show_char ();
+diff -ru bash-1.14.7/lib/readline/rldefs.h bash-1.14.7.new2/lib/readline/rldefs.h
+--- bash-1.14.7/lib/readline/rldefs.h 1995-02-25 18:55:43.000000000 -0500
++++ bash-1.14.7.new2/lib/readline/rldefs.h 2015-03-17 02:45:26.611251831 -0400
+@@ -150,7 +150,7 @@
+ #endif /* !strchr && !__STDC__ */
+
+ #if defined (HAVE_VARARGS_H)
+-# include <varargs.h>
++# include <stdarg.h>
+ #endif /* HAVE_VARARGS_H */
+
+ /* This is needed to include support for TIOCGWINSZ and window resizing. */
+--- bash-1.14.7/print_cmd.c 1995-01-30 12:45:09.000000000 -0500
++++ bash-1.14.7.new2/print_cmd.c 2015-03-17 02:44:02.712916475 -0400
+@@ -20,7 +20,7 @@
+ #include <stdio.h>
+
+ #if defined (HAVE_VARARGS_H)
+-# include <varargs.h>
++# include <stdarg.h>
+ #endif
+
+ #if defined (HAVE_STRING_H)
+@@ -41,7 +41,7 @@
+ static int indentation = 0;
+ static int indentation_amount = 4;
+
+-static void cprintf (), newline (), indent (), the_printed_command_resize ();
++static void cprintf (char *, ...), newline (), indent (), the_printed_command_resize ();
+ static void semicolon ();
+
+ static void make_command_string_internal ();
+@@ -730,16 +730,14 @@
+
+ /* How to make the string. */
+ static void
+-cprintf (va_alist)
+- va_dcl
++cprintf (char *control, ...)
+ {
+ register char *s;
+- char *control, char_arg[2], *argp;
++ char char_arg[2], *argp;
+ int digit_arg, arg_len, c;
+ va_list args;
+
+- va_start (args);
+- control = va_arg (args, char *);
++ va_start (args, control);
+
+ arg_len = strlen (control);
+ the_printed_command_resize (arg_len + 1);
+diff -ru bash-1.14.7/shell.c bash-1.14.7.new2/shell.c
+--- bash-1.14.7/shell.c 1995-04-06 15:45:00.000000000 -0500
++++ bash-1.14.7.new2/shell.c 2015-03-17 02:38:18.483077935 -0400
+@@ -43,7 +43,7 @@
+ #include "bashansi.h"
+
+ #if defined (HAVE_VARARGS_H)
+-#include <varargs.h>
++#include <stdarg.h>
+ #endif
+
+ #include "shell.h"
diff --git a/public/bash-1.14.7-machines-config.patch b/public/bash-1.14.7-machines-config.patch
new file mode 100644
index 0000000..3773ba7
--- /dev/null
+++ b/public/bash-1.14.7-machines-config.patch
@@ -0,0 +1,21 @@
+diff -ru bash-1.14.7/machines.h bash-1.14.7.new2/machines.h
+--- bash-1.14.7/machines.h 1995-12-18 14:13:22.000000000 -0500
++++ bash-1.14.7.new2/machines.h 2015-03-17 02:50:38.618813331 -0400
+@@ -584,7 +584,7 @@
+ /* */
+ /* **************************************************************** */
+
+-#if defined (i386)
++#if defined (i386) || defined (__x86_64__)
+
+ /* Sequent Symmetry running Dynix/ptx 2.x */
+ # if !defined (done386) && defined (_SEQUENT_)
+@@ -891,6 +891,7 @@
+ # define HAVE_SYS_SIGLIST
+ # define HAVE_VFPRINTF
+ # define HAVE_VARARGS_H
++# define USE_TERMCAP_EMULATION
+ # define SEARCH_LIB_NEEDS_SPACE
+ # if defined (__GNUC__)
+ # define HAVE_FIXED_INCLUDES
+diff -ru bash-1.14.7/print_cmd.c bash-1.14.7.new2/print_cmd.c
diff --git a/public/bash-arrays.md b/public/bash-arrays.md
index cbbd4c4..23d90bb 100644
--- a/public/bash-arrays.md
+++ b/public/bash-arrays.md
@@ -407,8 +407,8 @@ for the arguments array, which is; though getting subset arrays from
`$@` and `$*` is not (tip: use `set --` to re-purpose the arguments array).
Writing for various versions of Bash, though, is pretty do-able.
-Everything here works all the way back in bash-2.0 (1996), with the
-following exceptions:
+Everything here works all the way back in bash-2.0 (December 1996),
+with the following exceptions:
* The `+=` operator wasn't added until Bash 3.1.
@@ -430,5 +430,6 @@ following exceptions:
* In Bash 4.1 and higher, it works in the way described in the
main part of this document.
-Bash 1.x won't compile with modern GCC, so I couldn't verify how it
-behaves.
+Now, Bash 1.x doesn't have arrays at all. `$@` and `$*` work, but
+using `:` to select a range of elements from them doesn't. Good thing
+most boxes have been updated since 1996!
diff --git a/public/build-bash-1.md b/public/build-bash-1.md
new file mode 100644
index 0000000..e70a36b
--- /dev/null
+++ b/public/build-bash-1.md
@@ -0,0 +1,87 @@
+Building Bash 1.14.7 on a modern system
+=======================================
+---
+date: "2015-03-18"
+---
+
+In a previous revision of my [Bash arrays post](./bash-arrays.html), I wrote:
+
+> Bash 1.x won't compile with modern GCC, so I couldn't verify how it
+> behaves.
+
+I recall spending a little time fighting with it, but apparently I
+didn't try very hard: getting Bash 1.14.7 to build on a modern box is
+mostly just adjusting it to use `stdarg` instead of the
+no-longer-implemented `varargs`. There's also a little fiddling with
+the pre-autoconf automatic configuration.
+
+## stdarg
+
+Converting to `stdarg` is pretty simple: For each variadic function
+(functions that take a variable number of arguments), follow these steps:
+
+1. Replace `#include <varargs.h>` with `#include <stdarg.h>`
+2. Replace `function_name (va_alist) va_dcl` with
+ `function_name (char *format, ...)`.
+3. Removing the declaration and assignment for `format` from the
+ function body.
+4. Replace `va_start (args);` with `va_start (args, format);` in the
+ function bodies.
+5. Replace `function_name ();` with `function_name (char *, ...)` in
+ header files and/or at the top of C files.
+
+There's one function that uses the variable name `control` instead of
+`format`.
+
+I've prepared [a patch](./bash-1.14.7-gcc4-stdarg.patch) that does this.
+
+## Configuration
+
+Instead of using autoconf-style tests to test for compiler and
+platform features, Bash 1 used the file `machines.h` that had
+`#ifdefs` and a huge database of of different operating systems for
+different platforms. It's gross. And quite likely won't handle your
+modern operating system.
+
+I made these two small changes to `machines.h` to get it to work
+correctly on my box:
+
+1. Replace `#if defined (i386)` with
+ `#if defined (i386) || defined (__x86_64__)`. The purpose of this
+ is obvious.
+2. Add `#define USE_TERMCAP_EMULATION` to the section for Linux [sic]
+ on i386
+ (`# if !defined (done386) && (defined (__linux__) || defined (linux))`.
+ What this does is tell it to use link against libcurses to use
+ curses termcap emulation, instead of linking against libtermcap
+ (which doesn't exist on modern GNU/Linux systems).
+
+Again, I've prepared [a patch](./bash-1.14.7-machines-config.patch)
+that does this.
+
+## Building
+
+With those adjustments, it should build, but with quite a few
+warnings. Making a couple of changes to `CFLAGS` should fix that:
+
+ make CFLAGS='-O -g -Werror -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -Wno-deprecated-declarations -include stdio.h -include stdlib.h -include string.h -Dexp2=bash_exp2'
+
+That's a doozy! Let's break it down:
+
+- `-O -g` The default value for CFLAGS (defined in `cpp-Makefile`)
+- `-Werror` Treat warnings as errors; force us to deal with any issues.
+- `-Wno-int-to-pointer-cast -Wno-pointer-to-int-cast` Allow casting
+ between integers and pointers. Unfortunately, the way this version
+ of Bash was designed requires this.
+- `-Wno-deprecated-declarations`. The `getwd` function in `unistd.h`
+ is considered deprecated (use `getcwd` instead). However, if
+ `getcwd` is available, Bash uses it's own `getwd` wrapper around
+ `getcwd` (implemented in `general.c`), and only uses the signature
+ from `unistd.h`, not the actually implementation from libc.
+- `-include stdio.h -include stdlib.h -include string.h` Several files
+ are missing these header file includes. If not for `-Werror`, the
+ default function signature fallbacks would work.
+- `-Dexp2=bash_exp2` Avoid a conflict between the parser's `exp2`
+ helper function and `math.h`'s base-2 exponential function.
+
+Have fun, software archaeologists!