summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MSVC/getopt/getopt.c2116
-rw-r--r--MSVC/getopt/getopt.h360
-rw-r--r--MSVC/getopt/getopt1.c376
-rw-r--r--MSVC/readline/ansi_stdlib.h108
-rw-r--r--MSVC/readline/bind.c4310
-rw-r--r--MSVC/readline/callback.c308
-rw-r--r--MSVC/readline/chardefs.h324
-rw-r--r--MSVC/readline/compat.c222
-rw-r--r--MSVC/readline/complete.c4008
-rw-r--r--MSVC/readline/config.h314
-rw-r--r--MSVC/readline/dirent.c714
-rw-r--r--MSVC/readline/dirent.h294
-rw-r--r--MSVC/readline/display.c4602
-rw-r--r--MSVC/readline/emacs_keymap.c1746
-rw-r--r--MSVC/readline/funmap.c502
-rw-r--r--MSVC/readline/histexpand.c2978
-rw-r--r--MSVC/readline/histfile.c974
-rw-r--r--MSVC/readline/histlib.h164
-rw-r--r--MSVC/readline/history.c758
-rw-r--r--MSVC/readline/history.h496
-rw-r--r--MSVC/readline/histsearch.c386
-rw-r--r--MSVC/readline/input.c1488
-rw-r--r--MSVC/readline/isearch.c1116
-rw-r--r--MSVC/readline/keymaps.c296
-rw-r--r--MSVC/readline/keymaps.h216
-rw-r--r--MSVC/readline/kill.c1300
-rw-r--r--MSVC/readline/macro.c520
-rw-r--r--MSVC/readline/mbutil.c690
-rw-r--r--MSVC/readline/misc.c988
-rw-r--r--MSVC/readline/nls.c456
-rw-r--r--MSVC/readline/parens.c354
-rw-r--r--MSVC/readline/posixdir.h114
-rw-r--r--MSVC/readline/posixjmp.h80
-rw-r--r--MSVC/readline/posixstat.h284
-rw-r--r--MSVC/readline/readline.c1958
-rw-r--r--MSVC/readline/readline.h1612
-rw-r--r--MSVC/readline/rlconf.h160
-rw-r--r--MSVC/readline/rldefs.h326
-rw-r--r--MSVC/readline/rldynlink.h34
-rw-r--r--MSVC/readline/rlmbutil.h216
-rw-r--r--MSVC/readline/rlprivate.h568
-rw-r--r--MSVC/readline/rlshell.h74
-rw-r--r--MSVC/readline/rlstdc.h90
-rw-r--r--MSVC/readline/rltty.c2092
-rw-r--r--MSVC/readline/rltty.h164
-rw-r--r--MSVC/readline/rltypedefs.h176
-rw-r--r--MSVC/readline/rlwinsize.h110
-rw-r--r--MSVC/readline/savestring.c72
-rw-r--r--MSVC/readline/search.c926
-rw-r--r--MSVC/readline/shell.c462
-rw-r--r--MSVC/readline/signals.c888
-rw-r--r--MSVC/readline/tcap.h116
-rw-r--r--MSVC/readline/terminal.c1614
-rw-r--r--MSVC/readline/text.c3076
-rw-r--r--MSVC/readline/tilde.c940
-rw-r--r--MSVC/readline/tilde.h160
-rw-r--r--MSVC/readline/undo.c522
-rw-r--r--MSVC/readline/util.c672
-rw-r--r--MSVC/readline/vi_keymap.c1754
-rw-r--r--MSVC/readline/vi_mode.c2966
-rw-r--r--MSVC/readline/xmalloc.c172
-rw-r--r--MSVC/readline/xmalloc.h92
-rw-r--r--MSVC/regex/regex.c9896
-rw-r--r--MSVC/regex/regex.h996
-rw-r--r--include/Action.h64
-rw-r--r--include/BLua.h752
-rw-r--r--include/BString.h202
-rw-r--r--include/Buffer.h122
-rw-r--r--include/Color.h640
-rw-r--r--include/ConfigFile.h38
-rw-r--r--include/Confirm.h40
-rw-r--r--include/CopyJob.h52
-rw-r--r--include/Exceptions.h320
-rw-r--r--include/Form.h46
-rw-r--r--include/GMPString.h36
-rw-r--r--include/Handle.h184
-rw-r--r--include/HttpServ.h60
-rw-r--r--include/IRC.h402
-rw-r--r--include/Image.h106
-rw-r--r--include/InPipe.h38
-rw-r--r--include/Input.h232
-rw-r--r--include/LuaHandle.h162
-rw-r--r--include/Main.h120
-rw-r--r--include/Menu.h44
-rw-r--r--include/Message.h40
-rw-r--r--include/OutPipe.h38
-rw-r--r--include/Output.h142
-rw-r--r--include/ReadJob.h40
-rw-r--r--include/Regex.h44
-rw-r--r--include/SQL.h50
-rw-r--r--include/Socket.h66
-rw-r--r--include/Table.h42
-rw-r--r--include/Task.h110
-rw-r--r--include/TaskMan.h148
-rw-r--r--include/Variables.h56
-rw-r--r--include/generic.h388
-rw-r--r--include/gettext.h128
-rw-r--r--include/template.h6
-rw-r--r--lib/Action.cc182
-rw-r--r--lib/BLua.cc1334
-rw-r--r--lib/Buffer.cc416
-rw-r--r--lib/ConfigFile.cc86
-rw-r--r--lib/Confirm.cc70
-rw-r--r--lib/CopyJob.cc168
-rw-r--r--lib/Exceptions.cc550
-rw-r--r--lib/Form.cc130
-rw-r--r--lib/GMPString.cc60
-rw-r--r--lib/Handle.cc1316
-rw-r--r--lib/HttpServ.cc946
-rw-r--r--lib/IRC.cc468
-rw-r--r--lib/Image.cc176
-rw-r--r--lib/InPipe.cc84
-rw-r--r--lib/Input.cc1160
-rw-r--r--lib/LuaHandle.cc1360
-rw-r--r--lib/Main.cc150
-rw-r--r--lib/Menu.cc70
-rw-r--r--lib/Message.cc60
-rw-r--r--lib/OutPipe.cc82
-rw-r--r--lib/Output.cc328
-rw-r--r--lib/ReadJob.cc104
-rw-r--r--lib/Regex.cc88
-rw-r--r--lib/SQL.cc152
-rw-r--r--lib/Socket.cc326
-rw-r--r--lib/String.cc1116
-rw-r--r--lib/Table.cc100
-rw-r--r--lib/Task.cc220
-rw-r--r--lib/TaskMan.cc912
-rw-r--r--lib/Variables.cc170
-rw-r--r--lib/checkargs.c170
-rw-r--r--lib/datecalc.c156
-rw-r--r--lib/fileutils.cc162
-rw-r--r--lib/generic.cc206
-rw-r--r--lib/lua/include/lauxlib.h298
-rw-r--r--lib/lua/include/lua.h800
-rw-r--r--lib/lua/include/lualib.h132
-rw-r--r--lib/lua/includes/lapi.h32
-rw-r--r--lib/lua/includes/lcode.h148
-rw-r--r--lib/lua/includes/ldebug.h62
-rw-r--r--lib/lua/includes/ldo.h120
-rw-r--r--lib/lua/includes/lfunc.h50
-rw-r--r--lib/lua/includes/lgc.h50
-rw-r--r--lib/lua/includes/llex.h150
-rw-r--r--lib/lua/includes/llimits.h370
-rw-r--r--lib/lua/includes/lmem.h88
-rw-r--r--lib/lua/includes/lobject.h672
-rw-r--r--lib/lua/includes/lopcodes.h476
-rw-r--r--lib/lua/includes/lparser.h142
-rw-r--r--lib/lua/includes/lstate.h400
-rw-r--r--lib/lua/includes/lstring.h66
-rw-r--r--lib/lua/includes/ltable.h62
-rw-r--r--lib/lua/includes/ltm.h102
-rw-r--r--lib/lua/includes/lundump.h68
-rw-r--r--lib/lua/includes/lvm.h70
-rw-r--r--lib/lua/includes/lzio.h128
-rw-r--r--lib/lua/src/LuaLib/lauxlib.c1182
-rw-r--r--lib/lua/src/LuaLib/lbaselib.c1348
-rw-r--r--lib/lua/src/LuaLib/ldblib.c598
-rw-r--r--lib/lua/src/LuaLib/ldirlib.c192
-rw-r--r--lib/lua/src/LuaLib/liolib.c1500
-rw-r--r--lib/lua/src/LuaLib/lmathlib.c492
-rw-r--r--lib/lua/src/LuaLib/loadlib.c410
-rw-r--r--lib/lua/src/LuaLib/lstrlib.c1540
-rw-r--r--lib/lua/src/LuaLib/ltablib.c500
-rw-r--r--lib/lua/src/lapi.c1844
-rw-r--r--lib/lua/src/lcode.c1428
-rw-r--r--lib/lua/src/ldebug.c1170
-rw-r--r--lib/lua/src/ldo.c930
-rw-r--r--lib/lua/src/ldump.c340
-rw-r--r--lib/lua/src/lfunc.c270
-rw-r--r--lib/lua/src/lgc.c986
-rw-r--r--lib/lua/src/llex.c884
-rw-r--r--lib/lua/src/lmem.c182
-rw-r--r--lib/lua/src/lobject.c396
-rw-r--r--lib/lua/src/lopcodes.c204
-rw-r--r--lib/lua/src/lparser.c2658
-rw-r--r--lib/lua/src/lstate.c440
-rw-r--r--lib/lua/src/lstring.c204
-rw-r--r--lib/lua/src/ltable.c1018
-rw-r--r--lib/lua/src/ltests.c1704
-rw-r--r--lib/lua/src/ltm.c140
-rw-r--r--lib/lua/src/luacomp.c164
-rw-r--r--lib/lua/src/lundump.c572
-rw-r--r--lib/lua/src/lvm.c1568
-rw-r--r--lib/lua/src/lzio.c162
-rw-r--r--lib/zlib/include/deflate.h636
-rw-r--r--lib/zlib/include/infblock.h78
-rw-r--r--lib/zlib/include/infcodes.h54
-rw-r--r--lib/zlib/include/inffast.h34
-rw-r--r--lib/zlib/include/inffixed.h302
-rw-r--r--lib/zlib/include/inftrees.h116
-rw-r--r--lib/zlib/include/infutil.h196
-rw-r--r--lib/zlib/include/trees.h256
-rw-r--r--lib/zlib/include/zconf.h566
-rw-r--r--lib/zlib/include/zlib.h1786
-rw-r--r--lib/zlib/include/zutil.h440
-rw-r--r--lib/zlib/src/adler32.c96
-rw-r--r--lib/zlib/src/compress.c136
-rw-r--r--lib/zlib/src/crc32.c324
-rw-r--r--lib/zlib/src/deflate.c2700
-rw-r--r--lib/zlib/src/gzio.c1758
-rw-r--r--lib/zlib/src/infblock.c806
-rw-r--r--lib/zlib/src/infcodes.c502
-rw-r--r--lib/zlib/src/inffast.c366
-rw-r--r--lib/zlib/src/inflate.c732
-rw-r--r--lib/zlib/src/inftrees.c908
-rw-r--r--lib/zlib/src/infutil.c174
-rw-r--r--lib/zlib/src/trees.c2428
-rw-r--r--lib/zlib/src/uncompr.c116
-rw-r--r--lib/zlib/src/zutil.c450
-rw-r--r--src/Main.cc430
-rw-r--r--src/misc.cc132
-rw-r--r--src/paq.cc330
212 files changed, 65633 insertions, 65633 deletions
diff --git a/MSVC/getopt/getopt.c b/MSVC/getopt/getopt.c
index 23b62ae..16b27fb 100644
--- a/MSVC/getopt/getopt.c
+++ b/MSVC/getopt/getopt.c
@@ -1,1058 +1,1058 @@
-/* Getopt for GNU.
- NOTE: getopt is now part of the C library, so if you don't know what
- "Keep this file name-space clean" means, talk to drepper@gnu.org
- before changing it!
- Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
- Ditto for AIX 3.2 and <stdlib.h>. */
-#ifndef _NO_PROTO
-# define _NO_PROTO
-#endif
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if !defined __STDC__ || !__STDC__
-/* This is a separate conditional since some stdc systems
- reject `defined (const)'. */
-# ifndef const
-# define const
-# endif
-#endif
-
-#include <stdio.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
-
-#define GETOPT_INTERFACE_VERSION 2
-#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
-# include <gnu-versions.h>
-# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
-# define ELIDE_CODE
-# endif
-#endif
-
-#ifndef ELIDE_CODE
-
-
-/* This needs to come after some library #include
- to get __GNU_LIBRARY__ defined. */
-#ifdef __GNU_LIBRARY__
-/* Don't include stdlib.h for non-GNU C libraries because some of them
- contain conflicting prototypes for getopt. */
-# include <stdlib.h>
-# include <unistd.h>
-#endif /* GNU C library. */
-
-#ifdef VMS
-# include <unixlib.h>
-# if HAVE_STRING_H - 0
-# include <string.h>
-# endif
-#endif
-
-#ifndef _
-/* This is for other GNU distributions with internationalized messages. */
-# if defined HAVE_LIBINTL_H || defined _LIBC
-# include <libintl.h>
-# ifndef _
-# define _(msgid) gettext (msgid)
-# endif
-# else
-# define _(msgid) (msgid)
-# endif
-#endif
-
-/* This version of `getopt' appears to the caller like standard Unix `getopt'
- but it behaves differently for the user, since it allows the user
- to intersperse the options with the other arguments.
-
- As `getopt' works, it permutes the elements of ARGV so that,
- when it is done, all the options precede everything else. Thus
- all application programs are extended to handle flexible argument order.
-
- Setting the environment variable POSIXLY_CORRECT disables permutation.
- Then the behavior is completely standard.
-
- GNU application programs can use a third alternative mode in which
- they can distinguish the relative order of options and other arguments. */
-
-#include "getopt.h"
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-char *optarg = NULL;
- /*
- Above initialization is required to avoid following problem on MacOS X 10.1,10.2.6
- (This is the only difference from gengetopt-2.5. ... 2003/07/14 ... )
- ld: multiple definitions of symbol _getopt
- /usr/lib/libm.dylib(getopt.So) definition of _getopt
- ../lib/libnmzut.a(getopt.o) definition of _getopt in section (__TEXT,__text)
- */
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns -1, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-/* 1003.2 says this must be 1 before any call. */
-int optind = 1;
-
-/* Formerly, initialization of getopt depended on optind==0, which
- causes problems with re-calling getopt as programs generally don't
- know that. */
-
-int __getopt_initialized;
-
-/* The next char to be scanned in the option-element
- in which the last option character we returned was found.
- This allows us to pick up the scan where we left off.
-
- If this is zero, or a null string, it means resume the scan
- by advancing to the next ARGV-element. */
-
-static char *nextchar;
-
-/* Callers store zero here to inhibit the error message
- for unrecognized options. */
-
-int opterr = 1;
-
-/* Set to an option character which was unrecognized.
- This must be initialized on some systems to avoid linking in the
- system's own getopt implementation. */
-
-int optopt = '?';
-
-/* Describe how to deal with options that follow non-option ARGV-elements.
-
- If the caller did not specify anything,
- the default is REQUIRE_ORDER if the environment variable
- POSIXLY_CORRECT is defined, PERMUTE otherwise.
-
- REQUIRE_ORDER means don't recognize them as options;
- stop option processing when the first non-option is seen.
- This is what Unix does.
- This mode of operation is selected by either setting the environment
- variable POSIXLY_CORRECT, or using `+' as the first character
- of the list of option characters.
-
- PERMUTE is the default. We permute the contents of ARGV as we scan,
- so that eventually all the non-options are at the end. This allows options
- to be given in any order, even with programs that were not written to
- expect this.
-
- RETURN_IN_ORDER is an option available to programs that were written
- to expect options and other ARGV-elements in any order and that care about
- the ordering of the two. We describe each non-option ARGV-element
- as if it were the argument of an option with character code 1.
- Using `-' as the first character of the list of option characters
- selects this mode of operation.
-
- The special argument `--' forces an end of option-scanning regardless
- of the value of `ordering'. In the case of RETURN_IN_ORDER, only
- `--' can cause `getopt' to return -1 with `optind' != ARGC. */
-
-static enum
-{
- REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
-} ordering;
-
-/* Value of POSIXLY_CORRECT environment variable. */
-static char *posixly_correct;
-
-#ifdef __GNU_LIBRARY__
-/* We want to avoid inclusion of string.h with non-GNU libraries
- because there are many ways it can cause trouble.
- On some systems, it contains special magic macros that don't work
- in GCC. */
-# include <string.h>
-# define my_index strchr
-#else
-
-#include <string.h>
-
-/* Avoid depending on library functions or files
- whose names are inconsistent. */
-
-#ifndef getenv
-extern char *getenv ();
-#endif
-
-static char *
-my_index (str, chr)
- const char *str;
- int chr;
-{
- while (*str)
- {
- if (*str == chr)
- return (char *) str;
- str++;
- }
- return 0;
-}
-
-/* If using GCC, we can safely declare strlen this way.
- If not using GCC, it is ok not to declare it. */
-#ifdef __GNUC__
-/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
- That was relevant to code that was here before. */
-# if (!defined __STDC__ || !__STDC__) && !defined strlen
-/* gcc with -traditional declares the built-in strlen to return int,
- and has done so at least since version 2.4.5. -- rms. */
-extern int strlen (const char *);
-# endif /* not __STDC__ */
-#endif /* __GNUC__ */
-
-#endif /* not __GNU_LIBRARY__ */
-
-/* Handle permutation of arguments. */
-
-/* Describe the part of ARGV that contains non-options that have
- been skipped. `first_nonopt' is the index in ARGV of the first of them;
- `last_nonopt' is the index after the last of them. */
-
-static int first_nonopt;
-static int last_nonopt;
-
-#ifdef _LIBC
-/* Stored original parameters.
- XXX This is no good solution. We should rather copy the args so
- that we can compare them later. But we must not use malloc(3). */
-extern int __libc_argc;
-extern char **__libc_argv;
-
-/* Bash 2.0 gives us an environment variable containing flags
- indicating ARGV elements that should not be considered arguments. */
-
-# ifdef USE_NONOPTION_FLAGS
-/* Defined in getopt_init.c */
-extern char *__getopt_nonoption_flags;
-
-static int nonoption_flags_max_len;
-static int nonoption_flags_len;
-# endif
-
-# ifdef USE_NONOPTION_FLAGS
-# define SWAP_FLAGS(ch1, ch2) \
- if (nonoption_flags_len > 0) \
- { \
- char __tmp = __getopt_nonoption_flags[ch1]; \
- __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
- __getopt_nonoption_flags[ch2] = __tmp; \
- }
-# else
-# define SWAP_FLAGS(ch1, ch2)
-# endif
-#else /* !_LIBC */
-# define SWAP_FLAGS(ch1, ch2)
-#endif /* _LIBC */
-
-/* Exchange two adjacent subsequences of ARGV.
- One subsequence is elements [first_nonopt,last_nonopt)
- which contains all the non-options that have been skipped so far.
- The other is elements [last_nonopt,optind), which contains all
- the options processed since those non-options were skipped.
-
- `first_nonopt' and `last_nonopt' are relocated so that they describe
- the new indices of the non-options in ARGV after they are moved. */
-
-#if defined __STDC__ && __STDC__
-static void exchange (char **);
-#endif
-
-static void
-exchange (argv)
- char **argv;
-{
- int bottom = first_nonopt;
- int middle = last_nonopt;
- int top = optind;
- char *tem;
-
- /* Exchange the shorter segment with the far end of the longer segment.
- That puts the shorter segment into the right place.
- It leaves the longer segment in the right place overall,
- but it consists of two parts that need to be swapped next. */
-
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
- /* First make sure the handling of the `__getopt_nonoption_flags'
- string can work normally. Our top argument must be in the range
- of the string. */
- if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
- {
- /* We must extend the array. The user plays games with us and
- presents new arguments. */
- char *new_str = malloc (top + 1);
- if (new_str == NULL)
- nonoption_flags_len = nonoption_flags_max_len = 0;
- else
- {
- memset (__mempcpy (new_str, __getopt_nonoption_flags,
- nonoption_flags_max_len),
- '\0', top + 1 - nonoption_flags_max_len);
- nonoption_flags_max_len = top + 1;
- __getopt_nonoption_flags = new_str;
- }
- }
-#endif
-
- while (top > middle && middle > bottom)
- {
- if (top - middle > middle - bottom)
- {
- /* Bottom segment is the short one. */
- int len = middle - bottom;
- register int i;
-
- /* Swap it with the top part of the top segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[top - (middle - bottom) + i];
- argv[top - (middle - bottom) + i] = tem;
- SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
- }
- /* Exclude the moved bottom segment from further swapping. */
- top -= len;
- }
- else
- {
- /* Top segment is the short one. */
- int len = top - middle;
- register int i;
-
- /* Swap it with the bottom part of the bottom segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[middle + i];
- argv[middle + i] = tem;
- SWAP_FLAGS (bottom + i, middle + i);
- }
- /* Exclude the moved top segment from further swapping. */
- bottom += len;
- }
- }
-
- /* Update records for the slots the non-options now occupy. */
-
- first_nonopt += (optind - last_nonopt);
- last_nonopt = optind;
-}
-
-/* Initialize the internal data when the first call is made. */
-
-#if defined __STDC__ && __STDC__
-static const char *_getopt_initialize (int, char *const *, const char *);
-#endif
-static const char *
-_getopt_initialize (argc, argv, optstring)
- int argc;
- char *const *argv;
- const char *optstring;
-{
- /* Start processing options with ARGV-element 1 (since ARGV-element 0
- is the program name); the sequence of previously skipped
- non-option ARGV-elements is empty. */
-
- first_nonopt = last_nonopt = optind;
-
- nextchar = NULL;
-
- posixly_correct = getenv ("POSIXLY_CORRECT");
-
- /* Determine how to handle the ordering of options and nonoptions. */
-
- if (optstring[0] == '-')
- {
- ordering = RETURN_IN_ORDER;
- ++optstring;
- }
- else if (optstring[0] == '+')
- {
- ordering = REQUIRE_ORDER;
- ++optstring;
- }
- else if (posixly_correct != NULL)
- ordering = REQUIRE_ORDER;
- else
- ordering = PERMUTE;
-
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
- if (posixly_correct == NULL
- && argc == __libc_argc && argv == __libc_argv)
- {
- if (nonoption_flags_max_len == 0)
- {
- if (__getopt_nonoption_flags == NULL
- || __getopt_nonoption_flags[0] == '\0')
- nonoption_flags_max_len = -1;
- else
- {
- const char *orig_str = __getopt_nonoption_flags;
- int len = nonoption_flags_max_len = strlen (orig_str);
- if (nonoption_flags_max_len < argc)
- nonoption_flags_max_len = argc;
- __getopt_nonoption_flags =
- (char *) malloc (nonoption_flags_max_len);
- if (__getopt_nonoption_flags == NULL)
- nonoption_flags_max_len = -1;
- else
- memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
- '\0', nonoption_flags_max_len - len);
- }
- }
- nonoption_flags_len = nonoption_flags_max_len;
- }
- else
- nonoption_flags_len = 0;
-#endif
-
- return optstring;
-}
-
-/* Scan elements of ARGV (whose length is ARGC) for option characters
- given in OPTSTRING.
-
- If an element of ARGV starts with '-', and is not exactly "-" or "--",
- then it is an option element. The characters of this element
- (aside from the initial '-') are option characters. If `getopt'
- is called repeatedly, it returns successively each of the option characters
- from each of the option elements.
-
- If `getopt' finds another option character, it returns that character,
- updating `optind' and `nextchar' so that the next call to `getopt' can
- resume the scan with the following option character or ARGV-element.
-
- If there are no more option characters, `getopt' returns -1.
- Then `optind' is the index in ARGV of the first ARGV-element
- that is not an option. (The ARGV-elements have been permuted
- so that those that are not options now come last.)
-
- OPTSTRING is a string containing the legitimate option characters.
- If an option character is seen that is not listed in OPTSTRING,
- return '?' after printing an error message. If you set `opterr' to
- zero, the error message is suppressed but we still return '?'.
-
- If a char in OPTSTRING is followed by a colon, that means it wants an arg,
- so the following text in the same ARGV-element, or the text of the following
- ARGV-element, is returned in `optarg'. Two colons mean an option that
- wants an optional arg; if there is text in the current ARGV-element,
- it is returned in `optarg', otherwise `optarg' is set to zero.
-
- If OPTSTRING starts with `-' or `+', it requests different methods of
- handling the non-option ARGV-elements.
- See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
-
- Long-named options begin with `--' instead of `-'.
- Their names may be abbreviated as long as the abbreviation is unique
- or is an exact match for some defined option. If they have an
- argument, it follows the option name in the same ARGV-element, separated
- from the option name by a `=', or else the in next ARGV-element.
- When `getopt' finds a long-named option, it returns 0 if that option's
- `flag' field is nonzero, the value of the option's `val' field
- if the `flag' field is zero.
-
- The elements of ARGV aren't really const, because we permute them.
- But we pretend they're const in the prototype to be compatible
- with other systems.
-
- LONGOPTS is a vector of `struct option' terminated by an
- element containing a name which is zero.
-
- LONGIND returns the index in LONGOPT of the long-named option found.
- It is only valid when a long-named option has been found by the most
- recent call.
-
- If LONG_ONLY is nonzero, '-' as well as '--' can introduce
- long-named options. */
-
-int
-_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
- int argc;
- char *const *argv;
- const char *optstring;
- const struct option *longopts;
- int *longind;
- int long_only;
-{
- int print_errors = opterr;
- if (optstring[0] == ':')
- print_errors = 0;
-
- if (argc < 1)
- return -1;
-
- optarg = NULL;
-
- if (optind == 0 || !__getopt_initialized)
- {
- if (optind == 0)
- optind = 1; /* Don't scan ARGV[0], the program name. */
- optstring = _getopt_initialize (argc, argv, optstring);
- __getopt_initialized = 1;
- }
-
- /* Test whether ARGV[optind] points to a non-option argument.
- Either it does not have option syntax, or there is an environment flag
- from the shell indicating it is not an option. The later information
- is only used when the used in the GNU libc. */
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
-# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
- || (optind < nonoption_flags_len \
- && __getopt_nonoption_flags[optind] == '1'))
-#else
-# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
-#endif
-
- if (nextchar == NULL || *nextchar == '\0')
- {
- /* Advance to the next ARGV-element. */
-
- /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
- moved back by the user (who may also have changed the arguments). */
- if (last_nonopt > optind)
- last_nonopt = optind;
- if (first_nonopt > optind)
- first_nonopt = optind;
-
- if (ordering == PERMUTE)
- {
- /* If we have just processed some options following some non-options,
- exchange them so that the options come first. */
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange ((char **) argv);
- else if (last_nonopt != optind)
- first_nonopt = optind;
-
- /* Skip any additional non-options
- and extend the range of non-options previously skipped. */
-
- while (optind < argc && NONOPTION_P)
- optind++;
- last_nonopt = optind;
- }
-
- /* The special ARGV-element `--' means premature end of options.
- Skip it like a null option,
- then exchange with previous non-options as if it were an option,
- then skip everything else like a non-option. */
-
- if (optind != argc && !strcmp (argv[optind], "--"))
- {
- optind++;
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange ((char **) argv);
- else if (first_nonopt == last_nonopt)
- first_nonopt = optind;
- last_nonopt = argc;
-
- optind = argc;
- }
-
- /* If we have done all the ARGV-elements, stop the scan
- and back over any non-options that we skipped and permuted. */
-
- if (optind == argc)
- {
- /* Set the next-arg-index to point at the non-options
- that we previously skipped, so the caller will digest them. */
- if (first_nonopt != last_nonopt)
- optind = first_nonopt;
- return -1;
- }
-
- /* If we have come to a non-option and did not permute it,
- either stop the scan or describe it to the caller and pass it by. */
-
- if (NONOPTION_P)
- {
- if (ordering == REQUIRE_ORDER)
- return -1;
- optarg = argv[optind++];
- return 1;
- }
-
- /* We have found another option-ARGV-element.
- Skip the initial punctuation. */
-
- nextchar = (argv[optind] + 1
- + (longopts != NULL && argv[optind][1] == '-'));
- }
-
- /* Decode the current option-ARGV-element. */
-
- /* Check whether the ARGV-element is a long option.
-
- If long_only and the ARGV-element has the form "-f", where f is
- a valid short option, don't consider it an abbreviated form of
- a long option that starts with f. Otherwise there would be no
- way to give the -f short option.
-
- On the other hand, if there's a long option "fubar" and
- the ARGV-element is "-fu", do consider that an abbreviation of
- the long option, just like "--fu", and not "-f" with arg "u".
-
- This distinction seems to be the most useful approach. */
-
- if (longopts != NULL
- && (argv[optind][1] == '-'
- || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
- {
- char *nameend;
- const struct option *p;
- const struct option *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound = -1;
- int option_index;
-
- for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
- /* Do nothing. */ ;
-
- /* Test all long options for either exact match
- or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name; p++, option_index++)
- if (!strncmp (p->name, nextchar, nameend - nextchar))
- {
- if ((unsigned int) (nameend - nextchar)
- == (unsigned int) strlen (p->name))
- {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- }
- else if (pfound == NULL)
- {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- }
- else if (long_only
- || pfound->has_arg != p->has_arg
- || pfound->flag != p->flag
- || pfound->val != p->val)
- /* Second or later nonexact match found. */
- ambig = 1;
- }
-
- if (ambig && !exact)
- {
- if (print_errors)
- fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
- argv[0], argv[optind]);
- nextchar += strlen (nextchar);
- optind++;
- optopt = 0;
- return '?';
- }
-
- if (pfound != NULL)
- {
- option_index = indfound;
- optind++;
- if (*nameend)
- {
- /* Don't test has_arg with >, because some C compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- optarg = nameend + 1;
- else
- {
- if (print_errors)
- {
- if (argv[optind - 1][1] == '-')
- /* --option */
- fprintf (stderr,
- _("%s: option `--%s' doesn't allow an argument\n"),
- argv[0], pfound->name);
- else
- /* +option or -option */
- fprintf (stderr,
- _("%s: option `%c%s' doesn't allow an argument\n"),
- argv[0], argv[optind - 1][0], pfound->name);
- }
-
- nextchar += strlen (nextchar);
-
- optopt = pfound->val;
- return '?';
- }
- }
- else if (pfound->has_arg == 1)
- {
- if (optind < argc)
- optarg = argv[optind++];
- else
- {
- if (print_errors)
- fprintf (stderr,
- _("%s: option `%s' requires an argument\n"),
- argv[0], argv[optind - 1]);
- nextchar += strlen (nextchar);
- optopt = pfound->val;
- return optstring[0] == ':' ? ':' : '?';
- }
- }
- nextchar += strlen (nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag)
- {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
-
- /* Can't find it as a long option. If this is not getopt_long_only,
- or the option starts with '--' or is not a valid short
- option, then it's an error.
- Otherwise interpret it as a short option. */
- if (!long_only || argv[optind][1] == '-'
- || my_index (optstring, *nextchar) == NULL)
- {
- if (print_errors)
- {
- if (argv[optind][1] == '-')
- /* --option */
- fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
- argv[0], nextchar);
- else
- /* +option or -option */
- fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
- argv[0], argv[optind][0], nextchar);
- }
- nextchar = (char *) "";
- optind++;
- optopt = 0;
- return '?';
- }
- }
-
- /* Look at and handle the next short option-character. */
-
- {
- char c = *nextchar++;
- char *temp = my_index (optstring, c);
-
- /* Increment `optind' when we start to process its last character. */
- if (*nextchar == '\0')
- ++optind;
-
- if (temp == NULL || c == ':')
- {
- if (print_errors)
- {
- if (posixly_correct)
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr, _("%s: illegal option -- %c\n"),
- argv[0], c);
- else
- fprintf (stderr, _("%s: invalid option -- %c\n"),
- argv[0], c);
- }
- optopt = c;
- return '?';
- }
- /* Convenience. Treat POSIX -W foo same as long option --foo */
- if (temp[0] == 'W' && temp[1] == ';')
- {
- char *nameend;
- const struct option *p;
- const struct option *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound = 0;
- int option_index;
-
- /* This is an option that requires an argument. */
- if (*nextchar != '\0')
- {
- optarg = nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- we must advance to the next element now. */
- optind++;
- }
- else if (optind == argc)
- {
- if (print_errors)
- {
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr, _("%s: option requires an argument -- %c\n"),
- argv[0], c);
- }
- optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- return c;
- }
- else
- /* We already incremented `optind' once;
- increment it again when taking next ARGV-elt as argument. */
- optarg = argv[optind++];
-
- /* optarg is now the argument, see if it's in the
- table of longopts. */
-
- for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
- /* Do nothing. */ ;
-
- /* Test all long options for either exact match
- or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name; p++, option_index++)
- if (!strncmp (p->name, nextchar, nameend - nextchar))
- {
- if ((unsigned int) (nameend - nextchar) == strlen (p->name))
- {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- }
- else if (pfound == NULL)
- {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- }
- else
- /* Second or later nonexact match found. */
- ambig = 1;
- }
- if (ambig && !exact)
- {
- if (print_errors)
- fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
- argv[0], argv[optind]);
- nextchar += strlen (nextchar);
- optind++;
- return '?';
- }
- if (pfound != NULL)
- {
- option_index = indfound;
- if (*nameend)
- {
- /* Don't test has_arg with >, because some C compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- optarg = nameend + 1;
- else
- {
- if (print_errors)
- fprintf (stderr, _("\
-%s: option `-W %s' doesn't allow an argument\n"),
- argv[0], pfound->name);
-
- nextchar += strlen (nextchar);
- return '?';
- }
- }
- else if (pfound->has_arg == 1)
- {
- if (optind < argc)
- optarg = argv[optind++];
- else
- {
- if (print_errors)
- fprintf (stderr,
- _("%s: option `%s' requires an argument\n"),
- argv[0], argv[optind - 1]);
- nextchar += strlen (nextchar);
- return optstring[0] == ':' ? ':' : '?';
- }
- }
- nextchar += strlen (nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag)
- {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
- nextchar = NULL;
- return 'W'; /* Let the application handle it. */
- }
- if (temp[1] == ':')
- {
- if (temp[2] == ':')
- {
- /* This is an option that accepts an argument optionally. */
- if (*nextchar != '\0')
- {
- optarg = nextchar;
- optind++;
- }
- else
- optarg = NULL;
- nextchar = NULL;
- }
- else
- {
- /* This is an option that requires an argument. */
- if (*nextchar != '\0')
- {
- optarg = nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- we must advance to the next element now. */
- optind++;
- }
- else if (optind == argc)
- {
- if (print_errors)
- {
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr,
- _("%s: option requires an argument -- %c\n"),
- argv[0], c);
- }
- optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- }
- else
- /* We already incremented `optind' once;
- increment it again when taking next ARGV-elt as argument. */
- optarg = argv[optind++];
- nextchar = NULL;
- }
- }
- return c;
- }
-}
-
-int
-getopt (argc, argv, optstring)
- int argc;
- char *const *argv;
- const char *optstring;
-{
- return _getopt_internal (argc, argv, optstring,
- (const struct option *) 0,
- (int *) 0,
- 0);
-}
-
-#endif /* Not ELIDE_CODE. */
-
-#ifdef TEST
-
-/* Compile with -DTEST to make an executable for use in testing
- the above definition of `getopt'. */
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- int c;
- int digit_optind = 0;
-
- while (1)
- {
- int this_option_optind = optind ? optind : 1;
-
- c = getopt (argc, argv, "abc:d:0123456789");
- if (c == -1)
- break;
-
- switch (c)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf ("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf ("option %c\n", c);
- break;
-
- case 'a':
- printf ("option a\n");
- break;
-
- case 'b':
- printf ("option b\n");
- break;
-
- case 'c':
- printf ("option c with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf ("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc)
- {
- printf ("non-option ARGV-elements: ");
- while (optind < argc)
- printf ("%s ", argv[optind++]);
- printf ("\n");
- }
-
- exit (0);
-}
-
-#endif /* TEST */
+/* Getopt for GNU.
+ NOTE: getopt is now part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to drepper@gnu.org
+ before changing it!
+ Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+# ifndef const
+# define const
+# endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+# define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library. */
+
+#ifdef VMS
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+# include <string.h>
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages. */
+# if defined HAVE_LIBINTL_H || defined _LIBC
+# include <libintl.h>
+# ifndef _
+# define _(msgid) gettext (msgid)
+# endif
+# else
+# define _(msgid) (msgid)
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+char *optarg = NULL;
+ /*
+ Above initialization is required to avoid following problem on MacOS X 10.1,10.2.6
+ (This is the only difference from gengetopt-2.5. ... 2003/07/14 ... )
+ ld: multiple definitions of symbol _getopt
+ /usr/lib/libm.dylib(getopt.So) definition of _getopt
+ ../lib/libnmzut.a(getopt.o) definition of _getopt in section (__TEXT,__text)
+ */
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+ causes problems with re-calling getopt as programs generally don't
+ know that. */
+
+int __getopt_initialized;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+ because there are many ways it can cause trouble.
+ On some systems, it contains special magic macros that don't work
+ in GCC. */
+# include <string.h>
+# define my_index strchr
+#else
+
+#include <string.h>
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+ const char *str;
+ int chr;
+{
+ while (*str)
+ {
+ if (*str == chr)
+ return (char *) str;
+ str++;
+ }
+ return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments. */
+
+/* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Stored original parameters.
+ XXX This is no good solution. We should rather copy the args so
+ that we can compare them later. But we must not use malloc(3). */
+extern int __libc_argc;
+extern char **__libc_argv;
+
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+# ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+# endif
+
+# ifdef USE_NONOPTION_FLAGS
+# define SWAP_FLAGS(ch1, ch2) \
+ if (nonoption_flags_len > 0) \
+ { \
+ char __tmp = __getopt_nonoption_flags[ch1]; \
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
+ __getopt_nonoption_flags[ch2] = __tmp; \
+ }
+# else
+# define SWAP_FLAGS(ch1, ch2)
+# endif
+#else /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+ char **argv;
+{
+ int bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ /* First make sure the handling of the `__getopt_nonoption_flags'
+ string can work normally. Our top argument must be in the range
+ of the string. */
+ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+ {
+ /* We must extend the array. The user plays games with us and
+ presents new arguments. */
+ char *new_str = malloc (top + 1);
+ if (new_str == NULL)
+ nonoption_flags_len = nonoption_flags_max_len = 0;
+ else
+ {
+ memset (__mempcpy (new_str, __getopt_nonoption_flags,
+ nonoption_flags_max_len),
+ '\0', top + 1 - nonoption_flags_max_len);
+ nonoption_flags_max_len = top + 1;
+ __getopt_nonoption_flags = new_str;
+ }
+ }
+#endif
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS (bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ if (posixly_correct == NULL
+ && argc == __libc_argc && argv == __libc_argv)
+ {
+ if (nonoption_flags_max_len == 0)
+ {
+ if (__getopt_nonoption_flags == NULL
+ || __getopt_nonoption_flags[0] == '\0')
+ nonoption_flags_max_len = -1;
+ else
+ {
+ const char *orig_str = __getopt_nonoption_flags;
+ int len = nonoption_flags_max_len = strlen (orig_str);
+ if (nonoption_flags_max_len < argc)
+ nonoption_flags_max_len = argc;
+ __getopt_nonoption_flags =
+ (char *) malloc (nonoption_flags_max_len);
+ if (__getopt_nonoption_flags == NULL)
+ nonoption_flags_max_len = -1;
+ else
+ memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+ '\0', nonoption_flags_max_len - len);
+ }
+ }
+ nonoption_flags_len = nonoption_flags_max_len;
+ }
+ else
+ nonoption_flags_len = 0;
+#endif
+
+ return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+ const struct option *longopts;
+ int *longind;
+ int long_only;
+{
+ int print_errors = opterr;
+ if (optstring[0] == ':')
+ print_errors = 0;
+
+ if (argc < 1)
+ return -1;
+
+ optarg = NULL;
+
+ if (optind == 0 || !__getopt_initialized)
+ {
+ if (optind == 0)
+ optind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize (argc, argv, optstring);
+ __getopt_initialized = 1;
+ }
+
+ /* Test whether ARGV[optind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
+ || (optind < nonoption_flags_len \
+ && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (last_nonopt > optind)
+ last_nonopt = optind;
+ if (first_nonopt > optind)
+ first_nonopt = optind;
+
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < argc && NONOPTION_P)
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != argc && !strcmp (argv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = argc;
+
+ optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (NONOPTION_P)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return -1;
+ optarg = argv[optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[optind] + 1
+ + (longopts != NULL && argv[optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar)
+ == (unsigned int) strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else if (long_only
+ || pfound->has_arg != p->has_arg
+ || pfound->flag != p->flag
+ || pfound->val != p->val)
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ {
+ if (argv[optind - 1][1] == '-')
+ /* --option */
+ fprintf (stderr,
+ _("%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+ else
+ /* +option or -option */
+ fprintf (stderr,
+ _("%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[optind - 1][0], pfound->name);
+ }
+
+ nextchar += strlen (nextchar);
+
+ optopt = pfound->val;
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (print_errors)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ optopt = pfound->val;
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[optind][1] == '-'
+ || my_index (optstring, *nextchar) == NULL)
+ {
+ if (print_errors)
+ {
+ if (argv[optind][1] == '-')
+ /* --option */
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+ argv[0], nextchar);
+ else
+ /* +option or -option */
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[optind][0], nextchar);
+ }
+ nextchar = (char *) "";
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = my_index (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == '\0')
+ ++optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (print_errors)
+ {
+ if (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: illegal option -- %c\n"),
+ argv[0], c);
+ else
+ fprintf (stderr, _("%s: invalid option -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ return '?';
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (print_errors)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = NULL;
+ nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+ nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+getopt (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+#endif /* Not ELIDE_CODE. */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+ the above definition of `getopt'. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/MSVC/getopt/getopt.h b/MSVC/getopt/getopt.h
index 74d0d2b..a1b8dd6 100644
--- a/MSVC/getopt/getopt.h
+++ b/MSVC/getopt/getopt.h
@@ -1,180 +1,180 @@
-/* Declarations for getopt.
- Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#ifndef _GETOPT_H
-
-#ifndef __need_getopt
-# define _GETOPT_H 1
-#endif
-
-/* If __GNU_LIBRARY__ is not already defined, either we are being used
- standalone, or this is the first header included in the source file.
- If we are being used with glibc, we need to include <features.h>, but
- that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
- not defined, include <ctype.h>, which will pull in <features.h> for us
- if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
- doesn't flood the namespace with stuff the way some other headers do.) */
-#if !defined __GNU_LIBRARY__
-# include <ctype.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-extern char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns -1, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-extern int optind;
-
-/* Callers store zero here to inhibit the error message `getopt' prints
- for unrecognized options. */
-
-extern int opterr;
-
-/* Set to an option character which was unrecognized. */
-
-extern int optopt;
-
-#ifndef __need_getopt
-/* Describe the long-named options requested by the application.
- The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
- of `struct option' terminated by an element containing a name which is
- zero.
-
- The field `has_arg' is:
- no_argument (or 0) if the option does not take an argument,
- required_argument (or 1) if the option requires an argument,
- optional_argument (or 2) if the option takes an optional argument.
-
- If the field `flag' is not NULL, it points to a variable that is set
- to the value given in the field `val' when the option is found, but
- left unchanged if the option is not found.
-
- To have a long-named option do something other than set an `int' to
- a compiled-in constant, such as set a value from `optarg', set the
- option's `flag' field to zero and its `val' field to a nonzero
- value (the equivalent single-letter option character, if there is
- one). For long options that have a zero `flag' field, `getopt'
- returns the contents of the `val' field. */
-
-struct option
-{
-# if (defined __STDC__ && __STDC__) || defined __cplusplus
- const char *name;
-# else
- char *name;
-# endif
- /* has_arg can't be an enum because some compilers complain about
- type mismatches in all the code that assumes it is an int. */
- int has_arg;
- int *flag;
- int val;
-};
-
-/* Names for the values of the `has_arg' field of `struct option'. */
-
-# define no_argument 0
-# define required_argument 1
-# define optional_argument 2
-#endif /* need getopt */
-
-
-/* Get definitions and prototypes for functions to process the
- arguments in ARGV (ARGC of them, minus the program name) for
- options given in OPTS.
-
- Return the option character from OPTS just read. Return -1 when
- there are no more options. For unrecognized options, or options
- missing arguments, `optopt' is set to the option letter, and '?' is
- returned.
-
- The OPTS string is a list of characters which are recognized option
- letters, optionally followed by colons, specifying that that letter
- takes an argument, to be placed in `optarg'.
-
- If a letter in OPTS is followed by two colons, its argument is
- optional. This behavior is specific to the GNU `getopt'.
-
- The argument `--' causes premature termination of argument
- scanning, explicitly telling `getopt' that there are no more
- options.
-
- If OPTS begins with `--', then non-option arguments are treated as
- arguments to the option '\0'. This behavior is specific to the GNU
- `getopt'. */
-
-#if (defined __STDC__ && __STDC__) || defined __cplusplus
-# ifdef __GNU_LIBRARY__
-/* Many other libraries have conflicting prototypes for getopt, with
- differences in the consts, in stdlib.h. To avoid compilation
- errors, only prototype getopt for the GNU C library. */
-extern int getopt (int __argc, char *const *__argv, const char *__shortopts);
-# else /* not __GNU_LIBRARY__ */
-extern int getopt ();
-# endif /* __GNU_LIBRARY__ */
-
-# ifndef __need_getopt
-extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
- const struct option *__longopts, int *__longind);
-extern int getopt_long_only (int __argc, char *const *__argv,
- const char *__shortopts,
- const struct option *__longopts, int *__longind);
-
-/* Internal only. Users should not call this directly. */
-extern int _getopt_internal (int __argc, char *const *__argv,
- const char *__shortopts,
- const struct option *__longopts, int *__longind,
- int __long_only);
-# endif
-#else /* not __STDC__ */
-extern int getopt ();
-# ifndef __need_getopt
-extern int getopt_long ();
-extern int getopt_long_only ();
-
-extern int _getopt_internal ();
-# endif
-#endif /* __STDC__ */
-
-#ifdef __cplusplus
-}
-#endif
-
-/* Make sure we later can get all the definitions and declarations. */
-#undef __need_getopt
-
-#endif /* getopt.h */
+/* Declarations for getopt.
+ Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+ standalone, or this is the first header included in the source file.
+ If we are being used with glibc, we need to include <features.h>, but
+ that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
+ not defined, include <ctype.h>, which will pull in <features.h> for us
+ if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
+ doesn't flood the namespace with stuff the way some other headers do.) */
+#if !defined __GNU_LIBRARY__
+# include <ctype.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+# if (defined __STDC__ && __STDC__) || defined __cplusplus
+ const char *name;
+# else
+ char *name;
+# endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+# define no_argument 0
+# define required_argument 1
+# define optional_argument 2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+ arguments in ARGV (ARGC of them, minus the program name) for
+ options given in OPTS.
+
+ Return the option character from OPTS just read. Return -1 when
+ there are no more options. For unrecognized options, or options
+ missing arguments, `optopt' is set to the option letter, and '?' is
+ returned.
+
+ The OPTS string is a list of characters which are recognized option
+ letters, optionally followed by colons, specifying that that letter
+ takes an argument, to be placed in `optarg'.
+
+ If a letter in OPTS is followed by two colons, its argument is
+ optional. This behavior is specific to the GNU `getopt'.
+
+ The argument `--' causes premature termination of argument
+ scanning, explicitly telling `getopt' that there are no more
+ options.
+
+ If OPTS begins with `--', then non-option arguments are treated as
+ arguments to the option '\0'. This behavior is specific to the GNU
+ `getopt'. */
+
+#if (defined __STDC__ && __STDC__) || defined __cplusplus
+# ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+extern int getopt (int __argc, char *const *__argv, const char *__shortopts);
+# else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+# endif /* __GNU_LIBRARY__ */
+
+# ifndef __need_getopt
+extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+extern int getopt_long_only (int __argc, char *const *__argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal (int __argc, char *const *__argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind,
+ int __long_only);
+# endif
+#else /* not __STDC__ */
+extern int getopt ();
+# ifndef __need_getopt
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+# endif
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations. */
+#undef __need_getopt
+
+#endif /* getopt.h */
diff --git a/MSVC/getopt/getopt1.c b/MSVC/getopt/getopt1.c
index 1544891..22a7efb 100644
--- a/MSVC/getopt/getopt1.c
+++ b/MSVC/getopt/getopt1.c
@@ -1,188 +1,188 @@
-/* getopt_long and getopt_long_only entry points for GNU getopt.
- Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "getopt.h"
-
-#if !defined __STDC__ || !__STDC__
-/* This is a separate conditional since some stdc systems
- reject `defined (const)'. */
-#ifndef const
-#define const
-#endif
-#endif
-
-#include <stdio.h>
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
-
-#define GETOPT_INTERFACE_VERSION 2
-#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
-#include <gnu-versions.h>
-#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
-#define ELIDE_CODE
-#endif
-#endif
-
-#ifndef ELIDE_CODE
-
-
-/* This needs to come after some library #include
- to get __GNU_LIBRARY__ defined. */
-#ifdef __GNU_LIBRARY__
-#include <stdlib.h>
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-int
-getopt_long (argc, argv, options, long_options, opt_index)
- int argc;
- char *const *argv;
- const char *options;
- const struct option *long_options;
- int *opt_index;
-{
- return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
-}
-
-/* Like getopt_long, but '-' as well as '--' can indicate a long option.
- If an option that starts with '-' (not '--') doesn't match a long option,
- but does match a short option, it is parsed as a short option
- instead. */
-
-int
-getopt_long_only (argc, argv, options, long_options, opt_index)
- int argc;
- char *const *argv;
- const char *options;
- const struct option *long_options;
- int *opt_index;
-{
- return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
-}
-
-
-#endif /* Not ELIDE_CODE. */
-
-#ifdef TEST
-
-#include <stdio.h>
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- int c;
- int digit_optind = 0;
-
- while (1)
- {
- int this_option_optind = optind ? optind : 1;
- int option_index = 0;
- static struct option long_options[] =
- {
- {"add", 1, 0, 0},
- {"append", 0, 0, 0},
- {"delete", 1, 0, 0},
- {"verbose", 0, 0, 0},
- {"create", 0, 0, 0},
- {"file", 1, 0, 0},
- {0, 0, 0, 0}
- };
-
- c = getopt_long (argc, argv, "abc:d:0123456789",
- long_options, &option_index);
- if (c == -1)
- break;
-
- switch (c)
- {
- case 0:
- printf ("option %s", long_options[option_index].name);
- if (optarg)
- printf (" with arg %s", optarg);
- printf ("\n");
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf ("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf ("option %c\n", c);
- break;
-
- case 'a':
- printf ("option a\n");
- break;
-
- case 'b':
- printf ("option b\n");
- break;
-
- case 'c':
- printf ("option c with value `%s'\n", optarg);
- break;
-
- case 'd':
- printf ("option d with value `%s'\n", optarg);
- break;
-
- case '?':
- break;
-
- default:
- printf ("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc)
- {
- printf ("non-option ARGV-elements: ");
- while (optind < argc)
- printf ("%s ", argv[optind++]);
- printf ("\n");
- }
-
- exit (0);
-}
-
-#endif /* TEST */
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+ Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* Not ELIDE_CODE. */
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ {"add", 1, 0, 0},
+ {"append", 0, 0, 0},
+ {"delete", 1, 0, 0},
+ {"verbose", 0, 0, 0},
+ {"create", 0, 0, 0},
+ {"file", 1, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "abc:d:0123456789",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 0:
+ printf ("option %s", long_options[option_index].name);
+ if (optarg)
+ printf (" with arg %s", optarg);
+ printf ("\n");
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case 'd':
+ printf ("option d with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/MSVC/readline/ansi_stdlib.h b/MSVC/readline/ansi_stdlib.h
index 660c8c9..db13cd2 100644
--- a/MSVC/readline/ansi_stdlib.h
+++ b/MSVC/readline/ansi_stdlib.h
@@ -1,54 +1,54 @@
-/* ansi_stdlib.h -- An ANSI Standard stdlib.h. */
-/* A minimal stdlib.h containing extern declarations for those functions
- that bash uses. */
-
-/* Copyright (C) 1993 Free Software Foundation, Inc.
-
- This file is part of GNU Bash, the Bourne Again SHell.
-
- Bash 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, or (at your option) any later
- version.
-
- Bash 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 Bash; see the file COPYING. If not, write to the Free Software
- Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_STDLIB_H_)
-#define _STDLIB_H_ 1
-
-/* String conversion functions. */
-extern int atoi ();
-
-extern double atof ();
-extern double strtod ();
-
-/* Memory allocation functions. */
-/* Generic pointer type. */
-#ifndef PTR_T
-
-#if defined (__STDC__)
-# define PTR_T void *
-#else
-# define PTR_T char *
-#endif
-
-#endif /* PTR_T */
-
-extern PTR_T malloc ();
-extern PTR_T realloc ();
-extern void free ();
-
-/* Other miscellaneous functions. */
-extern void abort ();
-extern void exit ();
-extern char *getenv ();
-extern void qsort ();
-
-#endif /* _STDLIB_H */
+/* ansi_stdlib.h -- An ANSI Standard stdlib.h. */
+/* A minimal stdlib.h containing extern declarations for those functions
+ that bash uses. */
+
+/* Copyright (C) 1993 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ Bash 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, or (at your option) any later
+ version.
+
+ Bash 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 Bash; see the file COPYING. If not, write to the Free Software
+ Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_STDLIB_H_)
+#define _STDLIB_H_ 1
+
+/* String conversion functions. */
+extern int atoi ();
+
+extern double atof ();
+extern double strtod ();
+
+/* Memory allocation functions. */
+/* Generic pointer type. */
+#ifndef PTR_T
+
+#if defined (__STDC__)
+# define PTR_T void *
+#else
+# define PTR_T char *
+#endif
+
+#endif /* PTR_T */
+
+extern PTR_T malloc ();
+extern PTR_T realloc ();
+extern void free ();
+
+/* Other miscellaneous functions. */
+extern void abort ();
+extern void exit ();
+extern char *getenv ();
+extern void qsort ();
+
+#endif /* _STDLIB_H */
diff --git a/MSVC/readline/bind.c b/MSVC/readline/bind.c
index b5ad721..242b5ba 100644
--- a/MSVC/readline/bind.c
+++ b/MSVC/readline/bind.c
@@ -1,2155 +1,2155 @@
-/* bind.c -- key binding and startup file support for the readline library. */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#if defined (HAVE_SYS_FILE_H)
-# include <sys/file.h>
-#endif /* HAVE_SYS_FILE_H */
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <errno.h>
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-#include "posixstat.h"
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "rlshell.h"
-#include "xmalloc.h"
-
-#if !defined (strchr) && !defined (__STDC__) && !defined _MSC_VER
-extern char *strchr (), *strrchr ();
-#endif /* !strchr && !__STDC__ */
-
-/* Variables exported by this file. */
-Keymap rl_binding_keymap;
-
-static char *_rl_read_file PARAMS((char *, size_t *));
-static void _rl_init_file_error PARAMS((const char *));
-static int _rl_read_init_file PARAMS((const char *, int));
-static int glean_key_from_name PARAMS((char *));
-static int substring_member_of_array PARAMS((char *, const char **));
-
-static int currently_reading_init_file;
-
-/* used only in this file */
-static int _rl_prefer_visible_bell = 1;
-
-/* **************************************************************** */
-/* */
-/* Binding keys */
-/* */
-/* **************************************************************** */
-
-/* rl_add_defun (char *name, rl_command_func_t *function, int key)
- Add NAME to the list of named functions. Make FUNCTION be the function
- that gets called. If KEY is not -1, then bind it. */
-int
-rl_add_defun (name, function, key)
- const char *name;
- rl_command_func_t *function;
- int key;
-{
- if (key != -1)
- rl_bind_key (key, function);
- rl_add_funmap_entry (name, function);
- return 0;
-}
-
-/* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */
-int
-rl_bind_key (key, function)
- int key;
- rl_command_func_t *function;
-{
- if (key < 0)
- return (key);
-
- if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
- {
- if (_rl_keymap[ESC].type == ISKMAP)
- {
- Keymap escmap;
-
- escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC);
- key = UNMETA (key);
- escmap[key].type = ISFUNC;
- escmap[key].function = function;
- return (0);
- }
- return (key);
- }
-
- _rl_keymap[key].type = ISFUNC;
- _rl_keymap[key].function = function;
- rl_binding_keymap = _rl_keymap;
- return (0);
-}
-
-/* Bind KEY to FUNCTION in MAP. Returns non-zero in case of invalid
- KEY. */
-int
-rl_bind_key_in_map (key, function, map)
- int key;
- rl_command_func_t *function;
- Keymap map;
-{
- int result;
- Keymap oldmap;
-
- oldmap = _rl_keymap;
- _rl_keymap = map;
- result = rl_bind_key (key, function);
- _rl_keymap = oldmap;
- return (result);
-}
-
-/* Make KEY do nothing in the currently selected keymap.
- Returns non-zero in case of error. */
-int
-rl_unbind_key (key)
- int key;
-{
- return (rl_bind_key (key, (rl_command_func_t *)NULL));
-}
-
-/* Make KEY do nothing in MAP.
- Returns non-zero in case of error. */
-int
-rl_unbind_key_in_map (key, map)
- int key;
- Keymap map;
-{
- return (rl_bind_key_in_map (key, (rl_command_func_t *)NULL, map));
-}
-
-/* Unbind all keys bound to FUNCTION in MAP. */
-int
-rl_unbind_function_in_map (func, map)
- rl_command_func_t *func;
- Keymap map;
-{
- register int i, rval;
-
- for (i = rval = 0; i < KEYMAP_SIZE; i++)
- {
- if (map[i].type == ISFUNC && map[i].function == func)
- {
- map[i].function = (rl_command_func_t *)NULL;
- rval = 1;
- }
- }
- return rval;
-}
-
-int
-rl_unbind_command_in_map (command, map)
- const char *command;
- Keymap map;
-{
- rl_command_func_t *func;
-
- func = rl_named_function (command);
- if (func == 0)
- return 0;
- return (rl_unbind_function_in_map (func, map));
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
- FUNCTION. This makes new keymaps as necessary. The initial
- place to do bindings is in MAP. */
-int
-rl_set_key (keyseq, function, map)
- const char *keyseq;
- rl_command_func_t *function;
- Keymap map;
-{
- return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
- the string of characters MACRO. This makes new keymaps as
- necessary. The initial place to do bindings is in MAP. */
-int
-rl_macro_bind (keyseq, macro, map)
- const char *keyseq, *macro;
- Keymap map;
-{
- char *macro_keys;
- int macro_keys_len;
-
- macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1);
-
- if (rl_translate_keyseq (macro, macro_keys, &macro_keys_len))
- {
- free (macro_keys);
- return -1;
- }
- rl_generic_bind (ISMACR, keyseq, macro_keys, map);
- return 0;
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
- the arbitrary pointer DATA. TYPE says what kind of data is
- pointed to by DATA, right now this can be a function (ISFUNC),
- a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps
- as necessary. The initial place to do bindings is in MAP. */
-int
-rl_generic_bind (type, keyseq, data, map)
- int type;
- const char *keyseq;
- char *data;
- Keymap map;
-{
- char *keys;
- int keys_len;
- register int i;
- KEYMAP_ENTRY k;
-
- k.function = 0;
-
- /* If no keys to bind to, exit right away. */
- if (!keyseq || !*keyseq)
- {
- if (type == ISMACR)
- free (data);
- return -1;
- }
-
- keys = (char *)xmalloc (1 + (2 * strlen (keyseq)));
-
- /* Translate the ASCII representation of KEYSEQ into an array of
- characters. Stuff the characters into KEYS, and the length of
- KEYS into KEYS_LEN. */
- if (rl_translate_keyseq (keyseq, keys, &keys_len))
- {
- free (keys);
- return -1;
- }
-
- /* Bind keys, making new keymaps as necessary. */
- for (i = 0; i < keys_len; i++)
- {
- unsigned char uc = keys[i];
- int ic;
-
- ic = uc;
- if (ic < 0 || ic >= KEYMAP_SIZE)
- return -1;
-
- if (_rl_convert_meta_chars_to_ascii && META_CHAR (ic))
- {
- ic = UNMETA (ic);
- if (map[ESC].type == ISKMAP)
- map = FUNCTION_TO_KEYMAP (map, ESC);
- }
-
- if ((i + 1) < keys_len)
- {
- if (map[ic].type != ISKMAP)
- {
- /* We allow subsequences of keys. If a keymap is being
- created that will `shadow' an existing function or macro
- key binding, we save that keybinding into the ANYOTHERKEY
- index in the new map. The dispatch code will look there
- to find the function to execute if the subsequence is not
- matched. ANYOTHERKEY was chosen to be greater than
- UCHAR_MAX. */
- k = map[ic];
-
- map[ic].type = ISKMAP;
- map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());
- }
- map = FUNCTION_TO_KEYMAP (map, ic);
- /* The dispatch code will return this function if no matching
- key sequence is found in the keymap. This (with a little
- help from the dispatch code in readline.c) allows `a' to be
- mapped to something, `abc' to be mapped to something else,
- and the function bound to `a' to be executed when the user
- types `abx', leaving `bx' in the input queue. */
- if (k.function /* && k.type == ISFUNC */)
- {
- map[ANYOTHERKEY] = k;
- k.function = 0;
- }
- }
- else
- {
- if (map[ic].type == ISMACR)
- free ((char *)map[ic].function);
- else if (map[ic].type == ISKMAP)
- {
- map = FUNCTION_TO_KEYMAP (map, ic);
- ic = ANYOTHERKEY;
- }
-
- map[ic].function = KEYMAP_TO_FUNCTION (data);
- map[ic].type = type;
- }
-
- rl_binding_keymap = map;
- }
- free (keys);
- return 0;
-}
-
-/* Translate the ASCII representation of SEQ, stuffing the values into ARRAY,
- an array of characters. LEN gets the final length of ARRAY. Return
- non-zero if there was an error parsing SEQ. */
-int
-rl_translate_keyseq (seq, array, len)
- const char *seq;
- char *array;
- int *len;
-{
- register int i, c, l, temp;
-
- for (i = l = 0; (c = seq[i]); i++)
- {
- if (c == '\\')
- {
- c = seq[++i];
-
- if (c == 0)
- break;
-
- /* Handle \C- and \M- prefixes. */
- if ((c == 'C' || c == 'M') && seq[i + 1] == '-')
- {
- /* Handle special case of backwards define. */
- if (strncmp (&seq[i], "C-\\M-", 5) == 0)
- {
- array[l++] = ESC; /* ESC is meta-prefix */
- i += 5;
- array[l++] = CTRL (_rl_to_upper (seq[i]));
- if (seq[i] == '\0')
- i--;
- }
- else if (c == 'M')
- {
- i++;
- array[l++] = ESC; /* ESC is meta-prefix */
- }
- else if (c == 'C')
- {
- i += 2;
- /* Special hack for C-?... */
- array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
- }
- continue;
- }
-
- /* Translate other backslash-escaped characters. These are the
- same escape sequences that bash's `echo' and `printf' builtins
- handle, with the addition of \d -> RUBOUT. A backslash
- preceding a character that is not special is stripped. */
- switch (c)
- {
- case 'a':
- array[l++] = '\007';
- break;
- case 'b':
- array[l++] = '\b';
- break;
- case 'd':
- array[l++] = RUBOUT; /* readline-specific */
- break;
- case 'e':
- array[l++] = ESC;
- break;
- case 'f':
- array[l++] = '\f';
- break;
- case 'n':
- array[l++] = NEWLINE;
- break;
- case 'r':
- array[l++] = RETURN;
- break;
- case 't':
- array[l++] = TAB;
- break;
- case 'v':
- array[l++] = 0x0B;
- break;
- case '\\':
- array[l++] = '\\';
- break;
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- i++;
- for (temp = 2, c -= '0'; ISOCTAL (seq[i]) && temp--; i++)
- c = (c * 8) + OCTVALUE (seq[i]);
- i--; /* auto-increment in for loop */
- array[l++] = c & largest_char;
- break;
- case 'x':
- i++;
- for (temp = 2, c = 0; ISXDIGIT ((unsigned char)seq[i]) && temp--; i++)
- c = (c * 16) + HEXVALUE (seq[i]);
- if (temp == 2)
- c = 'x';
- i--; /* auto-increment in for loop */
- array[l++] = c & largest_char;
- break;
- default: /* backslashes before non-special chars just add the char */
- array[l++] = c;
- break; /* the backslash is stripped */
- }
- continue;
- }
-
- array[l++] = c;
- }
-
- *len = l;
- array[l] = '\0';
- return (0);
-}
-
-char *
-rl_untranslate_keyseq (seq)
- int seq;
-{
- static char kseq[16];
- int i, c;
-
- i = 0;
- c = seq;
- if (META_CHAR (c))
- {
- kseq[i++] = '\\';
- kseq[i++] = 'M';
- kseq[i++] = '-';
- c = UNMETA (c);
- }
- else if (CTRL_CHAR (c))
- {
- kseq[i++] = '\\';
- kseq[i++] = 'C';
- kseq[i++] = '-';
- c = _rl_to_lower (UNCTRL (c));
- }
- else if (c == RUBOUT)
- {
- kseq[i++] = '\\';
- kseq[i++] = 'C';
- kseq[i++] = '-';
- c = '?';
- }
-
- if (c == ESC)
- {
- kseq[i++] = '\\';
- c = 'e';
- }
- else if (c == '\\' || c == '"')
- {
- kseq[i++] = '\\';
- }
-
- kseq[i++] = (unsigned char) c;
- kseq[i] = '\0';
- return kseq;
-}
-
-static char *
-_rl_untranslate_macro_value (seq)
- char *seq;
-{
- char *ret, *r, *s;
- int c;
-
- r = ret = (char *)xmalloc (7 * strlen (seq) + 1);
- for (s = seq; *s; s++)
- {
- c = *s;
- if (META_CHAR (c))
- {
- *r++ = '\\';
- *r++ = 'M';
- *r++ = '-';
- c = UNMETA (c);
- }
- else if (CTRL_CHAR (c) && c != ESC)
- {
- *r++ = '\\';
- *r++ = 'C';
- *r++ = '-';
- c = _rl_to_lower (UNCTRL (c));
- }
- else if (c == RUBOUT)
- {
- *r++ = '\\';
- *r++ = 'C';
- *r++ = '-';
- c = '?';
- }
-
- if (c == ESC)
- {
- *r++ = '\\';
- c = 'e';
- }
- else if (c == '\\' || c == '"')
- *r++ = '\\';
-
- *r++ = (unsigned char)c;
- }
- *r = '\0';
- return ret;
-}
-
-/* Return a pointer to the function that STRING represents.
- If STRING doesn't have a matching function, then a NULL pointer
- is returned. */
-rl_command_func_t *
-rl_named_function (string)
- const char *string;
-{
- register int i;
-
- rl_initialize_funmap ();
-
- for (i = 0; funmap[i]; i++)
- if (_rl_stricmp (funmap[i]->name, string) == 0)
- return (funmap[i]->function);
- return ((rl_command_func_t *)NULL);
-}
-
-/* Return the function (or macro) definition which would be invoked via
- KEYSEQ if executed in MAP. If MAP is NULL, then the current keymap is
- used. TYPE, if non-NULL, is a pointer to an int which will receive the
- type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap),
- or ISMACR (macro). */
-rl_command_func_t *
-rl_function_of_keyseq (keyseq, map, type)
- const char *keyseq;
- Keymap map;
- int *type;
-{
- register int i;
-
- if (!map)
- map = _rl_keymap;
-
- for (i = 0; keyseq && keyseq[i]; i++)
- {
- unsigned char ic = keyseq[i];
-
- if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
- {
- if (map[ESC].type != ISKMAP)
- {
- if (type)
- *type = map[ESC].type;
-
- return (map[ESC].function);
- }
- else
- {
- map = FUNCTION_TO_KEYMAP (map, ESC);
- ic = UNMETA (ic);
- }
- }
-
- if (map[ic].type == ISKMAP)
- {
- /* If this is the last key in the key sequence, return the
- map. */
- if (!keyseq[i + 1])
- {
- if (type)
- *type = ISKMAP;
-
- return (map[ic].function);
- }
- else
- map = FUNCTION_TO_KEYMAP (map, ic);
- }
- else
- {
- if (type)
- *type = map[ic].type;
-
- return (map[ic].function);
- }
- }
- return ((rl_command_func_t *) NULL);
-}
-
-/* The last key bindings file read. */
-static char *last_readline_init_file = (char *)NULL;
-
-/* The file we're currently reading key bindings from. */
-static const char *current_readline_init_file;
-static int current_readline_init_include_level;
-static int current_readline_init_lineno;
-
-/* Read FILENAME into a locally-allocated buffer and return the buffer.
- The size of the buffer is returned in *SIZEP. Returns NULL if any
- errors were encountered. */
-static char *
-_rl_read_file (filename, sizep)
- char *filename;
- size_t *sizep;
-{
- struct stat finfo;
- size_t file_size;
- char *buffer;
- int i, file;
-
- if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0)
- return ((char *)NULL);
-
- file_size = (size_t)finfo.st_size;
-
- /* check for overflow on very large files */
- if (file_size != finfo.st_size || file_size + 1 < file_size)
- {
- if (file >= 0)
- close (file);
-#if defined (EFBIG)
- errno = EFBIG;
-#endif
- return ((char *)NULL);
- }
-
- /* Read the file into BUFFER. */
- buffer = (char *)xmalloc (file_size + 1);
- i = read (file, buffer, file_size);
- close (file);
-
- if (i < 0)
- {
- free (buffer);
- return ((char *)NULL);
- }
-
- buffer[i] = '\0';
- if (sizep)
- *sizep = i;
-
- return (buffer);
-}
-
-/* Re-read the current keybindings file. */
-int
-rl_re_read_init_file (count, ignore)
- int count, ignore;
-{
- int r;
- r = rl_read_init_file ((const char *)NULL);
- rl_set_keymap_from_edit_mode ();
- return r;
-}
-
-/* Do key bindings from a file. If FILENAME is NULL it defaults
- to the first non-null filename from this list:
- 1. the filename used for the previous call
- 2. the value of the shell variable `INPUTRC'
- 3. ~/.inputrc
- If the file existed and could be opened and read, 0 is returned,
- otherwise errno is returned. */
-int
-rl_read_init_file (filename)
- const char *filename;
-{
- /* Default the filename. */
- if (filename == 0)
- {
- filename = last_readline_init_file;
- if (filename == 0)
- filename = sh_get_env_value ("INPUTRC");
- if (filename == 0)
- filename = DEFAULT_INPUTRC;
- }
-
- if (*filename == 0)
- filename = DEFAULT_INPUTRC;
-
-#if defined (__MSDOS__)
- if (_rl_read_init_file (filename, 0) == 0)
- return 0;
- filename = "~/_inputrc";
-#endif
- return (_rl_read_init_file (filename, 0));
-}
-
-static int
-_rl_read_init_file (filename, include_level)
- const char *filename;
- int include_level;
-{
- register int i;
- char *buffer, *openname, *line, *end;
- size_t file_size;
-
- current_readline_init_file = filename;
- current_readline_init_include_level = include_level;
-
- openname = tilde_expand (filename);
- buffer = _rl_read_file (openname, &file_size);
- free (openname);
-#if defined _WIN32 && defined INITFILES_IN_REGISTRY
- if (buffer == 0)
- {
- openname = get_user_registry_string(READLINE_REGKEY, INPUTRC_REGVAL);
- if (openname)
- {
- buffer = _rl_read_file (openname, &file_size);
- free (openname);
- }
- }
-#endif /* _WIN32 ... */
- if (buffer == 0)
- return (errno);
-
- if (include_level == 0 && filename != last_readline_init_file)
- {
- FREE (last_readline_init_file);
- last_readline_init_file = savestring (filename);
- }
-
- currently_reading_init_file = 1;
-
- /* Loop over the lines in the file. Lines that start with `#' are
- comments; all other lines are commands for readline initialization. */
- current_readline_init_lineno = 1;
- line = buffer;
- end = buffer + file_size;
- while (line < end)
- {
- /* Find the end of this line. */
- for (i = 0; line + i != end && line[i] != '\n'; i++);
-
-#if defined (__CYGWIN__)
- /* ``Be liberal in what you accept.'' */
- if (line[i] == '\n' && line[i-1] == '\r')
- line[i - 1] = '\0';
-#endif
-
- /* Mark end of line. */
- line[i] = '\0';
-
- /* Skip leading whitespace. */
- while (*line && whitespace (*line))
- {
- line++;
- i--;
- }
-
- /* If the line is not a comment, then parse it. */
- if (*line && *line != '#')
- rl_parse_and_bind (line);
-
- /* Move to the next line. */
- line += i + 1;
- current_readline_init_lineno++;
- }
-
- free (buffer);
- currently_reading_init_file = 0;
- return (0);
-}
-
-static void
-_rl_init_file_error (msg)
- const char *msg;
-{
- if (currently_reading_init_file)
- fprintf (stderr, "readline: %s: line %d: %s\n", current_readline_init_file,
- current_readline_init_lineno, msg);
- else
- fprintf (stderr, "readline: %s\n", msg);
-}
-
-/* **************************************************************** */
-/* */
-/* Parser Directives */
-/* */
-/* **************************************************************** */
-
-typedef int _rl_parser_func_t PARAMS((char *));
-
-/* Things that mean `Control'. */
-const char *_rl_possible_control_prefixes[] = {
- "Control-", "C-", "CTRL-", (const char *)NULL
-};
-
-const char *_rl_possible_meta_prefixes[] = {
- "Meta", "M-", (const char *)NULL
-};
-
-/* Conditionals. */
-
-/* Calling programs set this to have their argv[0]. */
-const char *rl_readline_name = "other";
-
-/* Stack of previous values of parsing_conditionalized_out. */
-static unsigned char *if_stack = (unsigned char *)NULL;
-static int if_stack_depth;
-static int if_stack_size;
-
-/* Push _rl_parsing_conditionalized_out, and set parser state based
- on ARGS. */
-static int
-parser_if (char *args)
-{
- register int i;
-
- /* Push parser state. */
- if (if_stack_depth + 1 >= if_stack_size)
- {
- if (!if_stack)
- if_stack = (unsigned char *)xmalloc (if_stack_size = 20);
- else
- if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20);
- }
- if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out;
-
- /* If parsing is turned off, then nothing can turn it back on except
- for finding the matching endif. In that case, return right now. */
- if (_rl_parsing_conditionalized_out)
- return 0;
-
- /* Isolate first argument. */
- for (i = 0; args[i] && !whitespace (args[i]); i++);
-
- if (args[i])
- args[i++] = '\0';
-
- /* Handle "$if term=foo" and "$if mode=emacs" constructs. If this
- isn't term=foo, or mode=emacs, then check to see if the first
- word in ARGS is the same as the value stored in rl_readline_name. */
- if (rl_terminal_name && _rl_strnicmp (args, "term=", 5) == 0)
- {
- char *tem, *tname;
-
- /* Terminals like "aaa-60" are equivalent to "aaa". */
- tname = savestring (rl_terminal_name);
- tem = strchr (tname, '-');
- if (tem)
- *tem = '\0';
-
- /* Test the `long' and `short' forms of the terminal name so that
- if someone has a `sun-cmd' and does not want to have bindings
- that will be executed if the terminal is a `sun', they can put
- `$if term=sun-cmd' into their .inputrc. */
- _rl_parsing_conditionalized_out = _rl_stricmp (args + 5, tname) &&
- _rl_stricmp (args + 5, rl_terminal_name);
- free (tname);
- }
-#if defined (VI_MODE)
- else if (_rl_strnicmp (args, "mode=", 5) == 0)
- {
- int mode;
-
- if (_rl_stricmp (args + 5, "emacs") == 0)
- mode = emacs_mode;
- else if (_rl_stricmp (args + 5, "vi") == 0)
- mode = vi_mode;
- else
- mode = no_mode;
-
- _rl_parsing_conditionalized_out = mode != rl_editing_mode;
- }
-#endif /* VI_MODE */
- /* Check to see if the first word in ARGS is the same as the
- value stored in rl_readline_name. */
- else if (_rl_stricmp (args, rl_readline_name) == 0)
- _rl_parsing_conditionalized_out = 0;
- else
- _rl_parsing_conditionalized_out = 1;
- return 0;
-}
-
-/* Invert the current parser state if there is anything on the stack. */
-static int
-parser_else (char *args)
-{
- register int i;
-
- if (if_stack_depth == 0)
- {
- _rl_init_file_error ("$else found without matching $if");
- return 0;
- }
-
- /* Check the previous (n - 1) levels of the stack to make sure that
- we haven't previously turned off parsing. */
- for (i = 0; i < if_stack_depth - 1; i++)
- if (if_stack[i] == 1)
- return 0;
-
- /* Invert the state of parsing if at top level. */
- _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out;
- return 0;
-}
-
-/* Terminate a conditional, popping the value of
- _rl_parsing_conditionalized_out from the stack. */
-static int
-parser_endif (char *args)
-{
- if (if_stack_depth)
- _rl_parsing_conditionalized_out = if_stack[--if_stack_depth];
- else
- _rl_init_file_error ("$endif without matching $if");
- return 0;
-}
-
-static int
-parser_include (char *args)
-{
- const char *old_init_file;
- char *e;
- int old_line_number, old_include_level, r;
-
- if (_rl_parsing_conditionalized_out)
- return (0);
-
- old_init_file = current_readline_init_file;
- old_line_number = current_readline_init_lineno;
- old_include_level = current_readline_init_include_level;
-
- e = strchr (args, '\n');
- if (e)
- *e = '\0';
- r = _rl_read_init_file ((const char *)args, old_include_level + 1);
-
- current_readline_init_file = old_init_file;
- current_readline_init_lineno = old_line_number;
- current_readline_init_include_level = old_include_level;
-
- return r;
-}
-
-/* Associate textual names with actual functions. */
-static struct {
- const char *name;
- _rl_parser_func_t *function;
-} parser_directives [] = {
- { "if", parser_if },
- { "endif", parser_endif },
- { "else", parser_else },
- { "include", parser_include },
- { (char *)0x0, (_rl_parser_func_t *)0x0 }
-};
-
-/* Handle a parser directive. STATEMENT is the line of the directive
- without any leading `$'. */
-static int
-handle_parser_directive (statement)
- char *statement;
-{
- register int i;
- char *directive, *args;
-
- /* Isolate the actual directive. */
-
- /* Skip whitespace. */
- for (i = 0; whitespace (statement[i]); i++);
-
- directive = &statement[i];
-
- for (; statement[i] && !whitespace (statement[i]); i++);
-
- if (statement[i])
- statement[i++] = '\0';
-
- for (; statement[i] && whitespace (statement[i]); i++);
-
- args = &statement[i];
-
- /* Lookup the command, and act on it. */
- for (i = 0; parser_directives[i].name; i++)
- if (_rl_stricmp (directive, parser_directives[i].name) == 0)
- {
- (*parser_directives[i].function) (args);
- return (0);
- }
-
- /* display an error message about the unknown parser directive */
- _rl_init_file_error ("unknown parser directive");
- return (1);
-}
-
-/* Read the binding command from STRING and perform it.
- A key binding command looks like: Keyname: function-name\0,
- a variable binding command looks like: set variable value.
- A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */
-int
-rl_parse_and_bind (string)
- char *string;
-{
- char *funname, *kname;
- register int c, i;
- int key, equivalency;
-
- while (string && whitespace (*string))
- string++;
-
- if (!string || !*string || *string == '#')
- return 0;
-
- /* If this is a parser directive, act on it. */
- if (*string == '$')
- {
- handle_parser_directive (&string[1]);
- return 0;
- }
-
- /* If we aren't supposed to be parsing right now, then we're done. */
- if (_rl_parsing_conditionalized_out)
- return 0;
-
- i = 0;
- /* If this keyname is a complex key expression surrounded by quotes,
- advance to after the matching close quote. This code allows the
- backslash to quote characters in the key expression. */
- if (*string == '"')
- {
- int passc = 0;
-
- for (i = 1; (c = string[i]); i++)
- {
- if (passc)
- {
- passc = 0;
- continue;
- }
-
- if (c == '\\')
- {
- passc++;
- continue;
- }
-
- if (c == '"')
- break;
- }
- /* If we didn't find a closing quote, abort the line. */
- if (string[i] == '\0')
- {
- _rl_init_file_error ("no closing `\"' in key binding");
- return 1;
- }
- }
-
- /* Advance to the colon (:) or whitespace which separates the two objects. */
- for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );
-
- equivalency = (c == ':' && string[i + 1] == '=');
-
- /* Mark the end of the command (or keyname). */
- if (string[i])
- string[i++] = '\0';
-
- /* If doing assignment, skip the '=' sign as well. */
- if (equivalency)
- string[i++] = '\0';
-
- /* If this is a command to set a variable, then do that. */
- if (_rl_stricmp (string, "set") == 0)
- {
- char *var = string + i;
- char *value;
-
- /* Make VAR point to start of variable name. */
- while (*var && whitespace (*var)) var++;
-
- /* Make VALUE point to start of value string. */
- value = var;
- while (*value && !whitespace (*value)) value++;
- if (*value)
- *value++ = '\0';
- while (*value && whitespace (*value)) value++;
-
- rl_variable_bind (var, value);
- return 0;
- }
-
- /* Skip any whitespace between keyname and funname. */
- for (; string[i] && whitespace (string[i]); i++);
- funname = &string[i];
-
- /* Now isolate funname.
- For straight function names just look for whitespace, since
- that will signify the end of the string. But this could be a
- macro definition. In that case, the string is quoted, so skip
- to the matching delimiter. We allow the backslash to quote the
- delimiter characters in the macro body. */
- /* This code exists to allow whitespace in macro expansions, which
- would otherwise be gobbled up by the next `for' loop.*/
- /* XXX - it may be desirable to allow backslash quoting only if " is
- the quoted string delimiter, like the shell. */
- if (*funname == '\'' || *funname == '"')
- {
- int delimiter = string[i++], passc;
-
- for (passc = 0; (c = string[i]); i++)
- {
- if (passc)
- {
- passc = 0;
- continue;
- }
-
- if (c == '\\')
- {
- passc = 1;
- continue;
- }
-
- if (c == delimiter)
- break;
- }
- if (c)
- i++;
- }
-
- /* Advance to the end of the string. */
- for (; string[i] && !whitespace (string[i]); i++);
-
- /* No extra whitespace at the end of the string. */
- string[i] = '\0';
-
- /* Handle equivalency bindings here. Make the left-hand side be exactly
- whatever the right-hand evaluates to, including keymaps. */
- if (equivalency)
- {
- return 0;
- }
-
- /* If this is a new-style key-binding, then do the binding with
- rl_set_key (). Otherwise, let the older code deal with it. */
- if (*string == '"')
- {
- char *seq;
- register int j, k, passc;
-
- seq = (char *)xmalloc (1 + strlen (string));
- for (j = 1, k = passc = 0; string[j]; j++)
- {
- /* Allow backslash to quote characters, but leave them in place.
- This allows a string to end with a backslash quoting another
- backslash, or with a backslash quoting a double quote. The
- backslashes are left in place for rl_translate_keyseq (). */
- if (passc || (string[j] == '\\'))
- {
- seq[k++] = string[j];
- passc = !passc;
- continue;
- }
-
- if (string[j] == '"')
- break;
-
- seq[k++] = string[j];
- }
- seq[k] = '\0';
-
- /* Binding macro? */
- if (*funname == '\'' || *funname == '"')
- {
- j = strlen (funname);
-
- /* Remove the delimiting quotes from each end of FUNNAME. */
- if (j && funname[j - 1] == *funname)
- funname[j - 1] = '\0';
-
- rl_macro_bind (seq, &funname[1], _rl_keymap);
- }
- else
- rl_set_key (seq, rl_named_function (funname), _rl_keymap);
-
- free (seq);
- return 0;
- }
-
- /* Get the actual character we want to deal with. */
- kname = strrchr (string, '-');
- if (!kname)
- kname = string;
- else
- kname++;
-
- key = glean_key_from_name (kname);
-
- /* Add in control and meta bits. */
- if (substring_member_of_array (string, _rl_possible_control_prefixes))
- key = CTRL (_rl_to_upper (key));
-
- if (substring_member_of_array (string, _rl_possible_meta_prefixes))
- key = META (key);
-
- /* Temporary. Handle old-style keyname with macro-binding. */
- if (*funname == '\'' || *funname == '"')
- {
- char useq[2];
- int fl = strlen (funname);
-
- useq[0] = key; useq[1] = '\0';
- if (fl && funname[fl - 1] == *funname)
- funname[fl - 1] = '\0';
-
- rl_macro_bind (useq, &funname[1], _rl_keymap);
- }
-#if defined (PREFIX_META_HACK)
- /* Ugly, but working hack to keep prefix-meta around. */
- else if (_rl_stricmp (funname, "prefix-meta") == 0)
- {
- char seq[2];
-
- seq[0] = key;
- seq[1] = '\0';
- rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, _rl_keymap);
- }
-#endif /* PREFIX_META_HACK */
- else
- rl_bind_key (key, rl_named_function (funname));
- return 0;
-}
-
-/* Simple structure for boolean readline variables (i.e., those that can
- have one of two values; either "On" or 1 for truth, or "Off" or 0 for
- false. */
-
-#define V_SPECIAL 0x1
-
-static struct {
- const char *name;
- int *value;
- int flags;
-} boolean_varlist [] = {
- { "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL },
- { "byte-oriented", &rl_byte_oriented, 0 },
- { "completion-ignore-case", &_rl_completion_case_fold, 0 },
- { "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
- { "disable-completion", &rl_inhibit_completion, 0 },
- { "enable-keypad", &_rl_enable_keypad, 0 },
- { "expand-tilde", &rl_complete_with_tilde_expansion, 0 },
- { "history-preserve-point", &_rl_history_preserve_point, 0 },
- { "horizontal-scroll-mode", &_rl_horizontal_scroll_mode, 0 },
- { "input-meta", &_rl_meta_flag, 0 },
- { "mark-directories", &_rl_complete_mark_directories, 0 },
- { "mark-modified-lines", &_rl_mark_modified_lines, 0 },
- { "mark-symlinked-directories", &_rl_complete_mark_symlink_dirs, 0 },
- { "match-hidden-files", &_rl_match_hidden_files, 0 },
- { "meta-flag", &_rl_meta_flag, 0 },
- { "output-meta", &_rl_output_meta_chars, 0 },
- { "page-completions", &_rl_page_completions, 0 },
- { "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL },
- { "print-completions-horizontally", &_rl_print_completions_horizontally, 0 },
- { "show-all-if-ambiguous", &_rl_complete_show_all, 0 },
-#if defined (VISIBLE_STATS)
- { "visible-stats", &rl_visible_stats, 0 },
-#endif /* VISIBLE_STATS */
- { (char *)NULL, (int *)NULL }
-};
-
-static int
-find_boolean_var (name)
- const char *name;
-{
- register int i;
-
- for (i = 0; boolean_varlist[i].name; i++)
- if (_rl_stricmp (name, boolean_varlist[i].name) == 0)
- return i;
- return -1;
-}
-
-/* Hooks for handling special boolean variables, where a
- function needs to be called or another variable needs
- to be changed when they're changed. */
-static void
-hack_special_boolean_var (i)
- int i;
-{
- const char *name;
-
- name = boolean_varlist[i].name;
-
- if (_rl_stricmp (name, "blink-matching-paren") == 0)
- _rl_enable_paren_matching (rl_blink_matching_paren);
- else if (_rl_stricmp (name, "prefer-visible-bell") == 0)
- {
- if (_rl_prefer_visible_bell)
- _rl_bell_preference = VISIBLE_BELL;
- else
- _rl_bell_preference = AUDIBLE_BELL;
- }
-}
-
-typedef int _rl_sv_func_t PARAMS((const char *));
-
-/* These *must* correspond to the array indices for the appropriate
- string variable. (Though they're not used right now.) */
-#define V_BELLSTYLE 0
-#define V_COMBEGIN 1
-#define V_EDITMODE 2
-#define V_ISRCHTERM 3
-#define V_KEYMAP 4
-
-#define V_STRING 1
-#define V_INT 2
-
-/* Forward declarations */
-static int sv_bell_style PARAMS((const char *));
-static int sv_combegin PARAMS((const char *));
-static int sv_compquery PARAMS((const char *));
-static int sv_editmode PARAMS((const char *));
-static int sv_isrchterm PARAMS((const char *));
-static int sv_keymap PARAMS((const char *));
-
-static struct {
- const char *name;
- int flags;
- _rl_sv_func_t *set_func;
-} string_varlist[] = {
- { "bell-style", V_STRING, sv_bell_style },
- { "comment-begin", V_STRING, sv_combegin },
- { "completion-query-items", V_INT, sv_compquery },
- { "editing-mode", V_STRING, sv_editmode },
- { "isearch-terminators", V_STRING, sv_isrchterm },
- { "keymap", V_STRING, sv_keymap },
- { (char *)NULL, 0 }
-};
-
-static int
-find_string_var (name)
- const char *name;
-{
- register int i;
-
- for (i = 0; string_varlist[i].name; i++)
- if (_rl_stricmp (name, string_varlist[i].name) == 0)
- return i;
- return -1;
-}
-
-/* A boolean value that can appear in a `set variable' command is true if
- the value is null or empty, `on' (case-insenstive), or "1". Any other
- values result in 0 (false). */
-static int
-bool_to_int (value)
- const char *value;
-{
- return (value == 0 || *value == '\0' ||
- (_rl_stricmp (value, "on") == 0) ||
- (value[0] == '1' && value[1] == '\0'));
-}
-
-int
-rl_variable_bind (name, value)
- const char *name, *value;
-{
- register int i;
- int v;
-
- /* Check for simple variables first. */
- i = find_boolean_var (name);
- if (i >= 0)
- {
- *boolean_varlist[i].value = bool_to_int (value);
- if (boolean_varlist[i].flags & V_SPECIAL)
- hack_special_boolean_var (i);
- return 0;
- }
-
- i = find_string_var (name);
-
- /* For the time being, unknown variable names or string names without a
- handler function are simply ignored. */
- if (i < 0 || string_varlist[i].set_func == 0)
- return 0;
-
- v = (*string_varlist[i].set_func) (value);
- return v;
-}
-
-static int
-sv_editmode (value)
- const char *value;
-{
- if (_rl_strnicmp (value, "vi", 2) == 0)
- {
-#if defined (VI_MODE)
- _rl_keymap = vi_insertion_keymap;
- rl_editing_mode = vi_mode;
-#endif /* VI_MODE */
- return 0;
- }
- else if (_rl_strnicmp (value, "emacs", 5) == 0)
- {
- _rl_keymap = emacs_standard_keymap;
- rl_editing_mode = emacs_mode;
- return 0;
- }
- return 1;
-}
-
-static int
-sv_combegin (value)
- const char *value;
-{
- if (value && *value)
- {
- FREE (_rl_comment_begin);
- _rl_comment_begin = savestring (value);
- return 0;
- }
- return 1;
-}
-
-static int
-sv_compquery (value)
- const char *value;
-{
- int nval = 100;
-
- if (value && *value)
- {
- nval = atoi (value);
- if (nval < 0)
- nval = 0;
- }
- rl_completion_query_items = nval;
- return 0;
-}
-
-static int
-sv_keymap (value)
- const char *value;
-{
- Keymap kmap;
-
- kmap = rl_get_keymap_by_name (value);
- if (kmap)
- {
- rl_set_keymap (kmap);
- return 0;
- }
- return 1;
-}
-
-static int
-sv_bell_style (value)
- const char *value;
-{
- if (value == 0 || *value == '\0')
- _rl_bell_preference = AUDIBLE_BELL;
- else if (_rl_stricmp (value, "none") == 0 || _rl_stricmp (value, "off") == 0)
- _rl_bell_preference = NO_BELL;
- else if (_rl_stricmp (value, "audible") == 0 || _rl_stricmp (value, "on") == 0)
- _rl_bell_preference = AUDIBLE_BELL;
- else if (_rl_stricmp (value, "visible") == 0)
- _rl_bell_preference = VISIBLE_BELL;
- else
- return 1;
- return 0;
-}
-
-static int
-sv_isrchterm (value)
- const char *value;
-{
- int beg, end, delim;
- char *v;
-
- if (value == 0)
- return 1;
-
- /* Isolate the value and translate it into a character string. */
- v = savestring (value);
- FREE (_rl_isearch_terminators);
- if (v[0] == '"' || v[0] == '\'')
- {
- delim = v[0];
- for (beg = end = 1; v[end] && v[end] != delim; end++)
- ;
- }
- else
- {
- for (beg = end = 0; whitespace (v[end]) == 0; end++)
- ;
- }
-
- v[end] = '\0';
-
- /* The value starts at v + beg. Translate it into a character string. */
- _rl_isearch_terminators = (char *)xmalloc (2 * strlen (v) + 1);
- rl_translate_keyseq (v + beg, _rl_isearch_terminators, &end);
- _rl_isearch_terminators[end] = '\0';
-
- free (v);
- return 0;
-}
-
-/* Return the character which matches NAME.
- For example, `Space' returns ' '. */
-
-typedef struct {
- const char *name;
- int value;
-} assoc_list;
-
-static assoc_list name_key_alist[] = {
- { "DEL", 0x7f },
- { "ESC", '\033' },
- { "Escape", '\033' },
- { "LFD", '\n' },
- { "Newline", '\n' },
- { "RET", '\r' },
- { "Return", '\r' },
- { "Rubout", 0x7f },
- { "SPC", ' ' },
- { "Space", ' ' },
- { "Tab", 0x09 },
- { (char *)0x0, 0 }
-};
-
-static int
-glean_key_from_name (name)
- char *name;
-{
- register int i;
-
- for (i = 0; name_key_alist[i].name; i++)
- if (_rl_stricmp (name, name_key_alist[i].name) == 0)
- return (name_key_alist[i].value);
-
- return (*(unsigned char *)name); /* XXX was return (*name) */
-}
-
-/* Auxiliary functions to manage keymaps. */
-static struct {
- const char *name;
- Keymap map;
-} keymap_names[] = {
- { "emacs", emacs_standard_keymap },
- { "emacs-standard", emacs_standard_keymap },
- { "emacs-meta", emacs_meta_keymap },
- { "emacs-ctlx", emacs_ctlx_keymap },
-#if defined (VI_MODE)
- { "vi", vi_movement_keymap },
- { "vi-move", vi_movement_keymap },
- { "vi-command", vi_movement_keymap },
- { "vi-insert", vi_insertion_keymap },
-#endif /* VI_MODE */
- { (char *)0x0, (Keymap)0x0 }
-};
-
-Keymap
-rl_get_keymap_by_name (name)
- const char *name;
-{
- register int i;
-
- for (i = 0; keymap_names[i].name; i++)
- if (_rl_stricmp (name, keymap_names[i].name) == 0)
- return (keymap_names[i].map);
- return ((Keymap) NULL);
-}
-
-char *
-rl_get_keymap_name (map)
- Keymap map;
-{
- register int i;
- for (i = 0; keymap_names[i].name; i++)
- if (map == keymap_names[i].map)
- return ((char *)keymap_names[i].name);
- return ((char *)NULL);
-}
-
-void
-rl_set_keymap (map)
- Keymap map;
-{
- if (map)
- _rl_keymap = map;
-}
-
-Keymap
-rl_get_keymap ()
-{
- return (_rl_keymap);
-}
-
-void
-rl_set_keymap_from_edit_mode ()
-{
- if (rl_editing_mode == emacs_mode)
- _rl_keymap = emacs_standard_keymap;
-#if defined (VI_MODE)
- else if (rl_editing_mode == vi_mode)
- _rl_keymap = vi_insertion_keymap;
-#endif /* VI_MODE */
-}
-
-char *
-rl_get_keymap_name_from_edit_mode ()
-{
- if (rl_editing_mode == emacs_mode)
- return "emacs";
-#if defined (VI_MODE)
- else if (rl_editing_mode == vi_mode)
- return "vi";
-#endif /* VI_MODE */
- else
- return "none";
-}
-
-/* **************************************************************** */
-/* */
-/* Key Binding and Function Information */
-/* */
-/* **************************************************************** */
-
-/* Each of the following functions produces information about the
- state of keybindings and functions known to Readline. The info
- is always printed to rl_outstream, and in such a way that it can
- be read back in (i.e., passed to rl_parse_and_bind (). */
-
-/* Print the names of functions known to Readline. */
-void
-rl_list_funmap_names ()
-{
- register int i;
- const char **funmap_names;
-
- funmap_names = rl_funmap_names ();
-
- if (!funmap_names)
- return;
-
- for (i = 0; funmap_names[i]; i++)
- fprintf (rl_outstream, "%s\n", funmap_names[i]);
-
- free ((void *)funmap_names);
-}
-
-static char *
-_rl_get_keyname (key)
- int key;
-{
- char *keyname;
- int i, c;
-
- keyname = (char *)xmalloc (8);
-
- c = key;
- /* Since this is going to be used to write out keysequence-function
- pairs for possible inclusion in an inputrc file, we don't want to
- do any special meta processing on KEY. */
-
-#if 1
- /* XXX - Experimental */
- /* We might want to do this, but the old version of the code did not. */
-
- /* If this is an escape character, we don't want to do any more processing.
- Just add the special ESC key sequence and return. */
- if (c == ESC)
- {
- keyname[0] = '\\';
- keyname[1] = 'e';
- keyname[2] = '\0';
- return keyname;
- }
-#endif
-
- /* RUBOUT is translated directly into \C-? */
- if (key == RUBOUT)
- {
- keyname[0] = '\\';
- keyname[1] = 'C';
- keyname[2] = '-';
- keyname[3] = '?';
- keyname[4] = '\0';
- return keyname;
- }
-
- i = 0;
- /* Now add special prefixes needed for control characters. This can
- potentially change C. */
- if (CTRL_CHAR (c))
- {
- keyname[i++] = '\\';
- keyname[i++] = 'C';
- keyname[i++] = '-';
- c = _rl_to_lower (UNCTRL (c));
- }
-
- /* XXX experimental code. Turn the characters that are not ASCII or
- ISO Latin 1 (128 - 159) into octal escape sequences (\200 - \237).
- This changes C. */
- if (c >= 128 && c <= 159)
- {
- keyname[i++] = '\\';
- keyname[i++] = '2';
- c -= 128;
- keyname[i++] = (c / 8) + '0';
- c = (c % 8) + '0';
- }
-
- /* Now, if the character needs to be quoted with a backslash, do that. */
- if (c == '\\' || c == '"')
- keyname[i++] = '\\';
-
- /* Now add the key, terminate the string, and return it. */
- keyname[i++] = (char) c;
- keyname[i] = '\0';
-
- return keyname;
-}
-
-/* Return a NULL terminated array of strings which represent the key
- sequences that are used to invoke FUNCTION in MAP. */
-char **
-rl_invoking_keyseqs_in_map (function, map)
- rl_command_func_t *function;
- Keymap map;
-{
- register int key;
- char **result;
- int result_index, result_size;
-
- result = (char **)NULL;
- result_index = result_size = 0;
-
- for (key = 0; key < KEYMAP_SIZE; key++)
- {
- switch (map[key].type)
- {
- case ISMACR:
- /* Macros match, if, and only if, the pointers are identical.
- Thus, they are treated exactly like functions in here. */
- case ISFUNC:
- /* If the function in the keymap is the one we are looking for,
- then add the current KEY to the list of invoking keys. */
- if (map[key].function == function)
- {
- char *keyname;
-
- keyname = _rl_get_keyname (key);
-
- if (result_index + 2 > result_size)
- {
- result_size += 10;
- result = (char **)xrealloc (result, result_size * sizeof (char *));
- }
-
- result[result_index++] = keyname;
- result[result_index] = (char *)NULL;
- }
- break;
-
- case ISKMAP:
- {
- char **seqs;
- register int i;
-
- /* Find the list of keyseqs in this map which have FUNCTION as
- their target. Add the key sequences found to RESULT. */
- if (map[key].function)
- seqs =
- rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key));
- else
- break;
-
- if (seqs == 0)
- break;
-
- for (i = 0; seqs[i]; i++)
- {
- char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
-
- if (key == ESC)
-#if 0
- sprintf (keyname, "\\e");
-#else
- /* XXX - experimental */
- sprintf (keyname, "\\M-");
-#endif
- else if (CTRL_CHAR (key))
- sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key)));
- else if (key == RUBOUT)
- sprintf (keyname, "\\C-?");
- else if (key == '\\' || key == '"')
- {
- keyname[0] = '\\';
- keyname[1] = (char) key;
- keyname[2] = '\0';
- }
- else
- {
- keyname[0] = (char) key;
- keyname[1] = '\0';
- }
-
- strcat (keyname, seqs[i]);
- free (seqs[i]);
-
- if (result_index + 2 > result_size)
- {
- result_size += 10;
- result = (char **)xrealloc (result, result_size * sizeof (char *));
- }
-
- result[result_index++] = keyname;
- result[result_index] = (char *)NULL;
- }
-
- free (seqs);
- }
- break;
- }
- }
- return (result);
-}
-
-/* Return a NULL terminated array of strings which represent the key
- sequences that can be used to invoke FUNCTION using the current keymap. */
-char **
-rl_invoking_keyseqs (function)
- rl_command_func_t *function;
-{
- return (rl_invoking_keyseqs_in_map (function, _rl_keymap));
-}
-
-/* Print all of the functions and their bindings to rl_outstream. If
- PRINT_READABLY is non-zero, then print the output in such a way
- that it can be read back in. */
-void
-rl_function_dumper (print_readably)
- int print_readably;
-{
- register int i;
- const char **names;
- const char *name;
-
- names = rl_funmap_names ();
-
- fprintf (rl_outstream, "\n");
-
- for (i = 0; (name = names[i]); i++)
- {
- rl_command_func_t *function;
- char **invokers;
-
- function = rl_named_function (name);
- invokers = rl_invoking_keyseqs_in_map (function, _rl_keymap);
-
- if (print_readably)
- {
- if (!invokers)
- fprintf (rl_outstream, "# %s (not bound)\n", name);
- else
- {
- register int j;
-
- for (j = 0; invokers[j]; j++)
- {
- fprintf (rl_outstream, "\"%s\": %s\n",
- invokers[j], name);
- free (invokers[j]);
- }
-
- free (invokers);
- }
- }
- else
- {
- if (!invokers)
- fprintf (rl_outstream, "%s is not bound to any keys\n",
- name);
- else
- {
- register int j;
-
- fprintf (rl_outstream, "%s can be found on ", name);
-
- for (j = 0; invokers[j] && j < 5; j++)
- {
- fprintf (rl_outstream, "\"%s\"%s", invokers[j],
- invokers[j + 1] ? ", " : ".\n");
- }
-
- if (j == 5 && invokers[j])
- fprintf (rl_outstream, "...\n");
-
- for (j = 0; invokers[j]; j++)
- free (invokers[j]);
-
- free (invokers);
- }
- }
- }
-}
-
-/* Print all of the current functions and their bindings to
- rl_outstream. If an explicit argument is given, then print
- the output in such a way that it can be read back in. */
-int
-rl_dump_functions (count, key)
- int count, key;
-{
- if (rl_dispatching)
- fprintf (rl_outstream, "\r\n");
- rl_function_dumper (rl_explicit_arg);
- rl_on_new_line ();
- return (0);
-}
-
-static void
-_rl_macro_dumper_internal (print_readably, map, prefix)
- int print_readably;
- Keymap map;
- char *prefix;
-{
- register int key;
- char *keyname, *out;
- int prefix_len;
-
- for (key = 0; key < KEYMAP_SIZE; key++)
- {
- switch (map[key].type)
- {
- case ISMACR:
- keyname = _rl_get_keyname (key);
- out = _rl_untranslate_macro_value ((char *)map[key].function);
-
- if (print_readably)
- fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "",
- keyname,
- out ? out : "");
- else
- fprintf (rl_outstream, "%s%s outputs %s\n", prefix ? prefix : "",
- keyname,
- out ? out : "");
- free (keyname);
- free (out);
- break;
- case ISFUNC:
- break;
- case ISKMAP:
- prefix_len = prefix ? strlen (prefix) : 0;
- if (key == ESC)
- {
- keyname = (char *)xmalloc (3 + prefix_len);
- if (prefix)
- strcpy (keyname, prefix);
- keyname[prefix_len] = '\\';
- keyname[prefix_len + 1] = 'e';
- keyname[prefix_len + 2] = '\0';
- }
- else
- {
- keyname = _rl_get_keyname (key);
- if (prefix)
- {
- out = (char *)xmalloc (strlen (keyname) + prefix_len + 1);
- strcpy (out, prefix);
- strcpy (out + prefix_len, keyname);
- free (keyname);
- keyname = out;
- }
- }
-
- _rl_macro_dumper_internal (print_readably, FUNCTION_TO_KEYMAP (map, key), keyname);
- free (keyname);
- break;
- }
- }
-}
-
-void
-rl_macro_dumper (print_readably)
- int print_readably;
-{
- _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL);
-}
-
-int
-rl_dump_macros (count, key)
- int count, key;
-{
- if (rl_dispatching)
- fprintf (rl_outstream, "\r\n");
- rl_macro_dumper (rl_explicit_arg);
- rl_on_new_line ();
- return (0);
-}
-
-void
-rl_variable_dumper (print_readably)
- int print_readably;
-{
- int i;
- const char *kname;
-
- for (i = 0; boolean_varlist[i].name; i++)
- {
- if (print_readably)
- fprintf (rl_outstream, "set %s %s\n", boolean_varlist[i].name,
- *boolean_varlist[i].value ? "on" : "off");
- else
- fprintf (rl_outstream, "%s is set to `%s'\n", boolean_varlist[i].name,
- *boolean_varlist[i].value ? "on" : "off");
- }
-
- /* bell-style */
- switch (_rl_bell_preference)
- {
- case NO_BELL:
- kname = "none"; break;
- case VISIBLE_BELL:
- kname = "visible"; break;
- case AUDIBLE_BELL:
- default:
- kname = "audible"; break;
- }
- if (print_readably)
- fprintf (rl_outstream, "set bell-style %s\n", kname);
- else
- fprintf (rl_outstream, "bell-style is set to `%s'\n", kname);
-
- /* comment-begin */
- if (print_readably)
- fprintf (rl_outstream, "set comment-begin %s\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
- else
- fprintf (rl_outstream, "comment-begin is set to `%s'\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
-
- /* completion-query-items */
- if (print_readably)
- fprintf (rl_outstream, "set completion-query-items %d\n", rl_completion_query_items);
- else
- fprintf (rl_outstream, "completion-query-items is set to `%d'\n", rl_completion_query_items);
-
- /* editing-mode */
- if (print_readably)
- fprintf (rl_outstream, "set editing-mode %s\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi");
- else
- fprintf (rl_outstream, "editing-mode is set to `%s'\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi");
-
- /* isearch-terminators */
- if (_rl_isearch_terminators)
- {
- char *disp;
-
- disp = _rl_untranslate_macro_value (_rl_isearch_terminators);
-
- if (print_readably)
- fprintf (rl_outstream, "set isearch-terminators \"%s\"\n", disp);
- else
- fprintf (rl_outstream, "isearch-terminators is set to \"%s\"\n", disp);
-
- free (disp);
- }
-
- /* keymap */
- kname = rl_get_keymap_name (_rl_keymap);
- if (kname == 0)
- kname = rl_get_keymap_name_from_edit_mode ();
- if (print_readably)
- fprintf (rl_outstream, "set keymap %s\n", kname ? kname : "none");
- else
- fprintf (rl_outstream, "keymap is set to `%s'\n", kname ? kname : "none");
-}
-
-/* Print all of the current variables and their values to
- rl_outstream. If an explicit argument is given, then print
- the output in such a way that it can be read back in. */
-int
-rl_dump_variables (count, key)
- int count, key;
-{
- if (rl_dispatching)
- fprintf (rl_outstream, "\r\n");
- rl_variable_dumper (rl_explicit_arg);
- rl_on_new_line ();
- return (0);
-}
-
-/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
- now, this is always used to attempt to bind the arrow keys, hence the
- check for rl_vi_movement_mode. */
-void
-_rl_bind_if_unbound (keyseq, default_func)
- const char *keyseq;
- rl_command_func_t *default_func;
-{
- rl_command_func_t *func;
-
- if (keyseq)
- {
- func = rl_function_of_keyseq (keyseq, _rl_keymap, (int *)NULL);
-#if defined (VI_MODE)
- if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
-#else
- if (!func || func == rl_do_lowercase_version)
-#endif
- rl_set_key (keyseq, default_func, _rl_keymap);
- }
-}
-
-/* Return non-zero if any members of ARRAY are a substring in STRING. */
-static int
-substring_member_of_array (string, array)
- char *string;
- const char **array;
-{
- while (*array)
- {
- if (_rl_strindex (string, *array))
- return (1);
- array++;
- }
- return (0);
-}
-
+/* bind.c -- key binding and startup file support for the readline library. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#if defined (HAVE_SYS_FILE_H)
+# include <sys/file.h>
+#endif /* HAVE_SYS_FILE_H */
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <errno.h>
+
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+#include "posixstat.h"
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "rlshell.h"
+#include "xmalloc.h"
+
+#if !defined (strchr) && !defined (__STDC__) && !defined _MSC_VER
+extern char *strchr (), *strrchr ();
+#endif /* !strchr && !__STDC__ */
+
+/* Variables exported by this file. */
+Keymap rl_binding_keymap;
+
+static char *_rl_read_file PARAMS((char *, size_t *));
+static void _rl_init_file_error PARAMS((const char *));
+static int _rl_read_init_file PARAMS((const char *, int));
+static int glean_key_from_name PARAMS((char *));
+static int substring_member_of_array PARAMS((char *, const char **));
+
+static int currently_reading_init_file;
+
+/* used only in this file */
+static int _rl_prefer_visible_bell = 1;
+
+/* **************************************************************** */
+/* */
+/* Binding keys */
+/* */
+/* **************************************************************** */
+
+/* rl_add_defun (char *name, rl_command_func_t *function, int key)
+ Add NAME to the list of named functions. Make FUNCTION be the function
+ that gets called. If KEY is not -1, then bind it. */
+int
+rl_add_defun (name, function, key)
+ const char *name;
+ rl_command_func_t *function;
+ int key;
+{
+ if (key != -1)
+ rl_bind_key (key, function);
+ rl_add_funmap_entry (name, function);
+ return 0;
+}
+
+/* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */
+int
+rl_bind_key (key, function)
+ int key;
+ rl_command_func_t *function;
+{
+ if (key < 0)
+ return (key);
+
+ if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
+ {
+ if (_rl_keymap[ESC].type == ISKMAP)
+ {
+ Keymap escmap;
+
+ escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC);
+ key = UNMETA (key);
+ escmap[key].type = ISFUNC;
+ escmap[key].function = function;
+ return (0);
+ }
+ return (key);
+ }
+
+ _rl_keymap[key].type = ISFUNC;
+ _rl_keymap[key].function = function;
+ rl_binding_keymap = _rl_keymap;
+ return (0);
+}
+
+/* Bind KEY to FUNCTION in MAP. Returns non-zero in case of invalid
+ KEY. */
+int
+rl_bind_key_in_map (key, function, map)
+ int key;
+ rl_command_func_t *function;
+ Keymap map;
+{
+ int result;
+ Keymap oldmap;
+
+ oldmap = _rl_keymap;
+ _rl_keymap = map;
+ result = rl_bind_key (key, function);
+ _rl_keymap = oldmap;
+ return (result);
+}
+
+/* Make KEY do nothing in the currently selected keymap.
+ Returns non-zero in case of error. */
+int
+rl_unbind_key (key)
+ int key;
+{
+ return (rl_bind_key (key, (rl_command_func_t *)NULL));
+}
+
+/* Make KEY do nothing in MAP.
+ Returns non-zero in case of error. */
+int
+rl_unbind_key_in_map (key, map)
+ int key;
+ Keymap map;
+{
+ return (rl_bind_key_in_map (key, (rl_command_func_t *)NULL, map));
+}
+
+/* Unbind all keys bound to FUNCTION in MAP. */
+int
+rl_unbind_function_in_map (func, map)
+ rl_command_func_t *func;
+ Keymap map;
+{
+ register int i, rval;
+
+ for (i = rval = 0; i < KEYMAP_SIZE; i++)
+ {
+ if (map[i].type == ISFUNC && map[i].function == func)
+ {
+ map[i].function = (rl_command_func_t *)NULL;
+ rval = 1;
+ }
+ }
+ return rval;
+}
+
+int
+rl_unbind_command_in_map (command, map)
+ const char *command;
+ Keymap map;
+{
+ rl_command_func_t *func;
+
+ func = rl_named_function (command);
+ if (func == 0)
+ return 0;
+ return (rl_unbind_function_in_map (func, map));
+}
+
+/* Bind the key sequence represented by the string KEYSEQ to
+ FUNCTION. This makes new keymaps as necessary. The initial
+ place to do bindings is in MAP. */
+int
+rl_set_key (keyseq, function, map)
+ const char *keyseq;
+ rl_command_func_t *function;
+ Keymap map;
+{
+ return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
+}
+
+/* Bind the key sequence represented by the string KEYSEQ to
+ the string of characters MACRO. This makes new keymaps as
+ necessary. The initial place to do bindings is in MAP. */
+int
+rl_macro_bind (keyseq, macro, map)
+ const char *keyseq, *macro;
+ Keymap map;
+{
+ char *macro_keys;
+ int macro_keys_len;
+
+ macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1);
+
+ if (rl_translate_keyseq (macro, macro_keys, &macro_keys_len))
+ {
+ free (macro_keys);
+ return -1;
+ }
+ rl_generic_bind (ISMACR, keyseq, macro_keys, map);
+ return 0;
+}
+
+/* Bind the key sequence represented by the string KEYSEQ to
+ the arbitrary pointer DATA. TYPE says what kind of data is
+ pointed to by DATA, right now this can be a function (ISFUNC),
+ a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps
+ as necessary. The initial place to do bindings is in MAP. */
+int
+rl_generic_bind (type, keyseq, data, map)
+ int type;
+ const char *keyseq;
+ char *data;
+ Keymap map;
+{
+ char *keys;
+ int keys_len;
+ register int i;
+ KEYMAP_ENTRY k;
+
+ k.function = 0;
+
+ /* If no keys to bind to, exit right away. */
+ if (!keyseq || !*keyseq)
+ {
+ if (type == ISMACR)
+ free (data);
+ return -1;
+ }
+
+ keys = (char *)xmalloc (1 + (2 * strlen (keyseq)));
+
+ /* Translate the ASCII representation of KEYSEQ into an array of
+ characters. Stuff the characters into KEYS, and the length of
+ KEYS into KEYS_LEN. */
+ if (rl_translate_keyseq (keyseq, keys, &keys_len))
+ {
+ free (keys);
+ return -1;
+ }
+
+ /* Bind keys, making new keymaps as necessary. */
+ for (i = 0; i < keys_len; i++)
+ {
+ unsigned char uc = keys[i];
+ int ic;
+
+ ic = uc;
+ if (ic < 0 || ic >= KEYMAP_SIZE)
+ return -1;
+
+ if (_rl_convert_meta_chars_to_ascii && META_CHAR (ic))
+ {
+ ic = UNMETA (ic);
+ if (map[ESC].type == ISKMAP)
+ map = FUNCTION_TO_KEYMAP (map, ESC);
+ }
+
+ if ((i + 1) < keys_len)
+ {
+ if (map[ic].type != ISKMAP)
+ {
+ /* We allow subsequences of keys. If a keymap is being
+ created that will `shadow' an existing function or macro
+ key binding, we save that keybinding into the ANYOTHERKEY
+ index in the new map. The dispatch code will look there
+ to find the function to execute if the subsequence is not
+ matched. ANYOTHERKEY was chosen to be greater than
+ UCHAR_MAX. */
+ k = map[ic];
+
+ map[ic].type = ISKMAP;
+ map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());
+ }
+ map = FUNCTION_TO_KEYMAP (map, ic);
+ /* The dispatch code will return this function if no matching
+ key sequence is found in the keymap. This (with a little
+ help from the dispatch code in readline.c) allows `a' to be
+ mapped to something, `abc' to be mapped to something else,
+ and the function bound to `a' to be executed when the user
+ types `abx', leaving `bx' in the input queue. */
+ if (k.function /* && k.type == ISFUNC */)
+ {
+ map[ANYOTHERKEY] = k;
+ k.function = 0;
+ }
+ }
+ else
+ {
+ if (map[ic].type == ISMACR)
+ free ((char *)map[ic].function);
+ else if (map[ic].type == ISKMAP)
+ {
+ map = FUNCTION_TO_KEYMAP (map, ic);
+ ic = ANYOTHERKEY;
+ }
+
+ map[ic].function = KEYMAP_TO_FUNCTION (data);
+ map[ic].type = type;
+ }
+
+ rl_binding_keymap = map;
+ }
+ free (keys);
+ return 0;
+}
+
+/* Translate the ASCII representation of SEQ, stuffing the values into ARRAY,
+ an array of characters. LEN gets the final length of ARRAY. Return
+ non-zero if there was an error parsing SEQ. */
+int
+rl_translate_keyseq (seq, array, len)
+ const char *seq;
+ char *array;
+ int *len;
+{
+ register int i, c, l, temp;
+
+ for (i = l = 0; (c = seq[i]); i++)
+ {
+ if (c == '\\')
+ {
+ c = seq[++i];
+
+ if (c == 0)
+ break;
+
+ /* Handle \C- and \M- prefixes. */
+ if ((c == 'C' || c == 'M') && seq[i + 1] == '-')
+ {
+ /* Handle special case of backwards define. */
+ if (strncmp (&seq[i], "C-\\M-", 5) == 0)
+ {
+ array[l++] = ESC; /* ESC is meta-prefix */
+ i += 5;
+ array[l++] = CTRL (_rl_to_upper (seq[i]));
+ if (seq[i] == '\0')
+ i--;
+ }
+ else if (c == 'M')
+ {
+ i++;
+ array[l++] = ESC; /* ESC is meta-prefix */
+ }
+ else if (c == 'C')
+ {
+ i += 2;
+ /* Special hack for C-?... */
+ array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
+ }
+ continue;
+ }
+
+ /* Translate other backslash-escaped characters. These are the
+ same escape sequences that bash's `echo' and `printf' builtins
+ handle, with the addition of \d -> RUBOUT. A backslash
+ preceding a character that is not special is stripped. */
+ switch (c)
+ {
+ case 'a':
+ array[l++] = '\007';
+ break;
+ case 'b':
+ array[l++] = '\b';
+ break;
+ case 'd':
+ array[l++] = RUBOUT; /* readline-specific */
+ break;
+ case 'e':
+ array[l++] = ESC;
+ break;
+ case 'f':
+ array[l++] = '\f';
+ break;
+ case 'n':
+ array[l++] = NEWLINE;
+ break;
+ case 'r':
+ array[l++] = RETURN;
+ break;
+ case 't':
+ array[l++] = TAB;
+ break;
+ case 'v':
+ array[l++] = 0x0B;
+ break;
+ case '\\':
+ array[l++] = '\\';
+ break;
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ i++;
+ for (temp = 2, c -= '0'; ISOCTAL (seq[i]) && temp--; i++)
+ c = (c * 8) + OCTVALUE (seq[i]);
+ i--; /* auto-increment in for loop */
+ array[l++] = c & largest_char;
+ break;
+ case 'x':
+ i++;
+ for (temp = 2, c = 0; ISXDIGIT ((unsigned char)seq[i]) && temp--; i++)
+ c = (c * 16) + HEXVALUE (seq[i]);
+ if (temp == 2)
+ c = 'x';
+ i--; /* auto-increment in for loop */
+ array[l++] = c & largest_char;
+ break;
+ default: /* backslashes before non-special chars just add the char */
+ array[l++] = c;
+ break; /* the backslash is stripped */
+ }
+ continue;
+ }
+
+ array[l++] = c;
+ }
+
+ *len = l;
+ array[l] = '\0';
+ return (0);
+}
+
+char *
+rl_untranslate_keyseq (seq)
+ int seq;
+{
+ static char kseq[16];
+ int i, c;
+
+ i = 0;
+ c = seq;
+ if (META_CHAR (c))
+ {
+ kseq[i++] = '\\';
+ kseq[i++] = 'M';
+ kseq[i++] = '-';
+ c = UNMETA (c);
+ }
+ else if (CTRL_CHAR (c))
+ {
+ kseq[i++] = '\\';
+ kseq[i++] = 'C';
+ kseq[i++] = '-';
+ c = _rl_to_lower (UNCTRL (c));
+ }
+ else if (c == RUBOUT)
+ {
+ kseq[i++] = '\\';
+ kseq[i++] = 'C';
+ kseq[i++] = '-';
+ c = '?';
+ }
+
+ if (c == ESC)
+ {
+ kseq[i++] = '\\';
+ c = 'e';
+ }
+ else if (c == '\\' || c == '"')
+ {
+ kseq[i++] = '\\';
+ }
+
+ kseq[i++] = (unsigned char) c;
+ kseq[i] = '\0';
+ return kseq;
+}
+
+static char *
+_rl_untranslate_macro_value (seq)
+ char *seq;
+{
+ char *ret, *r, *s;
+ int c;
+
+ r = ret = (char *)xmalloc (7 * strlen (seq) + 1);
+ for (s = seq; *s; s++)
+ {
+ c = *s;
+ if (META_CHAR (c))
+ {
+ *r++ = '\\';
+ *r++ = 'M';
+ *r++ = '-';
+ c = UNMETA (c);
+ }
+ else if (CTRL_CHAR (c) && c != ESC)
+ {
+ *r++ = '\\';
+ *r++ = 'C';
+ *r++ = '-';
+ c = _rl_to_lower (UNCTRL (c));
+ }
+ else if (c == RUBOUT)
+ {
+ *r++ = '\\';
+ *r++ = 'C';
+ *r++ = '-';
+ c = '?';
+ }
+
+ if (c == ESC)
+ {
+ *r++ = '\\';
+ c = 'e';
+ }
+ else if (c == '\\' || c == '"')
+ *r++ = '\\';
+
+ *r++ = (unsigned char)c;
+ }
+ *r = '\0';
+ return ret;
+}
+
+/* Return a pointer to the function that STRING represents.
+ If STRING doesn't have a matching function, then a NULL pointer
+ is returned. */
+rl_command_func_t *
+rl_named_function (string)
+ const char *string;
+{
+ register int i;
+
+ rl_initialize_funmap ();
+
+ for (i = 0; funmap[i]; i++)
+ if (_rl_stricmp (funmap[i]->name, string) == 0)
+ return (funmap[i]->function);
+ return ((rl_command_func_t *)NULL);
+}
+
+/* Return the function (or macro) definition which would be invoked via
+ KEYSEQ if executed in MAP. If MAP is NULL, then the current keymap is
+ used. TYPE, if non-NULL, is a pointer to an int which will receive the
+ type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap),
+ or ISMACR (macro). */
+rl_command_func_t *
+rl_function_of_keyseq (keyseq, map, type)
+ const char *keyseq;
+ Keymap map;
+ int *type;
+{
+ register int i;
+
+ if (!map)
+ map = _rl_keymap;
+
+ for (i = 0; keyseq && keyseq[i]; i++)
+ {
+ unsigned char ic = keyseq[i];
+
+ if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
+ {
+ if (map[ESC].type != ISKMAP)
+ {
+ if (type)
+ *type = map[ESC].type;
+
+ return (map[ESC].function);
+ }
+ else
+ {
+ map = FUNCTION_TO_KEYMAP (map, ESC);
+ ic = UNMETA (ic);
+ }
+ }
+
+ if (map[ic].type == ISKMAP)
+ {
+ /* If this is the last key in the key sequence, return the
+ map. */
+ if (!keyseq[i + 1])
+ {
+ if (type)
+ *type = ISKMAP;
+
+ return (map[ic].function);
+ }
+ else
+ map = FUNCTION_TO_KEYMAP (map, ic);
+ }
+ else
+ {
+ if (type)
+ *type = map[ic].type;
+
+ return (map[ic].function);
+ }
+ }
+ return ((rl_command_func_t *) NULL);
+}
+
+/* The last key bindings file read. */
+static char *last_readline_init_file = (char *)NULL;
+
+/* The file we're currently reading key bindings from. */
+static const char *current_readline_init_file;
+static int current_readline_init_include_level;
+static int current_readline_init_lineno;
+
+/* Read FILENAME into a locally-allocated buffer and return the buffer.
+ The size of the buffer is returned in *SIZEP. Returns NULL if any
+ errors were encountered. */
+static char *
+_rl_read_file (filename, sizep)
+ char *filename;
+ size_t *sizep;
+{
+ struct stat finfo;
+ size_t file_size;
+ char *buffer;
+ int i, file;
+
+ if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0)
+ return ((char *)NULL);
+
+ file_size = (size_t)finfo.st_size;
+
+ /* check for overflow on very large files */
+ if (file_size != finfo.st_size || file_size + 1 < file_size)
+ {
+ if (file >= 0)
+ close (file);
+#if defined (EFBIG)
+ errno = EFBIG;
+#endif
+ return ((char *)NULL);
+ }
+
+ /* Read the file into BUFFER. */
+ buffer = (char *)xmalloc (file_size + 1);
+ i = read (file, buffer, file_size);
+ close (file);
+
+ if (i < 0)
+ {
+ free (buffer);
+ return ((char *)NULL);
+ }
+
+ buffer[i] = '\0';
+ if (sizep)
+ *sizep = i;
+
+ return (buffer);
+}
+
+/* Re-read the current keybindings file. */
+int
+rl_re_read_init_file (count, ignore)
+ int count, ignore;
+{
+ int r;
+ r = rl_read_init_file ((const char *)NULL);
+ rl_set_keymap_from_edit_mode ();
+ return r;
+}
+
+/* Do key bindings from a file. If FILENAME is NULL it defaults
+ to the first non-null filename from this list:
+ 1. the filename used for the previous call
+ 2. the value of the shell variable `INPUTRC'
+ 3. ~/.inputrc
+ If the file existed and could be opened and read, 0 is returned,
+ otherwise errno is returned. */
+int
+rl_read_init_file (filename)
+ const char *filename;
+{
+ /* Default the filename. */
+ if (filename == 0)
+ {
+ filename = last_readline_init_file;
+ if (filename == 0)
+ filename = sh_get_env_value ("INPUTRC");
+ if (filename == 0)
+ filename = DEFAULT_INPUTRC;
+ }
+
+ if (*filename == 0)
+ filename = DEFAULT_INPUTRC;
+
+#if defined (__MSDOS__)
+ if (_rl_read_init_file (filename, 0) == 0)
+ return 0;
+ filename = "~/_inputrc";
+#endif
+ return (_rl_read_init_file (filename, 0));
+}
+
+static int
+_rl_read_init_file (filename, include_level)
+ const char *filename;
+ int include_level;
+{
+ register int i;
+ char *buffer, *openname, *line, *end;
+ size_t file_size;
+
+ current_readline_init_file = filename;
+ current_readline_init_include_level = include_level;
+
+ openname = tilde_expand (filename);
+ buffer = _rl_read_file (openname, &file_size);
+ free (openname);
+#if defined _WIN32 && defined INITFILES_IN_REGISTRY
+ if (buffer == 0)
+ {
+ openname = get_user_registry_string(READLINE_REGKEY, INPUTRC_REGVAL);
+ if (openname)
+ {
+ buffer = _rl_read_file (openname, &file_size);
+ free (openname);
+ }
+ }
+#endif /* _WIN32 ... */
+ if (buffer == 0)
+ return (errno);
+
+ if (include_level == 0 && filename != last_readline_init_file)
+ {
+ FREE (last_readline_init_file);
+ last_readline_init_file = savestring (filename);
+ }
+
+ currently_reading_init_file = 1;
+
+ /* Loop over the lines in the file. Lines that start with `#' are
+ comments; all other lines are commands for readline initialization. */
+ current_readline_init_lineno = 1;
+ line = buffer;
+ end = buffer + file_size;
+ while (line < end)
+ {
+ /* Find the end of this line. */
+ for (i = 0; line + i != end && line[i] != '\n'; i++);
+
+#if defined (__CYGWIN__)
+ /* ``Be liberal in what you accept.'' */
+ if (line[i] == '\n' && line[i-1] == '\r')
+ line[i - 1] = '\0';
+#endif
+
+ /* Mark end of line. */
+ line[i] = '\0';
+
+ /* Skip leading whitespace. */
+ while (*line && whitespace (*line))
+ {
+ line++;
+ i--;
+ }
+
+ /* If the line is not a comment, then parse it. */
+ if (*line && *line != '#')
+ rl_parse_and_bind (line);
+
+ /* Move to the next line. */
+ line += i + 1;
+ current_readline_init_lineno++;
+ }
+
+ free (buffer);
+ currently_reading_init_file = 0;
+ return (0);
+}
+
+static void
+_rl_init_file_error (msg)
+ const char *msg;
+{
+ if (currently_reading_init_file)
+ fprintf (stderr, "readline: %s: line %d: %s\n", current_readline_init_file,
+ current_readline_init_lineno, msg);
+ else
+ fprintf (stderr, "readline: %s\n", msg);
+}
+
+/* **************************************************************** */
+/* */
+/* Parser Directives */
+/* */
+/* **************************************************************** */
+
+typedef int _rl_parser_func_t PARAMS((char *));
+
+/* Things that mean `Control'. */
+const char *_rl_possible_control_prefixes[] = {
+ "Control-", "C-", "CTRL-", (const char *)NULL
+};
+
+const char *_rl_possible_meta_prefixes[] = {
+ "Meta", "M-", (const char *)NULL
+};
+
+/* Conditionals. */
+
+/* Calling programs set this to have their argv[0]. */
+const char *rl_readline_name = "other";
+
+/* Stack of previous values of parsing_conditionalized_out. */
+static unsigned char *if_stack = (unsigned char *)NULL;
+static int if_stack_depth;
+static int if_stack_size;
+
+/* Push _rl_parsing_conditionalized_out, and set parser state based
+ on ARGS. */
+static int
+parser_if (char *args)
+{
+ register int i;
+
+ /* Push parser state. */
+ if (if_stack_depth + 1 >= if_stack_size)
+ {
+ if (!if_stack)
+ if_stack = (unsigned char *)xmalloc (if_stack_size = 20);
+ else
+ if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20);
+ }
+ if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out;
+
+ /* If parsing is turned off, then nothing can turn it back on except
+ for finding the matching endif. In that case, return right now. */
+ if (_rl_parsing_conditionalized_out)
+ return 0;
+
+ /* Isolate first argument. */
+ for (i = 0; args[i] && !whitespace (args[i]); i++);
+
+ if (args[i])
+ args[i++] = '\0';
+
+ /* Handle "$if term=foo" and "$if mode=emacs" constructs. If this
+ isn't term=foo, or mode=emacs, then check to see if the first
+ word in ARGS is the same as the value stored in rl_readline_name. */
+ if (rl_terminal_name && _rl_strnicmp (args, "term=", 5) == 0)
+ {
+ char *tem, *tname;
+
+ /* Terminals like "aaa-60" are equivalent to "aaa". */
+ tname = savestring (rl_terminal_name);
+ tem = strchr (tname, '-');
+ if (tem)
+ *tem = '\0';
+
+ /* Test the `long' and `short' forms of the terminal name so that
+ if someone has a `sun-cmd' and does not want to have bindings
+ that will be executed if the terminal is a `sun', they can put
+ `$if term=sun-cmd' into their .inputrc. */
+ _rl_parsing_conditionalized_out = _rl_stricmp (args + 5, tname) &&
+ _rl_stricmp (args + 5, rl_terminal_name);
+ free (tname);
+ }
+#if defined (VI_MODE)
+ else if (_rl_strnicmp (args, "mode=", 5) == 0)
+ {
+ int mode;
+
+ if (_rl_stricmp (args + 5, "emacs") == 0)
+ mode = emacs_mode;
+ else if (_rl_stricmp (args + 5, "vi") == 0)
+ mode = vi_mode;
+ else
+ mode = no_mode;
+
+ _rl_parsing_conditionalized_out = mode != rl_editing_mode;
+ }
+#endif /* VI_MODE */
+ /* Check to see if the first word in ARGS is the same as the
+ value stored in rl_readline_name. */
+ else if (_rl_stricmp (args, rl_readline_name) == 0)
+ _rl_parsing_conditionalized_out = 0;
+ else
+ _rl_parsing_conditionalized_out = 1;
+ return 0;
+}
+
+/* Invert the current parser state if there is anything on the stack. */
+static int
+parser_else (char *args)
+{
+ register int i;
+
+ if (if_stack_depth == 0)
+ {
+ _rl_init_file_error ("$else found without matching $if");
+ return 0;
+ }
+
+ /* Check the previous (n - 1) levels of the stack to make sure that
+ we haven't previously turned off parsing. */
+ for (i = 0; i < if_stack_depth - 1; i++)
+ if (if_stack[i] == 1)
+ return 0;
+
+ /* Invert the state of parsing if at top level. */
+ _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out;
+ return 0;
+}
+
+/* Terminate a conditional, popping the value of
+ _rl_parsing_conditionalized_out from the stack. */
+static int
+parser_endif (char *args)
+{
+ if (if_stack_depth)
+ _rl_parsing_conditionalized_out = if_stack[--if_stack_depth];
+ else
+ _rl_init_file_error ("$endif without matching $if");
+ return 0;
+}
+
+static int
+parser_include (char *args)
+{
+ const char *old_init_file;
+ char *e;
+ int old_line_number, old_include_level, r;
+
+ if (_rl_parsing_conditionalized_out)
+ return (0);
+
+ old_init_file = current_readline_init_file;
+ old_line_number = current_readline_init_lineno;
+ old_include_level = current_readline_init_include_level;
+
+ e = strchr (args, '\n');
+ if (e)
+ *e = '\0';
+ r = _rl_read_init_file ((const char *)args, old_include_level + 1);
+
+ current_readline_init_file = old_init_file;
+ current_readline_init_lineno = old_line_number;
+ current_readline_init_include_level = old_include_level;
+
+ return r;
+}
+
+/* Associate textual names with actual functions. */
+static struct {
+ const char *name;
+ _rl_parser_func_t *function;
+} parser_directives [] = {
+ { "if", parser_if },
+ { "endif", parser_endif },
+ { "else", parser_else },
+ { "include", parser_include },
+ { (char *)0x0, (_rl_parser_func_t *)0x0 }
+};
+
+/* Handle a parser directive. STATEMENT is the line of the directive
+ without any leading `$'. */
+static int
+handle_parser_directive (statement)
+ char *statement;
+{
+ register int i;
+ char *directive, *args;
+
+ /* Isolate the actual directive. */
+
+ /* Skip whitespace. */
+ for (i = 0; whitespace (statement[i]); i++);
+
+ directive = &statement[i];
+
+ for (; statement[i] && !whitespace (statement[i]); i++);
+
+ if (statement[i])
+ statement[i++] = '\0';
+
+ for (; statement[i] && whitespace (statement[i]); i++);
+
+ args = &statement[i];
+
+ /* Lookup the command, and act on it. */
+ for (i = 0; parser_directives[i].name; i++)
+ if (_rl_stricmp (directive, parser_directives[i].name) == 0)
+ {
+ (*parser_directives[i].function) (args);
+ return (0);
+ }
+
+ /* display an error message about the unknown parser directive */
+ _rl_init_file_error ("unknown parser directive");
+ return (1);
+}
+
+/* Read the binding command from STRING and perform it.
+ A key binding command looks like: Keyname: function-name\0,
+ a variable binding command looks like: set variable value.
+ A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */
+int
+rl_parse_and_bind (string)
+ char *string;
+{
+ char *funname, *kname;
+ register int c, i;
+ int key, equivalency;
+
+ while (string && whitespace (*string))
+ string++;
+
+ if (!string || !*string || *string == '#')
+ return 0;
+
+ /* If this is a parser directive, act on it. */
+ if (*string == '$')
+ {
+ handle_parser_directive (&string[1]);
+ return 0;
+ }
+
+ /* If we aren't supposed to be parsing right now, then we're done. */
+ if (_rl_parsing_conditionalized_out)
+ return 0;
+
+ i = 0;
+ /* If this keyname is a complex key expression surrounded by quotes,
+ advance to after the matching close quote. This code allows the
+ backslash to quote characters in the key expression. */
+ if (*string == '"')
+ {
+ int passc = 0;
+
+ for (i = 1; (c = string[i]); i++)
+ {
+ if (passc)
+ {
+ passc = 0;
+ continue;
+ }
+
+ if (c == '\\')
+ {
+ passc++;
+ continue;
+ }
+
+ if (c == '"')
+ break;
+ }
+ /* If we didn't find a closing quote, abort the line. */
+ if (string[i] == '\0')
+ {
+ _rl_init_file_error ("no closing `\"' in key binding");
+ return 1;
+ }
+ }
+
+ /* Advance to the colon (:) or whitespace which separates the two objects. */
+ for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );
+
+ equivalency = (c == ':' && string[i + 1] == '=');
+
+ /* Mark the end of the command (or keyname). */
+ if (string[i])
+ string[i++] = '\0';
+
+ /* If doing assignment, skip the '=' sign as well. */
+ if (equivalency)
+ string[i++] = '\0';
+
+ /* If this is a command to set a variable, then do that. */
+ if (_rl_stricmp (string, "set") == 0)
+ {
+ char *var = string + i;
+ char *value;
+
+ /* Make VAR point to start of variable name. */
+ while (*var && whitespace (*var)) var++;
+
+ /* Make VALUE point to start of value string. */
+ value = var;
+ while (*value && !whitespace (*value)) value++;
+ if (*value)
+ *value++ = '\0';
+ while (*value && whitespace (*value)) value++;
+
+ rl_variable_bind (var, value);
+ return 0;
+ }
+
+ /* Skip any whitespace between keyname and funname. */
+ for (; string[i] && whitespace (string[i]); i++);
+ funname = &string[i];
+
+ /* Now isolate funname.
+ For straight function names just look for whitespace, since
+ that will signify the end of the string. But this could be a
+ macro definition. In that case, the string is quoted, so skip
+ to the matching delimiter. We allow the backslash to quote the
+ delimiter characters in the macro body. */
+ /* This code exists to allow whitespace in macro expansions, which
+ would otherwise be gobbled up by the next `for' loop.*/
+ /* XXX - it may be desirable to allow backslash quoting only if " is
+ the quoted string delimiter, like the shell. */
+ if (*funname == '\'' || *funname == '"')
+ {
+ int delimiter = string[i++], passc;
+
+ for (passc = 0; (c = string[i]); i++)
+ {
+ if (passc)
+ {
+ passc = 0;
+ continue;
+ }
+
+ if (c == '\\')
+ {
+ passc = 1;
+ continue;
+ }
+
+ if (c == delimiter)
+ break;
+ }
+ if (c)
+ i++;
+ }
+
+ /* Advance to the end of the string. */
+ for (; string[i] && !whitespace (string[i]); i++);
+
+ /* No extra whitespace at the end of the string. */
+ string[i] = '\0';
+
+ /* Handle equivalency bindings here. Make the left-hand side be exactly
+ whatever the right-hand evaluates to, including keymaps. */
+ if (equivalency)
+ {
+ return 0;
+ }
+
+ /* If this is a new-style key-binding, then do the binding with
+ rl_set_key (). Otherwise, let the older code deal with it. */
+ if (*string == '"')
+ {
+ char *seq;
+ register int j, k, passc;
+
+ seq = (char *)xmalloc (1 + strlen (string));
+ for (j = 1, k = passc = 0; string[j]; j++)
+ {
+ /* Allow backslash to quote characters, but leave them in place.
+ This allows a string to end with a backslash quoting another
+ backslash, or with a backslash quoting a double quote. The
+ backslashes are left in place for rl_translate_keyseq (). */
+ if (passc || (string[j] == '\\'))
+ {
+ seq[k++] = string[j];
+ passc = !passc;
+ continue;
+ }
+
+ if (string[j] == '"')
+ break;
+
+ seq[k++] = string[j];
+ }
+ seq[k] = '\0';
+
+ /* Binding macro? */
+ if (*funname == '\'' || *funname == '"')
+ {
+ j = strlen (funname);
+
+ /* Remove the delimiting quotes from each end of FUNNAME. */
+ if (j && funname[j - 1] == *funname)
+ funname[j - 1] = '\0';
+
+ rl_macro_bind (seq, &funname[1], _rl_keymap);
+ }
+ else
+ rl_set_key (seq, rl_named_function (funname), _rl_keymap);
+
+ free (seq);
+ return 0;
+ }
+
+ /* Get the actual character we want to deal with. */
+ kname = strrchr (string, '-');
+ if (!kname)
+ kname = string;
+ else
+ kname++;
+
+ key = glean_key_from_name (kname);
+
+ /* Add in control and meta bits. */
+ if (substring_member_of_array (string, _rl_possible_control_prefixes))
+ key = CTRL (_rl_to_upper (key));
+
+ if (substring_member_of_array (string, _rl_possible_meta_prefixes))
+ key = META (key);
+
+ /* Temporary. Handle old-style keyname with macro-binding. */
+ if (*funname == '\'' || *funname == '"')
+ {
+ char useq[2];
+ int fl = strlen (funname);
+
+ useq[0] = key; useq[1] = '\0';
+ if (fl && funname[fl - 1] == *funname)
+ funname[fl - 1] = '\0';
+
+ rl_macro_bind (useq, &funname[1], _rl_keymap);
+ }
+#if defined (PREFIX_META_HACK)
+ /* Ugly, but working hack to keep prefix-meta around. */
+ else if (_rl_stricmp (funname, "prefix-meta") == 0)
+ {
+ char seq[2];
+
+ seq[0] = key;
+ seq[1] = '\0';
+ rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, _rl_keymap);
+ }
+#endif /* PREFIX_META_HACK */
+ else
+ rl_bind_key (key, rl_named_function (funname));
+ return 0;
+}
+
+/* Simple structure for boolean readline variables (i.e., those that can
+ have one of two values; either "On" or 1 for truth, or "Off" or 0 for
+ false. */
+
+#define V_SPECIAL 0x1
+
+static struct {
+ const char *name;
+ int *value;
+ int flags;
+} boolean_varlist [] = {
+ { "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL },
+ { "byte-oriented", &rl_byte_oriented, 0 },
+ { "completion-ignore-case", &_rl_completion_case_fold, 0 },
+ { "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
+ { "disable-completion", &rl_inhibit_completion, 0 },
+ { "enable-keypad", &_rl_enable_keypad, 0 },
+ { "expand-tilde", &rl_complete_with_tilde_expansion, 0 },
+ { "history-preserve-point", &_rl_history_preserve_point, 0 },
+ { "horizontal-scroll-mode", &_rl_horizontal_scroll_mode, 0 },
+ { "input-meta", &_rl_meta_flag, 0 },
+ { "mark-directories", &_rl_complete_mark_directories, 0 },
+ { "mark-modified-lines", &_rl_mark_modified_lines, 0 },
+ { "mark-symlinked-directories", &_rl_complete_mark_symlink_dirs, 0 },
+ { "match-hidden-files", &_rl_match_hidden_files, 0 },
+ { "meta-flag", &_rl_meta_flag, 0 },
+ { "output-meta", &_rl_output_meta_chars, 0 },
+ { "page-completions", &_rl_page_completions, 0 },
+ { "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL },
+ { "print-completions-horizontally", &_rl_print_completions_horizontally, 0 },
+ { "show-all-if-ambiguous", &_rl_complete_show_all, 0 },
+#if defined (VISIBLE_STATS)
+ { "visible-stats", &rl_visible_stats, 0 },
+#endif /* VISIBLE_STATS */
+ { (char *)NULL, (int *)NULL }
+};
+
+static int
+find_boolean_var (name)
+ const char *name;
+{
+ register int i;
+
+ for (i = 0; boolean_varlist[i].name; i++)
+ if (_rl_stricmp (name, boolean_varlist[i].name) == 0)
+ return i;
+ return -1;
+}
+
+/* Hooks for handling special boolean variables, where a
+ function needs to be called or another variable needs
+ to be changed when they're changed. */
+static void
+hack_special_boolean_var (i)
+ int i;
+{
+ const char *name;
+
+ name = boolean_varlist[i].name;
+
+ if (_rl_stricmp (name, "blink-matching-paren") == 0)
+ _rl_enable_paren_matching (rl_blink_matching_paren);
+ else if (_rl_stricmp (name, "prefer-visible-bell") == 0)
+ {
+ if (_rl_prefer_visible_bell)
+ _rl_bell_preference = VISIBLE_BELL;
+ else
+ _rl_bell_preference = AUDIBLE_BELL;
+ }
+}
+
+typedef int _rl_sv_func_t PARAMS((const char *));
+
+/* These *must* correspond to the array indices for the appropriate
+ string variable. (Though they're not used right now.) */
+#define V_BELLSTYLE 0
+#define V_COMBEGIN 1
+#define V_EDITMODE 2
+#define V_ISRCHTERM 3
+#define V_KEYMAP 4
+
+#define V_STRING 1
+#define V_INT 2
+
+/* Forward declarations */
+static int sv_bell_style PARAMS((const char *));
+static int sv_combegin PARAMS((const char *));
+static int sv_compquery PARAMS((const char *));
+static int sv_editmode PARAMS((const char *));
+static int sv_isrchterm PARAMS((const char *));
+static int sv_keymap PARAMS((const char *));
+
+static struct {
+ const char *name;
+ int flags;
+ _rl_sv_func_t *set_func;
+} string_varlist[] = {
+ { "bell-style", V_STRING, sv_bell_style },
+ { "comment-begin", V_STRING, sv_combegin },
+ { "completion-query-items", V_INT, sv_compquery },
+ { "editing-mode", V_STRING, sv_editmode },
+ { "isearch-terminators", V_STRING, sv_isrchterm },
+ { "keymap", V_STRING, sv_keymap },
+ { (char *)NULL, 0 }
+};
+
+static int
+find_string_var (name)
+ const char *name;
+{
+ register int i;
+
+ for (i = 0; string_varlist[i].name; i++)
+ if (_rl_stricmp (name, string_varlist[i].name) == 0)
+ return i;
+ return -1;
+}
+
+/* A boolean value that can appear in a `set variable' command is true if
+ the value is null or empty, `on' (case-insenstive), or "1". Any other
+ values result in 0 (false). */
+static int
+bool_to_int (value)
+ const char *value;
+{
+ return (value == 0 || *value == '\0' ||
+ (_rl_stricmp (value, "on") == 0) ||
+ (value[0] == '1' && value[1] == '\0'));
+}
+
+int
+rl_variable_bind (name, value)
+ const char *name, *value;
+{
+ register int i;
+ int v;
+
+ /* Check for simple variables first. */
+ i = find_boolean_var (name);
+ if (i >= 0)
+ {
+ *boolean_varlist[i].value = bool_to_int (value);
+ if (boolean_varlist[i].flags & V_SPECIAL)
+ hack_special_boolean_var (i);
+ return 0;
+ }
+
+ i = find_string_var (name);
+
+ /* For the time being, unknown variable names or string names without a
+ handler function are simply ignored. */
+ if (i < 0 || string_varlist[i].set_func == 0)
+ return 0;
+
+ v = (*string_varlist[i].set_func) (value);
+ return v;
+}
+
+static int
+sv_editmode (value)
+ const char *value;
+{
+ if (_rl_strnicmp (value, "vi", 2) == 0)
+ {
+#if defined (VI_MODE)
+ _rl_keymap = vi_insertion_keymap;
+ rl_editing_mode = vi_mode;
+#endif /* VI_MODE */
+ return 0;
+ }
+ else if (_rl_strnicmp (value, "emacs", 5) == 0)
+ {
+ _rl_keymap = emacs_standard_keymap;
+ rl_editing_mode = emacs_mode;
+ return 0;
+ }
+ return 1;
+}
+
+static int
+sv_combegin (value)
+ const char *value;
+{
+ if (value && *value)
+ {
+ FREE (_rl_comment_begin);
+ _rl_comment_begin = savestring (value);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+sv_compquery (value)
+ const char *value;
+{
+ int nval = 100;
+
+ if (value && *value)
+ {
+ nval = atoi (value);
+ if (nval < 0)
+ nval = 0;
+ }
+ rl_completion_query_items = nval;
+ return 0;
+}
+
+static int
+sv_keymap (value)
+ const char *value;
+{
+ Keymap kmap;
+
+ kmap = rl_get_keymap_by_name (value);
+ if (kmap)
+ {
+ rl_set_keymap (kmap);
+ return 0;
+ }
+ return 1;
+}
+
+static int
+sv_bell_style (value)
+ const char *value;
+{
+ if (value == 0 || *value == '\0')
+ _rl_bell_preference = AUDIBLE_BELL;
+ else if (_rl_stricmp (value, "none") == 0 || _rl_stricmp (value, "off") == 0)
+ _rl_bell_preference = NO_BELL;
+ else if (_rl_stricmp (value, "audible") == 0 || _rl_stricmp (value, "on") == 0)
+ _rl_bell_preference = AUDIBLE_BELL;
+ else if (_rl_stricmp (value, "visible") == 0)
+ _rl_bell_preference = VISIBLE_BELL;
+ else
+ return 1;
+ return 0;
+}
+
+static int
+sv_isrchterm (value)
+ const char *value;
+{
+ int beg, end, delim;
+ char *v;
+
+ if (value == 0)
+ return 1;
+
+ /* Isolate the value and translate it into a character string. */
+ v = savestring (value);
+ FREE (_rl_isearch_terminators);
+ if (v[0] == '"' || v[0] == '\'')
+ {
+ delim = v[0];
+ for (beg = end = 1; v[end] && v[end] != delim; end++)
+ ;
+ }
+ else
+ {
+ for (beg = end = 0; whitespace (v[end]) == 0; end++)
+ ;
+ }
+
+ v[end] = '\0';
+
+ /* The value starts at v + beg. Translate it into a character string. */
+ _rl_isearch_terminators = (char *)xmalloc (2 * strlen (v) + 1);
+ rl_translate_keyseq (v + beg, _rl_isearch_terminators, &end);
+ _rl_isearch_terminators[end] = '\0';
+
+ free (v);
+ return 0;
+}
+
+/* Return the character which matches NAME.
+ For example, `Space' returns ' '. */
+
+typedef struct {
+ const char *name;
+ int value;
+} assoc_list;
+
+static assoc_list name_key_alist[] = {
+ { "DEL", 0x7f },
+ { "ESC", '\033' },
+ { "Escape", '\033' },
+ { "LFD", '\n' },
+ { "Newline", '\n' },
+ { "RET", '\r' },
+ { "Return", '\r' },
+ { "Rubout", 0x7f },
+ { "SPC", ' ' },
+ { "Space", ' ' },
+ { "Tab", 0x09 },
+ { (char *)0x0, 0 }
+};
+
+static int
+glean_key_from_name (name)
+ char *name;
+{
+ register int i;
+
+ for (i = 0; name_key_alist[i].name; i++)
+ if (_rl_stricmp (name, name_key_alist[i].name) == 0)
+ return (name_key_alist[i].value);
+
+ return (*(unsigned char *)name); /* XXX was return (*name) */
+}
+
+/* Auxiliary functions to manage keymaps. */
+static struct {
+ const char *name;
+ Keymap map;
+} keymap_names[] = {
+ { "emacs", emacs_standard_keymap },
+ { "emacs-standard", emacs_standard_keymap },
+ { "emacs-meta", emacs_meta_keymap },
+ { "emacs-ctlx", emacs_ctlx_keymap },
+#if defined (VI_MODE)
+ { "vi", vi_movement_keymap },
+ { "vi-move", vi_movement_keymap },
+ { "vi-command", vi_movement_keymap },
+ { "vi-insert", vi_insertion_keymap },
+#endif /* VI_MODE */
+ { (char *)0x0, (Keymap)0x0 }
+};
+
+Keymap
+rl_get_keymap_by_name (name)
+ const char *name;
+{
+ register int i;
+
+ for (i = 0; keymap_names[i].name; i++)
+ if (_rl_stricmp (name, keymap_names[i].name) == 0)
+ return (keymap_names[i].map);
+ return ((Keymap) NULL);
+}
+
+char *
+rl_get_keymap_name (map)
+ Keymap map;
+{
+ register int i;
+ for (i = 0; keymap_names[i].name; i++)
+ if (map == keymap_names[i].map)
+ return ((char *)keymap_names[i].name);
+ return ((char *)NULL);
+}
+
+void
+rl_set_keymap (map)
+ Keymap map;
+{
+ if (map)
+ _rl_keymap = map;
+}
+
+Keymap
+rl_get_keymap ()
+{
+ return (_rl_keymap);
+}
+
+void
+rl_set_keymap_from_edit_mode ()
+{
+ if (rl_editing_mode == emacs_mode)
+ _rl_keymap = emacs_standard_keymap;
+#if defined (VI_MODE)
+ else if (rl_editing_mode == vi_mode)
+ _rl_keymap = vi_insertion_keymap;
+#endif /* VI_MODE */
+}
+
+char *
+rl_get_keymap_name_from_edit_mode ()
+{
+ if (rl_editing_mode == emacs_mode)
+ return "emacs";
+#if defined (VI_MODE)
+ else if (rl_editing_mode == vi_mode)
+ return "vi";
+#endif /* VI_MODE */
+ else
+ return "none";
+}
+
+/* **************************************************************** */
+/* */
+/* Key Binding and Function Information */
+/* */
+/* **************************************************************** */
+
+/* Each of the following functions produces information about the
+ state of keybindings and functions known to Readline. The info
+ is always printed to rl_outstream, and in such a way that it can
+ be read back in (i.e., passed to rl_parse_and_bind (). */
+
+/* Print the names of functions known to Readline. */
+void
+rl_list_funmap_names ()
+{
+ register int i;
+ const char **funmap_names;
+
+ funmap_names = rl_funmap_names ();
+
+ if (!funmap_names)
+ return;
+
+ for (i = 0; funmap_names[i]; i++)
+ fprintf (rl_outstream, "%s\n", funmap_names[i]);
+
+ free ((void *)funmap_names);
+}
+
+static char *
+_rl_get_keyname (key)
+ int key;
+{
+ char *keyname;
+ int i, c;
+
+ keyname = (char *)xmalloc (8);
+
+ c = key;
+ /* Since this is going to be used to write out keysequence-function
+ pairs for possible inclusion in an inputrc file, we don't want to
+ do any special meta processing on KEY. */
+
+#if 1
+ /* XXX - Experimental */
+ /* We might want to do this, but the old version of the code did not. */
+
+ /* If this is an escape character, we don't want to do any more processing.
+ Just add the special ESC key sequence and return. */
+ if (c == ESC)
+ {
+ keyname[0] = '\\';
+ keyname[1] = 'e';
+ keyname[2] = '\0';
+ return keyname;
+ }
+#endif
+
+ /* RUBOUT is translated directly into \C-? */
+ if (key == RUBOUT)
+ {
+ keyname[0] = '\\';
+ keyname[1] = 'C';
+ keyname[2] = '-';
+ keyname[3] = '?';
+ keyname[4] = '\0';
+ return keyname;
+ }
+
+ i = 0;
+ /* Now add special prefixes needed for control characters. This can
+ potentially change C. */
+ if (CTRL_CHAR (c))
+ {
+ keyname[i++] = '\\';
+ keyname[i++] = 'C';
+ keyname[i++] = '-';
+ c = _rl_to_lower (UNCTRL (c));
+ }
+
+ /* XXX experimental code. Turn the characters that are not ASCII or
+ ISO Latin 1 (128 - 159) into octal escape sequences (\200 - \237).
+ This changes C. */
+ if (c >= 128 && c <= 159)
+ {
+ keyname[i++] = '\\';
+ keyname[i++] = '2';
+ c -= 128;
+ keyname[i++] = (c / 8) + '0';
+ c = (c % 8) + '0';
+ }
+
+ /* Now, if the character needs to be quoted with a backslash, do that. */
+ if (c == '\\' || c == '"')
+ keyname[i++] = '\\';
+
+ /* Now add the key, terminate the string, and return it. */
+ keyname[i++] = (char) c;
+ keyname[i] = '\0';
+
+ return keyname;
+}
+
+/* Return a NULL terminated array of strings which represent the key
+ sequences that are used to invoke FUNCTION in MAP. */
+char **
+rl_invoking_keyseqs_in_map (function, map)
+ rl_command_func_t *function;
+ Keymap map;
+{
+ register int key;
+ char **result;
+ int result_index, result_size;
+
+ result = (char **)NULL;
+ result_index = result_size = 0;
+
+ for (key = 0; key < KEYMAP_SIZE; key++)
+ {
+ switch (map[key].type)
+ {
+ case ISMACR:
+ /* Macros match, if, and only if, the pointers are identical.
+ Thus, they are treated exactly like functions in here. */
+ case ISFUNC:
+ /* If the function in the keymap is the one we are looking for,
+ then add the current KEY to the list of invoking keys. */
+ if (map[key].function == function)
+ {
+ char *keyname;
+
+ keyname = _rl_get_keyname (key);
+
+ if (result_index + 2 > result_size)
+ {
+ result_size += 10;
+ result = (char **)xrealloc (result, result_size * sizeof (char *));
+ }
+
+ result[result_index++] = keyname;
+ result[result_index] = (char *)NULL;
+ }
+ break;
+
+ case ISKMAP:
+ {
+ char **seqs;
+ register int i;
+
+ /* Find the list of keyseqs in this map which have FUNCTION as
+ their target. Add the key sequences found to RESULT. */
+ if (map[key].function)
+ seqs =
+ rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key));
+ else
+ break;
+
+ if (seqs == 0)
+ break;
+
+ for (i = 0; seqs[i]; i++)
+ {
+ char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
+
+ if (key == ESC)
+#if 0
+ sprintf (keyname, "\\e");
+#else
+ /* XXX - experimental */
+ sprintf (keyname, "\\M-");
+#endif
+ else if (CTRL_CHAR (key))
+ sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key)));
+ else if (key == RUBOUT)
+ sprintf (keyname, "\\C-?");
+ else if (key == '\\' || key == '"')
+ {
+ keyname[0] = '\\';
+ keyname[1] = (char) key;
+ keyname[2] = '\0';
+ }
+ else
+ {
+ keyname[0] = (char) key;
+ keyname[1] = '\0';
+ }
+
+ strcat (keyname, seqs[i]);
+ free (seqs[i]);
+
+ if (result_index + 2 > result_size)
+ {
+ result_size += 10;
+ result = (char **)xrealloc (result, result_size * sizeof (char *));
+ }
+
+ result[result_index++] = keyname;
+ result[result_index] = (char *)NULL;
+ }
+
+ free (seqs);
+ }
+ break;
+ }
+ }
+ return (result);
+}
+
+/* Return a NULL terminated array of strings which represent the key
+ sequences that can be used to invoke FUNCTION using the current keymap. */
+char **
+rl_invoking_keyseqs (function)
+ rl_command_func_t *function;
+{
+ return (rl_invoking_keyseqs_in_map (function, _rl_keymap));
+}
+
+/* Print all of the functions and their bindings to rl_outstream. If
+ PRINT_READABLY is non-zero, then print the output in such a way
+ that it can be read back in. */
+void
+rl_function_dumper (print_readably)
+ int print_readably;
+{
+ register int i;
+ const char **names;
+ const char *name;
+
+ names = rl_funmap_names ();
+
+ fprintf (rl_outstream, "\n");
+
+ for (i = 0; (name = names[i]); i++)
+ {
+ rl_command_func_t *function;
+ char **invokers;
+
+ function = rl_named_function (name);
+ invokers = rl_invoking_keyseqs_in_map (function, _rl_keymap);
+
+ if (print_readably)
+ {
+ if (!invokers)
+ fprintf (rl_outstream, "# %s (not bound)\n", name);
+ else
+ {
+ register int j;
+
+ for (j = 0; invokers[j]; j++)
+ {
+ fprintf (rl_outstream, "\"%s\": %s\n",
+ invokers[j], name);
+ free (invokers[j]);
+ }
+
+ free (invokers);
+ }
+ }
+ else
+ {
+ if (!invokers)
+ fprintf (rl_outstream, "%s is not bound to any keys\n",
+ name);
+ else
+ {
+ register int j;
+
+ fprintf (rl_outstream, "%s can be found on ", name);
+
+ for (j = 0; invokers[j] && j < 5; j++)
+ {
+ fprintf (rl_outstream, "\"%s\"%s", invokers[j],
+ invokers[j + 1] ? ", " : ".\n");
+ }
+
+ if (j == 5 && invokers[j])
+ fprintf (rl_outstream, "...\n");
+
+ for (j = 0; invokers[j]; j++)
+ free (invokers[j]);
+
+ free (invokers);
+ }
+ }
+ }
+}
+
+/* Print all of the current functions and their bindings to
+ rl_outstream. If an explicit argument is given, then print
+ the output in such a way that it can be read back in. */
+int
+rl_dump_functions (count, key)
+ int count, key;
+{
+ if (rl_dispatching)
+ fprintf (rl_outstream, "\r\n");
+ rl_function_dumper (rl_explicit_arg);
+ rl_on_new_line ();
+ return (0);
+}
+
+static void
+_rl_macro_dumper_internal (print_readably, map, prefix)
+ int print_readably;
+ Keymap map;
+ char *prefix;
+{
+ register int key;
+ char *keyname, *out;
+ int prefix_len;
+
+ for (key = 0; key < KEYMAP_SIZE; key++)
+ {
+ switch (map[key].type)
+ {
+ case ISMACR:
+ keyname = _rl_get_keyname (key);
+ out = _rl_untranslate_macro_value ((char *)map[key].function);
+
+ if (print_readably)
+ fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "",
+ keyname,
+ out ? out : "");
+ else
+ fprintf (rl_outstream, "%s%s outputs %s\n", prefix ? prefix : "",
+ keyname,
+ out ? out : "");
+ free (keyname);
+ free (out);
+ break;
+ case ISFUNC:
+ break;
+ case ISKMAP:
+ prefix_len = prefix ? strlen (prefix) : 0;
+ if (key == ESC)
+ {
+ keyname = (char *)xmalloc (3 + prefix_len);
+ if (prefix)
+ strcpy (keyname, prefix);
+ keyname[prefix_len] = '\\';
+ keyname[prefix_len + 1] = 'e';
+ keyname[prefix_len + 2] = '\0';
+ }
+ else
+ {
+ keyname = _rl_get_keyname (key);
+ if (prefix)
+ {
+ out = (char *)xmalloc (strlen (keyname) + prefix_len + 1);
+ strcpy (out, prefix);
+ strcpy (out + prefix_len, keyname);
+ free (keyname);
+ keyname = out;
+ }
+ }
+
+ _rl_macro_dumper_internal (print_readably, FUNCTION_TO_KEYMAP (map, key), keyname);
+ free (keyname);
+ break;
+ }
+ }
+}
+
+void
+rl_macro_dumper (print_readably)
+ int print_readably;
+{
+ _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL);
+}
+
+int
+rl_dump_macros (count, key)
+ int count, key;
+{
+ if (rl_dispatching)
+ fprintf (rl_outstream, "\r\n");
+ rl_macro_dumper (rl_explicit_arg);
+ rl_on_new_line ();
+ return (0);
+}
+
+void
+rl_variable_dumper (print_readably)
+ int print_readably;
+{
+ int i;
+ const char *kname;
+
+ for (i = 0; boolean_varlist[i].name; i++)
+ {
+ if (print_readably)
+ fprintf (rl_outstream, "set %s %s\n", boolean_varlist[i].name,
+ *boolean_varlist[i].value ? "on" : "off");
+ else
+ fprintf (rl_outstream, "%s is set to `%s'\n", boolean_varlist[i].name,
+ *boolean_varlist[i].value ? "on" : "off");
+ }
+
+ /* bell-style */
+ switch (_rl_bell_preference)
+ {
+ case NO_BELL:
+ kname = "none"; break;
+ case VISIBLE_BELL:
+ kname = "visible"; break;
+ case AUDIBLE_BELL:
+ default:
+ kname = "audible"; break;
+ }
+ if (print_readably)
+ fprintf (rl_outstream, "set bell-style %s\n", kname);
+ else
+ fprintf (rl_outstream, "bell-style is set to `%s'\n", kname);
+
+ /* comment-begin */
+ if (print_readably)
+ fprintf (rl_outstream, "set comment-begin %s\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
+ else
+ fprintf (rl_outstream, "comment-begin is set to `%s'\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
+
+ /* completion-query-items */
+ if (print_readably)
+ fprintf (rl_outstream, "set completion-query-items %d\n", rl_completion_query_items);
+ else
+ fprintf (rl_outstream, "completion-query-items is set to `%d'\n", rl_completion_query_items);
+
+ /* editing-mode */
+ if (print_readably)
+ fprintf (rl_outstream, "set editing-mode %s\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi");
+ else
+ fprintf (rl_outstream, "editing-mode is set to `%s'\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi");
+
+ /* isearch-terminators */
+ if (_rl_isearch_terminators)
+ {
+ char *disp;
+
+ disp = _rl_untranslate_macro_value (_rl_isearch_terminators);
+
+ if (print_readably)
+ fprintf (rl_outstream, "set isearch-terminators \"%s\"\n", disp);
+ else
+ fprintf (rl_outstream, "isearch-terminators is set to \"%s\"\n", disp);
+
+ free (disp);
+ }
+
+ /* keymap */
+ kname = rl_get_keymap_name (_rl_keymap);
+ if (kname == 0)
+ kname = rl_get_keymap_name_from_edit_mode ();
+ if (print_readably)
+ fprintf (rl_outstream, "set keymap %s\n", kname ? kname : "none");
+ else
+ fprintf (rl_outstream, "keymap is set to `%s'\n", kname ? kname : "none");
+}
+
+/* Print all of the current variables and their values to
+ rl_outstream. If an explicit argument is given, then print
+ the output in such a way that it can be read back in. */
+int
+rl_dump_variables (count, key)
+ int count, key;
+{
+ if (rl_dispatching)
+ fprintf (rl_outstream, "\r\n");
+ rl_variable_dumper (rl_explicit_arg);
+ rl_on_new_line ();
+ return (0);
+}
+
+/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
+ now, this is always used to attempt to bind the arrow keys, hence the
+ check for rl_vi_movement_mode. */
+void
+_rl_bind_if_unbound (keyseq, default_func)
+ const char *keyseq;
+ rl_command_func_t *default_func;
+{
+ rl_command_func_t *func;
+
+ if (keyseq)
+ {
+ func = rl_function_of_keyseq (keyseq, _rl_keymap, (int *)NULL);
+#if defined (VI_MODE)
+ if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
+#else
+ if (!func || func == rl_do_lowercase_version)
+#endif
+ rl_set_key (keyseq, default_func, _rl_keymap);
+ }
+}
+
+/* Return non-zero if any members of ARRAY are a substring in STRING. */
+static int
+substring_member_of_array (string, array)
+ char *string;
+ const char **array;
+{
+ while (*array)
+ {
+ if (_rl_strindex (string, *array))
+ return (1);
+ array++;
+ }
+ return (0);
+}
+
diff --git a/MSVC/readline/callback.c b/MSVC/readline/callback.c
index 1845510..85e2ee5 100644
--- a/MSVC/readline/callback.c
+++ b/MSVC/readline/callback.c
@@ -1,154 +1,154 @@
-/* callback.c -- functions to use readline as an X `callback' mechanism. */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include "rlconf.h"
-
-#if defined (READLINE_CALLBACKS)
-
-#include <sys/types.h>
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif
-
-#include <stdio.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "readline.h"
-#include "rlprivate.h"
-
-/* **************************************************************** */
-/* */
-/* Callback Readline Functions */
-/* */
-/* **************************************************************** */
-
-/* Allow using readline in situations where a program may have multiple
- things to handle at once, and dispatches them via select(). Call
- rl_callback_handler_install() with the prompt and a function to call
- whenever a complete line of input is ready. The user must then
- call rl_callback_read_char() every time some input is available, and
- rl_callback_read_char() will call the user's function with the complete
- text read in at each end of line. The terminal is kept prepped and
- signals handled all the time, except during calls to the user's function. */
-
-rl_vcpfunc_t *rl_linefunc; /* user callback function */
-static int in_handler; /* terminal_prepped and signals set? */
-
-/* Make sure the terminal is set up, initialize readline, and prompt. */
-static void
-_rl_callback_newline ()
-{
- rl_initialize ();
-
- if (in_handler == 0)
- {
- in_handler = 1;
-
- (*rl_prep_term_function) (_rl_meta_flag);
-
-#if defined (HANDLE_SIGNALS)
- rl_set_signals ();
-#endif
- }
-
- readline_internal_setup ();
-}
-
-/* Install a readline handler, set up the terminal, and issue the prompt. */
-void
-rl_callback_handler_install (prompt, linefunc)
- const char *prompt;
- rl_vcpfunc_t *linefunc;
-{
- rl_set_prompt (prompt);
- rl_linefunc = linefunc;
- _rl_callback_newline ();
-}
-
-/* Read one character, and dispatch to the handler if it ends the line. */
-void
-rl_callback_read_char ()
-{
- char *line;
- int eof;
-
- if (rl_linefunc == NULL)
- {
- fprintf (stderr, "readline: readline_callback_read_char() called with no handler!\r\n");
- abort ();
- }
-
- eof = readline_internal_char ();
-
- /* We loop in case some function has pushed input back with rl_execute_next. */
- for (;;)
- {
- if (rl_done)
- {
- line = readline_internal_teardown (eof);
-
- (*rl_deprep_term_function) ();
-#if defined (HANDLE_SIGNALS)
- rl_clear_signals ();
-#endif
- in_handler = 0;
- (*rl_linefunc) (line);
-
- /* If the user did not clear out the line, do it for him. */
- if (rl_line_buffer[0])
- _rl_init_line_state ();
-
- /* Redisplay the prompt if readline_handler_{install,remove}
- not called. */
- if (in_handler == 0 && rl_linefunc)
- _rl_callback_newline ();
- }
- if (rl_pending_input)
- eof = readline_internal_char ();
- else
- break;
- }
-}
-
-/* Remove the handler, and make sure the terminal is in its normal state. */
-void
-rl_callback_handler_remove ()
-{
- rl_linefunc = NULL;
- if (in_handler)
- {
- in_handler = 0;
- (*rl_deprep_term_function) ();
-#if defined (HANDLE_SIGNALS)
- rl_clear_signals ();
-#endif
- }
-}
-
-#endif
+/* callback.c -- functions to use readline as an X `callback' mechanism. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include "rlconf.h"
+
+#if defined (READLINE_CALLBACKS)
+
+#include <sys/types.h>
+
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif
+
+#include <stdio.h>
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+#include "readline.h"
+#include "rlprivate.h"
+
+/* **************************************************************** */
+/* */
+/* Callback Readline Functions */
+/* */
+/* **************************************************************** */
+
+/* Allow using readline in situations where a program may have multiple
+ things to handle at once, and dispatches them via select(). Call
+ rl_callback_handler_install() with the prompt and a function to call
+ whenever a complete line of input is ready. The user must then
+ call rl_callback_read_char() every time some input is available, and
+ rl_callback_read_char() will call the user's function with the complete
+ text read in at each end of line. The terminal is kept prepped and
+ signals handled all the time, except during calls to the user's function. */
+
+rl_vcpfunc_t *rl_linefunc; /* user callback function */
+static int in_handler; /* terminal_prepped and signals set? */
+
+/* Make sure the terminal is set up, initialize readline, and prompt. */
+static void
+_rl_callback_newline ()
+{
+ rl_initialize ();
+
+ if (in_handler == 0)
+ {
+ in_handler = 1;
+
+ (*rl_prep_term_function) (_rl_meta_flag);
+
+#if defined (HANDLE_SIGNALS)
+ rl_set_signals ();
+#endif
+ }
+
+ readline_internal_setup ();
+}
+
+/* Install a readline handler, set up the terminal, and issue the prompt. */
+void
+rl_callback_handler_install (prompt, linefunc)
+ const char *prompt;
+ rl_vcpfunc_t *linefunc;
+{
+ rl_set_prompt (prompt);
+ rl_linefunc = linefunc;
+ _rl_callback_newline ();
+}
+
+/* Read one character, and dispatch to the handler if it ends the line. */
+void
+rl_callback_read_char ()
+{
+ char *line;
+ int eof;
+
+ if (rl_linefunc == NULL)
+ {
+ fprintf (stderr, "readline: readline_callback_read_char() called with no handler!\r\n");
+ abort ();
+ }
+
+ eof = readline_internal_char ();
+
+ /* We loop in case some function has pushed input back with rl_execute_next. */
+ for (;;)
+ {
+ if (rl_done)
+ {
+ line = readline_internal_teardown (eof);
+
+ (*rl_deprep_term_function) ();
+#if defined (HANDLE_SIGNALS)
+ rl_clear_signals ();
+#endif
+ in_handler = 0;
+ (*rl_linefunc) (line);
+
+ /* If the user did not clear out the line, do it for him. */
+ if (rl_line_buffer[0])
+ _rl_init_line_state ();
+
+ /* Redisplay the prompt if readline_handler_{install,remove}
+ not called. */
+ if (in_handler == 0 && rl_linefunc)
+ _rl_callback_newline ();
+ }
+ if (rl_pending_input)
+ eof = readline_internal_char ();
+ else
+ break;
+ }
+}
+
+/* Remove the handler, and make sure the terminal is in its normal state. */
+void
+rl_callback_handler_remove ()
+{
+ rl_linefunc = NULL;
+ if (in_handler)
+ {
+ in_handler = 0;
+ (*rl_deprep_term_function) ();
+#if defined (HANDLE_SIGNALS)
+ rl_clear_signals ();
+#endif
+ }
+}
+
+#endif
diff --git a/MSVC/readline/chardefs.h b/MSVC/readline/chardefs.h
index e09fcea..8c429d4 100644
--- a/MSVC/readline/chardefs.h
+++ b/MSVC/readline/chardefs.h
@@ -1,162 +1,162 @@
-/* chardefs.h -- Character definitions for readline. */
-
-/* Copyright (C) 1994 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#ifndef _CHARDEFS_H_
-#define _CHARDEFS_H_
-
-#include <ctype.h>
-
-#if defined (HAVE_STRING_H)
-# if ! defined (STDC_HEADERS) && defined (HAVE_MEMORY_H)
-# include <memory.h>
-# endif
-# include <string.h>
-#endif /* HAVE_STRING_H */
-#if defined (HAVE_STRINGS_H)
-# include <strings.h>
-#endif /* HAVE_STRINGS_H */
-
-#ifndef whitespace
-#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
-#endif
-
-#ifdef CTRL
-# undef CTRL
-#endif
-#ifdef UNCTRL
-# undef UNCTRL
-#endif
-
-/* Some character stuff. */
-#define control_character_threshold 0x020 /* Smaller than this is control. */
-#define control_character_mask 0x1f /* 0x20 - 1 */
-#define control_character_bit 0x40 /* 0x000000, must be off. */
-
-#if !defined (_WIN32)
- #define meta_character_threshold 0x07f /* Larger than this is Meta. */
- #define meta_character_bit 0x080 /* x0000000, must be on. */
- #define largest_char 255 /* Largest character value. */
-#else /* _WIN32 */
- #define meta_character_threshold 0x0ff /* Larger than this is Meta. */
- #define meta_character_bit 0x100 /* x0000000, must be on. */
- #define largest_char 0x1ff /* Largest character value. */
-#endif /* _WIN32 */
-
-#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0))
-#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char)
-
-#define CTRL(c) ((c) & control_character_mask)
-#define META(c) ((c) | meta_character_bit)
-
-#define UNMETA(c) ((c) & (~meta_character_bit))
-#define UNCTRL(c) _rl_to_upper(((c)|control_character_bit))
-
-#if defined STDC_HEADERS || (!defined (isascii) && !defined (HAVE_ISASCII))
-# define IN_CTYPE_DOMAIN(c) 1
-#else
-# define IN_CTYPE_DOMAIN(c) isascii(c)
-#endif
-
-#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT)
-# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
-#endif
-
-#define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
-
-/* Some systems define these; we want our definitions. */
-#undef ISPRINT
-
-#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c))
-#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
-#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
-#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
-#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
-#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
-#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
-
-#define _rl_lowercase_p(c) (NON_NEGATIVE(c) && ISLOWER(c))
-#define _rl_uppercase_p(c) (NON_NEGATIVE(c) && ISUPPER(c))
-#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
-
-#define _rl_pure_alphabetic(c) (NON_NEGATIVE(c) && ISALPHA(c))
-#define ALPHABETIC(c) (NON_NEGATIVE(c) && ISALNUM(c))
-
-#ifndef _rl_to_upper
-# define _rl_to_upper(c) (_rl_lowercase_p(c) ? toupper((unsigned char)c) : (c))
-# define _rl_to_lower(c) (_rl_uppercase_p(c) ? tolower((unsigned char)c) : (c))
-#endif
-
-#ifndef _rl_digit_value
-# define _rl_digit_value(x) ((x) - '0')
-#endif
-
-#ifndef _rl_isident
-# define _rl_isident(c) (ISALNUM(c) || (c) == '_')
-#endif
-
-#ifndef ISOCTAL
-# define ISOCTAL(c) ((c) >= '0' && (c) <= '7')
-#endif
-#define OCTVALUE(c) ((c) - '0')
-
-#define HEXVALUE(c) \
- (((c) >= 'a' && (c) <= 'f') \
- ? (c)-'a'+10 \
- : (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0')
-
-#ifndef NEWLINE
-#define NEWLINE '\n'
-#endif
-
-#ifndef RETURN
-#define RETURN CTRL('M')
-#endif
-
-#ifndef RUBOUT
-#define RUBOUT 0x7f
-#endif
-
-#ifndef TAB
-#define TAB '\t'
-#endif
-
-#ifdef ABORT_CHAR
-#undef ABORT_CHAR
-#endif
-#define ABORT_CHAR CTRL('G')
-
-#ifdef PAGE
-#undef PAGE
-#endif
-#define PAGE CTRL('L')
-
-#ifdef SPACE
-#undef SPACE
-#endif
-#define SPACE ' ' /* XXX - was 0x20 */
-
-#ifdef ESC
-#undef ESC
-#endif
-#define ESC CTRL('[')
-
-#endif /* _CHARDEFS_H_ */
+/* chardefs.h -- Character definitions for readline. */
+
+/* Copyright (C) 1994 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#ifndef _CHARDEFS_H_
+#define _CHARDEFS_H_
+
+#include <ctype.h>
+
+#if defined (HAVE_STRING_H)
+# if ! defined (STDC_HEADERS) && defined (HAVE_MEMORY_H)
+# include <memory.h>
+# endif
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#if defined (HAVE_STRINGS_H)
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#ifndef whitespace
+#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
+#endif
+
+#ifdef CTRL
+# undef CTRL
+#endif
+#ifdef UNCTRL
+# undef UNCTRL
+#endif
+
+/* Some character stuff. */
+#define control_character_threshold 0x020 /* Smaller than this is control. */
+#define control_character_mask 0x1f /* 0x20 - 1 */
+#define control_character_bit 0x40 /* 0x000000, must be off. */
+
+#if !defined (_WIN32)
+ #define meta_character_threshold 0x07f /* Larger than this is Meta. */
+ #define meta_character_bit 0x080 /* x0000000, must be on. */
+ #define largest_char 255 /* Largest character value. */
+#else /* _WIN32 */
+ #define meta_character_threshold 0x0ff /* Larger than this is Meta. */
+ #define meta_character_bit 0x100 /* x0000000, must be on. */
+ #define largest_char 0x1ff /* Largest character value. */
+#endif /* _WIN32 */
+
+#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0))
+#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char)
+
+#define CTRL(c) ((c) & control_character_mask)
+#define META(c) ((c) | meta_character_bit)
+
+#define UNMETA(c) ((c) & (~meta_character_bit))
+#define UNCTRL(c) _rl_to_upper(((c)|control_character_bit))
+
+#if defined STDC_HEADERS || (!defined (isascii) && !defined (HAVE_ISASCII))
+# define IN_CTYPE_DOMAIN(c) 1
+#else
+# define IN_CTYPE_DOMAIN(c) isascii(c)
+#endif
+
+#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT)
+# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
+#endif
+
+#define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
+
+/* Some systems define these; we want our definitions. */
+#undef ISPRINT
+
+#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c))
+#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
+#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
+#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
+#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
+#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
+#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
+
+#define _rl_lowercase_p(c) (NON_NEGATIVE(c) && ISLOWER(c))
+#define _rl_uppercase_p(c) (NON_NEGATIVE(c) && ISUPPER(c))
+#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
+
+#define _rl_pure_alphabetic(c) (NON_NEGATIVE(c) && ISALPHA(c))
+#define ALPHABETIC(c) (NON_NEGATIVE(c) && ISALNUM(c))
+
+#ifndef _rl_to_upper
+# define _rl_to_upper(c) (_rl_lowercase_p(c) ? toupper((unsigned char)c) : (c))
+# define _rl_to_lower(c) (_rl_uppercase_p(c) ? tolower((unsigned char)c) : (c))
+#endif
+
+#ifndef _rl_digit_value
+# define _rl_digit_value(x) ((x) - '0')
+#endif
+
+#ifndef _rl_isident
+# define _rl_isident(c) (ISALNUM(c) || (c) == '_')
+#endif
+
+#ifndef ISOCTAL
+# define ISOCTAL(c) ((c) >= '0' && (c) <= '7')
+#endif
+#define OCTVALUE(c) ((c) - '0')
+
+#define HEXVALUE(c) \
+ (((c) >= 'a' && (c) <= 'f') \
+ ? (c)-'a'+10 \
+ : (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0')
+
+#ifndef NEWLINE
+#define NEWLINE '\n'
+#endif
+
+#ifndef RETURN
+#define RETURN CTRL('M')
+#endif
+
+#ifndef RUBOUT
+#define RUBOUT 0x7f
+#endif
+
+#ifndef TAB
+#define TAB '\t'
+#endif
+
+#ifdef ABORT_CHAR
+#undef ABORT_CHAR
+#endif
+#define ABORT_CHAR CTRL('G')
+
+#ifdef PAGE
+#undef PAGE
+#endif
+#define PAGE CTRL('L')
+
+#ifdef SPACE
+#undef SPACE
+#endif
+#define SPACE ' ' /* XXX - was 0x20 */
+
+#ifdef ESC
+#undef ESC
+#endif
+#define ESC CTRL('[')
+
+#endif /* _CHARDEFS_H_ */
diff --git a/MSVC/readline/compat.c b/MSVC/readline/compat.c
index 393703f..5e0aec8 100644
--- a/MSVC/readline/compat.c
+++ b/MSVC/readline/compat.c
@@ -1,111 +1,111 @@
-/* compat.c -- backwards compatibility functions. */
-
-/* Copyright (C) 2000 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <stdio.h>
-
-#include "rlstdc.h"
-#include "rltypedefs.h"
-
-extern void rl_free_undo_list PARAMS((void));
-extern int rl_maybe_save_line PARAMS((void));
-extern int rl_maybe_unsave_line PARAMS((void));
-extern int rl_maybe_replace_line PARAMS((void));
-
-extern int rl_crlf PARAMS((void));
-extern int rl_ding PARAMS((void));
-extern int rl_alphabetic PARAMS((int));
-
-extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *));
-extern char *rl_username_completion_function PARAMS((const char *, int));
-extern char *rl_filename_completion_function PARAMS((const char *, int));
-
-/* Provide backwards-compatible entry points for old function names. */
-
-void
-free_undo_list ()
-{
- rl_free_undo_list ();
-}
-
-int
-maybe_replace_line ()
-{
- return rl_maybe_replace_line ();
-}
-
-int
-maybe_save_line ()
-{
- return rl_maybe_save_line ();
-}
-
-int
-maybe_unsave_line ()
-{
- return rl_maybe_unsave_line ();
-}
-
-int
-ding ()
-{
- return rl_ding ();
-}
-
-int
-crlf ()
-{
- return rl_crlf ();
-}
-
-int
-alphabetic (c)
- int c;
-{
- return rl_alphabetic (c);
-}
-
-char **
-completion_matches (s, f)
- const char *s;
- rl_compentry_func_t *f;
-{
- return rl_completion_matches (s, f);
-}
-
-char *
-username_completion_function (s, i)
- const char *s;
- int i;
-{
- return rl_username_completion_function (s, i);
-}
-
-char *
-filename_completion_function (s, i)
- const char *s;
- int i;
-{
- return rl_filename_completion_function (s, i);
-}
+/* compat.c -- backwards compatibility functions. */
+
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include "rlstdc.h"
+#include "rltypedefs.h"
+
+extern void rl_free_undo_list PARAMS((void));
+extern int rl_maybe_save_line PARAMS((void));
+extern int rl_maybe_unsave_line PARAMS((void));
+extern int rl_maybe_replace_line PARAMS((void));
+
+extern int rl_crlf PARAMS((void));
+extern int rl_ding PARAMS((void));
+extern int rl_alphabetic PARAMS((int));
+
+extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *));
+extern char *rl_username_completion_function PARAMS((const char *, int));
+extern char *rl_filename_completion_function PARAMS((const char *, int));
+
+/* Provide backwards-compatible entry points for old function names. */
+
+void
+free_undo_list ()
+{
+ rl_free_undo_list ();
+}
+
+int
+maybe_replace_line ()
+{
+ return rl_maybe_replace_line ();
+}
+
+int
+maybe_save_line ()
+{
+ return rl_maybe_save_line ();
+}
+
+int
+maybe_unsave_line ()
+{
+ return rl_maybe_unsave_line ();
+}
+
+int
+ding ()
+{
+ return rl_ding ();
+}
+
+int
+crlf ()
+{
+ return rl_crlf ();
+}
+
+int
+alphabetic (c)
+ int c;
+{
+ return rl_alphabetic (c);
+}
+
+char **
+completion_matches (s, f)
+ const char *s;
+ rl_compentry_func_t *f;
+{
+ return rl_completion_matches (s, f);
+}
+
+char *
+username_completion_function (s, i)
+ const char *s;
+ int i;
+{
+ return rl_username_completion_function (s, i);
+}
+
+char *
+filename_completion_function (s, i)
+ const char *s;
+ int i;
+{
+ return rl_filename_completion_function (s, i);
+}
diff --git a/MSVC/readline/complete.c b/MSVC/readline/complete.c
index 336f6f9..0d918a1 100644
--- a/MSVC/readline/complete.c
+++ b/MSVC/readline/complete.c
@@ -1,2004 +1,2004 @@
-/* complete.c -- filename completion for readline. */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <fcntl.h>
-#if defined (HAVE_SYS_FILE_H)
-#include <sys/file.h>
-#endif
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-
-#include <errno.h>
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-#if !defined _WIN32
-#include <pwd.h>
-#endif
-
-#include "posixdir.h"
-#include "posixstat.h"
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "xmalloc.h"
-#include "rlprivate.h"
-
-#if defined __STDC__ || defined _MSC_VER
-typedef int QSFUNC (const void *, const void *);
-#else
-typedef int QSFUNC ();
-#endif
-
-#ifdef HAVE_LSTAT
-# define LSTAT lstat
-#else
-# define LSTAT stat
-#endif
-
-/* Unix version of a hidden file. Could be different on other systems. */
-#define HIDDEN_FILE(fname) ((fname)[0] == '.')
-
-/* Most systems don't declare getpwent in <pwd.h> if _POSIX_SOURCE is
- defined. */
-#if !defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE)
-extern struct passwd *getpwent PARAMS((void));
-#endif /* !HAVE_GETPW_DECLS || _POSIX_SOURCE */
-
-/* If non-zero, then this is the address of a function to call when
- completing a word would normally display the list of possible matches.
- This function is called instead of actually doing the display.
- It takes three arguments: (char **matches, int num_matches, int max_length)
- where MATCHES is the array of strings that matched, NUM_MATCHES is the
- number of strings in that array, and MAX_LENGTH is the length of the
- longest string in that array. */
-rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)NULL;
-
-#if defined (VISIBLE_STATS)
-# if !defined (X_OK)
-# define X_OK 1
-# endif
-static int stat_char PARAMS((char *));
-#endif
-
-static char *rl_quote_filename PARAMS((char *, int, char *));
-
-static void set_completion_defaults PARAMS((int));
-static int get_y_or_n PARAMS((int));
-static int _rl_internal_pager PARAMS((int));
-static char *printable_part PARAMS((char *));
-static int print_filename PARAMS((char *, char *));
-
-static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
-
-static char **remove_duplicate_matches PARAMS((char **));
-static void insert_match PARAMS((char *, int, int, char *));
-static int append_to_match PARAMS((char *, int, int, int));
-static void insert_all_matches PARAMS((char **, int, char *));
-static void display_matches PARAMS((char **));
-static int compute_lcd_of_matches PARAMS((char **, int, const char *));
-static int postprocess_matches PARAMS((char ***, int));
-
-static char *make_quoted_replacement PARAMS((char *, int, char *));
-
-/* **************************************************************** */
-/* */
-/* Completion matching, from readline's point of view. */
-/* */
-/* **************************************************************** */
-
-/* Variables known only to the readline library. */
-
-/* If non-zero, non-unique completions always show the list of matches. */
-int _rl_complete_show_all = 0;
-
-/* If non-zero, completed directory names have a slash appended. */
-int _rl_complete_mark_directories = 1;
-
-/* If non-zero, the symlinked directory completion behavior introduced in
- readline-4.2a is disabled, and symlinks that point to directories have
- a slash appended (subject to the value of _rl_complete_mark_directories).
- This is user-settable via the mark-symlinked-directories variable. */
-int _rl_complete_mark_symlink_dirs = 0;
-
-/* If non-zero, completions are printed horizontally in alphabetical order,
- like `ls -x'. */
-int _rl_print_completions_horizontally;
-
-/* Non-zero means that case is not significant in filename completion. */
-#if defined (__MSDOS__) && !defined (__DJGPP__)
-int _rl_completion_case_fold = 1;
-#else
-int _rl_completion_case_fold;
-#endif
-
-/* If non-zero, don't match hidden files (filenames beginning with a `.' on
- Unix) when doing filename completion. */
-int _rl_match_hidden_files = 1;
-
-/* Global variables available to applications using readline. */
-
-#if defined (VISIBLE_STATS)
-/* Non-zero means add an additional character to each filename displayed
- during listing completion iff rl_filename_completion_desired which helps
- to indicate the type of file being listed. */
-int rl_visible_stats = 0;
-#endif /* VISIBLE_STATS */
-
-/* If non-zero, then this is the address of a function to call when
- completing on a directory name. The function is called with
- the address of a string (the current directory name) as an arg. */
-rl_icppfunc_t *rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
-
-rl_icppfunc_t *rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
-
-/* Non-zero means readline completion functions perform tilde expansion. */
-int rl_complete_with_tilde_expansion = 0;
-
-/* Pointer to the generator function for completion_matches ().
- NULL means to use rl_filename_completion_function (), the default filename
- completer. */
-rl_compentry_func_t *rl_completion_entry_function = (rl_compentry_func_t *)NULL;
-
-/* Pointer to alternative function to create matches.
- Function is called with TEXT, START, and END.
- START and END are indices in RL_LINE_BUFFER saying what the boundaries
- of TEXT are.
- If this function exists and returns NULL then call the value of
- rl_completion_entry_function to try to match, otherwise use the
- array of strings returned. */
-rl_completion_func_t *rl_attempted_completion_function = (rl_completion_func_t *)NULL;
-
-/* Non-zero means to suppress normal filename completion after the
- user-specified completion function has been called. */
-int rl_attempted_completion_over = 0;
-
-/* Set to a character indicating the type of completion being performed
- by rl_complete_internal, available for use by application completion
- functions. */
-int rl_completion_type = 0;
-
-/* Up to this many items will be displayed in response to a
- possible-completions call. After that, we ask the user if
- she is sure she wants to see them all. */
-int rl_completion_query_items = 100;
-
-int _rl_page_completions = 1;
-
-/* The basic list of characters that signal a break between words for the
- completer routine. The contents of this variable is what breaks words
- in the shell, i.e. " \t\n\"\\'`@$><=" */
-const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; /* }) */
-
-/* List of basic quoting characters. */
-const char *rl_basic_quote_characters = "\"'";
-
-/* The list of characters that signal a break between words for
- rl_complete_internal. The default list is the contents of
- rl_basic_word_break_characters. */
-const char *rl_completer_word_break_characters = (const char *)NULL;
-
-/* List of characters which can be used to quote a substring of the line.
- Completion occurs on the entire substring, and within the substring
- rl_completer_word_break_characters are treated as any other character,
- unless they also appear within this list. */
-const char *rl_completer_quote_characters = (const char *)NULL;
-
-/* List of characters that should be quoted in filenames by the completer. */
-const char *rl_filename_quote_characters = (const char *)NULL;
-
-/* List of characters that are word break characters, but should be left
- in TEXT when it is passed to the completion function. The shell uses
- this to help determine what kind of completing to do. */
-const char *rl_special_prefixes = (const char *)NULL;
-
-/* If non-zero, then disallow duplicates in the matches. */
-int rl_ignore_completion_duplicates = 1;
-
-/* Non-zero means that the results of the matches are to be treated
- as filenames. This is ALWAYS zero on entry, and can only be changed
- within a completion entry finder function. */
-int rl_filename_completion_desired = 0;
-
-/* Non-zero means that the results of the matches are to be quoted using
- double quotes (or an application-specific quoting mechanism) if the
- filename contains any characters in rl_filename_quote_chars. This is
- ALWAYS non-zero on entry, and can only be changed within a completion
- entry finder function. */
-int rl_filename_quoting_desired = 1;
-
-/* This function, if defined, is called by the completer when real
- filename completion is done, after all the matching names have been
- generated. It is passed a (char**) known as matches in the code below.
- It consists of a NULL-terminated array of pointers to potential
- matching strings. The 1st element (matches[0]) is the maximal
- substring that is common to all matches. This function can re-arrange
- the list of matches as required, but all elements of the array must be
- free()'d if they are deleted. The main intent of this function is
- to implement FIGNORE a la SunOS csh. */
-rl_compignore_func_t *rl_ignore_some_completions_function = (rl_compignore_func_t *)NULL;
-
-/* Set to a function to quote a filename in an application-specific fashion.
- Called with the text to quote, the type of match found (single or multiple)
- and a pointer to the quoting character to be used, which the function can
- reset if desired. */
-rl_quote_func_t *rl_filename_quoting_function = rl_quote_filename;
-
-/* Function to call to remove quoting characters from a filename. Called
- before completion is attempted, so the embedded quotes do not interfere
- with matching names in the file system. Readline doesn't do anything
- with this; it's set only by applications. */
-rl_dequote_func_t *rl_filename_dequoting_function = (rl_dequote_func_t *)NULL;
-
-/* Function to call to decide whether or not a word break character is
- quoted. If a character is quoted, it does not break words for the
- completer. */
-rl_linebuf_func_t *rl_char_is_quoted_p = (rl_linebuf_func_t *)NULL;
-
-/* If non-zero, the completion functions don't append anything except a
- possible closing quote. This is set to 0 by rl_complete_internal and
- may be changed by an application-specific completion function. */
-int rl_completion_suppress_append = 0;
-
-/* Character appended to completed words when at the end of the line. The
- default is a space. */
-int rl_completion_append_character = ' ';
-
-/* If non-zero, a slash will be appended to completed filenames that are
- symbolic links to directory names, subject to the value of the
- mark-directories variable (which is user-settable). This exists so
- that application completion functions can override the user's preference
- (set via the mark-symlinked-directories variable) if appropriate.
- It's set to the value of _rl_complete_mark_symlink_dirs in
- rl_complete_internal before any application-specific completion
- function is called, so without that function doing anything, the user's
- preferences are honored. */
-int rl_completion_mark_symlink_dirs;
-
-/* If non-zero, inhibit completion (temporarily). */
-int rl_inhibit_completion;
-
-/* Variables local to this file. */
-
-/* Local variable states what happened during the last completion attempt. */
-static int completion_changed_buffer;
-
-/*************************************/
-/* */
-/* Bindable completion functions */
-/* */
-/*************************************/
-
-/* Complete the word at or before point. You have supplied the function
- that does the initial simple matching selection algorithm (see
- rl_completion_matches ()). The default is to do filename completion. */
-int
-rl_complete (ignore, invoking_key)
- int ignore, invoking_key;
-{
- if (rl_inhibit_completion)
- return (_rl_insert_char (ignore, invoking_key));
- else if (rl_last_func == rl_complete && !completion_changed_buffer)
- return (rl_complete_internal ('?'));
- else if (_rl_complete_show_all)
- return (rl_complete_internal ('!'));
- else
- return (rl_complete_internal (TAB));
-}
-
-/* List the possible completions. See description of rl_complete (). */
-int
-rl_possible_completions (ignore, invoking_key)
- int ignore, invoking_key;
-{
- return (rl_complete_internal ('?'));
-}
-
-int
-rl_insert_completions (ignore, invoking_key)
- int ignore, invoking_key;
-{
- return (rl_complete_internal ('*'));
-}
-
-/* Return the correct value to pass to rl_complete_internal performing
- the same tests as rl_complete. This allows consecutive calls to an
- application's completion function to list possible completions and for
- an application-specific completion function to honor the
- show-all-if-ambiguous readline variable. */
-int
-rl_completion_mode (cfunc)
- rl_command_func_t *cfunc;
-{
- if (rl_last_func == cfunc && !completion_changed_buffer)
- return '?';
- else if (_rl_complete_show_all)
- return '!';
- else
- return TAB;
-}
-
-/************************************/
-/* */
-/* Completion utility functions */
-/* */
-/************************************/
-
-/* Set default values for readline word completion. These are the variables
- that application completion functions can change or inspect. */
-static void
-set_completion_defaults (what_to_do)
- int what_to_do;
-{
- /* Only the completion entry function can change these. */
- rl_filename_completion_desired = 0;
- rl_filename_quoting_desired = 1;
- rl_completion_type = what_to_do;
- rl_completion_suppress_append = 0;
-
- /* The completion entry function may optionally change this. */
- rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
-}
-
-/* The user must press "y" or "n". Non-zero return means "y" pressed. */
-static int
-get_y_or_n (for_pager)
- int for_pager;
-{
- int c;
-
- for (;;)
- {
- RL_SETSTATE(RL_STATE_MOREINPUT);
- c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
- if (c == 'y' || c == 'Y' || c == ' ')
- return (1);
- if (c == 'n' || c == 'N' || c == RUBOUT)
- return (0);
- if (c == ABORT_CHAR)
- _rl_abort_internal ();
- if (for_pager && (c == NEWLINE || c == RETURN))
- return (2);
- if (for_pager && (c == 'q' || c == 'Q'))
- return (0);
- rl_ding ();
- }
-}
-
-static int
-_rl_internal_pager (lines)
- int lines;
-{
- int i;
-
- fprintf (rl_outstream, "--More--");
- fflush (rl_outstream);
- i = get_y_or_n (1);
- _rl_erase_entire_line ();
- if (i == 0)
- return -1;
- else if (i == 2)
- return (lines - 1);
- else
- return 0;
-}
-
-#if defined (VISIBLE_STATS)
-/* Return the character which best describes FILENAME.
- `@' for symbolic links
- `/' for directories
- `*' for executables
- `=' for sockets
- `|' for FIFOs
- `%' for character special devices
- `#' for block special devices */
-static int
-stat_char (filename)
- char *filename;
-{
- struct stat finfo;
- int character, r;
-
-#if defined (HAVE_LSTAT) && defined (S_ISLNK)
- r = lstat (filename, &finfo);
-#else
- r = stat (filename, &finfo);
-#endif
-
- if (r == -1)
- return (0);
-
- character = 0;
- if (S_ISDIR (finfo.st_mode))
- character = '/';
-#if defined (S_ISCHR)
- else if (S_ISCHR (finfo.st_mode))
- character = '%';
-#endif /* S_ISCHR */
-#if defined (S_ISBLK)
- else if (S_ISBLK (finfo.st_mode))
- character = '#';
-#endif /* S_ISBLK */
-#if defined (S_ISLNK)
- else if (S_ISLNK (finfo.st_mode))
- character = '@';
-#endif /* S_ISLNK */
-#if defined (S_ISSOCK)
- else if (S_ISSOCK (finfo.st_mode))
- character = '=';
-#endif /* S_ISSOCK */
-#if defined (S_ISFIFO)
- else if (S_ISFIFO (finfo.st_mode))
- character = '|';
-#endif
- else if (S_ISREG (finfo.st_mode))
- {
- if (access (filename, X_OK) == 0)
- character = '*';
- }
- return (character);
-}
-#endif /* VISIBLE_STATS */
-
-/* Return the portion of PATHNAME that should be output when listing
- possible completions. If we are hacking filename completion, we
- are only interested in the basename, the portion following the
- final slash. Otherwise, we return what we were passed. Since
- printing empty strings is not very informative, if we're doing
- filename completion, and the basename is the empty string, we look
- for the previous slash and return the portion following that. If
- there's no previous slash, we just return what we were passed. */
-static char *
-printable_part (pathname)
- char *pathname;
-{
- char *temp, *x;
-
- if (rl_filename_completion_desired == 0) /* don't need to do anything */
- return (pathname);
-
- temp = strrchr (pathname, '/');
-#if defined (__MSDOS__)
- if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':')
- temp = pathname + 1;
-#endif
-
- if (temp == 0 || *temp == '\0')
- return (pathname);
- /* If the basename is NULL, we might have a pathname like '/usr/src/'.
- Look for a previous slash and, if one is found, return the portion
- following that slash. If there's no previous slash, just return the
- pathname we were passed. */
- else if (temp[1] == '\0')
- {
- for (x = temp - 1; x > pathname; x--)
- if (*x == '/')
- break;
- return ((*x == '/') ? x + 1 : pathname);
- }
- else
- return ++temp;
-}
-
-/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we
- are using it, check for and output a single character for `special'
- filenames. Return the number of characters we output. */
-
-#define PUTX(c) \
- do { \
- if (CTRL_CHAR (c)) \
- { \
- putc ('^', rl_outstream); \
- putc (UNCTRL (c), rl_outstream); \
- printed_len += 2; \
- } \
- else if (c == RUBOUT) \
- { \
- putc ('^', rl_outstream); \
- putc ('?', rl_outstream); \
- printed_len += 2; \
- } \
- else \
- { \
- putc (c, rl_outstream); \
- printed_len++; \
- } \
- } while (0)
-
-static int
-print_filename (to_print, full_pathname)
- char *to_print, *full_pathname;
-{
- int printed_len = 0;
-#if !defined (VISIBLE_STATS)
- char *s;
-
- for (s = to_print; *s; s++)
- {
- PUTX (*s);
- }
-#else
- char *s, c, *new_full_pathname;
- int extension_char, slen, tlen;
-
- for (s = to_print; *s; s++)
- {
- PUTX (*s);
- }
-
- if (rl_filename_completion_desired && rl_visible_stats)
- {
- /* If to_print != full_pathname, to_print is the basename of the
- path passed. In this case, we try to expand the directory
- name before checking for the stat character. */
- if (to_print != full_pathname)
- {
- /* Terminate the directory name. */
- c = to_print[-1];
- to_print[-1] = '\0';
-
- /* If setting the last slash in full_pathname to a NUL results in
- full_pathname being the empty string, we are trying to complete
- files in the root directory. If we pass a null string to the
- bash directory completion hook, for example, it will expand it
- to the current directory. We just want the `/'. */
- s = tilde_expand (full_pathname && *full_pathname ? full_pathname : "/");
- if (rl_directory_completion_hook)
- (*rl_directory_completion_hook) (&s);
-
- slen = strlen (s);
- tlen = strlen (to_print);
- new_full_pathname = (char *)xmalloc (slen + tlen + 2);
- strcpy (new_full_pathname, s);
- new_full_pathname[slen] = '/';
- strcpy (new_full_pathname + slen + 1, to_print);
-
- extension_char = stat_char (new_full_pathname);
-
- free (new_full_pathname);
- to_print[-1] = c;
- }
- else
- {
- s = tilde_expand (full_pathname);
- extension_char = stat_char (s);
- }
-
- free (s);
- if (extension_char)
- {
- putc (extension_char, rl_outstream);
- printed_len++;
- }
- }
-#endif /* VISIBLE_STATS */
- return printed_len;
-}
-
-static char *
-rl_quote_filename (s, rtype, qcp)
- char *s;
- int rtype;
- char *qcp;
-{
- char *r;
-
- r = (char *)xmalloc (strlen (s) + 2);
- *r = *rl_completer_quote_characters;
- strcpy (r + 1, s);
- if (qcp)
- *qcp = *rl_completer_quote_characters;
- return r;
-}
-
-/* Find the bounds of the current word for completion purposes, and leave
- rl_point set to the end of the word. This function skips quoted
- substrings (characters between matched pairs of characters in
- rl_completer_quote_characters). First we try to find an unclosed
- quoted substring on which to do matching. If one is not found, we use
- the word break characters to find the boundaries of the current word.
- We call an application-specific function to decide whether or not a
- particular word break character is quoted; if that function returns a
- non-zero result, the character does not break a word. This function
- returns the opening quote character if we found an unclosed quoted
- substring, '\0' otherwise. FP, if non-null, is set to a value saying
- which (shell-like) quote characters we found (single quote, double
- quote, or backslash) anywhere in the string. DP, if non-null, is set to
- the value of the delimiter character that caused a word break. */
-
-char
-_rl_find_completion_word (fp, dp)
- int *fp, *dp;
-{
- int scan, end, found_quote, delimiter, pass_next, isbrk;
- char quote_char;
-
- end = rl_point;
- found_quote = delimiter = 0;
- quote_char = '\0';
-
- if (rl_completer_quote_characters)
- {
- /* We have a list of characters which can be used in pairs to
- quote substrings for the completer. Try to find the start
- of an unclosed quoted substring. */
- /* FOUND_QUOTE is set so we know what kind of quotes we found. */
- for (scan = pass_next = 0; scan < end; scan++)
- {
- if (pass_next)
- {
- pass_next = 0;
- continue;
- }
-
- /* Shell-like semantics for single quotes -- don't allow backslash
- to quote anything in single quotes, especially not the closing
- quote. If you don't like this, take out the check on the value
- of quote_char. */
- if (quote_char != '\'' && rl_line_buffer[scan] == '\\')
- {
- pass_next = 1;
- found_quote |= RL_QF_BACKSLASH;
- continue;
- }
-
- if (quote_char != '\0')
- {
- /* Ignore everything until the matching close quote char. */
- if (rl_line_buffer[scan] == quote_char)
- {
- /* Found matching close. Abandon this substring. */
- quote_char = '\0';
- rl_point = end;
- }
- }
- else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan]))
- {
- /* Found start of a quoted substring. */
- quote_char = rl_line_buffer[scan];
- rl_point = scan + 1;
- /* Shell-like quoting conventions. */
- if (quote_char == '\'')
- found_quote |= RL_QF_SINGLE_QUOTE;
- else if (quote_char == '"')
- found_quote |= RL_QF_DOUBLE_QUOTE;
- else
- found_quote |= RL_QF_OTHER_QUOTE;
- }
- }
- }
-
- if (rl_point == end && quote_char == '\0')
- {
- /* We didn't find an unclosed quoted substring upon which to do
- completion, so use the word break characters to find the
- substring on which to complete. */
-#if defined (HANDLE_MULTIBYTE)
- while (rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_ANY))
-#else
- while (--rl_point)
-#endif
- {
- scan = rl_line_buffer[rl_point];
-
- if (strchr (rl_completer_word_break_characters, scan) == 0)
- continue;
-
- /* Call the application-specific function to tell us whether
- this word break character is quoted and should be skipped. */
- if (rl_char_is_quoted_p && found_quote &&
- (*rl_char_is_quoted_p) (rl_line_buffer, rl_point))
- continue;
-
- /* Convoluted code, but it avoids an n^2 algorithm with calls
- to char_is_quoted. */
- break;
- }
- }
-
- /* If we are at an unquoted word break, then advance past it. */
- scan = rl_line_buffer[rl_point];
-
- /* If there is an application-specific function to say whether or not
- a character is quoted and we found a quote character, let that
- function decide whether or not a character is a word break, even
- if it is found in rl_completer_word_break_characters. Don't bother
- if we're at the end of the line, though. */
- if (scan)
- {
- if (rl_char_is_quoted_p)
- isbrk = (found_quote == 0 ||
- (*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
- strchr (rl_completer_word_break_characters, scan) != 0;
- else
- isbrk = strchr (rl_completer_word_break_characters, scan) != 0;
-
- if (isbrk)
- {
- /* If the character that caused the word break was a quoting
- character, then remember it as the delimiter. */
- if (rl_basic_quote_characters &&
- strchr (rl_basic_quote_characters, scan) &&
- (end - rl_point) > 1)
- delimiter = scan;
-
- /* If the character isn't needed to determine something special
- about what kind of completion to perform, then advance past it. */
- if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0)
- rl_point++;
- }
- }
-
- if (fp)
- *fp = found_quote;
- if (dp)
- *dp = delimiter;
-
- return (quote_char);
-}
-
-static char **
-gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
- char *text;
- int start, end;
- rl_compentry_func_t *our_func;
- int found_quote, quote_char;
-{
- char **matches, *temp;
-
- /* If the user wants to TRY to complete, but then wants to give
- up and use the default completion function, they set the
- variable rl_attempted_completion_function. */
- if (rl_attempted_completion_function)
- {
- matches = (*rl_attempted_completion_function) (text, start, end);
-
- if (matches || rl_attempted_completion_over)
- {
- rl_attempted_completion_over = 0;
- return (matches);
- }
- }
-
- /* Beware -- we're stripping the quotes here. Do this only if we know
- we are doing filename completion and the application has defined a
- filename dequoting function. */
- temp = (char *)NULL;
-
- if (found_quote && our_func == rl_filename_completion_function &&
- rl_filename_dequoting_function)
- {
- /* delete single and double quotes */
- temp = (*rl_filename_dequoting_function) (text, quote_char);
- text = temp; /* not freeing text is not a memory leak */
- }
-
- matches = rl_completion_matches (text, our_func);
- FREE (temp);
- return matches;
-}
-
-/* Filter out duplicates in MATCHES. This frees up the strings in
- MATCHES. */
-static char **
-remove_duplicate_matches (matches)
- char **matches;
-{
- char *lowest_common;
- int i, j, newlen;
- char dead_slot;
- char **temp_array;
-
- /* Sort the items. */
- for (i = 0; matches[i]; i++)
- ;
-
- /* Sort the array without matches[0], since we need it to
- stay in place no matter what. */
- if (i)
- qsort (matches+1, i-1, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
-
- /* Remember the lowest common denominator for it may be unique. */
- lowest_common = savestring (matches[0]);
-
- for (i = newlen = 0; matches[i + 1]; i++)
- {
- if (strcmp (matches[i], matches[i + 1]) == 0)
- {
- free (matches[i]);
- matches[i] = (char *)&dead_slot;
- }
- else
- newlen++;
- }
-
- /* We have marked all the dead slots with (char *)&dead_slot.
- Copy all the non-dead entries into a new array. */
- temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *));
- for (i = j = 1; matches[i]; i++)
- {
- if (matches[i] != (char *)&dead_slot)
- temp_array[j++] = matches[i];
- }
- temp_array[j] = (char *)NULL;
-
- if (matches[0] != (char *)&dead_slot)
- free (matches[0]);
-
- /* Place the lowest common denominator back in [0]. */
- temp_array[0] = lowest_common;
-
- /* If there is one string left, and it is identical to the
- lowest common denominator, then the LCD is the string to
- insert. */
- if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0)
- {
- free (temp_array[1]);
- temp_array[1] = (char *)NULL;
- }
- return (temp_array);
-}
-
-/* Find the common prefix of the list of matches, and put it into
- matches[0]. */
-static int
-compute_lcd_of_matches (match_list, matches, text)
- char **match_list;
- int matches;
- const char *text;
-{
- register int i, c1, c2, si;
- int low; /* Count of max-matched characters. */
-#if defined (HANDLE_MULTIBYTE)
- int v;
- mbstate_t ps1, ps2;
- wchar_t wc1, wc2;
-#endif
-
- /* If only one match, just use that. Otherwise, compare each
- member of the list with the next, finding out where they
- stop matching. */
- if (matches == 1)
- {
- match_list[0] = match_list[1];
- match_list[1] = (char *)NULL;
- return 1;
- }
-
- for (i = 1, low = 100000; i < matches; i++)
- {
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- memset (&ps1, 0, sizeof (mbstate_t));
- memset (&ps2, 0, sizeof (mbstate_t));
- }
-#endif
- if (_rl_completion_case_fold)
- {
- for (si = 0;
- (c1 = _rl_to_lower(match_list[i][si])) &&
- (c2 = _rl_to_lower(match_list[i + 1][si]));
- si++)
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- v = mbrtowc (&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1);
- mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2);
- wc1 = towlower (wc1);
- wc2 = towlower (wc2);
- if (wc1 != wc2)
- break;
- else if (v > 1)
- si += v - 1;
- }
- else
-#endif
- if (c1 != c2)
- break;
- }
- else
- {
- for (si = 0;
- (c1 = match_list[i][si]) &&
- (c2 = match_list[i + 1][si]);
- si++)
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- mbstate_t ps_back = ps1;
- if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2))
- break;
- else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1)
- si += v - 1;
- }
- else
-#endif
- if (c1 != c2)
- break;
- }
-
- if (low > si)
- low = si;
- }
-
- /* If there were multiple matches, but none matched up to even the
- first character, and the user typed something, use that as the
- value of matches[0]. */
- if (low == 0 && text && *text)
- {
- match_list[0] = (char *)xmalloc (strlen (text) + 1);
- strcpy (match_list[0], text);
- }
- else
- {
- match_list[0] = (char *)xmalloc (low + 1);
-
- /* XXX - this might need changes in the presence of multibyte chars */
-
- /* If we are ignoring case, try to preserve the case of the string
- the user typed in the face of multiple matches differing in case. */
- if (_rl_completion_case_fold)
- {
- /* sort the list to get consistent answers. */
- qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
-
- si = strlen (text);
- if (si <= low)
- {
- for (i = 1; i <= matches; i++)
- if (strncmp (match_list[i], text, si) == 0)
- {
- strncpy (match_list[0], match_list[i], low);
- break;
- }
- /* no casematch, use first entry */
- if (i > matches)
- strncpy (match_list[0], match_list[1], low);
- }
- else
- /* otherwise, just use the text the user typed. */
- strncpy (match_list[0], text, low);
- }
- else
- strncpy (match_list[0], match_list[1], low);
-
- match_list[0][low] = '\0';
- }
-
- return matches;
-}
-
-static int
-postprocess_matches (matchesp, matching_filenames)
- char ***matchesp;
- int matching_filenames;
-{
- char *t, **matches, **temp_matches;
- int nmatch, i;
-
- matches = *matchesp;
-
- if (matches == 0)
- return 0;
-
- /* It seems to me that in all the cases we handle we would like
- to ignore duplicate possiblilities. Scan for the text to
- insert being identical to the other completions. */
- if (rl_ignore_completion_duplicates)
- {
- temp_matches = remove_duplicate_matches (matches);
- free (matches);
- matches = temp_matches;
- }
-
- /* If we are matching filenames, then here is our chance to
- do clever processing by re-examining the list. Call the
- ignore function with the array as a parameter. It can
- munge the array, deleting matches as it desires. */
- if (rl_ignore_some_completions_function && matching_filenames)
- {
- for (nmatch = 1; matches[nmatch]; nmatch++)
- ;
- (void)(*rl_ignore_some_completions_function) (matches);
- if (matches == 0 || matches[0] == 0)
- {
- FREE (matches);
- *matchesp = (char **)0;
- return 0;
- }
- else
- {
- /* If we removed some matches, recompute the common prefix. */
- for (i = 1; matches[i]; i++)
- ;
- if (i > 1 && i < nmatch)
- {
- t = matches[0];
- compute_lcd_of_matches (matches, i - 1, t);
- FREE (t);
- }
- }
- }
-
- *matchesp = matches;
- return (1);
-}
-
-/* A convenience function for displaying a list of strings in
- columnar format on readline's output stream. MATCHES is the list
- of strings, in argv format, LEN is the number of strings in MATCHES,
- and MAX is the length of the longest string in MATCHES. */
-void
-rl_display_match_list (matches, len, max)
- char **matches;
- int len, max;
-{
- int count, limit, printed_len, lines;
- int i, j, k, l;
- char *temp;
-
- /* How many items of MAX length can we fit in the screen window? */
- max += 2;
- limit = _rl_screenwidth / max;
- if (limit != 1 && (limit * max == _rl_screenwidth))
- limit--;
-
- /* Avoid a possible floating exception. If max > _rl_screenwidth,
- limit will be 0 and a divide-by-zero fault will result. */
- if (limit == 0)
- limit = 1;
-
- /* How many iterations of the printing loop? */
- count = (len + (limit - 1)) / limit;
-
- /* Watch out for special case. If LEN is less than LIMIT, then
- just do the inner printing loop.
- 0 < len <= limit implies count = 1. */
-
- /* Sort the items if they are not already sorted. */
- if (rl_ignore_completion_duplicates == 0)
- qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
-
- rl_crlf ();
-
- lines = 0;
- if (_rl_print_completions_horizontally == 0)
- {
- /* Print the sorted items, up-and-down alphabetically, like ls. */
- for (i = 1; i <= count; i++)
- {
- for (j = 0, l = i; j < limit; j++)
- {
- if (l > len || matches[l] == 0)
- break;
- else
- {
- temp = printable_part (matches[l]);
- printed_len = print_filename (temp, matches[l]);
-
- if (j + 1 < limit)
- for (k = 0; k < max - printed_len; k++)
- putc (' ', rl_outstream);
- }
- l += count;
- }
- rl_crlf ();
- lines++;
- if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count)
- {
- lines = _rl_internal_pager (lines);
- if (lines < 0)
- return;
- }
- }
- }
- else
- {
- /* Print the sorted items, across alphabetically, like ls -x. */
- for (i = 1; matches[i]; i++)
- {
- temp = printable_part (matches[i]);
- printed_len = print_filename (temp, matches[i]);
- /* Have we reached the end of this line? */
- if (matches[i+1])
- {
- if (i && (limit > 1) && (i % limit) == 0)
- {
- rl_crlf ();
- lines++;
- if (_rl_page_completions && lines >= _rl_screenheight - 1)
- {
- lines = _rl_internal_pager (lines);
- if (lines < 0)
- return;
- }
- }
- else
- for (k = 0; k < max - printed_len; k++)
- putc (' ', rl_outstream);
- }
- }
- rl_crlf ();
- }
-}
-
-/* Display MATCHES, a list of matching filenames in argv format. This
- handles the simple case -- a single match -- first. If there is more
- than one match, we compute the number of strings in the list and the
- length of the longest string, which will be needed by the display
- function. If the application wants to handle displaying the list of
- matches itself, it sets RL_COMPLETION_DISPLAY_MATCHES_HOOK to the
- address of a function, and we just call it. If we're handling the
- display ourselves, we just call rl_display_match_list. We also check
- that the list of matches doesn't exceed the user-settable threshold,
- and ask the user if he wants to see the list if there are more matches
- than RL_COMPLETION_QUERY_ITEMS. */
-static void
-display_matches (matches)
- char **matches;
-{
- int len, max, i;
- char *temp;
-
- /* Move to the last visible line of a possibly-multiple-line command. */
- _rl_move_vert (_rl_vis_botlin);
-
- /* Handle simple case first. What if there is only one answer? */
- if (matches[1] == 0)
- {
- temp = printable_part (matches[0]);
- rl_crlf ();
- print_filename (temp, matches[0]);
- rl_crlf ();
-
- rl_forced_update_display ();
- rl_display_fixed = 1;
-
- return;
- }
-
- /* There is more than one answer. Find out how many there are,
- and find the maximum printed length of a single entry. */
- for (max = 0, i = 1; matches[i]; i++)
- {
- temp = printable_part (matches[i]);
- len = strlen (temp);
-
- if (len > max)
- max = len;
- }
-
- len = i - 1;
-
- /* If the caller has defined a display hook, then call that now. */
- if (rl_completion_display_matches_hook)
- {
- (*rl_completion_display_matches_hook) (matches, len, max);
- return;
- }
-
- /* If there are many items, then ask the user if she really wants to
- see them all. */
- if (len >= rl_completion_query_items)
- {
- rl_crlf ();
- fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
- fflush (rl_outstream);
- if (get_y_or_n (0) == 0)
- {
- rl_crlf ();
-
- rl_forced_update_display ();
- rl_display_fixed = 1;
-
- return;
- }
- }
-
- rl_display_match_list (matches, len, max);
-
- rl_forced_update_display ();
- rl_display_fixed = 1;
-}
-
-static char *
-make_quoted_replacement (match, mtype, qc)
- char *match;
- int mtype;
- char *qc; /* Pointer to quoting character, if any */
-{
- int should_quote, do_replace;
- char *replacement;
-
- /* If we are doing completion on quoted substrings, and any matches
- contain any of the completer_word_break_characters, then auto-
- matically prepend the substring with a quote character (just pick
- the first one from the list of such) if it does not already begin
- with a quote string. FIXME: Need to remove any such automatically
- inserted quote character when it no longer is necessary, such as
- if we change the string we are completing on and the new set of
- matches don't require a quoted substring. */
- replacement = match;
-
- should_quote = match && rl_completer_quote_characters &&
- rl_filename_completion_desired &&
- rl_filename_quoting_desired;
-
- if (should_quote)
- should_quote = should_quote && (!qc || !*qc ||
- (rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc)));
-
- if (should_quote)
- {
- /* If there is a single match, see if we need to quote it.
- This also checks whether the common prefix of several
- matches needs to be quoted. */
- should_quote = rl_filename_quote_characters
- ? (_rl_strpbrk (match, rl_filename_quote_characters) != 0)
- : 0;
-
- do_replace = should_quote ? mtype : NO_MATCH;
- /* Quote the replacement, since we found an embedded
- word break character in a potential match. */
- if (do_replace != NO_MATCH && rl_filename_quoting_function)
- replacement = (*rl_filename_quoting_function) (match, do_replace, qc);
- }
- return (replacement);
-}
-
-static void
-insert_match (match, start, mtype, qc)
- char *match;
- int start, mtype;
- char *qc;
-{
- char *replacement;
- char oqc;
-
- oqc = qc ? *qc : '\0';
- replacement = make_quoted_replacement (match, mtype, qc);
-
- /* Now insert the match. */
- if (replacement)
- {
- /* Don't double an opening quote character. */
- if (qc && *qc && start && rl_line_buffer[start - 1] == *qc &&
- replacement[0] == *qc)
- start--;
- /* If make_quoted_replacement changed the quoting character, remove
- the opening quote and insert the (fully-quoted) replacement. */
- else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc &&
- replacement[0] != oqc)
- start--;
- _rl_replace_text (replacement, start, rl_point - 1);
- if (replacement != match)
- free (replacement);
- }
-}
-
-/* Append any necessary closing quote and a separator character to the
- just-inserted match. If the user has specified that directories
- should be marked by a trailing `/', append one of those instead. The
- default trailing character is a space. Returns the number of characters
- appended. If NONTRIVIAL_MATCH is set, we test for a symlink (if the OS
- has them) and don't add a suffix for a symlink to a directory. A
- nontrivial match is one that actually adds to the word being completed.
- The variable rl_completion_mark_symlink_dirs controls this behavior
- (it's initially set to the what the user has chosen, indicated by the
- value of _rl_complete_mark_symlink_dirs, but may be modified by an
- application's completion function). */
-static int
-append_to_match (text, delimiter, quote_char, nontrivial_match)
- char *text;
- int delimiter, quote_char, nontrivial_match;
-{
- char temp_string[4], *filename;
- int temp_string_index, s;
- struct stat finfo;
-
- temp_string_index = 0;
- if (quote_char && rl_point && rl_line_buffer[rl_point - 1] != quote_char)
- temp_string[temp_string_index++] = quote_char;
-
- if (delimiter)
- temp_string[temp_string_index++] = delimiter;
- else if (rl_completion_suppress_append == 0 && rl_completion_append_character)
- temp_string[temp_string_index++] = rl_completion_append_character;
-
- temp_string[temp_string_index++] = '\0';
-
- if (rl_filename_completion_desired)
- {
- filename = tilde_expand (text);
- s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0)
- ? LSTAT (filename, &finfo)
- : stat (filename, &finfo);
- if (s == 0 && S_ISDIR (finfo.st_mode))
- {
- if (_rl_complete_mark_directories)
- {
- /* This is clumsy. Avoid putting in a double slash if point
- is at the end of the line and the previous character is a
- slash. */
- if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/')
- ;
- else if (rl_line_buffer[rl_point] != '/')
- rl_insert_text ("/");
- }
- }
-#ifdef S_ISLNK
- /* Don't add anything if the filename is a symlink and resolves to a
- directory. */
- else if (s == 0 && S_ISLNK (finfo.st_mode) &&
- stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode))
- ;
-#endif
- else
- {
- if (rl_point == rl_end && temp_string_index)
- rl_insert_text (temp_string);
- }
- free (filename);
- }
- else
- {
- if (rl_point == rl_end && temp_string_index)
- rl_insert_text (temp_string);
- }
-
- return (temp_string_index);
-}
-
-static void
-insert_all_matches (matches, point, qc)
- char **matches;
- int point;
- char *qc;
-{
- int i;
- char *rp;
-
- rl_begin_undo_group ();
- /* remove any opening quote character; make_quoted_replacement will add
- it back. */
- if (qc && *qc && point && rl_line_buffer[point - 1] == *qc)
- point--;
- rl_delete_text (point, rl_point);
- rl_point = point;
-
- if (matches[1])
- {
- for (i = 1; matches[i]; i++)
- {
- rp = make_quoted_replacement (matches[i], SINGLE_MATCH, qc);
- rl_insert_text (rp);
- rl_insert_text (" ");
- if (rp != matches[i])
- free (rp);
- }
- }
- else
- {
- rp = make_quoted_replacement (matches[0], SINGLE_MATCH, qc);
- rl_insert_text (rp);
- rl_insert_text (" ");
- if (rp != matches[0])
- free (rp);
- }
- rl_end_undo_group ();
-}
-
-void
-_rl_free_match_list (matches)
- char **matches;
-{
- register int i;
-
- if (matches == 0)
- return;
-
- for (i = 0; matches[i]; i++)
- free (matches[i]);
- free (matches);
-}
-
-/* Complete the word at or before point.
- WHAT_TO_DO says what to do with the completion.
- `?' means list the possible completions.
- TAB means do standard completion.
- `*' means insert all of the possible completions.
- `!' means to do standard completion, and list all possible completions if
- there is more than one. */
-int
-rl_complete_internal (what_to_do)
- int what_to_do;
-{
- char **matches;
- rl_compentry_func_t *our_func;
- int start, end, delimiter, found_quote, i, nontrivial_lcd;
- char *text, *saved_line_buffer;
- char quote_char;
-
- RL_SETSTATE(RL_STATE_COMPLETING);
-
- set_completion_defaults (what_to_do);
-
- saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL;
- our_func = rl_completion_entry_function
- ? rl_completion_entry_function
- : rl_filename_completion_function;
-
- /* We now look backwards for the start of a filename/variable word. */
- end = rl_point;
- found_quote = delimiter = 0;
- quote_char = '\0';
-
- if (rl_point)
- /* This (possibly) changes rl_point. If it returns a non-zero char,
- we know we have an open quote. */
- quote_char = _rl_find_completion_word (&found_quote, &delimiter);
-
- start = rl_point;
- rl_point = end;
-
- text = rl_copy_text (start, end);
- matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char);
- /* nontrivial_lcd is set if the common prefix adds something to the word
- being completed. */
- nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
- free (text);
-
- if (matches == 0)
- {
- rl_ding ();
- FREE (saved_line_buffer);
- completion_changed_buffer = 0;
- RL_UNSETSTATE(RL_STATE_COMPLETING);
- return (0);
- }
-
- /* If we are matching filenames, the attempted completion function will
- have set rl_filename_completion_desired to a non-zero value. The basic
- rl_filename_completion_function does this. */
- i = rl_filename_completion_desired;
-
- if (postprocess_matches (&matches, i) == 0)
- {
- rl_ding ();
- FREE (saved_line_buffer);
- completion_changed_buffer = 0;
- RL_UNSETSTATE(RL_STATE_COMPLETING);
- return (0);
- }
-
- switch (what_to_do)
- {
- case TAB:
- case '!':
- /* Insert the first match with proper quoting. */
- if (*matches[0])
- insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
-
- /* If there are more matches, ring the bell to indicate.
- If we are in vi mode, Posix.2 says to not ring the bell.
- If the `show-all-if-ambiguous' variable is set, display
- all the matches immediately. Otherwise, if this was the
- only match, and we are hacking files, check the file to
- see if it was a directory. If so, and the `mark-directories'
- variable is set, add a '/' to the name. If not, and we
- are at the end of the line, then add a space. */
- if (matches[1])
- {
- if (what_to_do == '!')
- {
- display_matches (matches);
- break;
- }
- else if (rl_editing_mode != vi_mode)
- rl_ding (); /* There are other matches remaining. */
- }
- else
- append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
-
- break;
-
- case '*':
- insert_all_matches (matches, start, &quote_char);
- break;
-
- case '?':
- display_matches (matches);
- break;
-
- default:
- fprintf (stderr, "\r\nreadline: bad value %d for what_to_do in rl_complete\n", what_to_do);
- rl_ding ();
- FREE (saved_line_buffer);
- RL_UNSETSTATE(RL_STATE_COMPLETING);
- return 1;
- }
-
- _rl_free_match_list (matches);
-
- /* Check to see if the line has changed through all of this manipulation. */
- if (saved_line_buffer)
- {
- completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0;
- free (saved_line_buffer);
- }
-
- RL_UNSETSTATE(RL_STATE_COMPLETING);
- return 0;
-}
-
-/***************************************************************/
-/* */
-/* Application-callable completion match generator functions */
-/* */
-/***************************************************************/
-
-/* Return an array of (char *) which is a list of completions for TEXT.
- If there are no completions, return a NULL pointer.
- The first entry in the returned array is the substitution for TEXT.
- The remaining entries are the possible completions.
- The array is terminated with a NULL pointer.
-
- ENTRY_FUNCTION is a function of two args, and returns a (char *).
- The first argument is TEXT.
- The second is a state argument; it should be zero on the first call, and
- non-zero on subsequent calls. It returns a NULL pointer to the caller
- when there are no more matches.
- */
-char **
-rl_completion_matches (text, entry_function)
- const char *text;
- rl_compentry_func_t *entry_function;
-{
- /* Number of slots in match_list. */
- int match_list_size;
-
- /* The list of matches. */
- char **match_list;
-
- /* Number of matches actually found. */
- int matches;
-
- /* Temporary string binder. */
- char *string;
-
- matches = 0;
- match_list_size = 10;
- match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));
- match_list[1] = (char *)NULL;
-
- while (string = (*entry_function) (text, matches))
- {
- if (matches + 1 == match_list_size)
- match_list = (char **)xrealloc
- (match_list, ((match_list_size += 10) + 1) * sizeof (char *));
-
- match_list[++matches] = string;
- match_list[matches + 1] = (char *)NULL;
- }
-
- /* If there were any matches, then look through them finding out the
- lowest common denominator. That then becomes match_list[0]. */
- if (matches)
- compute_lcd_of_matches (match_list, matches, text);
- else /* There were no matches. */
- {
- free (match_list);
- match_list = (char **)NULL;
- }
- return (match_list);
-}
-
-/* A completion function for usernames.
- TEXT contains a partial username preceded by a random
- character (usually `~'). */
-char *
-rl_username_completion_function (text, state)
- const char *text;
- int state;
-{
-#if defined _WIN32 || defined __OPENNT
- return (char *)NULL;
-#else /* !_WIN32 && !__OPENNT */
- static char *username = (char *)NULL;
- static struct passwd *entry;
- static int namelen, first_char, first_char_loc;
- char *value;
-
- if (state == 0)
- {
- FREE (username);
-
- first_char = *text;
- first_char_loc = first_char == '~';
-
- username = savestring (&text[first_char_loc]);
- namelen = strlen (username);
- setpwent ();
- }
-
- while (entry = getpwent ())
- {
- /* Null usernames should result in all users as possible completions. */
- if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))
- break;
- }
-
- if (entry == 0)
- {
- endpwent ();
- return ((char *)NULL);
- }
- else
- {
- value = (char *)xmalloc (2 + strlen (entry->pw_name));
-
- *value = *text;
-
- strcpy (value + first_char_loc, entry->pw_name);
-
- if (first_char == '~')
- rl_filename_completion_desired = 1;
-
- return (value);
- }
-#endif /* !_WIN32 && !__OPENNT */
-}
-
-/* Okay, now we write the entry_function for filename completion. In the
- general case. Note that completion in the shell is a little different
- because of all the pathnames that must be followed when looking up the
- completion for a command. */
-char *
-rl_filename_completion_function (text, state)
- const char *text;
- int state;
-{
- static DIR *directory = (DIR *)NULL;
- static char *filename = (char *)NULL;
- static char *dirname = (char *)NULL;
- static char *users_dirname = (char *)NULL;
- static int filename_len;
- char *temp;
- int dirlen;
- struct dirent *entry;
-
- /* If we don't have any state, then do some initialization. */
- if (state == 0)
- {
- /* If we were interrupted before closing the directory or reading
- all of its contents, close it. */
- if (directory)
- {
- closedir (directory);
- directory = (DIR *)NULL;
- }
- FREE (dirname);
- FREE (filename);
- FREE (users_dirname);
-
- filename = savestring (text);
- if (*text == 0)
- text = ".";
- dirname = savestring (text);
-
- temp = strrchr (dirname, '/');
-
-#if defined (__MSDOS__)
- /* special hack for //X/... */
- if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/')
- temp = strrchr (dirname + 3, '/');
-#endif
-
- if (temp)
- {
- strcpy (filename, ++temp);
- *temp = '\0';
- }
-#if defined (__MSDOS__)
- /* searches from current directory on the drive */
- else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':')
- {
- strcpy (filename, dirname + 2);
- dirname[2] = '\0';
- }
-#endif
- else
- {
- dirname[0] = '.';
- dirname[1] = '\0';
- }
-
- /* We aren't done yet. We also support the "~user" syntax. */
-
- /* Save the version of the directory that the user typed. */
- users_dirname = savestring (dirname);
-
- if (*dirname == '~')
- {
- temp = tilde_expand (dirname);
- free (dirname);
- dirname = temp;
- }
-
- if (rl_directory_rewrite_hook)
- (*rl_directory_rewrite_hook) (&dirname);
-
- if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))
- {
- free (users_dirname);
- users_dirname = savestring (dirname);
- }
-
- directory = opendir (dirname);
- filename_len = strlen (filename);
-
- rl_filename_completion_desired = 1;
- }
-
- /* At this point we should entertain the possibility of hacking wildcarded
- filenames, like /usr/man/man<WILD>/te<TAB>. If the directory name
- contains globbing characters, then build an array of directories, and
- then map over that list while completing. */
- /* *** UNIMPLEMENTED *** */
-
- /* Now that we have some state, we can read the directory. */
-
- entry = (struct dirent *)NULL;
- while (directory && (entry = readdir (directory)))
- {
- /* Special case for no filename. If the user has disabled the
- `match-hidden-files' variable, skip filenames beginning with `.'.
- All other entries except "." and ".." match. */
- if (filename_len == 0)
- {
- if (_rl_match_hidden_files == 0 && HIDDEN_FILE (entry->d_name))
- continue;
-
- if (entry->d_name[0] != '.' ||
- (entry->d_name[1] &&
- (entry->d_name[1] != '.' || entry->d_name[2])))
- break;
- }
- else
- {
- /* Otherwise, if these match up to the length of filename, then
- it is a match. */
- if (_rl_completion_case_fold)
- {
- if ((_rl_to_lower (entry->d_name[0]) == _rl_to_lower (filename[0])) &&
- (((int)D_NAMLEN (entry)) >= filename_len) &&
- (_rl_strnicmp (filename, entry->d_name, filename_len) == 0))
- break;
- }
- else
- {
- if ((entry->d_name[0] == filename[0]) &&
- (((int)D_NAMLEN (entry)) >= filename_len) &&
- (strncmp (filename, entry->d_name, filename_len) == 0))
- break;
- }
- }
- }
-
- if (entry == 0)
- {
- if (directory)
- {
- closedir (directory);
- directory = (DIR *)NULL;
- }
- if (dirname)
- {
- free (dirname);
- dirname = (char *)NULL;
- }
- if (filename)
- {
- free (filename);
- filename = (char *)NULL;
- }
- if (users_dirname)
- {
- free (users_dirname);
- users_dirname = (char *)NULL;
- }
-
- return (char *)NULL;
- }
- else
- {
- /* dirname && (strcmp (dirname, ".") != 0) */
- if (dirname && (dirname[0] != '.' || dirname[1]))
- {
- if (rl_complete_with_tilde_expansion && *users_dirname == '~')
- {
- dirlen = strlen (dirname);
- temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
- strcpy (temp, dirname);
- /* Canonicalization cuts off any final slash present. We
- may need to add it back. */
- if (dirname[dirlen - 1] != '/')
- {
- temp[dirlen++] = '/';
- temp[dirlen] = '\0';
- }
- }
- else
- {
- dirlen = strlen (users_dirname);
- temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
- strcpy (temp, users_dirname);
- /* Make sure that temp has a trailing slash here. */
- if (users_dirname[dirlen - 1] != '/')
- temp[dirlen++] = '/';
- }
-
- strcpy (temp + dirlen, entry->d_name);
- }
- else
- temp = savestring (entry->d_name);
-
- return (temp);
- }
-}
-
-/* An initial implementation of a menu completion function a la tcsh. The
- first time (if the last readline command was not rl_menu_complete), we
- generate the list of matches. This code is very similar to the code in
- rl_complete_internal -- there should be a way to combine the two. Then,
- for each item in the list of matches, we insert the match in an undoable
- fashion, with the appropriate character appended (this happens on the
- second and subsequent consecutive calls to rl_menu_complete). When we
- hit the end of the match list, we restore the original unmatched text,
- ring the bell, and reset the counter to zero. */
-int
-rl_menu_complete (count, ignore)
- int count, ignore;
-{
- rl_compentry_func_t *our_func;
- int matching_filenames, found_quote;
-
- static char *orig_text;
- static char **matches = (char **)0;
- static int match_list_index = 0;
- static int match_list_size = 0;
- static int orig_start, orig_end;
- static char quote_char;
- static int delimiter;
-
- /* The first time through, we generate the list of matches and set things
- up to insert them. */
- if (rl_last_func != rl_menu_complete)
- {
- /* Clean up from previous call, if any. */
- FREE (orig_text);
- if (matches)
- _rl_free_match_list (matches);
-
- match_list_index = match_list_size = 0;
- matches = (char **)NULL;
-
- /* Only the completion entry function can change these. */
- set_completion_defaults ('%');
-
- our_func = rl_completion_entry_function
- ? rl_completion_entry_function
- : rl_filename_completion_function;
-
- /* We now look backwards for the start of a filename/variable word. */
- orig_end = rl_point;
- found_quote = delimiter = 0;
- quote_char = '\0';
-
- if (rl_point)
- /* This (possibly) changes rl_point. If it returns a non-zero char,
- we know we have an open quote. */
- quote_char = _rl_find_completion_word (&found_quote, &delimiter);
-
- orig_start = rl_point;
- rl_point = orig_end;
-
- orig_text = rl_copy_text (orig_start, orig_end);
- matches = gen_completion_matches (orig_text, orig_start, orig_end,
- our_func, found_quote, quote_char);
-
- /* If we are matching filenames, the attempted completion function will
- have set rl_filename_completion_desired to a non-zero value. The basic
- rl_filename_completion_function does this. */
- matching_filenames = rl_filename_completion_desired;
-
- if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
- {
- rl_ding ();
- FREE (matches);
- matches = (char **)0;
- FREE (orig_text);
- orig_text = (char *)0;
- completion_changed_buffer = 0;
- return (0);
- }
-
- for (match_list_size = 0; matches[match_list_size]; match_list_size++)
- ;
- /* matches[0] is lcd if match_list_size > 1, but the circular buffer
- code below should take care of it. */
- }
-
- /* Now we have the list of matches. Replace the text between
- rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with
- matches[match_list_index], and add any necessary closing char. */
-
- if (matches == 0 || match_list_size == 0)
- {
- rl_ding ();
- FREE (matches);
- matches = (char **)0;
- completion_changed_buffer = 0;
- return (0);
- }
-
- match_list_index = (match_list_index + count) % match_list_size;
- if (match_list_index < 0)
- match_list_index += match_list_size;
-
- if (match_list_index == 0 && match_list_size > 1)
- {
- rl_ding ();
- insert_match (orig_text, orig_start, MULT_MATCH, &quote_char);
- }
- else
- {
- insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, &quote_char);
- append_to_match (matches[match_list_index], delimiter, quote_char,
- strcmp (orig_text, matches[match_list_index]));
- }
-
- completion_changed_buffer = 1;
- return (0);
-}
+/* complete.c -- filename completion for readline. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#if defined (HAVE_SYS_FILE_H)
+#include <sys/file.h>
+#endif
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <stdio.h>
+
+#include <errno.h>
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+#if !defined _WIN32
+#include <pwd.h>
+#endif
+
+#include "posixdir.h"
+#include "posixstat.h"
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+#include "rlmbutil.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "xmalloc.h"
+#include "rlprivate.h"
+
+#if defined __STDC__ || defined _MSC_VER
+typedef int QSFUNC (const void *, const void *);
+#else
+typedef int QSFUNC ();
+#endif
+
+#ifdef HAVE_LSTAT
+# define LSTAT lstat
+#else
+# define LSTAT stat
+#endif
+
+/* Unix version of a hidden file. Could be different on other systems. */
+#define HIDDEN_FILE(fname) ((fname)[0] == '.')
+
+/* Most systems don't declare getpwent in <pwd.h> if _POSIX_SOURCE is
+ defined. */
+#if !defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE)
+extern struct passwd *getpwent PARAMS((void));
+#endif /* !HAVE_GETPW_DECLS || _POSIX_SOURCE */
+
+/* If non-zero, then this is the address of a function to call when
+ completing a word would normally display the list of possible matches.
+ This function is called instead of actually doing the display.
+ It takes three arguments: (char **matches, int num_matches, int max_length)
+ where MATCHES is the array of strings that matched, NUM_MATCHES is the
+ number of strings in that array, and MAX_LENGTH is the length of the
+ longest string in that array. */
+rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)NULL;
+
+#if defined (VISIBLE_STATS)
+# if !defined (X_OK)
+# define X_OK 1
+# endif
+static int stat_char PARAMS((char *));
+#endif
+
+static char *rl_quote_filename PARAMS((char *, int, char *));
+
+static void set_completion_defaults PARAMS((int));
+static int get_y_or_n PARAMS((int));
+static int _rl_internal_pager PARAMS((int));
+static char *printable_part PARAMS((char *));
+static int print_filename PARAMS((char *, char *));
+
+static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
+
+static char **remove_duplicate_matches PARAMS((char **));
+static void insert_match PARAMS((char *, int, int, char *));
+static int append_to_match PARAMS((char *, int, int, int));
+static void insert_all_matches PARAMS((char **, int, char *));
+static void display_matches PARAMS((char **));
+static int compute_lcd_of_matches PARAMS((char **, int, const char *));
+static int postprocess_matches PARAMS((char ***, int));
+
+static char *make_quoted_replacement PARAMS((char *, int, char *));
+
+/* **************************************************************** */
+/* */
+/* Completion matching, from readline's point of view. */
+/* */
+/* **************************************************************** */
+
+/* Variables known only to the readline library. */
+
+/* If non-zero, non-unique completions always show the list of matches. */
+int _rl_complete_show_all = 0;
+
+/* If non-zero, completed directory names have a slash appended. */
+int _rl_complete_mark_directories = 1;
+
+/* If non-zero, the symlinked directory completion behavior introduced in
+ readline-4.2a is disabled, and symlinks that point to directories have
+ a slash appended (subject to the value of _rl_complete_mark_directories).
+ This is user-settable via the mark-symlinked-directories variable. */
+int _rl_complete_mark_symlink_dirs = 0;
+
+/* If non-zero, completions are printed horizontally in alphabetical order,
+ like `ls -x'. */
+int _rl_print_completions_horizontally;
+
+/* Non-zero means that case is not significant in filename completion. */
+#if defined (__MSDOS__) && !defined (__DJGPP__)
+int _rl_completion_case_fold = 1;
+#else
+int _rl_completion_case_fold;
+#endif
+
+/* If non-zero, don't match hidden files (filenames beginning with a `.' on
+ Unix) when doing filename completion. */
+int _rl_match_hidden_files = 1;
+
+/* Global variables available to applications using readline. */
+
+#if defined (VISIBLE_STATS)
+/* Non-zero means add an additional character to each filename displayed
+ during listing completion iff rl_filename_completion_desired which helps
+ to indicate the type of file being listed. */
+int rl_visible_stats = 0;
+#endif /* VISIBLE_STATS */
+
+/* If non-zero, then this is the address of a function to call when
+ completing on a directory name. The function is called with
+ the address of a string (the current directory name) as an arg. */
+rl_icppfunc_t *rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
+
+rl_icppfunc_t *rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
+
+/* Non-zero means readline completion functions perform tilde expansion. */
+int rl_complete_with_tilde_expansion = 0;
+
+/* Pointer to the generator function for completion_matches ().
+ NULL means to use rl_filename_completion_function (), the default filename
+ completer. */
+rl_compentry_func_t *rl_completion_entry_function = (rl_compentry_func_t *)NULL;
+
+/* Pointer to alternative function to create matches.
+ Function is called with TEXT, START, and END.
+ START and END are indices in RL_LINE_BUFFER saying what the boundaries
+ of TEXT are.
+ If this function exists and returns NULL then call the value of
+ rl_completion_entry_function to try to match, otherwise use the
+ array of strings returned. */
+rl_completion_func_t *rl_attempted_completion_function = (rl_completion_func_t *)NULL;
+
+/* Non-zero means to suppress normal filename completion after the
+ user-specified completion function has been called. */
+int rl_attempted_completion_over = 0;
+
+/* Set to a character indicating the type of completion being performed
+ by rl_complete_internal, available for use by application completion
+ functions. */
+int rl_completion_type = 0;
+
+/* Up to this many items will be displayed in response to a
+ possible-completions call. After that, we ask the user if
+ she is sure she wants to see them all. */
+int rl_completion_query_items = 100;
+
+int _rl_page_completions = 1;
+
+/* The basic list of characters that signal a break between words for the
+ completer routine. The contents of this variable is what breaks words
+ in the shell, i.e. " \t\n\"\\'`@$><=" */
+const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; /* }) */
+
+/* List of basic quoting characters. */
+const char *rl_basic_quote_characters = "\"'";
+
+/* The list of characters that signal a break between words for
+ rl_complete_internal. The default list is the contents of
+ rl_basic_word_break_characters. */
+const char *rl_completer_word_break_characters = (const char *)NULL;
+
+/* List of characters which can be used to quote a substring of the line.
+ Completion occurs on the entire substring, and within the substring
+ rl_completer_word_break_characters are treated as any other character,
+ unless they also appear within this list. */
+const char *rl_completer_quote_characters = (const char *)NULL;
+
+/* List of characters that should be quoted in filenames by the completer. */
+const char *rl_filename_quote_characters = (const char *)NULL;
+
+/* List of characters that are word break characters, but should be left
+ in TEXT when it is passed to the completion function. The shell uses
+ this to help determine what kind of completing to do. */
+const char *rl_special_prefixes = (const char *)NULL;
+
+/* If non-zero, then disallow duplicates in the matches. */
+int rl_ignore_completion_duplicates = 1;
+
+/* Non-zero means that the results of the matches are to be treated
+ as filenames. This is ALWAYS zero on entry, and can only be changed
+ within a completion entry finder function. */
+int rl_filename_completion_desired = 0;
+
+/* Non-zero means that the results of the matches are to be quoted using
+ double quotes (or an application-specific quoting mechanism) if the
+ filename contains any characters in rl_filename_quote_chars. This is
+ ALWAYS non-zero on entry, and can only be changed within a completion
+ entry finder function. */
+int rl_filename_quoting_desired = 1;
+
+/* This function, if defined, is called by the completer when real
+ filename completion is done, after all the matching names have been
+ generated. It is passed a (char**) known as matches in the code below.
+ It consists of a NULL-terminated array of pointers to potential
+ matching strings. The 1st element (matches[0]) is the maximal
+ substring that is common to all matches. This function can re-arrange
+ the list of matches as required, but all elements of the array must be
+ free()'d if they are deleted. The main intent of this function is
+ to implement FIGNORE a la SunOS csh. */
+rl_compignore_func_t *rl_ignore_some_completions_function = (rl_compignore_func_t *)NULL;
+
+/* Set to a function to quote a filename in an application-specific fashion.
+ Called with the text to quote, the type of match found (single or multiple)
+ and a pointer to the quoting character to be used, which the function can
+ reset if desired. */
+rl_quote_func_t *rl_filename_quoting_function = rl_quote_filename;
+
+/* Function to call to remove quoting characters from a filename. Called
+ before completion is attempted, so the embedded quotes do not interfere
+ with matching names in the file system. Readline doesn't do anything
+ with this; it's set only by applications. */
+rl_dequote_func_t *rl_filename_dequoting_function = (rl_dequote_func_t *)NULL;
+
+/* Function to call to decide whether or not a word break character is
+ quoted. If a character is quoted, it does not break words for the
+ completer. */
+rl_linebuf_func_t *rl_char_is_quoted_p = (rl_linebuf_func_t *)NULL;
+
+/* If non-zero, the completion functions don't append anything except a
+ possible closing quote. This is set to 0 by rl_complete_internal and
+ may be changed by an application-specific completion function. */
+int rl_completion_suppress_append = 0;
+
+/* Character appended to completed words when at the end of the line. The
+ default is a space. */
+int rl_completion_append_character = ' ';
+
+/* If non-zero, a slash will be appended to completed filenames that are
+ symbolic links to directory names, subject to the value of the
+ mark-directories variable (which is user-settable). This exists so
+ that application completion functions can override the user's preference
+ (set via the mark-symlinked-directories variable) if appropriate.
+ It's set to the value of _rl_complete_mark_symlink_dirs in
+ rl_complete_internal before any application-specific completion
+ function is called, so without that function doing anything, the user's
+ preferences are honored. */
+int rl_completion_mark_symlink_dirs;
+
+/* If non-zero, inhibit completion (temporarily). */
+int rl_inhibit_completion;
+
+/* Variables local to this file. */
+
+/* Local variable states what happened during the last completion attempt. */
+static int completion_changed_buffer;
+
+/*************************************/
+/* */
+/* Bindable completion functions */
+/* */
+/*************************************/
+
+/* Complete the word at or before point. You have supplied the function
+ that does the initial simple matching selection algorithm (see
+ rl_completion_matches ()). The default is to do filename completion. */
+int
+rl_complete (ignore, invoking_key)
+ int ignore, invoking_key;
+{
+ if (rl_inhibit_completion)
+ return (_rl_insert_char (ignore, invoking_key));
+ else if (rl_last_func == rl_complete && !completion_changed_buffer)
+ return (rl_complete_internal ('?'));
+ else if (_rl_complete_show_all)
+ return (rl_complete_internal ('!'));
+ else
+ return (rl_complete_internal (TAB));
+}
+
+/* List the possible completions. See description of rl_complete (). */
+int
+rl_possible_completions (ignore, invoking_key)
+ int ignore, invoking_key;
+{
+ return (rl_complete_internal ('?'));
+}
+
+int
+rl_insert_completions (ignore, invoking_key)
+ int ignore, invoking_key;
+{
+ return (rl_complete_internal ('*'));
+}
+
+/* Return the correct value to pass to rl_complete_internal performing
+ the same tests as rl_complete. This allows consecutive calls to an
+ application's completion function to list possible completions and for
+ an application-specific completion function to honor the
+ show-all-if-ambiguous readline variable. */
+int
+rl_completion_mode (cfunc)
+ rl_command_func_t *cfunc;
+{
+ if (rl_last_func == cfunc && !completion_changed_buffer)
+ return '?';
+ else if (_rl_complete_show_all)
+ return '!';
+ else
+ return TAB;
+}
+
+/************************************/
+/* */
+/* Completion utility functions */
+/* */
+/************************************/
+
+/* Set default values for readline word completion. These are the variables
+ that application completion functions can change or inspect. */
+static void
+set_completion_defaults (what_to_do)
+ int what_to_do;
+{
+ /* Only the completion entry function can change these. */
+ rl_filename_completion_desired = 0;
+ rl_filename_quoting_desired = 1;
+ rl_completion_type = what_to_do;
+ rl_completion_suppress_append = 0;
+
+ /* The completion entry function may optionally change this. */
+ rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
+}
+
+/* The user must press "y" or "n". Non-zero return means "y" pressed. */
+static int
+get_y_or_n (for_pager)
+ int for_pager;
+{
+ int c;
+
+ for (;;)
+ {
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+ if (c == 'y' || c == 'Y' || c == ' ')
+ return (1);
+ if (c == 'n' || c == 'N' || c == RUBOUT)
+ return (0);
+ if (c == ABORT_CHAR)
+ _rl_abort_internal ();
+ if (for_pager && (c == NEWLINE || c == RETURN))
+ return (2);
+ if (for_pager && (c == 'q' || c == 'Q'))
+ return (0);
+ rl_ding ();
+ }
+}
+
+static int
+_rl_internal_pager (lines)
+ int lines;
+{
+ int i;
+
+ fprintf (rl_outstream, "--More--");
+ fflush (rl_outstream);
+ i = get_y_or_n (1);
+ _rl_erase_entire_line ();
+ if (i == 0)
+ return -1;
+ else if (i == 2)
+ return (lines - 1);
+ else
+ return 0;
+}
+
+#if defined (VISIBLE_STATS)
+/* Return the character which best describes FILENAME.
+ `@' for symbolic links
+ `/' for directories
+ `*' for executables
+ `=' for sockets
+ `|' for FIFOs
+ `%' for character special devices
+ `#' for block special devices */
+static int
+stat_char (filename)
+ char *filename;
+{
+ struct stat finfo;
+ int character, r;
+
+#if defined (HAVE_LSTAT) && defined (S_ISLNK)
+ r = lstat (filename, &finfo);
+#else
+ r = stat (filename, &finfo);
+#endif
+
+ if (r == -1)
+ return (0);
+
+ character = 0;
+ if (S_ISDIR (finfo.st_mode))
+ character = '/';
+#if defined (S_ISCHR)
+ else if (S_ISCHR (finfo.st_mode))
+ character = '%';
+#endif /* S_ISCHR */
+#if defined (S_ISBLK)
+ else if (S_ISBLK (finfo.st_mode))
+ character = '#';
+#endif /* S_ISBLK */
+#if defined (S_ISLNK)
+ else if (S_ISLNK (finfo.st_mode))
+ character = '@';
+#endif /* S_ISLNK */
+#if defined (S_ISSOCK)
+ else if (S_ISSOCK (finfo.st_mode))
+ character = '=';
+#endif /* S_ISSOCK */
+#if defined (S_ISFIFO)
+ else if (S_ISFIFO (finfo.st_mode))
+ character = '|';
+#endif
+ else if (S_ISREG (finfo.st_mode))
+ {
+ if (access (filename, X_OK) == 0)
+ character = '*';
+ }
+ return (character);
+}
+#endif /* VISIBLE_STATS */
+
+/* Return the portion of PATHNAME that should be output when listing
+ possible completions. If we are hacking filename completion, we
+ are only interested in the basename, the portion following the
+ final slash. Otherwise, we return what we were passed. Since
+ printing empty strings is not very informative, if we're doing
+ filename completion, and the basename is the empty string, we look
+ for the previous slash and return the portion following that. If
+ there's no previous slash, we just return what we were passed. */
+static char *
+printable_part (pathname)
+ char *pathname;
+{
+ char *temp, *x;
+
+ if (rl_filename_completion_desired == 0) /* don't need to do anything */
+ return (pathname);
+
+ temp = strrchr (pathname, '/');
+#if defined (__MSDOS__)
+ if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':')
+ temp = pathname + 1;
+#endif
+
+ if (temp == 0 || *temp == '\0')
+ return (pathname);
+ /* If the basename is NULL, we might have a pathname like '/usr/src/'.
+ Look for a previous slash and, if one is found, return the portion
+ following that slash. If there's no previous slash, just return the
+ pathname we were passed. */
+ else if (temp[1] == '\0')
+ {
+ for (x = temp - 1; x > pathname; x--)
+ if (*x == '/')
+ break;
+ return ((*x == '/') ? x + 1 : pathname);
+ }
+ else
+ return ++temp;
+}
+
+/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we
+ are using it, check for and output a single character for `special'
+ filenames. Return the number of characters we output. */
+
+#define PUTX(c) \
+ do { \
+ if (CTRL_CHAR (c)) \
+ { \
+ putc ('^', rl_outstream); \
+ putc (UNCTRL (c), rl_outstream); \
+ printed_len += 2; \
+ } \
+ else if (c == RUBOUT) \
+ { \
+ putc ('^', rl_outstream); \
+ putc ('?', rl_outstream); \
+ printed_len += 2; \
+ } \
+ else \
+ { \
+ putc (c, rl_outstream); \
+ printed_len++; \
+ } \
+ } while (0)
+
+static int
+print_filename (to_print, full_pathname)
+ char *to_print, *full_pathname;
+{
+ int printed_len = 0;
+#if !defined (VISIBLE_STATS)
+ char *s;
+
+ for (s = to_print; *s; s++)
+ {
+ PUTX (*s);
+ }
+#else
+ char *s, c, *new_full_pathname;
+ int extension_char, slen, tlen;
+
+ for (s = to_print; *s; s++)
+ {
+ PUTX (*s);
+ }
+
+ if (rl_filename_completion_desired && rl_visible_stats)
+ {
+ /* If to_print != full_pathname, to_print is the basename of the
+ path passed. In this case, we try to expand the directory
+ name before checking for the stat character. */
+ if (to_print != full_pathname)
+ {
+ /* Terminate the directory name. */
+ c = to_print[-1];
+ to_print[-1] = '\0';
+
+ /* If setting the last slash in full_pathname to a NUL results in
+ full_pathname being the empty string, we are trying to complete
+ files in the root directory. If we pass a null string to the
+ bash directory completion hook, for example, it will expand it
+ to the current directory. We just want the `/'. */
+ s = tilde_expand (full_pathname && *full_pathname ? full_pathname : "/");
+ if (rl_directory_completion_hook)
+ (*rl_directory_completion_hook) (&s);
+
+ slen = strlen (s);
+ tlen = strlen (to_print);
+ new_full_pathname = (char *)xmalloc (slen + tlen + 2);
+ strcpy (new_full_pathname, s);
+ new_full_pathname[slen] = '/';
+ strcpy (new_full_pathname + slen + 1, to_print);
+
+ extension_char = stat_char (new_full_pathname);
+
+ free (new_full_pathname);
+ to_print[-1] = c;
+ }
+ else
+ {
+ s = tilde_expand (full_pathname);
+ extension_char = stat_char (s);
+ }
+
+ free (s);
+ if (extension_char)
+ {
+ putc (extension_char, rl_outstream);
+ printed_len++;
+ }
+ }
+#endif /* VISIBLE_STATS */
+ return printed_len;
+}
+
+static char *
+rl_quote_filename (s, rtype, qcp)
+ char *s;
+ int rtype;
+ char *qcp;
+{
+ char *r;
+
+ r = (char *)xmalloc (strlen (s) + 2);
+ *r = *rl_completer_quote_characters;
+ strcpy (r + 1, s);
+ if (qcp)
+ *qcp = *rl_completer_quote_characters;
+ return r;
+}
+
+/* Find the bounds of the current word for completion purposes, and leave
+ rl_point set to the end of the word. This function skips quoted
+ substrings (characters between matched pairs of characters in
+ rl_completer_quote_characters). First we try to find an unclosed
+ quoted substring on which to do matching. If one is not found, we use
+ the word break characters to find the boundaries of the current word.
+ We call an application-specific function to decide whether or not a
+ particular word break character is quoted; if that function returns a
+ non-zero result, the character does not break a word. This function
+ returns the opening quote character if we found an unclosed quoted
+ substring, '\0' otherwise. FP, if non-null, is set to a value saying
+ which (shell-like) quote characters we found (single quote, double
+ quote, or backslash) anywhere in the string. DP, if non-null, is set to
+ the value of the delimiter character that caused a word break. */
+
+char
+_rl_find_completion_word (fp, dp)
+ int *fp, *dp;
+{
+ int scan, end, found_quote, delimiter, pass_next, isbrk;
+ char quote_char;
+
+ end = rl_point;
+ found_quote = delimiter = 0;
+ quote_char = '\0';
+
+ if (rl_completer_quote_characters)
+ {
+ /* We have a list of characters which can be used in pairs to
+ quote substrings for the completer. Try to find the start
+ of an unclosed quoted substring. */
+ /* FOUND_QUOTE is set so we know what kind of quotes we found. */
+ for (scan = pass_next = 0; scan < end; scan++)
+ {
+ if (pass_next)
+ {
+ pass_next = 0;
+ continue;
+ }
+
+ /* Shell-like semantics for single quotes -- don't allow backslash
+ to quote anything in single quotes, especially not the closing
+ quote. If you don't like this, take out the check on the value
+ of quote_char. */
+ if (quote_char != '\'' && rl_line_buffer[scan] == '\\')
+ {
+ pass_next = 1;
+ found_quote |= RL_QF_BACKSLASH;
+ continue;
+ }
+
+ if (quote_char != '\0')
+ {
+ /* Ignore everything until the matching close quote char. */
+ if (rl_line_buffer[scan] == quote_char)
+ {
+ /* Found matching close. Abandon this substring. */
+ quote_char = '\0';
+ rl_point = end;
+ }
+ }
+ else if (strchr (rl_completer_quote_characters, rl_line_buffer[scan]))
+ {
+ /* Found start of a quoted substring. */
+ quote_char = rl_line_buffer[scan];
+ rl_point = scan + 1;
+ /* Shell-like quoting conventions. */
+ if (quote_char == '\'')
+ found_quote |= RL_QF_SINGLE_QUOTE;
+ else if (quote_char == '"')
+ found_quote |= RL_QF_DOUBLE_QUOTE;
+ else
+ found_quote |= RL_QF_OTHER_QUOTE;
+ }
+ }
+ }
+
+ if (rl_point == end && quote_char == '\0')
+ {
+ /* We didn't find an unclosed quoted substring upon which to do
+ completion, so use the word break characters to find the
+ substring on which to complete. */
+#if defined (HANDLE_MULTIBYTE)
+ while (rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_ANY))
+#else
+ while (--rl_point)
+#endif
+ {
+ scan = rl_line_buffer[rl_point];
+
+ if (strchr (rl_completer_word_break_characters, scan) == 0)
+ continue;
+
+ /* Call the application-specific function to tell us whether
+ this word break character is quoted and should be skipped. */
+ if (rl_char_is_quoted_p && found_quote &&
+ (*rl_char_is_quoted_p) (rl_line_buffer, rl_point))
+ continue;
+
+ /* Convoluted code, but it avoids an n^2 algorithm with calls
+ to char_is_quoted. */
+ break;
+ }
+ }
+
+ /* If we are at an unquoted word break, then advance past it. */
+ scan = rl_line_buffer[rl_point];
+
+ /* If there is an application-specific function to say whether or not
+ a character is quoted and we found a quote character, let that
+ function decide whether or not a character is a word break, even
+ if it is found in rl_completer_word_break_characters. Don't bother
+ if we're at the end of the line, though. */
+ if (scan)
+ {
+ if (rl_char_is_quoted_p)
+ isbrk = (found_quote == 0 ||
+ (*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
+ strchr (rl_completer_word_break_characters, scan) != 0;
+ else
+ isbrk = strchr (rl_completer_word_break_characters, scan) != 0;
+
+ if (isbrk)
+ {
+ /* If the character that caused the word break was a quoting
+ character, then remember it as the delimiter. */
+ if (rl_basic_quote_characters &&
+ strchr (rl_basic_quote_characters, scan) &&
+ (end - rl_point) > 1)
+ delimiter = scan;
+
+ /* If the character isn't needed to determine something special
+ about what kind of completion to perform, then advance past it. */
+ if (rl_special_prefixes == 0 || strchr (rl_special_prefixes, scan) == 0)
+ rl_point++;
+ }
+ }
+
+ if (fp)
+ *fp = found_quote;
+ if (dp)
+ *dp = delimiter;
+
+ return (quote_char);
+}
+
+static char **
+gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
+ char *text;
+ int start, end;
+ rl_compentry_func_t *our_func;
+ int found_quote, quote_char;
+{
+ char **matches, *temp;
+
+ /* If the user wants to TRY to complete, but then wants to give
+ up and use the default completion function, they set the
+ variable rl_attempted_completion_function. */
+ if (rl_attempted_completion_function)
+ {
+ matches = (*rl_attempted_completion_function) (text, start, end);
+
+ if (matches || rl_attempted_completion_over)
+ {
+ rl_attempted_completion_over = 0;
+ return (matches);
+ }
+ }
+
+ /* Beware -- we're stripping the quotes here. Do this only if we know
+ we are doing filename completion and the application has defined a
+ filename dequoting function. */
+ temp = (char *)NULL;
+
+ if (found_quote && our_func == rl_filename_completion_function &&
+ rl_filename_dequoting_function)
+ {
+ /* delete single and double quotes */
+ temp = (*rl_filename_dequoting_function) (text, quote_char);
+ text = temp; /* not freeing text is not a memory leak */
+ }
+
+ matches = rl_completion_matches (text, our_func);
+ FREE (temp);
+ return matches;
+}
+
+/* Filter out duplicates in MATCHES. This frees up the strings in
+ MATCHES. */
+static char **
+remove_duplicate_matches (matches)
+ char **matches;
+{
+ char *lowest_common;
+ int i, j, newlen;
+ char dead_slot;
+ char **temp_array;
+
+ /* Sort the items. */
+ for (i = 0; matches[i]; i++)
+ ;
+
+ /* Sort the array without matches[0], since we need it to
+ stay in place no matter what. */
+ if (i)
+ qsort (matches+1, i-1, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
+
+ /* Remember the lowest common denominator for it may be unique. */
+ lowest_common = savestring (matches[0]);
+
+ for (i = newlen = 0; matches[i + 1]; i++)
+ {
+ if (strcmp (matches[i], matches[i + 1]) == 0)
+ {
+ free (matches[i]);
+ matches[i] = (char *)&dead_slot;
+ }
+ else
+ newlen++;
+ }
+
+ /* We have marked all the dead slots with (char *)&dead_slot.
+ Copy all the non-dead entries into a new array. */
+ temp_array = (char **)xmalloc ((3 + newlen) * sizeof (char *));
+ for (i = j = 1; matches[i]; i++)
+ {
+ if (matches[i] != (char *)&dead_slot)
+ temp_array[j++] = matches[i];
+ }
+ temp_array[j] = (char *)NULL;
+
+ if (matches[0] != (char *)&dead_slot)
+ free (matches[0]);
+
+ /* Place the lowest common denominator back in [0]. */
+ temp_array[0] = lowest_common;
+
+ /* If there is one string left, and it is identical to the
+ lowest common denominator, then the LCD is the string to
+ insert. */
+ if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0)
+ {
+ free (temp_array[1]);
+ temp_array[1] = (char *)NULL;
+ }
+ return (temp_array);
+}
+
+/* Find the common prefix of the list of matches, and put it into
+ matches[0]. */
+static int
+compute_lcd_of_matches (match_list, matches, text)
+ char **match_list;
+ int matches;
+ const char *text;
+{
+ register int i, c1, c2, si;
+ int low; /* Count of max-matched characters. */
+#if defined (HANDLE_MULTIBYTE)
+ int v;
+ mbstate_t ps1, ps2;
+ wchar_t wc1, wc2;
+#endif
+
+ /* If only one match, just use that. Otherwise, compare each
+ member of the list with the next, finding out where they
+ stop matching. */
+ if (matches == 1)
+ {
+ match_list[0] = match_list[1];
+ match_list[1] = (char *)NULL;
+ return 1;
+ }
+
+ for (i = 1, low = 100000; i < matches; i++)
+ {
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ memset (&ps1, 0, sizeof (mbstate_t));
+ memset (&ps2, 0, sizeof (mbstate_t));
+ }
+#endif
+ if (_rl_completion_case_fold)
+ {
+ for (si = 0;
+ (c1 = _rl_to_lower(match_list[i][si])) &&
+ (c2 = _rl_to_lower(match_list[i + 1][si]));
+ si++)
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ v = mbrtowc (&wc1, match_list[i]+si, strlen (match_list[i]+si), &ps1);
+ mbrtowc (&wc2, match_list[i+1]+si, strlen (match_list[i+1]+si), &ps2);
+ wc1 = towlower (wc1);
+ wc2 = towlower (wc2);
+ if (wc1 != wc2)
+ break;
+ else if (v > 1)
+ si += v - 1;
+ }
+ else
+#endif
+ if (c1 != c2)
+ break;
+ }
+ else
+ {
+ for (si = 0;
+ (c1 = match_list[i][si]) &&
+ (c2 = match_list[i + 1][si]);
+ si++)
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ mbstate_t ps_back = ps1;
+ if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2))
+ break;
+ else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1)
+ si += v - 1;
+ }
+ else
+#endif
+ if (c1 != c2)
+ break;
+ }
+
+ if (low > si)
+ low = si;
+ }
+
+ /* If there were multiple matches, but none matched up to even the
+ first character, and the user typed something, use that as the
+ value of matches[0]. */
+ if (low == 0 && text && *text)
+ {
+ match_list[0] = (char *)xmalloc (strlen (text) + 1);
+ strcpy (match_list[0], text);
+ }
+ else
+ {
+ match_list[0] = (char *)xmalloc (low + 1);
+
+ /* XXX - this might need changes in the presence of multibyte chars */
+
+ /* If we are ignoring case, try to preserve the case of the string
+ the user typed in the face of multiple matches differing in case. */
+ if (_rl_completion_case_fold)
+ {
+ /* sort the list to get consistent answers. */
+ qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
+
+ si = strlen (text);
+ if (si <= low)
+ {
+ for (i = 1; i <= matches; i++)
+ if (strncmp (match_list[i], text, si) == 0)
+ {
+ strncpy (match_list[0], match_list[i], low);
+ break;
+ }
+ /* no casematch, use first entry */
+ if (i > matches)
+ strncpy (match_list[0], match_list[1], low);
+ }
+ else
+ /* otherwise, just use the text the user typed. */
+ strncpy (match_list[0], text, low);
+ }
+ else
+ strncpy (match_list[0], match_list[1], low);
+
+ match_list[0][low] = '\0';
+ }
+
+ return matches;
+}
+
+static int
+postprocess_matches (matchesp, matching_filenames)
+ char ***matchesp;
+ int matching_filenames;
+{
+ char *t, **matches, **temp_matches;
+ int nmatch, i;
+
+ matches = *matchesp;
+
+ if (matches == 0)
+ return 0;
+
+ /* It seems to me that in all the cases we handle we would like
+ to ignore duplicate possiblilities. Scan for the text to
+ insert being identical to the other completions. */
+ if (rl_ignore_completion_duplicates)
+ {
+ temp_matches = remove_duplicate_matches (matches);
+ free (matches);
+ matches = temp_matches;
+ }
+
+ /* If we are matching filenames, then here is our chance to
+ do clever processing by re-examining the list. Call the
+ ignore function with the array as a parameter. It can
+ munge the array, deleting matches as it desires. */
+ if (rl_ignore_some_completions_function && matching_filenames)
+ {
+ for (nmatch = 1; matches[nmatch]; nmatch++)
+ ;
+ (void)(*rl_ignore_some_completions_function) (matches);
+ if (matches == 0 || matches[0] == 0)
+ {
+ FREE (matches);
+ *matchesp = (char **)0;
+ return 0;
+ }
+ else
+ {
+ /* If we removed some matches, recompute the common prefix. */
+ for (i = 1; matches[i]; i++)
+ ;
+ if (i > 1 && i < nmatch)
+ {
+ t = matches[0];
+ compute_lcd_of_matches (matches, i - 1, t);
+ FREE (t);
+ }
+ }
+ }
+
+ *matchesp = matches;
+ return (1);
+}
+
+/* A convenience function for displaying a list of strings in
+ columnar format on readline's output stream. MATCHES is the list
+ of strings, in argv format, LEN is the number of strings in MATCHES,
+ and MAX is the length of the longest string in MATCHES. */
+void
+rl_display_match_list (matches, len, max)
+ char **matches;
+ int len, max;
+{
+ int count, limit, printed_len, lines;
+ int i, j, k, l;
+ char *temp;
+
+ /* How many items of MAX length can we fit in the screen window? */
+ max += 2;
+ limit = _rl_screenwidth / max;
+ if (limit != 1 && (limit * max == _rl_screenwidth))
+ limit--;
+
+ /* Avoid a possible floating exception. If max > _rl_screenwidth,
+ limit will be 0 and a divide-by-zero fault will result. */
+ if (limit == 0)
+ limit = 1;
+
+ /* How many iterations of the printing loop? */
+ count = (len + (limit - 1)) / limit;
+
+ /* Watch out for special case. If LEN is less than LIMIT, then
+ just do the inner printing loop.
+ 0 < len <= limit implies count = 1. */
+
+ /* Sort the items if they are not already sorted. */
+ if (rl_ignore_completion_duplicates == 0)
+ qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
+
+ rl_crlf ();
+
+ lines = 0;
+ if (_rl_print_completions_horizontally == 0)
+ {
+ /* Print the sorted items, up-and-down alphabetically, like ls. */
+ for (i = 1; i <= count; i++)
+ {
+ for (j = 0, l = i; j < limit; j++)
+ {
+ if (l > len || matches[l] == 0)
+ break;
+ else
+ {
+ temp = printable_part (matches[l]);
+ printed_len = print_filename (temp, matches[l]);
+
+ if (j + 1 < limit)
+ for (k = 0; k < max - printed_len; k++)
+ putc (' ', rl_outstream);
+ }
+ l += count;
+ }
+ rl_crlf ();
+ lines++;
+ if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count)
+ {
+ lines = _rl_internal_pager (lines);
+ if (lines < 0)
+ return;
+ }
+ }
+ }
+ else
+ {
+ /* Print the sorted items, across alphabetically, like ls -x. */
+ for (i = 1; matches[i]; i++)
+ {
+ temp = printable_part (matches[i]);
+ printed_len = print_filename (temp, matches[i]);
+ /* Have we reached the end of this line? */
+ if (matches[i+1])
+ {
+ if (i && (limit > 1) && (i % limit) == 0)
+ {
+ rl_crlf ();
+ lines++;
+ if (_rl_page_completions && lines >= _rl_screenheight - 1)
+ {
+ lines = _rl_internal_pager (lines);
+ if (lines < 0)
+ return;
+ }
+ }
+ else
+ for (k = 0; k < max - printed_len; k++)
+ putc (' ', rl_outstream);
+ }
+ }
+ rl_crlf ();
+ }
+}
+
+/* Display MATCHES, a list of matching filenames in argv format. This
+ handles the simple case -- a single match -- first. If there is more
+ than one match, we compute the number of strings in the list and the
+ length of the longest string, which will be needed by the display
+ function. If the application wants to handle displaying the list of
+ matches itself, it sets RL_COMPLETION_DISPLAY_MATCHES_HOOK to the
+ address of a function, and we just call it. If we're handling the
+ display ourselves, we just call rl_display_match_list. We also check
+ that the list of matches doesn't exceed the user-settable threshold,
+ and ask the user if he wants to see the list if there are more matches
+ than RL_COMPLETION_QUERY_ITEMS. */
+static void
+display_matches (matches)
+ char **matches;
+{
+ int len, max, i;
+ char *temp;
+
+ /* Move to the last visible line of a possibly-multiple-line command. */
+ _rl_move_vert (_rl_vis_botlin);
+
+ /* Handle simple case first. What if there is only one answer? */
+ if (matches[1] == 0)
+ {
+ temp = printable_part (matches[0]);
+ rl_crlf ();
+ print_filename (temp, matches[0]);
+ rl_crlf ();
+
+ rl_forced_update_display ();
+ rl_display_fixed = 1;
+
+ return;
+ }
+
+ /* There is more than one answer. Find out how many there are,
+ and find the maximum printed length of a single entry. */
+ for (max = 0, i = 1; matches[i]; i++)
+ {
+ temp = printable_part (matches[i]);
+ len = strlen (temp);
+
+ if (len > max)
+ max = len;
+ }
+
+ len = i - 1;
+
+ /* If the caller has defined a display hook, then call that now. */
+ if (rl_completion_display_matches_hook)
+ {
+ (*rl_completion_display_matches_hook) (matches, len, max);
+ return;
+ }
+
+ /* If there are many items, then ask the user if she really wants to
+ see them all. */
+ if (len >= rl_completion_query_items)
+ {
+ rl_crlf ();
+ fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
+ fflush (rl_outstream);
+ if (get_y_or_n (0) == 0)
+ {
+ rl_crlf ();
+
+ rl_forced_update_display ();
+ rl_display_fixed = 1;
+
+ return;
+ }
+ }
+
+ rl_display_match_list (matches, len, max);
+
+ rl_forced_update_display ();
+ rl_display_fixed = 1;
+}
+
+static char *
+make_quoted_replacement (match, mtype, qc)
+ char *match;
+ int mtype;
+ char *qc; /* Pointer to quoting character, if any */
+{
+ int should_quote, do_replace;
+ char *replacement;
+
+ /* If we are doing completion on quoted substrings, and any matches
+ contain any of the completer_word_break_characters, then auto-
+ matically prepend the substring with a quote character (just pick
+ the first one from the list of such) if it does not already begin
+ with a quote string. FIXME: Need to remove any such automatically
+ inserted quote character when it no longer is necessary, such as
+ if we change the string we are completing on and the new set of
+ matches don't require a quoted substring. */
+ replacement = match;
+
+ should_quote = match && rl_completer_quote_characters &&
+ rl_filename_completion_desired &&
+ rl_filename_quoting_desired;
+
+ if (should_quote)
+ should_quote = should_quote && (!qc || !*qc ||
+ (rl_completer_quote_characters && strchr (rl_completer_quote_characters, *qc)));
+
+ if (should_quote)
+ {
+ /* If there is a single match, see if we need to quote it.
+ This also checks whether the common prefix of several
+ matches needs to be quoted. */
+ should_quote = rl_filename_quote_characters
+ ? (_rl_strpbrk (match, rl_filename_quote_characters) != 0)
+ : 0;
+
+ do_replace = should_quote ? mtype : NO_MATCH;
+ /* Quote the replacement, since we found an embedded
+ word break character in a potential match. */
+ if (do_replace != NO_MATCH && rl_filename_quoting_function)
+ replacement = (*rl_filename_quoting_function) (match, do_replace, qc);
+ }
+ return (replacement);
+}
+
+static void
+insert_match (match, start, mtype, qc)
+ char *match;
+ int start, mtype;
+ char *qc;
+{
+ char *replacement;
+ char oqc;
+
+ oqc = qc ? *qc : '\0';
+ replacement = make_quoted_replacement (match, mtype, qc);
+
+ /* Now insert the match. */
+ if (replacement)
+ {
+ /* Don't double an opening quote character. */
+ if (qc && *qc && start && rl_line_buffer[start - 1] == *qc &&
+ replacement[0] == *qc)
+ start--;
+ /* If make_quoted_replacement changed the quoting character, remove
+ the opening quote and insert the (fully-quoted) replacement. */
+ else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc &&
+ replacement[0] != oqc)
+ start--;
+ _rl_replace_text (replacement, start, rl_point - 1);
+ if (replacement != match)
+ free (replacement);
+ }
+}
+
+/* Append any necessary closing quote and a separator character to the
+ just-inserted match. If the user has specified that directories
+ should be marked by a trailing `/', append one of those instead. The
+ default trailing character is a space. Returns the number of characters
+ appended. If NONTRIVIAL_MATCH is set, we test for a symlink (if the OS
+ has them) and don't add a suffix for a symlink to a directory. A
+ nontrivial match is one that actually adds to the word being completed.
+ The variable rl_completion_mark_symlink_dirs controls this behavior
+ (it's initially set to the what the user has chosen, indicated by the
+ value of _rl_complete_mark_symlink_dirs, but may be modified by an
+ application's completion function). */
+static int
+append_to_match (text, delimiter, quote_char, nontrivial_match)
+ char *text;
+ int delimiter, quote_char, nontrivial_match;
+{
+ char temp_string[4], *filename;
+ int temp_string_index, s;
+ struct stat finfo;
+
+ temp_string_index = 0;
+ if (quote_char && rl_point && rl_line_buffer[rl_point - 1] != quote_char)
+ temp_string[temp_string_index++] = quote_char;
+
+ if (delimiter)
+ temp_string[temp_string_index++] = delimiter;
+ else if (rl_completion_suppress_append == 0 && rl_completion_append_character)
+ temp_string[temp_string_index++] = rl_completion_append_character;
+
+ temp_string[temp_string_index++] = '\0';
+
+ if (rl_filename_completion_desired)
+ {
+ filename = tilde_expand (text);
+ s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0)
+ ? LSTAT (filename, &finfo)
+ : stat (filename, &finfo);
+ if (s == 0 && S_ISDIR (finfo.st_mode))
+ {
+ if (_rl_complete_mark_directories)
+ {
+ /* This is clumsy. Avoid putting in a double slash if point
+ is at the end of the line and the previous character is a
+ slash. */
+ if (rl_point && rl_line_buffer[rl_point] == '\0' && rl_line_buffer[rl_point - 1] == '/')
+ ;
+ else if (rl_line_buffer[rl_point] != '/')
+ rl_insert_text ("/");
+ }
+ }
+#ifdef S_ISLNK
+ /* Don't add anything if the filename is a symlink and resolves to a
+ directory. */
+ else if (s == 0 && S_ISLNK (finfo.st_mode) &&
+ stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode))
+ ;
+#endif
+ else
+ {
+ if (rl_point == rl_end && temp_string_index)
+ rl_insert_text (temp_string);
+ }
+ free (filename);
+ }
+ else
+ {
+ if (rl_point == rl_end && temp_string_index)
+ rl_insert_text (temp_string);
+ }
+
+ return (temp_string_index);
+}
+
+static void
+insert_all_matches (matches, point, qc)
+ char **matches;
+ int point;
+ char *qc;
+{
+ int i;
+ char *rp;
+
+ rl_begin_undo_group ();
+ /* remove any opening quote character; make_quoted_replacement will add
+ it back. */
+ if (qc && *qc && point && rl_line_buffer[point - 1] == *qc)
+ point--;
+ rl_delete_text (point, rl_point);
+ rl_point = point;
+
+ if (matches[1])
+ {
+ for (i = 1; matches[i]; i++)
+ {
+ rp = make_quoted_replacement (matches[i], SINGLE_MATCH, qc);
+ rl_insert_text (rp);
+ rl_insert_text (" ");
+ if (rp != matches[i])
+ free (rp);
+ }
+ }
+ else
+ {
+ rp = make_quoted_replacement (matches[0], SINGLE_MATCH, qc);
+ rl_insert_text (rp);
+ rl_insert_text (" ");
+ if (rp != matches[0])
+ free (rp);
+ }
+ rl_end_undo_group ();
+}
+
+void
+_rl_free_match_list (matches)
+ char **matches;
+{
+ register int i;
+
+ if (matches == 0)
+ return;
+
+ for (i = 0; matches[i]; i++)
+ free (matches[i]);
+ free (matches);
+}
+
+/* Complete the word at or before point.
+ WHAT_TO_DO says what to do with the completion.
+ `?' means list the possible completions.
+ TAB means do standard completion.
+ `*' means insert all of the possible completions.
+ `!' means to do standard completion, and list all possible completions if
+ there is more than one. */
+int
+rl_complete_internal (what_to_do)
+ int what_to_do;
+{
+ char **matches;
+ rl_compentry_func_t *our_func;
+ int start, end, delimiter, found_quote, i, nontrivial_lcd;
+ char *text, *saved_line_buffer;
+ char quote_char;
+
+ RL_SETSTATE(RL_STATE_COMPLETING);
+
+ set_completion_defaults (what_to_do);
+
+ saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL;
+ our_func = rl_completion_entry_function
+ ? rl_completion_entry_function
+ : rl_filename_completion_function;
+
+ /* We now look backwards for the start of a filename/variable word. */
+ end = rl_point;
+ found_quote = delimiter = 0;
+ quote_char = '\0';
+
+ if (rl_point)
+ /* This (possibly) changes rl_point. If it returns a non-zero char,
+ we know we have an open quote. */
+ quote_char = _rl_find_completion_word (&found_quote, &delimiter);
+
+ start = rl_point;
+ rl_point = end;
+
+ text = rl_copy_text (start, end);
+ matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char);
+ /* nontrivial_lcd is set if the common prefix adds something to the word
+ being completed. */
+ nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
+ free (text);
+
+ if (matches == 0)
+ {
+ rl_ding ();
+ FREE (saved_line_buffer);
+ completion_changed_buffer = 0;
+ RL_UNSETSTATE(RL_STATE_COMPLETING);
+ return (0);
+ }
+
+ /* If we are matching filenames, the attempted completion function will
+ have set rl_filename_completion_desired to a non-zero value. The basic
+ rl_filename_completion_function does this. */
+ i = rl_filename_completion_desired;
+
+ if (postprocess_matches (&matches, i) == 0)
+ {
+ rl_ding ();
+ FREE (saved_line_buffer);
+ completion_changed_buffer = 0;
+ RL_UNSETSTATE(RL_STATE_COMPLETING);
+ return (0);
+ }
+
+ switch (what_to_do)
+ {
+ case TAB:
+ case '!':
+ /* Insert the first match with proper quoting. */
+ if (*matches[0])
+ insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
+
+ /* If there are more matches, ring the bell to indicate.
+ If we are in vi mode, Posix.2 says to not ring the bell.
+ If the `show-all-if-ambiguous' variable is set, display
+ all the matches immediately. Otherwise, if this was the
+ only match, and we are hacking files, check the file to
+ see if it was a directory. If so, and the `mark-directories'
+ variable is set, add a '/' to the name. If not, and we
+ are at the end of the line, then add a space. */
+ if (matches[1])
+ {
+ if (what_to_do == '!')
+ {
+ display_matches (matches);
+ break;
+ }
+ else if (rl_editing_mode != vi_mode)
+ rl_ding (); /* There are other matches remaining. */
+ }
+ else
+ append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
+
+ break;
+
+ case '*':
+ insert_all_matches (matches, start, &quote_char);
+ break;
+
+ case '?':
+ display_matches (matches);
+ break;
+
+ default:
+ fprintf (stderr, "\r\nreadline: bad value %d for what_to_do in rl_complete\n", what_to_do);
+ rl_ding ();
+ FREE (saved_line_buffer);
+ RL_UNSETSTATE(RL_STATE_COMPLETING);
+ return 1;
+ }
+
+ _rl_free_match_list (matches);
+
+ /* Check to see if the line has changed through all of this manipulation. */
+ if (saved_line_buffer)
+ {
+ completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0;
+ free (saved_line_buffer);
+ }
+
+ RL_UNSETSTATE(RL_STATE_COMPLETING);
+ return 0;
+}
+
+/***************************************************************/
+/* */
+/* Application-callable completion match generator functions */
+/* */
+/***************************************************************/
+
+/* Return an array of (char *) which is a list of completions for TEXT.
+ If there are no completions, return a NULL pointer.
+ The first entry in the returned array is the substitution for TEXT.
+ The remaining entries are the possible completions.
+ The array is terminated with a NULL pointer.
+
+ ENTRY_FUNCTION is a function of two args, and returns a (char *).
+ The first argument is TEXT.
+ The second is a state argument; it should be zero on the first call, and
+ non-zero on subsequent calls. It returns a NULL pointer to the caller
+ when there are no more matches.
+ */
+char **
+rl_completion_matches (text, entry_function)
+ const char *text;
+ rl_compentry_func_t *entry_function;
+{
+ /* Number of slots in match_list. */
+ int match_list_size;
+
+ /* The list of matches. */
+ char **match_list;
+
+ /* Number of matches actually found. */
+ int matches;
+
+ /* Temporary string binder. */
+ char *string;
+
+ matches = 0;
+ match_list_size = 10;
+ match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));
+ match_list[1] = (char *)NULL;
+
+ while (string = (*entry_function) (text, matches))
+ {
+ if (matches + 1 == match_list_size)
+ match_list = (char **)xrealloc
+ (match_list, ((match_list_size += 10) + 1) * sizeof (char *));
+
+ match_list[++matches] = string;
+ match_list[matches + 1] = (char *)NULL;
+ }
+
+ /* If there were any matches, then look through them finding out the
+ lowest common denominator. That then becomes match_list[0]. */
+ if (matches)
+ compute_lcd_of_matches (match_list, matches, text);
+ else /* There were no matches. */
+ {
+ free (match_list);
+ match_list = (char **)NULL;
+ }
+ return (match_list);
+}
+
+/* A completion function for usernames.
+ TEXT contains a partial username preceded by a random
+ character (usually `~'). */
+char *
+rl_username_completion_function (text, state)
+ const char *text;
+ int state;
+{
+#if defined _WIN32 || defined __OPENNT
+ return (char *)NULL;
+#else /* !_WIN32 && !__OPENNT */
+ static char *username = (char *)NULL;
+ static struct passwd *entry;
+ static int namelen, first_char, first_char_loc;
+ char *value;
+
+ if (state == 0)
+ {
+ FREE (username);
+
+ first_char = *text;
+ first_char_loc = first_char == '~';
+
+ username = savestring (&text[first_char_loc]);
+ namelen = strlen (username);
+ setpwent ();
+ }
+
+ while (entry = getpwent ())
+ {
+ /* Null usernames should result in all users as possible completions. */
+ if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))
+ break;
+ }
+
+ if (entry == 0)
+ {
+ endpwent ();
+ return ((char *)NULL);
+ }
+ else
+ {
+ value = (char *)xmalloc (2 + strlen (entry->pw_name));
+
+ *value = *text;
+
+ strcpy (value + first_char_loc, entry->pw_name);
+
+ if (first_char == '~')
+ rl_filename_completion_desired = 1;
+
+ return (value);
+ }
+#endif /* !_WIN32 && !__OPENNT */
+}
+
+/* Okay, now we write the entry_function for filename completion. In the
+ general case. Note that completion in the shell is a little different
+ because of all the pathnames that must be followed when looking up the
+ completion for a command. */
+char *
+rl_filename_completion_function (text, state)
+ const char *text;
+ int state;
+{
+ static DIR *directory = (DIR *)NULL;
+ static char *filename = (char *)NULL;
+ static char *dirname = (char *)NULL;
+ static char *users_dirname = (char *)NULL;
+ static int filename_len;
+ char *temp;
+ int dirlen;
+ struct dirent *entry;
+
+ /* If we don't have any state, then do some initialization. */
+ if (state == 0)
+ {
+ /* If we were interrupted before closing the directory or reading
+ all of its contents, close it. */
+ if (directory)
+ {
+ closedir (directory);
+ directory = (DIR *)NULL;
+ }
+ FREE (dirname);
+ FREE (filename);
+ FREE (users_dirname);
+
+ filename = savestring (text);
+ if (*text == 0)
+ text = ".";
+ dirname = savestring (text);
+
+ temp = strrchr (dirname, '/');
+
+#if defined (__MSDOS__)
+ /* special hack for //X/... */
+ if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/')
+ temp = strrchr (dirname + 3, '/');
+#endif
+
+ if (temp)
+ {
+ strcpy (filename, ++temp);
+ *temp = '\0';
+ }
+#if defined (__MSDOS__)
+ /* searches from current directory on the drive */
+ else if (ISALPHA ((unsigned char)dirname[0]) && dirname[1] == ':')
+ {
+ strcpy (filename, dirname + 2);
+ dirname[2] = '\0';
+ }
+#endif
+ else
+ {
+ dirname[0] = '.';
+ dirname[1] = '\0';
+ }
+
+ /* We aren't done yet. We also support the "~user" syntax. */
+
+ /* Save the version of the directory that the user typed. */
+ users_dirname = savestring (dirname);
+
+ if (*dirname == '~')
+ {
+ temp = tilde_expand (dirname);
+ free (dirname);
+ dirname = temp;
+ }
+
+ if (rl_directory_rewrite_hook)
+ (*rl_directory_rewrite_hook) (&dirname);
+
+ if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))
+ {
+ free (users_dirname);
+ users_dirname = savestring (dirname);
+ }
+
+ directory = opendir (dirname);
+ filename_len = strlen (filename);
+
+ rl_filename_completion_desired = 1;
+ }
+
+ /* At this point we should entertain the possibility of hacking wildcarded
+ filenames, like /usr/man/man<WILD>/te<TAB>. If the directory name
+ contains globbing characters, then build an array of directories, and
+ then map over that list while completing. */
+ /* *** UNIMPLEMENTED *** */
+
+ /* Now that we have some state, we can read the directory. */
+
+ entry = (struct dirent *)NULL;
+ while (directory && (entry = readdir (directory)))
+ {
+ /* Special case for no filename. If the user has disabled the
+ `match-hidden-files' variable, skip filenames beginning with `.'.
+ All other entries except "." and ".." match. */
+ if (filename_len == 0)
+ {
+ if (_rl_match_hidden_files == 0 && HIDDEN_FILE (entry->d_name))
+ continue;
+
+ if (entry->d_name[0] != '.' ||
+ (entry->d_name[1] &&
+ (entry->d_name[1] != '.' || entry->d_name[2])))
+ break;
+ }
+ else
+ {
+ /* Otherwise, if these match up to the length of filename, then
+ it is a match. */
+ if (_rl_completion_case_fold)
+ {
+ if ((_rl_to_lower (entry->d_name[0]) == _rl_to_lower (filename[0])) &&
+ (((int)D_NAMLEN (entry)) >= filename_len) &&
+ (_rl_strnicmp (filename, entry->d_name, filename_len) == 0))
+ break;
+ }
+ else
+ {
+ if ((entry->d_name[0] == filename[0]) &&
+ (((int)D_NAMLEN (entry)) >= filename_len) &&
+ (strncmp (filename, entry->d_name, filename_len) == 0))
+ break;
+ }
+ }
+ }
+
+ if (entry == 0)
+ {
+ if (directory)
+ {
+ closedir (directory);
+ directory = (DIR *)NULL;
+ }
+ if (dirname)
+ {
+ free (dirname);
+ dirname = (char *)NULL;
+ }
+ if (filename)
+ {
+ free (filename);
+ filename = (char *)NULL;
+ }
+ if (users_dirname)
+ {
+ free (users_dirname);
+ users_dirname = (char *)NULL;
+ }
+
+ return (char *)NULL;
+ }
+ else
+ {
+ /* dirname && (strcmp (dirname, ".") != 0) */
+ if (dirname && (dirname[0] != '.' || dirname[1]))
+ {
+ if (rl_complete_with_tilde_expansion && *users_dirname == '~')
+ {
+ dirlen = strlen (dirname);
+ temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
+ strcpy (temp, dirname);
+ /* Canonicalization cuts off any final slash present. We
+ may need to add it back. */
+ if (dirname[dirlen - 1] != '/')
+ {
+ temp[dirlen++] = '/';
+ temp[dirlen] = '\0';
+ }
+ }
+ else
+ {
+ dirlen = strlen (users_dirname);
+ temp = (char *)xmalloc (2 + dirlen + D_NAMLEN (entry));
+ strcpy (temp, users_dirname);
+ /* Make sure that temp has a trailing slash here. */
+ if (users_dirname[dirlen - 1] != '/')
+ temp[dirlen++] = '/';
+ }
+
+ strcpy (temp + dirlen, entry->d_name);
+ }
+ else
+ temp = savestring (entry->d_name);
+
+ return (temp);
+ }
+}
+
+/* An initial implementation of a menu completion function a la tcsh. The
+ first time (if the last readline command was not rl_menu_complete), we
+ generate the list of matches. This code is very similar to the code in
+ rl_complete_internal -- there should be a way to combine the two. Then,
+ for each item in the list of matches, we insert the match in an undoable
+ fashion, with the appropriate character appended (this happens on the
+ second and subsequent consecutive calls to rl_menu_complete). When we
+ hit the end of the match list, we restore the original unmatched text,
+ ring the bell, and reset the counter to zero. */
+int
+rl_menu_complete (count, ignore)
+ int count, ignore;
+{
+ rl_compentry_func_t *our_func;
+ int matching_filenames, found_quote;
+
+ static char *orig_text;
+ static char **matches = (char **)0;
+ static int match_list_index = 0;
+ static int match_list_size = 0;
+ static int orig_start, orig_end;
+ static char quote_char;
+ static int delimiter;
+
+ /* The first time through, we generate the list of matches and set things
+ up to insert them. */
+ if (rl_last_func != rl_menu_complete)
+ {
+ /* Clean up from previous call, if any. */
+ FREE (orig_text);
+ if (matches)
+ _rl_free_match_list (matches);
+
+ match_list_index = match_list_size = 0;
+ matches = (char **)NULL;
+
+ /* Only the completion entry function can change these. */
+ set_completion_defaults ('%');
+
+ our_func = rl_completion_entry_function
+ ? rl_completion_entry_function
+ : rl_filename_completion_function;
+
+ /* We now look backwards for the start of a filename/variable word. */
+ orig_end = rl_point;
+ found_quote = delimiter = 0;
+ quote_char = '\0';
+
+ if (rl_point)
+ /* This (possibly) changes rl_point. If it returns a non-zero char,
+ we know we have an open quote. */
+ quote_char = _rl_find_completion_word (&found_quote, &delimiter);
+
+ orig_start = rl_point;
+ rl_point = orig_end;
+
+ orig_text = rl_copy_text (orig_start, orig_end);
+ matches = gen_completion_matches (orig_text, orig_start, orig_end,
+ our_func, found_quote, quote_char);
+
+ /* If we are matching filenames, the attempted completion function will
+ have set rl_filename_completion_desired to a non-zero value. The basic
+ rl_filename_completion_function does this. */
+ matching_filenames = rl_filename_completion_desired;
+
+ if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
+ {
+ rl_ding ();
+ FREE (matches);
+ matches = (char **)0;
+ FREE (orig_text);
+ orig_text = (char *)0;
+ completion_changed_buffer = 0;
+ return (0);
+ }
+
+ for (match_list_size = 0; matches[match_list_size]; match_list_size++)
+ ;
+ /* matches[0] is lcd if match_list_size > 1, but the circular buffer
+ code below should take care of it. */
+ }
+
+ /* Now we have the list of matches. Replace the text between
+ rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with
+ matches[match_list_index], and add any necessary closing char. */
+
+ if (matches == 0 || match_list_size == 0)
+ {
+ rl_ding ();
+ FREE (matches);
+ matches = (char **)0;
+ completion_changed_buffer = 0;
+ return (0);
+ }
+
+ match_list_index = (match_list_index + count) % match_list_size;
+ if (match_list_index < 0)
+ match_list_index += match_list_size;
+
+ if (match_list_index == 0 && match_list_size > 1)
+ {
+ rl_ding ();
+ insert_match (orig_text, orig_start, MULT_MATCH, &quote_char);
+ }
+ else
+ {
+ insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, &quote_char);
+ append_to_match (matches[match_list_index], delimiter, quote_char,
+ strcmp (orig_text, matches[match_list_index]));
+ }
+
+ completion_changed_buffer = 1;
+ return (0);
+}
diff --git a/MSVC/readline/config.h b/MSVC/readline/config.h
index 22e18d4..5434c38 100644
--- a/MSVC/readline/config.h
+++ b/MSVC/readline/config.h
@@ -1,157 +1,157 @@
-/* config.h. Generated automatically by configure. */
-/* config.h.in. Generated automatically from configure.in by autoheader. */
-
-/* Define if you have the strcoll function and it is properly defined. */
-#define HAVE_STRCOLL 1
-
-/* Define if on MINIX. */
-/* #undef _MINIX */
-
-/* Define if the system does not provide POSIX.1 features except
- with this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define if you need to in order for stat and other things to work. */
-/* #undef _POSIX_SOURCE */
-
-/* Define as the return type of signal handlers (int or void). */
-#define RETSIGTYPE void
-
-/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
-/* #undef STAT_MACROS_BROKEN */
-
-/* Definitions pulled in from aclocal.m4. */
-#define VOID_SIGHANDLER 1
-
-/* #undef GWINSZ_IN_SYS_IOCTL */
-
-/* #undef TIOCSTAT_IN_SYS_IOCTL */
-
-/* #undef HAVE_GETPW_DECLS */
-
-/* #undef FIONREAD_IN_SYS_IOCTL */
-
-/* #undef HAVE_BSD_SIGNALS */
-
-/* #undef HAVE_POSIX_SIGNALS */
-
-/* #undef HAVE_POSIX_SIGSETJMP */
-
-#define HAVE_USG_SIGHOLD 1
-
-/* #undef MUST_REINSTALL_SIGHANDLERS */
-
-/* #undef SPEED_T_IN_SYS_TYPES */
-
-/* #undef STRCOLL_BROKEN */
-
-#define STRUCT_DIRENT_HAS_D_FILENO 1
-
-/* #undef STRUCT_DIRENT_HAS_D_INO */
-
-/* #undef STRUCT_WINSIZE_IN_SYS_IOCTL */
-
-/* #undef STRUCT_WINSIZE_IN_TERMIOS */
-
-/* Define if you have the lstat function. */
-/* #define HAVE_LSTAT 1 */
-
-/* Define if you have the putenv function. */
-#define HAVE_PUTENV 1
-
-/* Define if you have the select function. */
-#define HAVE_SELECT 1
-
-/* Define if you have the setenv function. */
-#define HAVE_SETENV 1
-
-/* Define if you have the setlocale function. */
-#define HAVE_SETLOCALE 1
-
-/* Define if you have the strcasecmp function. */
-/* #define HAVE_STRCASECMP */
-
-/* Define if you have the tcgetattr function. */
-#define HAVE_TCGETATTR 1
-
-/* Define if you have the <dirent.h> header file. */
-#define HAVE_DIRENT_H 1
-
-/* Define if you have the <locale.h> header file. */
-#define HAVE_LOCALE_H 1
-
-/* Define if you have the <ndir.h> header file. */
-/* #undef HAVE_NDIR_H */
-
-/* Define if you have the <stdarg.h> header file. */
-#define HAVE_STDARG_H 1
-
-/* Define if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define if you have the <sys/dir.h> header file. */
-/* #undef HAVE_SYS_DIR_H */
-
-/* Define if you have the <sys/file.h> header file. */
-/* #define HAVE_SYS_FILE_H */
-
-/* Define if you have the <sys/ndir.h> header file. */
-/* #undef HAVE_SYS_NDIR_H */
-
-/* Define if you have the <sys/pte.h> header file. */
-/* #undef HAVE_SYS_PTE_H */
-
-/* Define if you have the <sys/ptem.h> header file. */
-/* #undef HAVE_SYS_PTEM_H */
-
-/* Define if you have the <sys/select.h> header file. */
-/* #undef HAVE_SYS_SELECT_H */
-
-/* Define if you have the <sys/stream.h> header file. */
-/* #undef HAVE_SYS_STREAM_H */
-
-/* Define if you have the <termcap.h> header file. */
-/* #undef HAVE_TERMCAP_H */
-
-/* Define if you have the <termio.h> header file. */
-/* #undef HAVE_TERMIO_H */
-
-/* Define if you have the <termios.h> header file. */
-/* #define HAVE_TERMIOS_H */
-
-/* Define if you have the <unistd.h> header file. */
-/* #define HAVE_UNISTD_H */
-
-/* Define if you have the <varargs.h> header file. */
-//#define HAVE_VARARGS_H 1
-
-/*
-#define HAVE_WCTYPE_H 1
-#define HAVE_WCHAR_H 1
-#define HAVE_MBSRTOWCS 1
-*/
-/* config.h.bot */
-/* modify settings or make new ones based on what autoconf tells us. */
-
-/* Ultrix botches type-ahead when switching from canonical to
- non-canonical mode, at least through version 4.3 */
-#if !defined (HAVE_TERMIOS_H) || !defined (HAVE_TCGETATTR) || defined (ultrix)
-# define TERMIOS_MISSING
-#endif
-
-#if defined (STRCOLL_BROKEN)
-# define HAVE_STRCOLL 1
-#endif
-
-#if (defined (__STDC__) || _MSC_VER) && defined (HAVE_STDARG_H)
-# define PREFER_STDARG
-# define USE_VARARGS
-#else
-# if defined (HAVE_VARARGS_H)
-# define PREFER_VARARGS
-# define USE_VARARGS
-# endif
-#endif
+/* config.h. Generated automatically by configure. */
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if you have the strcoll function and it is properly defined. */
+#define HAVE_STRCOLL 1
+
+/* Define if on MINIX. */
+/* #undef _MINIX */
+
+/* Define if the system does not provide POSIX.1 features except
+ with this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define if you need to in order for stat and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Define as the return type of signal handlers (int or void). */
+#define RETSIGTYPE void
+
+/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Definitions pulled in from aclocal.m4. */
+#define VOID_SIGHANDLER 1
+
+/* #undef GWINSZ_IN_SYS_IOCTL */
+
+/* #undef TIOCSTAT_IN_SYS_IOCTL */
+
+/* #undef HAVE_GETPW_DECLS */
+
+/* #undef FIONREAD_IN_SYS_IOCTL */
+
+/* #undef HAVE_BSD_SIGNALS */
+
+/* #undef HAVE_POSIX_SIGNALS */
+
+/* #undef HAVE_POSIX_SIGSETJMP */
+
+#define HAVE_USG_SIGHOLD 1
+
+/* #undef MUST_REINSTALL_SIGHANDLERS */
+
+/* #undef SPEED_T_IN_SYS_TYPES */
+
+/* #undef STRCOLL_BROKEN */
+
+#define STRUCT_DIRENT_HAS_D_FILENO 1
+
+/* #undef STRUCT_DIRENT_HAS_D_INO */
+
+/* #undef STRUCT_WINSIZE_IN_SYS_IOCTL */
+
+/* #undef STRUCT_WINSIZE_IN_TERMIOS */
+
+/* Define if you have the lstat function. */
+/* #define HAVE_LSTAT 1 */
+
+/* Define if you have the putenv function. */
+#define HAVE_PUTENV 1
+
+/* Define if you have the select function. */
+#define HAVE_SELECT 1
+
+/* Define if you have the setenv function. */
+#define HAVE_SETENV 1
+
+/* Define if you have the setlocale function. */
+#define HAVE_SETLOCALE 1
+
+/* Define if you have the strcasecmp function. */
+/* #define HAVE_STRCASECMP */
+
+/* Define if you have the tcgetattr function. */
+#define HAVE_TCGETATTR 1
+
+/* Define if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define if you have the <ndir.h> header file. */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/dir.h> header file. */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define if you have the <sys/file.h> header file. */
+/* #define HAVE_SYS_FILE_H */
+
+/* Define if you have the <sys/ndir.h> header file. */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the <sys/pte.h> header file. */
+/* #undef HAVE_SYS_PTE_H */
+
+/* Define if you have the <sys/ptem.h> header file. */
+/* #undef HAVE_SYS_PTEM_H */
+
+/* Define if you have the <sys/select.h> header file. */
+/* #undef HAVE_SYS_SELECT_H */
+
+/* Define if you have the <sys/stream.h> header file. */
+/* #undef HAVE_SYS_STREAM_H */
+
+/* Define if you have the <termcap.h> header file. */
+/* #undef HAVE_TERMCAP_H */
+
+/* Define if you have the <termio.h> header file. */
+/* #undef HAVE_TERMIO_H */
+
+/* Define if you have the <termios.h> header file. */
+/* #define HAVE_TERMIOS_H */
+
+/* Define if you have the <unistd.h> header file. */
+/* #define HAVE_UNISTD_H */
+
+/* Define if you have the <varargs.h> header file. */
+//#define HAVE_VARARGS_H 1
+
+/*
+#define HAVE_WCTYPE_H 1
+#define HAVE_WCHAR_H 1
+#define HAVE_MBSRTOWCS 1
+*/
+/* config.h.bot */
+/* modify settings or make new ones based on what autoconf tells us. */
+
+/* Ultrix botches type-ahead when switching from canonical to
+ non-canonical mode, at least through version 4.3 */
+#if !defined (HAVE_TERMIOS_H) || !defined (HAVE_TCGETATTR) || defined (ultrix)
+# define TERMIOS_MISSING
+#endif
+
+#if defined (STRCOLL_BROKEN)
+# define HAVE_STRCOLL 1
+#endif
+
+#if (defined (__STDC__) || _MSC_VER) && defined (HAVE_STDARG_H)
+# define PREFER_STDARG
+# define USE_VARARGS
+#else
+# if defined (HAVE_VARARGS_H)
+# define PREFER_VARARGS
+# define USE_VARARGS
+# endif
+#endif
diff --git a/MSVC/readline/dirent.c b/MSVC/readline/dirent.c
index a3e153d..475ef6a 100644
--- a/MSVC/readline/dirent.c
+++ b/MSVC/readline/dirent.c
@@ -1,357 +1,357 @@
-/*
- * dirent.c
- *
- * Derived from DIRLIB.C by Matt J. Weinstein
- * This note appears in the DIRLIB.H
- * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
- *
- * Updated by Jeremy Bettis <jeremy@hksys.com>
- * Significantly revised and rewinddir, seekdir and telldir added by Colin
- * Peters <colin@fu.is.saga-u.ac.jp>
- *
- * $Revision: 1.2 $
- * $Author: pixel $
- * $Date: 2004-11-27 21:44:17 $
- *
- */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <io.h>
-#include <direct.h>
-#include <sys/stat.h>
-
-#include "dirent.h"
-
-#define SUFFIX "*"
-#define SLASH "\\"
-
-char * __stdcall CharPrevA(const char *, const char *);
-
-static int
-isUNCRoot(const char *path)
-{
- if (path[0] == '\\' && path[1] == '\\') {
- const char *p;
- if (p = strchr(path + 3, '\\')) {
- if (!p[1])
- return 0;
- if (p = strchr(p + 1, '\\')) {
- if (!p[1])
- return 1;
- } else
- return 1;
- }
- }
- return 0;
-}
-
-#ifndef S_ISDIR
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif
-/*
- * opendir
- *
- * Returns a pointer to a DIR structure appropriately filled in to begin
- * searching a directory.
- */
-DIR *
-opendir (const char *szPath)
-{
- DIR *nd;
- struct _stat statDir;
- char buf1[_MAX_PATH];
- char buf2[_MAX_PATH];
- const char *p;
- char *q;
- int len;
-
- errno = 0;
-
- if (!szPath)
- {
- errno = EFAULT;
- return (DIR *) 0;
- }
-
- if (szPath[0] == '\0')
- {
- errno = ENOTDIR;
- return (DIR *) 0;
- }
-
- for (p = szPath, q = buf1; *p; p++, q++)
- {
- if (*p == '/')
- *q = '\\';
- else
- *q = *p;
- }
- *q = '\0';
-
- _fullpath(buf2, buf1, sizeof buf2);
- len = strlen(buf2);
- p = CharPrevA(buf2, buf2 + len);
- if (isUNCRoot(buf2)) {
- if (*p != '\\')
- strcat(buf2, "\\");
- } else if (*p == '\\' || *p == ':')
- strcat(buf2, ".");
-
- /* Attempt to determine if the given path really is a directory. */
- if (_stat (buf2, &statDir))
- {
- /* Error, stat should have set an error value. */
- return (DIR *) 0;
- }
-
- if (!S_ISDIR (statDir.st_mode))
- {
- /* Error, stat reports not a directory. */
- errno = ENOTDIR;
- return (DIR *) 0;
- }
-
- if (*p == '\\')
- buf2[len - 1] = '\0';
-
- /* Allocate enough space to store DIR structure and the complete
- * directory path given. */
- nd = (DIR *) malloc (sizeof (DIR) + strlen (buf2) + strlen (SLASH) +
- strlen (SUFFIX));
-
- if (!nd)
- {
- /* Error, out of memory. */
- errno = ENOMEM;
- return (DIR *) 0;
- }
-
- /* Create the search expression. */
- strcpy (nd->dd_name, buf2);
-
- /* Add on a slash. */
- strcat (nd->dd_name, SLASH);
-
- /* Add on the search pattern */
- strcat (nd->dd_name, SUFFIX);
-
- /* Initialize handle to -1 so that a premature closedir doesn't try
- * to call _findclose on it. */
- nd->dd_handle = -1;
-
- /* Initialize the status. */
- nd->dd_stat = 0;
-
- /* Initialize the dirent structure. ino and reclen are invalid under
- * Win32, and name simply points at the appropriate part of the
- * findfirst_t structure. */
- nd->dd_dir.d_ino = 0;
- nd->dd_dir.d_reclen = 0;
- nd->dd_dir.d_namlen = 0;
- nd->dd_dir.d_name = nd->dd_dta.name;
-
- return nd;
-}
-
-
-/*
- * readdir
- *
- * Return a pointer to a dirent structure filled with the information on the
- * next entry in the directory.
- */
-struct dirent *
-readdir (DIR * dirp)
-{
- errno = 0;
-
- /* Check for valid DIR struct. */
- if (!dirp)
- {
- errno = EFAULT;
- return (struct dirent *) 0;
- }
-
- if (dirp->dd_dir.d_name != dirp->dd_dta.name)
- {
- /* The structure does not seem to be set up correctly. */
- errno = EINVAL;
- return (struct dirent *) 0;
- }
-
- if (dirp->dd_stat < 0)
- {
- /* We have already returned all files in the directory
- * (or the structure has an invalid dd_stat). */
- return (struct dirent *) 0;
- }
- else if (dirp->dd_stat == 0)
- {
- /* We haven't started the search yet. */
- /* Start the search */
- dirp->dd_handle = _findfirst (dirp->dd_name, &(dirp->dd_dta));
-
- if (dirp->dd_handle == -1)
- {
- /* Whoops! Seems there are no files in that
- * directory. */
- dirp->dd_stat = -1;
- }
- else
- {
- dirp->dd_stat = 1;
- }
- }
- else
- {
- /* Get the next search entry. */
- if (_findnext (dirp->dd_handle, &(dirp->dd_dta)))
- {
- /* We are off the end or otherwise error. */
- _findclose (dirp->dd_handle);
- dirp->dd_handle = -1;
- dirp->dd_stat = -1;
- }
- else
- {
- /* Update the status to indicate the correct
- * number. */
- dirp->dd_stat++;
- }
- }
-
- if (dirp->dd_stat > 0)
- {
- /* Successfully got an entry. Everything about the file is
- * already appropriately filled in except the length of the
- * file name. */
- dirp->dd_dir.d_namlen = strlen (dirp->dd_dir.d_name);
- return &dirp->dd_dir;
- }
-
- return (struct dirent *) 0;
-}
-
-
-/*
- * closedir
- *
- * Frees up resources allocated by opendir.
- */
-int
-closedir (DIR * dirp)
-{
- int rc;
-
- errno = 0;
- rc = 0;
-
- if (!dirp)
- {
- errno = EFAULT;
- return -1;
- }
-
- if (dirp->dd_handle != -1)
- {
- rc = _findclose (dirp->dd_handle);
- }
-
- /* Delete the dir structure. */
- free (dirp);
-
- return rc;
-}
-
-/*
- * rewinddir
- *
- * Return to the beginning of the directory "stream". We simply call findclose
- * and then reset things like an opendir.
- */
-void
-rewinddir (DIR * dirp)
-{
- errno = 0;
-
- if (!dirp)
- {
- errno = EFAULT;
- return;
- }
-
- if (dirp->dd_handle != -1)
- {
- _findclose (dirp->dd_handle);
- }
-
- dirp->dd_handle = -1;
- dirp->dd_stat = 0;
-}
-
-/*
- * telldir
- *
- * Returns the "position" in the "directory stream" which can be used with
- * seekdir to go back to an old entry. We simply return the value in stat.
- */
-long
-telldir (DIR * dirp)
-{
- errno = 0;
-
- if (!dirp)
- {
- errno = EFAULT;
- return -1;
- }
- return dirp->dd_stat;
-}
-
-/*
- * seekdir
- *
- * Seek to an entry previously returned by telldir. We rewind the directory
- * and call readdir repeatedly until either dd_stat is the position number
- * or -1 (off the end). This is not perfect, in that the directory may
- * have changed while we weren't looking. But that is probably the case with
- * any such system.
- */
-void
-seekdir (DIR * dirp, long lPos)
-{
- errno = 0;
-
- if (!dirp)
- {
- errno = EFAULT;
- return;
- }
-
- if (lPos < -1)
- {
- /* Seeking to an invalid position. */
- errno = EINVAL;
- return;
- }
- else if (lPos == -1)
- {
- /* Seek past end. */
- if (dirp->dd_handle != -1)
- {
- _findclose (dirp->dd_handle);
- }
- dirp->dd_handle = -1;
- dirp->dd_stat = -1;
- }
- else
- {
- /* Rewind and read forward to the appropriate index. */
- rewinddir (dirp);
-
- while ((dirp->dd_stat < lPos) && readdir (dirp))
- ;
- }
-}
+/*
+ * dirent.c
+ *
+ * Derived from DIRLIB.C by Matt J. Weinstein
+ * This note appears in the DIRLIB.H
+ * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
+ *
+ * Updated by Jeremy Bettis <jeremy@hksys.com>
+ * Significantly revised and rewinddir, seekdir and telldir added by Colin
+ * Peters <colin@fu.is.saga-u.ac.jp>
+ *
+ * $Revision: 1.3 $
+ * $Author: pixel $
+ * $Date: 2004-11-27 21:47:24 $
+ *
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <io.h>
+#include <direct.h>
+#include <sys/stat.h>
+
+#include "dirent.h"
+
+#define SUFFIX "*"
+#define SLASH "\\"
+
+char * __stdcall CharPrevA(const char *, const char *);
+
+static int
+isUNCRoot(const char *path)
+{
+ if (path[0] == '\\' && path[1] == '\\') {
+ const char *p;
+ if (p = strchr(path + 3, '\\')) {
+ if (!p[1])
+ return 0;
+ if (p = strchr(p + 1, '\\')) {
+ if (!p[1])
+ return 1;
+ } else
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#ifndef S_ISDIR
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+/*
+ * opendir
+ *
+ * Returns a pointer to a DIR structure appropriately filled in to begin
+ * searching a directory.
+ */
+DIR *
+opendir (const char *szPath)
+{
+ DIR *nd;
+ struct _stat statDir;
+ char buf1[_MAX_PATH];
+ char buf2[_MAX_PATH];
+ const char *p;
+ char *q;
+ int len;
+
+ errno = 0;
+
+ if (!szPath)
+ {
+ errno = EFAULT;
+ return (DIR *) 0;
+ }
+
+ if (szPath[0] == '\0')
+ {
+ errno = ENOTDIR;
+ return (DIR *) 0;
+ }
+
+ for (p = szPath, q = buf1; *p; p++, q++)
+ {
+ if (*p == '/')
+ *q = '\\';
+ else
+ *q = *p;
+ }
+ *q = '\0';
+
+ _fullpath(buf2, buf1, sizeof buf2);
+ len = strlen(buf2);
+ p = CharPrevA(buf2, buf2 + len);
+ if (isUNCRoot(buf2)) {
+ if (*p != '\\')
+ strcat(buf2, "\\");
+ } else if (*p == '\\' || *p == ':')
+ strcat(buf2, ".");
+
+ /* Attempt to determine if the given path really is a directory. */
+ if (_stat (buf2, &statDir))
+ {
+ /* Error, stat should have set an error value. */
+ return (DIR *) 0;
+ }
+
+ if (!S_ISDIR (statDir.st_mode))
+ {
+ /* Error, stat reports not a directory. */
+ errno = ENOTDIR;
+ return (DIR *) 0;
+ }
+
+ if (*p == '\\')
+ buf2[len - 1] = '\0';
+
+ /* Allocate enough space to store DIR structure and the complete
+ * directory path given. */
+ nd = (DIR *) malloc (sizeof (DIR) + strlen (buf2) + strlen (SLASH) +
+ strlen (SUFFIX));
+
+ if (!nd)
+ {
+ /* Error, out of memory. */
+ errno = ENOMEM;
+ return (DIR *) 0;
+ }
+
+ /* Create the search expression. */
+ strcpy (nd->dd_name, buf2);
+
+ /* Add on a slash. */
+ strcat (nd->dd_name, SLASH);
+
+ /* Add on the search pattern */
+ strcat (nd->dd_name, SUFFIX);
+
+ /* Initialize handle to -1 so that a premature closedir doesn't try
+ * to call _findclose on it. */
+ nd->dd_handle = -1;
+
+ /* Initialize the status. */
+ nd->dd_stat = 0;
+
+ /* Initialize the dirent structure. ino and reclen are invalid under
+ * Win32, and name simply points at the appropriate part of the
+ * findfirst_t structure. */
+ nd->dd_dir.d_ino = 0;
+ nd->dd_dir.d_reclen = 0;
+ nd->dd_dir.d_namlen = 0;
+ nd->dd_dir.d_name = nd->dd_dta.name;
+
+ return nd;
+}
+
+
+/*
+ * readdir
+ *
+ * Return a pointer to a dirent structure filled with the information on the
+ * next entry in the directory.
+ */
+struct dirent *
+readdir (DIR * dirp)
+{
+ errno = 0;
+
+ /* Check for valid DIR struct. */
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return (struct dirent *) 0;
+ }
+
+ if (dirp->dd_dir.d_name != dirp->dd_dta.name)
+ {
+ /* The structure does not seem to be set up correctly. */
+ errno = EINVAL;
+ return (struct dirent *) 0;
+ }
+
+ if (dirp->dd_stat < 0)
+ {
+ /* We have already returned all files in the directory
+ * (or the structure has an invalid dd_stat). */
+ return (struct dirent *) 0;
+ }
+ else if (dirp->dd_stat == 0)
+ {
+ /* We haven't started the search yet. */
+ /* Start the search */
+ dirp->dd_handle = _findfirst (dirp->dd_name, &(dirp->dd_dta));
+
+ if (dirp->dd_handle == -1)
+ {
+ /* Whoops! Seems there are no files in that
+ * directory. */
+ dirp->dd_stat = -1;
+ }
+ else
+ {
+ dirp->dd_stat = 1;
+ }
+ }
+ else
+ {
+ /* Get the next search entry. */
+ if (_findnext (dirp->dd_handle, &(dirp->dd_dta)))
+ {
+ /* We are off the end or otherwise error. */
+ _findclose (dirp->dd_handle);
+ dirp->dd_handle = -1;
+ dirp->dd_stat = -1;
+ }
+ else
+ {
+ /* Update the status to indicate the correct
+ * number. */
+ dirp->dd_stat++;
+ }
+ }
+
+ if (dirp->dd_stat > 0)
+ {
+ /* Successfully got an entry. Everything about the file is
+ * already appropriately filled in except the length of the
+ * file name. */
+ dirp->dd_dir.d_namlen = strlen (dirp->dd_dir.d_name);
+ return &dirp->dd_dir;
+ }
+
+ return (struct dirent *) 0;
+}
+
+
+/*
+ * closedir
+ *
+ * Frees up resources allocated by opendir.
+ */
+int
+closedir (DIR * dirp)
+{
+ int rc;
+
+ errno = 0;
+ rc = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+
+ if (dirp->dd_handle != -1)
+ {
+ rc = _findclose (dirp->dd_handle);
+ }
+
+ /* Delete the dir structure. */
+ free (dirp);
+
+ return rc;
+}
+
+/*
+ * rewinddir
+ *
+ * Return to the beginning of the directory "stream". We simply call findclose
+ * and then reset things like an opendir.
+ */
+void
+rewinddir (DIR * dirp)
+{
+ errno = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return;
+ }
+
+ if (dirp->dd_handle != -1)
+ {
+ _findclose (dirp->dd_handle);
+ }
+
+ dirp->dd_handle = -1;
+ dirp->dd_stat = 0;
+}
+
+/*
+ * telldir
+ *
+ * Returns the "position" in the "directory stream" which can be used with
+ * seekdir to go back to an old entry. We simply return the value in stat.
+ */
+long
+telldir (DIR * dirp)
+{
+ errno = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+ return dirp->dd_stat;
+}
+
+/*
+ * seekdir
+ *
+ * Seek to an entry previously returned by telldir. We rewind the directory
+ * and call readdir repeatedly until either dd_stat is the position number
+ * or -1 (off the end). This is not perfect, in that the directory may
+ * have changed while we weren't looking. But that is probably the case with
+ * any such system.
+ */
+void
+seekdir (DIR * dirp, long lPos)
+{
+ errno = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return;
+ }
+
+ if (lPos < -1)
+ {
+ /* Seeking to an invalid position. */
+ errno = EINVAL;
+ return;
+ }
+ else if (lPos == -1)
+ {
+ /* Seek past end. */
+ if (dirp->dd_handle != -1)
+ {
+ _findclose (dirp->dd_handle);
+ }
+ dirp->dd_handle = -1;
+ dirp->dd_stat = -1;
+ }
+ else
+ {
+ /* Rewind and read forward to the appropriate index. */
+ rewinddir (dirp);
+
+ while ((dirp->dd_stat < lPos) && readdir (dirp))
+ ;
+ }
+}
diff --git a/MSVC/readline/dirent.h b/MSVC/readline/dirent.h
index df93f77..011fc8f 100644
--- a/MSVC/readline/dirent.h
+++ b/MSVC/readline/dirent.h
@@ -1,147 +1,147 @@
-/*
- * DIRENT.H (formerly DIRLIB.H)
- *
- * by M. J. Weinstein Released to public domain 1-Jan-89
- *
- * Because I have heard that this feature (opendir, readdir, closedir)
- * it so useful for programmers coming from UNIX or attempting to port
- * UNIX code, and because it is reasonably light weight, I have included
- * it in the Mingw32 package. I have also added an implementation of
- * rewinddir, seekdir and telldir.
- * - Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
- *
- * This code is distributed in the hope that is will be useful but
- * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
- * DISCLAIMED. This includeds but is not limited to warranties of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Revision: 1.2 $
- * $Author: pixel $
- * $Date: 2004-11-27 21:44:17 $
- *
- */
-
-#ifndef __STRICT_ANSI__
-
-#ifndef _DIRENT_H_
-#define _DIRENT_H_
-
-/* All the headers include this file. */
-//#include <_mingw.h>
-
-#include <io.h>
-
-#ifndef RC_INVOKED
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct dirent
-{
- long d_ino; /* Always zero. */
- unsigned short d_reclen; /* Always zero. */
- unsigned short d_namlen; /* Length of name in d_name. */
- char* d_name; /* File name. */
- /* NOTE: The name in the dirent structure points to the name in the
- * finddata_t structure in the DIR. */
-};
-
-/*
- * This is an internal data structure. Good programmers will not use it
- * except as an argument to one of the functions below.
- * dd_stat field is now int (was short in older versions).
- */
-typedef struct
-{
- /* disk transfer area for this dir */
- struct _finddata_t dd_dta;
-
- /* dirent struct to return from dir (NOTE: this makes this thread
- * safe as long as only one thread uses a particular DIR struct at
- * a time) */
- struct dirent dd_dir;
-
- /* _findnext handle */
- long dd_handle;
-
- /*
- * Status of search:
- * 0 = not started yet (next entry to read is first entry)
- * -1 = off the end
- * positive = 0 based index of next entry
- */
- int dd_stat;
-
- /* given path for dir with search pattern (struct is extended) */
- char dd_name[1];
-} DIR;
-
-DIR* __cdecl opendir (const char*);
-struct dirent* __cdecl readdir (DIR*);
-int __cdecl closedir (DIR*);
-void __cdecl rewinddir (DIR*);
-long __cdecl telldir (DIR*);
-void __cdecl seekdir (DIR*, long);
-
-
-/* wide char versions */
-
-struct _wdirent
-{
- long d_ino; /* Always zero. */
- unsigned short d_reclen; /* Always zero. */
- unsigned short d_namlen; /* Length of name in d_name. */
- wchar_t* d_name; /* File name. */
- /* NOTE: The name in the dirent structure points to the name in the * wfinddata_t structure in the _WDIR. */
-};
-
-/*
- * This is an internal data structure. Good programmers will not use it
- * except as an argument to one of the functions below.
- */
-typedef struct
-{
- /* disk transfer area for this dir */
- struct _wfinddata_t dd_dta;
-
- /* dirent struct to return from dir (NOTE: this makes this thread
- * safe as long as only one thread uses a particular DIR struct at
- * a time) */
- struct _wdirent dd_dir;
-
- /* _findnext handle */
- long dd_handle;
-
- /*
- * Status of search:
- * 0 = not started yet (next entry to read is first entry)
- * -1 = off the end
- * positive = 0 based index of next entry
- */
- int dd_stat;
-
- /* given path for dir with search pattern (struct is extended) */
- wchar_t dd_name[1];
-} _WDIR;
-
-
-
-_WDIR* __cdecl _wopendir (const wchar_t*);
-struct _wdirent* __cdecl _wreaddir (_WDIR*);
-int __cdecl _wclosedir (_WDIR*);
-void __cdecl _wrewinddir (_WDIR*);
-long __cdecl _wtelldir (_WDIR*);
-void __cdecl _wseekdir (_WDIR*, long);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* Not RC_INVOKED */
-
-#endif /* Not _DIRENT_H_ */
-
-#endif /* Not __STRICT_ANSI__ */
-
+/*
+ * DIRENT.H (formerly DIRLIB.H)
+ *
+ * by M. J. Weinstein Released to public domain 1-Jan-89
+ *
+ * Because I have heard that this feature (opendir, readdir, closedir)
+ * it so useful for programmers coming from UNIX or attempting to port
+ * UNIX code, and because it is reasonably light weight, I have included
+ * it in the Mingw32 package. I have also added an implementation of
+ * rewinddir, seekdir and telldir.
+ * - Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ * This code is distributed in the hope that is will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includeds but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.3 $
+ * $Author: pixel $
+ * $Date: 2004-11-27 21:47:24 $
+ *
+ */
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _DIRENT_H_
+#define _DIRENT_H_
+
+/* All the headers include this file. */
+//#include <_mingw.h>
+
+#include <io.h>
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dirent
+{
+ long d_ino; /* Always zero. */
+ unsigned short d_reclen; /* Always zero. */
+ unsigned short d_namlen; /* Length of name in d_name. */
+ char* d_name; /* File name. */
+ /* NOTE: The name in the dirent structure points to the name in the
+ * finddata_t structure in the DIR. */
+};
+
+/*
+ * This is an internal data structure. Good programmers will not use it
+ * except as an argument to one of the functions below.
+ * dd_stat field is now int (was short in older versions).
+ */
+typedef struct
+{
+ /* disk transfer area for this dir */
+ struct _finddata_t dd_dta;
+
+ /* dirent struct to return from dir (NOTE: this makes this thread
+ * safe as long as only one thread uses a particular DIR struct at
+ * a time) */
+ struct dirent dd_dir;
+
+ /* _findnext handle */
+ long dd_handle;
+
+ /*
+ * Status of search:
+ * 0 = not started yet (next entry to read is first entry)
+ * -1 = off the end
+ * positive = 0 based index of next entry
+ */
+ int dd_stat;
+
+ /* given path for dir with search pattern (struct is extended) */
+ char dd_name[1];
+} DIR;
+
+DIR* __cdecl opendir (const char*);
+struct dirent* __cdecl readdir (DIR*);
+int __cdecl closedir (DIR*);
+void __cdecl rewinddir (DIR*);
+long __cdecl telldir (DIR*);
+void __cdecl seekdir (DIR*, long);
+
+
+/* wide char versions */
+
+struct _wdirent
+{
+ long d_ino; /* Always zero. */
+ unsigned short d_reclen; /* Always zero. */
+ unsigned short d_namlen; /* Length of name in d_name. */
+ wchar_t* d_name; /* File name. */
+ /* NOTE: The name in the dirent structure points to the name in the * wfinddata_t structure in the _WDIR. */
+};
+
+/*
+ * This is an internal data structure. Good programmers will not use it
+ * except as an argument to one of the functions below.
+ */
+typedef struct
+{
+ /* disk transfer area for this dir */
+ struct _wfinddata_t dd_dta;
+
+ /* dirent struct to return from dir (NOTE: this makes this thread
+ * safe as long as only one thread uses a particular DIR struct at
+ * a time) */
+ struct _wdirent dd_dir;
+
+ /* _findnext handle */
+ long dd_handle;
+
+ /*
+ * Status of search:
+ * 0 = not started yet (next entry to read is first entry)
+ * -1 = off the end
+ * positive = 0 based index of next entry
+ */
+ int dd_stat;
+
+ /* given path for dir with search pattern (struct is extended) */
+ wchar_t dd_name[1];
+} _WDIR;
+
+
+
+_WDIR* __cdecl _wopendir (const wchar_t*);
+struct _wdirent* __cdecl _wreaddir (_WDIR*);
+int __cdecl _wclosedir (_WDIR*);
+void __cdecl _wrewinddir (_WDIR*);
+long __cdecl _wtelldir (_WDIR*);
+void __cdecl _wseekdir (_WDIR*, long);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Not RC_INVOKED */
+
+#endif /* Not _DIRENT_H_ */
+
+#endif /* Not __STRICT_ANSI__ */
+
diff --git a/MSVC/readline/display.c b/MSVC/readline/display.c
index 4ca0f05..3643b6f 100644
--- a/MSVC/readline/display.c
+++ b/MSVC/readline/display.c
@@ -1,2301 +1,2301 @@
-/* display.c -- readline redisplay facility. */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#include "posixstat.h"
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-/* Termcap library stuff. */
-#include "tcap.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-#if defined _WIN32
- #include <windows.h>
- extern int haveConsole; /* imported from rltty.c */
- extern HANDLE hStdout, hStdin;
- #if defined (WITH_MINI_MOUSE)
- extern COORD rlScreenEnd;
- extern int rlScreenMax;
- #endif /* WITH_MINI_MOUSE */
-#endif /* _WIN32 */
-
-#if !defined (strchr) && !defined (__STDC__) && !defined _MSC_VER
-extern char *strchr (), *strrchr ();
-#endif /* !strchr && !__STDC__ */
-
-#if defined (HACK_TERMCAP_MOTION)
-extern char *_rl_term_forward_char;
-#endif
-
-static void update_line PARAMS((char *, char *, int, int, int, int));
-
-#if defined _WIN32
-# define space_to_eol(count) _rl_clear_to_eol(count)
-# undef putc
-# define putc(ch,x) _rl_output_character_function (ch)
-# define cr() _rl_move_cursor_relative (0, 0)
-#else
-static void space_to_eol PARAMS((int));
-static void delete_chars PARAMS((int));
-static void insert_some_chars PARAMS((char *, int, int));
-static void cr PARAMS((void));
-#endif
-
-#if defined (HANDLE_MULTIBYTE)
-static int _rl_col_width PARAMS((char *, int, int));
-static int *_rl_wrapped_line;
-#else
-# define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s))
-#endif
-
-static int *inv_lbreaks, *vis_lbreaks;
-static int inv_lbsize, vis_lbsize;
-
-/* Heuristic used to decide whether it is faster to move from CUR to NEW
- by backing up or outputting a carriage return and moving forward. */
-#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
-
-/* **************************************************************** */
-/* */
-/* Display stuff */
-/* */
-/* **************************************************************** */
-
-/* This is the stuff that is hard for me. I never seem to write good
- display routines in C. Let's see how I do this time. */
-
-/* (PWP) Well... Good for a simple line updater, but totally ignores
- the problems of input lines longer than the screen width.
-
- update_line and the code that calls it makes a multiple line,
- automatically wrapping line update. Careful attention needs
- to be paid to the vertical position variables. */
-
-/* Keep two buffers; one which reflects the current contents of the
- screen, and the other to draw what we think the new contents should
- be. Then compare the buffers, and make whatever changes to the
- screen itself that we should. Finally, make the buffer that we
- just drew into be the one which reflects the current contents of the
- screen, and place the cursor where it belongs.
-
- Commands that want to can fix the display themselves, and then let
- this function know that the display has been fixed by setting the
- RL_DISPLAY_FIXED variable. This is good for efficiency. */
-
-/* Application-specific redisplay function. */
-rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
-
-/* Global variables declared here. */
-/* What YOU turn on when you have handled all redisplay yourself. */
-int rl_display_fixed = 0;
-
-int _rl_suppress_redisplay = 0;
-
-/* The stuff that gets printed out before the actual text of the line.
- This is usually pointing to rl_prompt. */
-char *rl_display_prompt = (char *)NULL;
-
-/* Pseudo-global variables declared here. */
-/* The visible cursor position. If you print some text, adjust this. */
-int _rl_last_c_pos = 0;
-int _rl_last_v_pos = 0;
-
-/* Number of lines currently on screen minus 1. */
-int _rl_vis_botlin = 0;
-
-/* Variables used only in this file. */
-/* The last left edge of text that was displayed. This is used when
- doing horizontal scrolling. It shifts in thirds of a screenwidth. */
-static int last_lmargin;
-
-/* The line display buffers. One is the line currently displayed on
- the screen. The other is the line about to be displayed. */
-static char *visible_line = (char *)NULL;
-static char *invisible_line = (char *)NULL;
-
-/* A buffer for `modeline' messages. */
-static char msg_buf[128];
-
-/* Non-zero forces the redisplay even if we thought it was unnecessary. */
-static int forced_display;
-
-/* Default and initial buffer size. Can grow. */
-static int line_size = 1024;
-
-/* Variables to keep track of the expanded prompt string, which may
- include invisible characters. */
-
-static char *local_prompt, *local_prompt_prefix;
-static int prompt_visible_length, prompt_prefix_length;
-
-/* The number of invisible characters in the line currently being
- displayed on the screen. */
-static int visible_wrap_offset;
-
-/* The number of invisible characters in the prompt string. Static so it
- can be shared between rl_redisplay and update_line */
-static int wrap_offset;
-
-/* The index of the last invisible character in the prompt string. */
-static int prompt_last_invisible;
-
-/* The length (buffer offset) of the first line of the last (possibly
- multi-line) buffer displayed on the screen. */
-static int visible_first_line_len;
-
-/* Number of invisible characters on the first physical line of the prompt.
- Only valid when the number of physical characters in the prompt exceeds
- (or is equal to) _rl_screenwidth. */
-static int prompt_invis_chars_first_line;
-
-static int prompt_last_screen_line;
-
-/* Expand the prompt string S and return the number of visible
- characters in *LP, if LP is not null. This is currently more-or-less
- a placeholder for expansion. LIP, if non-null is a place to store the
- index of the last invisible character in the returned string. NIFLP,
- if non-zero, is a place to store the number of invisible characters in
- the first prompt line. */
-
-/* Current implementation:
- \001 (^A) start non-visible characters
- \002 (^B) end non-visible characters
- all characters except \001 and \002 (following a \001) are copied to
- the returned string; all characters except those between \001 and
- \002 are assumed to be `visible'. */
-
-static char *
-expand_prompt (pmt, lp, lip, niflp)
- char *pmt;
- int *lp, *lip, *niflp;
-{
- char *r, *ret, *p;
- int l, rl, last, ignoring, ninvis, invfl;
-
- /* Short-circuit if we can. */
- if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
- {
- r = savestring (pmt);
- if (lp)
- *lp = strlen (r);
- return r;
- }
-
- l = strlen (pmt);
- r = ret = (char *)xmalloc (l + 1);
-
- invfl = 0; /* invisible chars in first line of prompt */
-
- for (rl = ignoring = last = ninvis = 0, p = pmt; p && *p; p++)
- {
- /* This code strips the invisible character string markers
- RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
- if (*p == RL_PROMPT_START_IGNORE)
- {
- ignoring++;
- continue;
- }
- else if (ignoring && *p == RL_PROMPT_END_IGNORE)
- {
- ignoring = 0;
- last = r - ret - 1;
- continue;
- }
- else
- {
- *r++ = *p;
- if (!ignoring)
- rl++;
- else
- ninvis++;
- if (rl == _rl_screenwidth)
- invfl = ninvis;
- }
- }
-
- if (rl < _rl_screenwidth)
- invfl = ninvis;
-
- *r = '\0';
- if (lp)
- *lp = rl;
- if (lip)
- *lip = last;
- if (niflp)
- *niflp = invfl;
- return ret;
-}
-
-/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from
- PMT and return the rest of PMT. */
-char *
-_rl_strip_prompt (pmt)
- char *pmt;
-{
- char *ret;
-
- ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL);
- return ret;
-}
-
-/*
- * Expand the prompt string into the various display components, if
- * necessary.
- *
- * local_prompt = expanded last line of string in rl_display_prompt
- * (portion after the final newline)
- * local_prompt_prefix = portion before last newline of rl_display_prompt,
- * expanded via expand_prompt
- * prompt_visible_length = number of visible characters in local_prompt
- * prompt_prefix_length = number of visible characters in local_prompt_prefix
- *
- * This function is called once per call to readline(). It may also be
- * called arbitrarily to expand the primary prompt.
- *
- * The return value is the number of visible characters on the last line
- * of the (possibly multi-line) prompt.
- */
-int
-rl_expand_prompt (prompt)
- char *prompt;
-{
- char *p, *t;
- int c;
-
- /* Clear out any saved values. */
- FREE (local_prompt);
- FREE (local_prompt_prefix);
-
- local_prompt = local_prompt_prefix = (char *)0;
- prompt_last_invisible = prompt_visible_length = 0;
-
- if (prompt == 0 || *prompt == 0)
- return (0);
-
- p = strrchr (prompt, '\n');
- if (!p)
- {
- /* The prompt is only one logical line, though it might wrap. */
- local_prompt = expand_prompt (prompt, &prompt_visible_length,
- &prompt_last_invisible,
- &prompt_invis_chars_first_line);
- local_prompt_prefix = (char *)0;
- return (prompt_visible_length);
- }
- else
- {
- /* The prompt spans multiple lines. */
- t = ++p;
- local_prompt = expand_prompt (p, &prompt_visible_length,
- &prompt_last_invisible,
- &prompt_invis_chars_first_line);
- c = *t; *t = '\0';
- /* The portion of the prompt string up to and including the
- final newline is now null-terminated. */
- local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
- (int *)NULL,
- &prompt_invis_chars_first_line);
- *t = c;
- return (prompt_prefix_length);
- }
-}
-
-/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated
- arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE
- and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is
- increased. If the lines have already been allocated, this ensures that
- they can hold at least MINSIZE characters. */
-static void
-init_line_structures (minsize)
- int minsize;
-{
- register int n;
-
- if (invisible_line == 0) /* initialize it */
- {
- if (line_size < minsize)
- line_size = minsize;
- visible_line = (char *)xmalloc (line_size);
- invisible_line = (char *)xmalloc (line_size);
- }
- else if (line_size < minsize) /* ensure it can hold MINSIZE chars */
- {
- line_size *= 2;
- if (line_size < minsize)
- line_size = minsize;
- visible_line = (char *)xrealloc (visible_line, line_size);
- invisible_line = (char *)xrealloc (invisible_line, line_size);
- }
-
- for (n = minsize; n < line_size; n++)
- {
- visible_line[n] = 0;
- invisible_line[n] = 1;
- }
-
- if (vis_lbreaks == 0)
- {
- /* should be enough. */
- inv_lbsize = vis_lbsize = 256;
- inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
- vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
-#if defined (HANDLE_MULTIBYTE)
- _rl_wrapped_line = (int *)xmalloc (vis_lbsize * sizeof (int));
-#endif
- inv_lbreaks[0] = vis_lbreaks[0] = 0;
- }
-}
-
-/* Basic redisplay algorithm. */
-void
-rl_redisplay ()
-{
- register int in, out, c, linenum, cursor_linenum;
- register char *line;
- int c_pos, inv_botlin, lb_botlin, lb_linenum;
- int newlines, lpos, temp;
- char *prompt_this_line;
-#if defined (HANDLE_MULTIBYTE)
- wchar_t wc;
- size_t wc_bytes;
- int wc_width;
- mbstate_t ps;
- int _rl_wrapped_multicolumn = 0;
-#endif
-
- if (!readline_echoing_p)
- return;
-
- if (!rl_display_prompt)
- rl_display_prompt = "";
-
- if (invisible_line == 0)
- {
- init_line_structures (0);
- rl_on_new_line ();
- }
-
- /* Draw the line into the buffer. */
- c_pos = -1;
-
- line = invisible_line;
- out = inv_botlin = 0;
-
- /* Mark the line as modified or not. We only do this for history
- lines. */
- if (_rl_mark_modified_lines && current_history () && rl_undo_list)
- {
- line[out++] = '*';
- line[out] = '\0';
- }
-
- /* If someone thought that the redisplay was handled, but the currently
- visible line has a different modification state than the one about
- to become visible, then correct the caller's misconception. */
- if (visible_line[0] != invisible_line[0])
- rl_display_fixed = 0;
-
- /* If the prompt to be displayed is the `primary' readline prompt (the
- one passed to readline()), use the values we have already expanded.
- If not, use what's already in rl_display_prompt. WRAP_OFFSET is the
- number of non-visible characters in the prompt string. */
- if (rl_display_prompt == rl_prompt || local_prompt)
- {
- int local_len = local_prompt ? strlen (local_prompt) : 0;
- if (local_prompt_prefix && forced_display)
- _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
-
- if (local_len > 0)
- {
- temp = local_len + out + 2;
- if (temp >= line_size)
- {
- line_size = (temp + 1024) - (temp % 1024);
- visible_line = (char *)xrealloc (visible_line, line_size);
- line = invisible_line = (char *)xrealloc (invisible_line, line_size);
- }
- strncpy (line + out, local_prompt, local_len);
- out += local_len;
- }
- line[out] = '\0';
- wrap_offset = local_len - prompt_visible_length;
- }
- else
- {
- int pmtlen;
- prompt_this_line = strrchr (rl_display_prompt, '\n');
- if (!prompt_this_line)
- prompt_this_line = rl_display_prompt;
- else
- {
- prompt_this_line++;
- pmtlen = prompt_this_line - rl_display_prompt; /* temp var */
- if (forced_display)
- {
- _rl_output_some_chars (rl_display_prompt, pmtlen);
- /* Make sure we are at column zero even after a newline,
- regardless of the state of terminal output processing. */
- if (pmtlen < 2 || prompt_this_line[-2] != '\r')
- cr ();
- }
- }
-
- pmtlen = strlen (prompt_this_line);
- temp = pmtlen + out + 2;
- if (temp >= line_size)
- {
- line_size = (temp + 1024) - (temp % 1024);
- visible_line = (char *)xrealloc (visible_line, line_size);
- line = invisible_line = (char *)xrealloc (invisible_line, line_size);
- }
- strncpy (line + out, prompt_this_line, pmtlen);
- out += pmtlen;
- line[out] = '\0';
- wrap_offset = prompt_invis_chars_first_line = 0;
- }
-
-#define CHECK_INV_LBREAKS() \
- do { \
- if (newlines >= (inv_lbsize - 2)) \
- { \
- inv_lbsize *= 2; \
- inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
- } \
- } while (0)
-
-#if defined (HANDLE_MULTIBYTE)
-#define CHECK_LPOS() \
- do { \
- lpos++; \
- if (lpos >= _rl_screenwidth) \
- { \
- if (newlines >= (inv_lbsize - 2)) \
- { \
- inv_lbsize *= 2; \
- inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
- _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \
- } \
- inv_lbreaks[++newlines] = out; \
- _rl_wrapped_line[newlines] = _rl_wrapped_multicolumn; \
- lpos = 0; \
- } \
- } while (0)
-#else
-#define CHECK_LPOS() \
- do { \
- lpos++; \
- if (lpos >= _rl_screenwidth) \
- { \
- if (newlines >= (inv_lbsize - 2)) \
- { \
- inv_lbsize *= 2; \
- inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
- } \
- inv_lbreaks[++newlines] = out; \
- lpos = 0; \
- } \
- } while (0)
-#endif
-
- /* inv_lbreaks[i] is where line i starts in the buffer. */
- inv_lbreaks[newlines = 0] = 0;
- lpos = out - wrap_offset;
-#if defined (HANDLE_MULTIBYTE)
- memset (_rl_wrapped_line, 0, vis_lbsize);
-#endif
-
- /* prompt_invis_chars_first_line is the number of invisible characters in
- the first physical line of the prompt.
- wrap_offset - prompt_invis_chars_first_line is the number of invis
- chars on the second line. */
-
- /* what if lpos is already >= _rl_screenwidth before we start drawing the
- contents of the command line? */
- while (lpos >= _rl_screenwidth)
- {
- /* fix from Darin Johnson <darin@acuson.com> for prompt string with
- invisible characters that is longer than the screen width. The
- prompt_invis_chars_first_line variable could be made into an array
- saying how many invisible characters there are per line, but that's
- probably too much work for the benefit gained. How many people have
- prompts that exceed two physical lines? */
- temp = ((newlines + 1) * _rl_screenwidth) +
-#if 0
- ((newlines == 0) ? prompt_invis_chars_first_line : 0) +
-#else
- ((newlines == 0 && local_prompt_prefix == 0) ? prompt_invis_chars_first_line : 0) +
-#endif
- ((newlines == 1) ? wrap_offset : 0);
-
- inv_lbreaks[++newlines] = temp;
- lpos -= _rl_screenwidth;
- }
-
- prompt_last_screen_line = newlines;
-
- /* Draw the rest of the line (after the prompt) into invisible_line, keeping
- track of where the cursor is (c_pos), the number of the line containing
- the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin).
- It maintains an array of line breaks for display (inv_lbreaks).
- This handles expanding tabs for display and displaying meta characters. */
- lb_linenum = 0;
-#if defined (HANDLE_MULTIBYTE)
- in = 0;
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- memset (&ps, 0, sizeof (mbstate_t));
- wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
- }
- else
- wc_bytes = 1;
- while (in < rl_end)
-#else
- for (in = 0; in < rl_end; in++)
-#endif
- {
- c = (unsigned char)rl_line_buffer[in];
-
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- if (wc_bytes == (size_t)-1 || wc_bytes == (size_t)-2)
- {
- /* Byte sequence is invalid or shortened. Assume that the
- first byte represents a character. */
- wc_bytes = 1;
- /* Assume that a character occupies a single column. */
- wc_width = 1;
- memset (&ps, 0, sizeof (mbstate_t));
- }
- else if (wc_bytes == (size_t)0)
- break; /* Found '\0' */
- else
- {
- temp = wcwidth (wc);
- wc_width = (temp < 0) ? 1 : temp;
- }
- }
-#endif
-
- if (out + 8 >= line_size) /* XXX - 8 for \t */
- {
- line_size *= 2;
- visible_line = (char *)xrealloc (visible_line, line_size);
- invisible_line = (char *)xrealloc (invisible_line, line_size);
- line = invisible_line;
- }
-
- if (in == rl_point)
- {
- c_pos = out;
- lb_linenum = newlines;
- }
-
-#if defined (HANDLE_MULTIBYTE)
- if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */
-#else
- if (META_CHAR (c))
-#endif
- {
- if (_rl_output_meta_chars == 0)
- {
- sprintf (line + out, "\\%o", c);
-
- if (lpos + 4 >= _rl_screenwidth)
- {
- temp = _rl_screenwidth - lpos;
- CHECK_INV_LBREAKS ();
- inv_lbreaks[++newlines] = out + temp;
- lpos = 4 - temp;
- }
- else
- lpos += 4;
-
- out += 4;
- }
- else
- {
- line[out++] = c;
- CHECK_LPOS();
- }
- }
-#if defined (DISPLAY_TABS)
- else if (c == '\t')
- {
- register int newout;
-
-#if 0
- newout = (out | (int)7) + 1;
-#else
- newout = out + 8 - lpos % 8;
-#endif
- temp = newout - out;
- if (lpos + temp >= _rl_screenwidth)
- {
- register int temp2;
- temp2 = _rl_screenwidth - lpos;
- CHECK_INV_LBREAKS ();
- inv_lbreaks[++newlines] = out + temp2;
- lpos = temp - temp2;
- while (out < newout)
- line[out++] = ' ';
- }
- else
- {
- while (out < newout)
- line[out++] = ' ';
- lpos += temp;
- }
- }
-#endif
- else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
- {
- line[out++] = '\0'; /* XXX - sentinel */
- CHECK_INV_LBREAKS ();
- inv_lbreaks[++newlines] = out;
- lpos = 0;
- }
- else if (CTRL_CHAR (c) || c == RUBOUT)
- {
- line[out++] = '^';
- CHECK_LPOS();
- line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
- CHECK_LPOS();
- }
- else
- {
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- register int i;
-
- _rl_wrapped_multicolumn = 0;
-
- if (_rl_screenwidth < lpos + wc_width)
- for (i = lpos; i < _rl_screenwidth; i++)
- {
- /* The space will be removed in update_line() */
- line[out++] = ' ';
- _rl_wrapped_multicolumn++;
- CHECK_LPOS();
- }
- if (in == rl_point)
- {
- c_pos = out;
- lb_linenum = newlines;
- }
- for (i = in; i < in+wc_bytes; i++)
- line[out++] = rl_line_buffer[i];
- for (i = 0; i < wc_width; i++)
- CHECK_LPOS();
- }
- else
- {
- line[out++] = c;
- CHECK_LPOS();
- }
-#else
- line[out++] = c;
- CHECK_LPOS();
-#endif
- }
-
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- in += wc_bytes;
- wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
- }
- else
- in++;
-#endif
-
- }
- line[out] = '\0';
- if (c_pos < 0)
- {
- c_pos = out;
- lb_linenum = newlines;
- }
-
- inv_botlin = lb_botlin = newlines;
- CHECK_INV_LBREAKS ();
- inv_lbreaks[newlines+1] = out;
- cursor_linenum = lb_linenum;
-
- /* C_POS == position in buffer where cursor should be placed.
- CURSOR_LINENUM == line number where the cursor should be placed. */
-
- /* PWP: now is when things get a bit hairy. The visible and invisible
- line buffers are really multiple lines, which would wrap every
- (screenwidth - 1) characters. Go through each in turn, finding
- the changed region and updating it. The line order is top to bottom. */
-
- /* If we can move the cursor up and down, then use multiple lines,
- otherwise, let long lines display in a single terminal line, and
- horizontally scroll it. */
-
- if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
- {
- int nleft, pos, changed_screen_line;
-
- if (!rl_display_fixed || forced_display)
- {
- forced_display = 0;
-
- /* If we have more than a screenful of material to display, then
- only display a screenful. We should display the last screen,
- not the first. */
- if (out >= _rl_screenchars)
- {
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
- else
- out = _rl_screenchars - 1;
- }
-
- /* The first line is at character position 0 in the buffer. The
- second and subsequent lines start at inv_lbreaks[N], offset by
- OFFSET (which has already been calculated above). */
-
-#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
-#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
-#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
-#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
-#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
-#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
-
- /* For each line in the buffer, do the updating display. */
- for (linenum = 0; linenum <= inv_botlin; linenum++)
- {
- update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
- VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
-
- /* If this is the line with the prompt, we might need to
- compensate for invisible characters in the new line. Do
- this only if there is not more than one new line (which
- implies that we completely overwrite the old visible line)
- and the new line is shorter than the old. Make sure we are
- at the end of the new line before clearing. */
- if (linenum == 0 &&
- inv_botlin == 0 && _rl_last_c_pos == out &&
- (wrap_offset > visible_wrap_offset) &&
- (_rl_last_c_pos < visible_first_line_len))
- {
- nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
- if (nleft)
- _rl_clear_to_eol (nleft);
- }
-
- /* Since the new first line is now visible, save its length. */
- if (linenum == 0)
- visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
- }
-
- /* We may have deleted some lines. If so, clear the left over
- blank ones at the bottom out. */
- if (_rl_vis_botlin > inv_botlin)
- {
- char *tt;
- for (; linenum <= _rl_vis_botlin; linenum++)
- {
- tt = VIS_CHARS (linenum);
- _rl_move_vert (linenum);
- _rl_move_cursor_relative (0, tt);
- _rl_clear_to_eol
- ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
- }
- }
- _rl_vis_botlin = inv_botlin;
-
- /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
- different screen line during this redisplay. */
- changed_screen_line = _rl_last_v_pos != cursor_linenum;
- if (changed_screen_line)
- {
- _rl_move_vert (cursor_linenum);
- /* If we moved up to the line with the prompt using _rl_term_up,
- the physical cursor position on the screen stays the same,
- but the buffer position needs to be adjusted to account
- for invisible characters. */
- if (cursor_linenum == 0 && wrap_offset)
- _rl_last_c_pos += wrap_offset;
- }
-
- /* We have to reprint the prompt if it contains invisible
- characters, since it's not generally OK to just reprint
- the characters from the current cursor position. But we
- only need to reprint it if the cursor is before the last
- invisible character in the prompt string. */
- nleft = prompt_visible_length + wrap_offset;
- if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
- _rl_last_c_pos <= prompt_last_invisible && local_prompt)
- {
-#if defined (__MSDOS__)
- putc ('\r', rl_outstream);
-#elif defined _WIN32
- cr ();
-#else
- if (_rl_term_cr)
- tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
- _rl_output_some_chars (local_prompt, nleft);
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- _rl_last_c_pos = _rl_col_width(local_prompt, 0, nleft);
- else
- _rl_last_c_pos = nleft;
- }
-
- /* Where on that line? And where does that line start
- in the buffer? */
- pos = inv_lbreaks[cursor_linenum];
- /* nleft == number of characters in the line buffer between the
- start of the line and the cursor position. */
- nleft = c_pos - pos;
-
- /* Since _rl_backspace() doesn't know about invisible characters in the
- prompt, and there's no good way to tell it, we compensate for
- those characters here and call _rl_backspace() directly. */
- if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
- {
- _rl_backspace (_rl_last_c_pos - nleft);
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- _rl_last_c_pos = _rl_col_width (&visible_line[pos], 0, nleft);
- else
- _rl_last_c_pos = nleft;
- }
-
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- _rl_move_cursor_relative (nleft, &invisible_line[pos]);
- else if (nleft != _rl_last_c_pos)
- _rl_move_cursor_relative (nleft, &invisible_line[pos]);
- }
- }
- else /* Do horizontal scrolling. */
- {
-#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
- int lmargin, ndisp, nleft, phys_c_pos, t;
-
- /* Always at top line. */
- _rl_last_v_pos = 0;
-
- /* Compute where in the buffer the displayed line should start. This
- will be LMARGIN. */
-
- /* The number of characters that will be displayed before the cursor. */
- ndisp = c_pos - wrap_offset;
- nleft = prompt_visible_length + wrap_offset;
- /* Where the new cursor position will be on the screen. This can be
- longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
- phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset);
- t = _rl_screenwidth / 3;
-
- /* If the number of characters had already exceeded the screenwidth,
- last_lmargin will be > 0. */
-
- /* If the number of characters to be displayed is more than the screen
- width, compute the starting offset so that the cursor is about
- two-thirds of the way across the screen. */
- if (phys_c_pos > _rl_screenwidth - 2)
- {
- lmargin = c_pos - (2 * t);
- if (lmargin < 0)
- lmargin = 0;
- /* If the left margin would be in the middle of a prompt with
- invisible characters, don't display the prompt at all. */
- if (wrap_offset && lmargin > 0 && lmargin < nleft)
- lmargin = nleft;
- }
- else if (ndisp < _rl_screenwidth - 2) /* XXX - was -1 */
- lmargin = 0;
- else if (phys_c_pos < 1)
- {
- /* If we are moving back towards the beginning of the line and
- the last margin is no longer correct, compute a new one. */
- lmargin = ((c_pos - 1) / t) * t; /* XXX */
- if (wrap_offset && lmargin > 0 && lmargin < nleft)
- lmargin = nleft;
- }
- else
- lmargin = last_lmargin;
-
- /* If the first character on the screen isn't the first character
- in the display line, indicate this with a special character. */
- if (lmargin > 0)
- line[lmargin] = '<';
-
- /* If SCREENWIDTH characters starting at LMARGIN do not encompass
- the whole line, indicate that with a special character at the
- right edge of the screen. If LMARGIN is 0, we need to take the
- wrap offset into account. */
- t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
- if (t < out)
- line[t - 1] = '>';
-
- if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
- {
- forced_display = 0;
- update_line (&visible_line[last_lmargin],
- &invisible_line[lmargin],
- 0,
- _rl_screenwidth + visible_wrap_offset,
- _rl_screenwidth + (lmargin ? 0 : wrap_offset),
- 0);
-
- /* If the visible new line is shorter than the old, but the number
- of invisible characters is greater, and we are at the end of
- the new line, we need to clear to eol. */
- t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
- if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
- (_rl_last_c_pos == out) &&
- t < visible_first_line_len)
- {
- nleft = _rl_screenwidth - t;
- _rl_clear_to_eol (nleft);
- }
- visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
- if (visible_first_line_len > _rl_screenwidth)
- visible_first_line_len = _rl_screenwidth;
-
- _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
- last_lmargin = lmargin;
- }
- }
- fflush (rl_outstream);
-
- /* Swap visible and non-visible lines. */
- {
- char *vtemp = visible_line;
- int *itemp = vis_lbreaks, ntemp = vis_lbsize;
-
- visible_line = invisible_line;
- invisible_line = vtemp;
-
- vis_lbreaks = inv_lbreaks;
- inv_lbreaks = itemp;
-
- vis_lbsize = inv_lbsize;
- inv_lbsize = ntemp;
-
- rl_display_fixed = 0;
- /* If we are displaying on a single line, and last_lmargin is > 0, we
- are not displaying any invisible characters, so set visible_wrap_offset
- to 0. */
- if (_rl_horizontal_scroll_mode && last_lmargin)
- visible_wrap_offset = 0;
- else
- visible_wrap_offset = wrap_offset;
- }
-}
-
-/* PWP: update_line() is based on finding the middle difference of each
- line on the screen; vis:
-
- /old first difference
- /beginning of line | /old last same /old EOL
- v v v v
-old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
-new: eddie> Oh, my little buggy says to me, as lurgid as
- ^ ^ ^ ^
- \beginning of line | \new last same \new end of line
- \new first difference
-
- All are character pointers for the sake of speed. Special cases for
- no differences, as well as for end of line additions must be handled.
-
- Could be made even smarter, but this works well enough */
-static void
-update_line (old, new, current_line, omax, nmax, inv_botlin)
- register char *old, *new;
- int current_line, omax, nmax, inv_botlin;
-{
- register char *ofd, *ols, *oe, *nfd, *nls, *ne;
- int temp, lendiff, wsatend, od, nd;
- int current_invis_chars;
- int col_lendiff, col_temp;
-#if defined (HANDLE_MULTIBYTE)
- mbstate_t ps_new, ps_old;
- int new_offset, old_offset, tmp;
-#endif
-
- /* If we're at the right edge of a terminal that supports xn, we're
- ready to wrap around, so do so. This fixes problems with knowing
- the exact cursor position and cut-and-paste with certain terminal
- emulators. In this calculation, TEMP is the physical screen
- position of the cursor. */
- temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
- if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
- && _rl_last_v_pos == current_line - 1)
- {
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- wchar_t wc;
- mbstate_t ps;
- int tempwidth, bytes;
- size_t ret;
-
- /* This fixes only double-column characters, but if the wrapped
- character comsumes more than three columns, spaces will be
- inserted in the string buffer. */
- if (_rl_wrapped_line[current_line] > 0)
- _rl_clear_to_eol (_rl_wrapped_line[current_line]);
-
- memset (&ps, 0, sizeof (mbstate_t));
- ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
- if (ret == (size_t)-1 || ret == (size_t)-2)
- {
- tempwidth = 1;
- ret = 1;
- }
- else if (ret == 0)
- tempwidth = 0;
- else
- tempwidth = wcwidth (wc);
-
- if (tempwidth > 0)
- {
- int count;
- bytes = ret;
- for (count = 0; count < bytes; count++)
- putc (new[count], rl_outstream);
- _rl_last_c_pos = tempwidth;
- _rl_last_v_pos++;
- memset (&ps, 0, sizeof (mbstate_t));
- ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
- if (ret != 0 && bytes != 0)
- {
- if (ret == (size_t)-1 || ret == (size_t)-2)
- memmove (old+bytes, old+1, strlen (old+1));
- else
- memmove (old+bytes, old+ret, strlen (old+ret));
- memcpy (old, new, bytes);
- }
- }
- else
- {
- putc (' ', rl_outstream);
- _rl_last_c_pos = 1;
- _rl_last_v_pos++;
- if (old[0] && new[0])
- old[0] = new[0];
- }
- }
- else
-#endif
- {
- if (new[0])
- putc (new[0], rl_outstream);
- else
- putc (' ', rl_outstream);
- _rl_last_c_pos = 1; /* XXX */
- _rl_last_v_pos++;
- if (old[0] && new[0])
- old[0] = new[0];
- }
- }
-
-
- /* Find first difference. */
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- memset (&ps_new, 0, sizeof(mbstate_t));
- memset (&ps_old, 0, sizeof(mbstate_t));
-
- new_offset = old_offset = 0;
- for (ofd = old, nfd = new;
- (ofd - old < omax) && *ofd &&
- _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
- {
- old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
- new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
- ofd = old + old_offset;
- nfd = new + new_offset;
- }
- }
- else
-#endif
- for (ofd = old, nfd = new;
- (ofd - old < omax) && *ofd && (*ofd == *nfd);
- ofd++, nfd++)
- ;
-
- /* Move to the end of the screen line. ND and OD are used to keep track
- of the distance between ne and new and oe and old, respectively, to
- move a subtraction out of each loop. */
- for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
- for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
-
- /* If no difference, continue to next line. */
- if (ofd == oe && nfd == ne)
- return;
-
- wsatend = 1; /* flag for trailing whitespace */
-
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
- nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
- while ((ols > ofd) && (nls > nfd))
- {
- memset (&ps_old, 0, sizeof (mbstate_t));
- memset (&ps_new, 0, sizeof (mbstate_t));
-
- _rl_adjust_point (old, ols - old, &ps_old);
- _rl_adjust_point (new, nls - new, &ps_new);
-
- if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
- break;
-
- if (*ols == ' ')
- wsatend = 0;
-
- ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
- nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
- }
- }
- else
- {
-#endif /* HANDLE_MULTIBYTE */
- ols = oe - 1; /* find last same */
- nls = ne - 1;
- while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
- {
- if (*ols != ' ')
- wsatend = 0;
- ols--;
- nls--;
- }
-#if defined (HANDLE_MULTIBYTE)
- }
-#endif
-
- if (wsatend)
- {
- ols = oe;
- nls = ne;
- }
-#if defined (HANDLE_MULTIBYTE)
- /* This may not work for stateful encoding, but who cares? To handle
- stateful encoding properly, we have to scan each string from the
- beginning and compare. */
- else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
-#else
- else if (*ols != *nls)
-#endif
- {
- if (*ols) /* don't step past the NUL */
- {
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
- else
- ols++;
- }
- if (*nls)
- {
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
- else
- nls++;
- }
- }
-
- /* count of invisible characters in the current invisible line. */
- current_invis_chars = W_OFFSET (current_line, wrap_offset);
- if (_rl_last_v_pos != current_line)
- {
- _rl_move_vert (current_line);
- if (current_line == 0 && visible_wrap_offset)
- _rl_last_c_pos += visible_wrap_offset;
- }
-
- /* If this is the first line and there are invisible characters in the
- prompt string, and the prompt string has not changed, and the current
- cursor position is before the last invisible character in the prompt,
- and the index of the character to move to is past the end of the prompt
- string, then redraw the entire prompt string. We can only do this
- reliably if the terminal supports a `cr' capability.
-
- This is not an efficiency hack -- there is a problem with redrawing
- portions of the prompt string if they contain terminal escape
- sequences (like drawing the `unbold' sequence without a corresponding
- `bold') that manifests itself on certain terminals. */
-
- lendiff = local_prompt ? strlen (local_prompt) : 0;
- od = ofd - old; /* index of first difference in visible line */
- if (current_line == 0 && !_rl_horizontal_scroll_mode &&
- _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
- od >= lendiff && _rl_last_c_pos <= prompt_last_invisible)
- {
-#if defined (__MSDOS__)
- putc ('\r', rl_outstream);
-#elif defined _WIN32
- cr();
-#else
- tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
- _rl_output_some_chars (local_prompt, lendiff);
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff);
- else
- _rl_last_c_pos = lendiff;
- }
-
- _rl_move_cursor_relative (od, old);
-
- /* if (len (new) > len (old))
- lendiff == difference in buffer
- col_lendiff == difference on screen
- When not using multibyte characters, these are equal */
- lendiff = (nls - nfd) - (ols - ofd);
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- col_lendiff = _rl_col_width (new, nfd - new, nls - new) - _rl_col_width (old, ofd - old, ols - old);
- else
- col_lendiff = lendiff;
-
- /* If we are changing the number of invisible characters in a line, and
- the spot of first difference is before the end of the invisible chars,
- lendiff needs to be adjusted. */
- if (current_line == 0 && !_rl_horizontal_scroll_mode &&
- current_invis_chars != visible_wrap_offset)
- {
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- lendiff += visible_wrap_offset - current_invis_chars;
- col_lendiff += visible_wrap_offset - current_invis_chars;
- }
- else
- {
- lendiff += visible_wrap_offset - current_invis_chars;
- col_lendiff = lendiff;
- }
- }
-
- /* Insert (diff (len (old), len (new)) ch. */
- temp = ne - nfd;
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- col_temp = _rl_col_width (new, nfd - new, ne - new);
- else
- col_temp = temp;
-
- if (col_lendiff > 0) /* XXX - was lendiff */
- {
-#if !defined _WIN32
- /* Non-zero if we're increasing the number of lines. */
- int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
- /* Sometimes it is cheaper to print the characters rather than
- use the terminal's capabilities. If we're growing the number
- of lines, make sure we actually cause the new line to wrap
- around on auto-wrapping terminals. */
- if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
- {
- /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
- _rl_horizontal_scroll_mode == 1, inserting the characters with
- _rl_term_IC or _rl_term_ic will screw up the screen because of the
- invisible characters. We need to just draw them. */
- if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
- lendiff <= prompt_visible_length || !current_invis_chars))
- {
- insert_some_chars (nfd, lendiff, col_lendiff);
- _rl_last_c_pos += col_lendiff;
- }
- else if (*ols == 0)
- {
- /* At the end of a line the characters do not have to
- be "inserted". They can just be placed on the screen. */
- /* However, this screws up the rest of this block, which
- assumes you've done the insert because you can. */
- _rl_output_some_chars (nfd, lendiff);
- _rl_last_c_pos += col_lendiff;
- }
- else
- {
- /* We have horizontal scrolling and we are not inserting at
- the end. We have invisible characters in this line. This
- is a dumb update. */
- _rl_output_some_chars (nfd, temp);
- _rl_last_c_pos += col_temp;
- return;
- }
- /* Copy (new) chars to screen from first diff to last match. */
- temp = nls - nfd;
- if ((temp - lendiff) > 0)
- {
- _rl_output_some_chars (nfd + lendiff, temp - lendiff);
-#if 0
- _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff) - col_lendiff;
-#else
- _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff);
-#endif
- }
- }
- else
-#endif /* !_WIN32 */
- {
- /* cannot insert chars, write to EOL */
- _rl_output_some_chars (nfd, temp);
- _rl_last_c_pos += col_temp;
- }
- }
- else /* Delete characters from line. */
- {
-#if !defined _WIN32
- /* If possible and inexpensive to use terminal deletion, then do so. */
- if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
- {
- /* If all we're doing is erasing the invisible characters in the
- prompt string, don't bother. It screws up the assumptions
- about what's on the screen. */
- if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
- -lendiff == visible_wrap_offset)
- col_lendiff = 0;
-
- if (col_lendiff)
- delete_chars (-col_lendiff); /* delete (diff) characters */
-
- /* Copy (new) chars to screen from first diff to last match */
- temp = nls - nfd;
- if (temp > 0)
- {
- _rl_output_some_chars (nfd, temp);
- _rl_last_c_pos += _rl_col_width (nfd, 0, temp);;
- }
- }
- /* Otherwise, print over the existing material. */
- else
-#endif /* !_WIN32 */
- {
- if (temp > 0)
- {
- _rl_output_some_chars (nfd, temp);
- _rl_last_c_pos += col_temp;
- }
- lendiff = (oe - old) - (ne - new);
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- col_lendiff = _rl_col_width (old, 0, oe - old) - _rl_col_width (new, 0, ne - new);
- else
- col_lendiff = lendiff;
-
- if (col_lendiff)
- {
- if (_rl_term_autowrap && current_line < inv_botlin)
- space_to_eol (col_lendiff);
- else
- _rl_clear_to_eol (col_lendiff);
- }
- }
- }
-}
-
-/* Tell the update routines that we have moved onto a new (empty) line. */
-int
-rl_on_new_line ()
-{
- if (visible_line)
- visible_line[0] = '\0';
-
- _rl_last_c_pos = _rl_last_v_pos = 0;
- _rl_vis_botlin = last_lmargin = 0;
- if (vis_lbreaks)
- vis_lbreaks[0] = vis_lbreaks[1] = 0;
- visible_wrap_offset = 0;
- return 0;
-}
-
-/* Tell the update routines that we have moved onto a new line with the
- prompt already displayed. Code originally from the version of readline
- distributed with CLISP. */
-int
-rl_on_new_line_with_prompt ()
-{
- int prompt_size, i, l, real_screenwidth, newlines;
- char *prompt_last_line;
-
- /* Initialize visible_line and invisible_line to ensure that they can hold
- the already-displayed prompt. */
- prompt_size = strlen (rl_prompt) + 1;
- init_line_structures (prompt_size);
-
- /* Make sure the line structures hold the already-displayed prompt for
- redisplay. */
- strcpy (visible_line, rl_prompt);
- strcpy (invisible_line, rl_prompt);
-
- /* If the prompt contains newlines, take the last tail. */
- prompt_last_line = strrchr (rl_prompt, '\n');
- if (!prompt_last_line)
- prompt_last_line = rl_prompt;
-
- l = strlen (prompt_last_line);
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l);
- else
- _rl_last_c_pos = l;
-
- /* Dissect prompt_last_line into screen lines. Note that here we have
- to use the real screenwidth. Readline's notion of screenwidth might be
- one less, see terminal.c. */
- real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1);
- _rl_last_v_pos = l / real_screenwidth;
- /* If the prompt length is a multiple of real_screenwidth, we don't know
- whether the cursor is at the end of the last line, or already at the
- beginning of the next line. Output a newline just to be safe. */
- if (l > 0 && (l % real_screenwidth) == 0)
- _rl_output_some_chars ("\n", 1);
- last_lmargin = 0;
-
- newlines = 0; i = 0;
- while (i <= l)
- {
- _rl_vis_botlin = newlines;
- vis_lbreaks[newlines++] = i;
- i += real_screenwidth;
- }
- vis_lbreaks[newlines] = l;
- visible_wrap_offset = 0;
-
- return 0;
-}
-
-/* Actually update the display, period. */
-int
-rl_forced_update_display ()
-{
- if (visible_line)
- {
- register char *temp = visible_line;
-
- while (*temp)
- *temp++ = '\0';
- }
- rl_on_new_line ();
- forced_display++;
- (*rl_redisplay_function) ();
- return 0;
-}
-
-/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
- DATA is the contents of the screen line of interest; i.e., where
- the movement is being done. */
-#if !defined _WIN32 /* replace next two functions */
-void
-_rl_move_cursor_relative (new, data)
- int new;
- const char *data;
-{
- register int i;
-
- /* If we don't have to do anything, then return. */
-#if defined (HANDLE_MULTIBYTE)
- /* If we have multibyte characters, NEW is indexed by the buffer point in
- a multibyte string, but _rl_last_c_pos is the display position. In
- this case, NEW's display position is not obvious. */
- if ((MB_CUR_MAX == 1 || rl_byte_oriented ) && _rl_last_c_pos == new) return;
-#else
- if (_rl_last_c_pos == new) return;
-#endif
-
- /* It may be faster to output a CR, and then move forwards instead
- of moving backwards. */
- /* i == current physical cursor position. */
- i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
- if (new == 0 || CR_FASTER (new, _rl_last_c_pos) ||
- (_rl_term_autowrap && i == _rl_screenwidth))
- {
-#if defined (__MSDOS__)
- putc ('\r', rl_outstream);
-#else
- tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif /* !__MSDOS__ */
- _rl_last_c_pos = 0;
- }
-
- if (_rl_last_c_pos < new)
- {
- /* Move the cursor forward. We do it by printing the command
- to move the cursor forward if there is one, else print that
- portion of the output buffer again. Which is cheaper? */
-
- /* The above comment is left here for posterity. It is faster
- to print one character (non-control) than to print a control
- sequence telling the terminal to move forward one character.
- That kind of control is for people who don't know what the
- data is underneath the cursor. */
-#if defined (HACK_TERMCAP_MOTION)
- if (_rl_term_forward_char)
- {
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- int width;
- width = _rl_col_width (data, _rl_last_c_pos, new);
- for (i = 0; i < width; i++)
- tputs (_rl_term_forward_char, 1, _rl_output_character_function);
- }
- else
- {
- for (i = _rl_last_c_pos; i < new; i++)
- tputs (_rl_term_forward_char, 1, _rl_output_character_function);
- }
- }
- else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- tputs (_rl_term_cr, 1, _rl_output_character_function);
- for (i = 0; i < new; i++)
- putc (data[i], rl_outstream);
- }
- else
- for (i = _rl_last_c_pos; i < new; i++)
- putc (data[i], rl_outstream);
-
-#else /* !HACK_TERMCAP_MOTION */
-
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- tputs (_rl_term_cr, 1, _rl_output_character_function);
- for (i = 0; i < new; i++)
- putc (data[i], rl_outstream);
- }
- else
- for (i = _rl_last_c_pos; i < new; i++)
- putc (data[i], rl_outstream);
-
-#endif /* !HACK_TERMCAP_MOTION */
-
- }
-#if defined (HANDLE_MULTIBYTE)
- /* NEW points to the buffer point, but _rl_last_c_pos is the display point.
- The byte length of the string is probably bigger than the column width
- of the string, which means that if NEW == _rl_last_c_pos, then NEW's
- display point is less than _rl_last_c_pos. */
- else if (_rl_last_c_pos >= new)
-#else
- else if (_rl_last_c_pos > new)
-#endif
- {
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- tputs (_rl_term_cr, 1, _rl_output_character_function);
- for (i = 0; i < new; i++)
- putc (data[i], rl_outstream);
- }
- else
- _rl_backspace (_rl_last_c_pos - new);
- }
-
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- _rl_last_c_pos = _rl_col_width (data, 0, new);
- else
- _rl_last_c_pos = new;
-}
-
-/* PWP: move the cursor up or down. */
-void
-_rl_move_vert (to)
- int to;
-{
- register int delta, i;
-
- if (_rl_last_v_pos == to || to > _rl_screenheight)
- return;
-
- if ((delta = to - _rl_last_v_pos) > 0)
- {
- for (i = 0; i < delta; i++)
- putc ('\n', rl_outstream);
-#if defined (__MSDOS__)
- putc ('\r', rl_outstream);
-#else
- tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
- _rl_last_c_pos = 0;
- }
- else
- { /* delta < 0 */
- if (_rl_term_up && *_rl_term_up)
- for (i = 0; i < -delta; i++)
- tputs (_rl_term_up, 1, _rl_output_character_function);
- }
-
- _rl_last_v_pos = to; /* Now TO is here */
-}
-
-#else /* _WIN32 */
-
-void
-_rl_move_cursor_relative (new, data)
- int new;
- const char *data;
-{
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- if ( (_rl_last_c_pos != new)
- && haveConsole && GetConsoleScreenBufferInfo(hStdout, &csbi) )
- {
- csbi.dwCursorPosition.X += new - _rl_last_c_pos;
- if ( SetConsoleCursorPosition(hStdout, csbi.dwCursorPosition) )
- _rl_last_c_pos = new;
- }
- return;
-}
-
-void
-_rl_move_vert (to)
- int to;
-{
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- if ( (_rl_last_v_pos != to) && (to <= _rl_screenheight)
- && haveConsole && GetConsoleScreenBufferInfo(hStdout, &csbi) )
- {
- csbi.dwCursorPosition.Y += to - _rl_last_v_pos;
- if ( SetConsoleCursorPosition(hStdout, csbi.dwCursorPosition) )
- _rl_last_v_pos = to;
- }
-}
-#endif /* _WIN32 */
-
-/* Physically print C on rl_outstream. This is for functions which know
- how to optimize the display. Return the number of characters output. */
-int
-rl_show_char (c)
- int c;
-{
- int n = 1;
- if (META_CHAR (c) && (_rl_output_meta_chars == 0))
- {
- fprintf (rl_outstream, "M-");
- n += 2;
- c = UNMETA (c);
- }
-
-#if defined (DISPLAY_TABS)
- if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
-#else
- if (CTRL_CHAR (c) || c == RUBOUT)
-#endif /* !DISPLAY_TABS */
- {
- fprintf (rl_outstream, "C-");
- n += 2;
- c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
- }
-
- putc (c, rl_outstream);
- fflush (rl_outstream);
- return n;
-}
-
-int
-rl_character_len (c, pos)
- register int c, pos;
-{
- unsigned char uc;
-
- uc = (unsigned char)c;
-
- if (META_CHAR (uc))
- return ((_rl_output_meta_chars == 0) ? 4 : 1);
-
- if (uc == '\t')
- {
-#if defined (DISPLAY_TABS)
- return (((pos | 7) + 1) - pos);
-#else
- return (2);
-#endif /* !DISPLAY_TABS */
- }
-
- if (CTRL_CHAR (c) || c == RUBOUT)
- return (2);
-
- return ((ISPRINT (uc)) ? 1 : 2);
-}
-
-/* How to print things in the "echo-area". The prompt is treated as a
- mini-modeline. */
-
-#if defined (USE_VARARGS)
-int
-#if defined (PREFER_STDARG)
-rl_message (const char *format, ...)
-#else
-rl_message (va_alist)
- va_dcl
-#endif
-{
- va_list args;
-#if defined (PREFER_VARARGS)
- char *format;
-#endif
-
-#if defined (PREFER_STDARG)
- va_start (args, format);
-#else
- va_start (args);
- format = va_arg (args, char *);
-#endif
-
-#if defined (HAVE_VSNPRINTF)
- vsnprintf (msg_buf, sizeof (msg_buf) - 1, format, args);
-#else
- vsprintf (msg_buf, format, args);
- msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
-#endif
- va_end (args);
-
- rl_display_prompt = msg_buf;
- (*rl_redisplay_function) ();
- return 0;
-}
-#else /* !USE_VARARGS */
-int
-rl_message (format, arg1, arg2)
- char *format;
-{
- sprintf (msg_buf, format, arg1, arg2);
- msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
- rl_display_prompt = msg_buf;
- (*rl_redisplay_function) ();
- return 0;
-}
-#endif /* !USE_VARARGS */
-
-/* How to clear things from the "echo-area". */
-int
-rl_clear_message ()
-{
- rl_display_prompt = rl_prompt;
- (*rl_redisplay_function) ();
- return 0;
-}
-
-int
-rl_reset_line_state ()
-{
- rl_on_new_line ();
-
- rl_display_prompt = rl_prompt ? rl_prompt : "";
- forced_display = 1;
- return 0;
-}
-
-static char *saved_local_prompt;
-static char *saved_local_prefix;
-static int saved_last_invisible;
-static int saved_visible_length;
-
-void
-rl_save_prompt ()
-{
- saved_local_prompt = local_prompt;
- saved_local_prefix = local_prompt_prefix;
- saved_last_invisible = prompt_last_invisible;
- saved_visible_length = prompt_visible_length;
-
- local_prompt = local_prompt_prefix = (char *)0;
- prompt_last_invisible = prompt_visible_length = 0;
-}
-
-void
-rl_restore_prompt ()
-{
- FREE (local_prompt);
- FREE (local_prompt_prefix);
-
- local_prompt = saved_local_prompt;
- local_prompt_prefix = saved_local_prefix;
- prompt_last_invisible = saved_last_invisible;
- prompt_visible_length = saved_visible_length;
-}
-
-char *
-_rl_make_prompt_for_search (pchar)
- int pchar;
-{
- int len;
- char *pmt;
-
- rl_save_prompt ();
-
- if (saved_local_prompt == 0)
- {
- len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
- pmt = (char *)xmalloc (len + 2);
- if (len)
- strcpy (pmt, rl_prompt);
- pmt[len] = pchar;
- pmt[len+1] = '\0';
- }
- else
- {
- len = *saved_local_prompt ? strlen (saved_local_prompt) : 0;
- pmt = (char *)xmalloc (len + 2);
- if (len)
- strcpy (pmt, saved_local_prompt);
- pmt[len] = pchar;
- pmt[len+1] = '\0';
- local_prompt = savestring (pmt);
- prompt_last_invisible = saved_last_invisible;
- prompt_visible_length = saved_visible_length + 1;
- }
- return pmt;
-}
-
-/* Quick redisplay hack when erasing characters at the end of the line. */
-void
-_rl_erase_at_end_of_line (l)
- int l;
-{
- register int i;
-
- _rl_backspace (l);
- for (i = 0; i < l; i++)
- putc (' ', rl_outstream);
- _rl_backspace (l);
- for (i = 0; i < l; i++)
- visible_line[--_rl_last_c_pos] = '\0';
- rl_display_fixed++;
-}
-
-#if !defined _WIN32
-
-/* Clear to the end of the line. COUNT is the minimum
- number of character spaces to clear, */
-void
-_rl_clear_to_eol (count)
- int count;
-{
- if (_rl_term_clreol)
- tputs (_rl_term_clreol, 1, _rl_output_character_function);
- else if (count)
- space_to_eol (count);
-}
-
-/* Clear to the end of the line using spaces. COUNT is the minimum
- number of character spaces to clear, */
-static void
-space_to_eol (count)
- int count;
-{
- register int i;
-
- for (i = 0; i < count; i++)
- putc (' ', rl_outstream);
-
- _rl_last_c_pos += count;
-}
-
-#else /* _WIN32 */
-
-void
-_rl_clear_to_eol (count)
- int count;
-{
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- if (haveConsole && GetConsoleScreenBufferInfo(hStdout, &csbi))
- {
- DWORD written;
- int linear_pos;
-
- linear_pos = (int)csbi.dwCursorPosition.Y * (int)csbi.dwSize.X
- + (int)csbi.dwCursorPosition.X;
-#if defined (WITH_MINI_MOUSE)
- if (linear_pos < rlScreenMax)
- {
- rlScreenEnd = csbi.dwCursorPosition;
- rlScreenMax = linear_pos;
- }
-#endif /* WITH_MINI_MOUSE */
- FillConsoleOutputCharacter(hStdout, ' ', count, csbi.dwCursorPosition, &written);
- }
- return;
-}
-
-#endif /* _WIN32 */
-
-void
-_rl_clear_screen ()
-{
-#if !defined __MSDOS__ && !defined _WIN32
- if (_rl_term_clrpag)
- tputs (_rl_term_clrpag, 1, _rl_output_character_function);
- else
-#endif
- rl_crlf ();
-}
-
-#if !defined _WIN32 /* insert_some_chars and delete_chars are too costly with Win32 console */
-/* Insert COUNT characters from STRING to the output stream at column COL. */
-static void
-insert_some_chars (string, count, col)
- char *string;
- int count, col;
-{
- /* DEBUGGING */
- if (MB_CUR_MAX == 1 || rl_byte_oriented)
- if (count != col)
- fprintf(stderr, "readline: debug: insert_some_chars: count (%d) != col (%d)\n", count, col);
-
- /* If IC is defined, then we do not have to "enter" insert mode. */
- if (_rl_term_IC)
- {
- char *buffer;
-
- buffer = tgoto (_rl_term_IC, 0, col);
- tputs (buffer, 1, _rl_output_character_function);
- _rl_output_some_chars (string, count);
- }
- else
- {
- register int i;
-
- /* If we have to turn on insert-mode, then do so. */
- if (_rl_term_im && *_rl_term_im)
- tputs (_rl_term_im, 1, _rl_output_character_function);
-
- /* If there is a special command for inserting characters, then
- use that first to open up the space. */
- if (_rl_term_ic && *_rl_term_ic)
- {
- for (i = col; i--; )
- tputs (_rl_term_ic, 1, _rl_output_character_function);
- }
-
- /* Print the text. */
- _rl_output_some_chars (string, count);
-
- /* If there is a string to turn off insert mode, we had best use
- it now. */
- if (_rl_term_ei && *_rl_term_ei)
- tputs (_rl_term_ei, 1, _rl_output_character_function);
- }
-}
-
-/* Delete COUNT characters from the display line. */
-static void
-delete_chars (count)
- int count;
-{
- if (count > _rl_screenwidth) /* XXX */
- return;
-
- if (_rl_term_DC && *_rl_term_DC)
- {
- char *buffer;
- buffer = tgoto (_rl_term_DC, count, count);
- tputs (buffer, count, _rl_output_character_function);
- }
- else
- {
- if (_rl_term_dc && *_rl_term_dc)
- while (count--)
- tputs (_rl_term_dc, 1, _rl_output_character_function);
- }
-}
-
-#endif /* !_WIN32 */
-
-void
-_rl_update_final ()
-{
- int full_lines;
-
- full_lines = 0;
- /* If the cursor is the only thing on an otherwise-blank last line,
- compensate so we don't print an extra CRLF. */
- if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
- visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
- {
- _rl_vis_botlin--;
- full_lines = 1;
- }
- _rl_move_vert (_rl_vis_botlin);
- /* If we've wrapped lines, remove the final xterm line-wrap flag. */
- if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth))
- {
- char *last_line;
-
- last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
- _rl_move_cursor_relative (_rl_screenwidth - 1, last_line);
- _rl_clear_to_eol (0);
- putc (last_line[_rl_screenwidth - 1], rl_outstream);
- }
- _rl_vis_botlin = 0;
- rl_crlf ();
- fflush (rl_outstream);
- rl_display_fixed++;
-}
-
-#if !defined _WIN32
-
-/* Move to the start of the current line. */
-static void
-cr ()
-{
- if (_rl_term_cr)
- {
-#if defined (__MSDOS__)
- putc ('\r', rl_outstream);
-#else
- tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif
- _rl_last_c_pos = 0;
- }
-}
-
-#endif
-
-/* Redraw the last line of a multi-line prompt that may possibly contain
- terminal escape sequences. Called with the cursor at column 0 of the
- line to draw the prompt on. */
-static void
-redraw_prompt (t)
- char *t;
-{
- char *oldp, *oldl, *oldlprefix;
- int oldlen, oldlast, oldplen, oldninvis;
-
- /* Geez, I should make this a struct. */
- oldp = rl_display_prompt;
- oldl = local_prompt;
- oldlprefix = local_prompt_prefix;
- oldlen = prompt_visible_length;
- oldplen = prompt_prefix_length;
- oldlast = prompt_last_invisible;
- oldninvis = prompt_invis_chars_first_line;
-
- rl_display_prompt = t;
- local_prompt = expand_prompt (t, &prompt_visible_length,
- &prompt_last_invisible,
- &prompt_invis_chars_first_line);
- local_prompt_prefix = (char *)NULL;
- rl_forced_update_display ();
-
- rl_display_prompt = oldp;
- local_prompt = oldl;
- local_prompt_prefix = oldlprefix;
- prompt_visible_length = oldlen;
- prompt_prefix_length = oldplen;
- prompt_last_invisible = oldlast;
- prompt_invis_chars_first_line = oldninvis;
-}
-
-/* Redisplay the current line after a SIGWINCH is received. */
-void
-_rl_redisplay_after_sigwinch ()
-{
- char *t;
-
- /* Clear the current line and put the cursor at column 0. Make sure
- the right thing happens if we have wrapped to a new screen line. */
- if (_rl_term_cr)
- {
-#if _WIN32
- _rl_move_cursor_relative (0, 0);
- space_to_eol (_rl_screenwidth);
- _rl_move_cursor_relative (0, 0);
-#else
-# if defined (__MSDOS__)
- putc ('\r', rl_outstream);
-# else
- tputs (_rl_term_cr, 1, _rl_output_character_function);
-# endif
- _rl_last_c_pos = 0;
-# if defined (__MSDOS__)
- space_to_eol (_rl_screenwidth);
- putc ('\r', rl_outstream);
-# else
- if (_rl_term_clreol)
- tputs (_rl_term_clreol, 1, _rl_output_character_function);
- else
- {
- space_to_eol (_rl_screenwidth);
- tputs (_rl_term_cr, 1, _rl_output_character_function);
- }
-# endif
-#endif
- if (_rl_last_v_pos > 0)
- _rl_move_vert (0);
- }
- else
- rl_crlf ();
-
- /* Redraw only the last line of a multi-line prompt. */
- t = strrchr (rl_display_prompt, '\n');
- if (t)
- redraw_prompt (++t);
- else
- rl_forced_update_display ();
-}
-
-void
-_rl_clean_up_for_exit ()
-{
- if (readline_echoing_p)
- {
- _rl_move_vert (_rl_vis_botlin);
- _rl_vis_botlin = 0;
- fflush (rl_outstream);
-#if !defined _WIN32
- rl_restart_output (1, 0);
-#endif
- }
-}
-
-void
-_rl_erase_entire_line ()
-{
- cr ();
- _rl_clear_to_eol (0);
- cr ();
- fflush (rl_outstream);
-}
-
-/* return the `current display line' of the cursor -- the number of lines to
- move up to get to the first screen line of the current readline line. */
-int
-_rl_current_display_line ()
-{
- int ret, nleft;
-
- /* Find out whether or not there might be invisible characters in the
- editing buffer. */
- if (rl_display_prompt == rl_prompt)
- nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length;
- else
- nleft = _rl_last_c_pos - _rl_screenwidth;
-
- if (nleft > 0)
- ret = 1 + nleft / _rl_screenwidth;
- else
- ret = 0;
-
- return ret;
-}
-
-#if defined (HANDLE_MULTIBYTE)
-/* Calculate the number of screen columns occupied by STR from START to END.
- In the case of multibyte characters with stateful encoding, we have to
- scan from the beginning of the string to take the state into account. */
-static int
-_rl_col_width (str, start, end)
- char *str;
- int start, end;
-{
- wchar_t wc;
- mbstate_t ps = {0};
- int tmp, point, width, max;
-
- if (end <= start)
- return 0;
-
- point = 0;
- max = end;
-
- while (point < start)
- {
- tmp = mbrlen (str + point, max, &ps);
- if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2)
- {
- /* In this case, the bytes are invalid or too short to compose a
- multibyte character, so we assume that the first byte represents
- a single character. */
- point++;
- max--;
-
- /* Clear the state of the byte sequence, because in this case the
- effect of mbstate is undefined. */
- memset (&ps, 0, sizeof (mbstate_t));
- }
- else if (tmp == 0)
- break; /* Found '\0' */
- else
- {
- point += tmp;
- max -= tmp;
- }
- }
-
- /* If START is not a byte that starts a character, then POINT will be
- greater than START. In this case, assume that (POINT - START) gives
- a byte count that is the number of columns of difference. */
- width = point - start;
-
- while (point < end)
- {
- tmp = mbrtowc (&wc, str + point, max, &ps);
- if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2)
- {
- /* In this case, the bytes are invalid or too short to compose a
- multibyte character, so we assume that the first byte represents
- a single character. */
- point++;
- max--;
-
- /* and assume that the byte occupies a single column. */
- width++;
-
- /* Clear the state of the byte sequence, because in this case the
- effect of mbstate is undefined. */
- memset (&ps, 0, sizeof (mbstate_t));
- }
- else if (tmp == 0)
- break; /* Found '\0' */
- else
- {
- point += tmp;
- max -= tmp;
- tmp = wcwidth(wc);
- width += (tmp >= 0) ? tmp : 1;
- }
- }
-
- width += point - end;
-
- return width;
-}
-#endif /* HANDLE_MULTIBYTE */
-
+/* display.c -- readline redisplay facility. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include "posixstat.h"
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <stdio.h>
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+#include "rlmbutil.h"
+
+/* Termcap library stuff. */
+#include "tcap.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "xmalloc.h"
+
+#if defined _WIN32
+ #include <windows.h>
+ extern int haveConsole; /* imported from rltty.c */
+ extern HANDLE hStdout, hStdin;
+ #if defined (WITH_MINI_MOUSE)
+ extern COORD rlScreenEnd;
+ extern int rlScreenMax;
+ #endif /* WITH_MINI_MOUSE */
+#endif /* _WIN32 */
+
+#if !defined (strchr) && !defined (__STDC__) && !defined _MSC_VER
+extern char *strchr (), *strrchr ();
+#endif /* !strchr && !__STDC__ */
+
+#if defined (HACK_TERMCAP_MOTION)
+extern char *_rl_term_forward_char;
+#endif
+
+static void update_line PARAMS((char *, char *, int, int, int, int));
+
+#if defined _WIN32
+# define space_to_eol(count) _rl_clear_to_eol(count)
+# undef putc
+# define putc(ch,x) _rl_output_character_function (ch)
+# define cr() _rl_move_cursor_relative (0, 0)
+#else
+static void space_to_eol PARAMS((int));
+static void delete_chars PARAMS((int));
+static void insert_some_chars PARAMS((char *, int, int));
+static void cr PARAMS((void));
+#endif
+
+#if defined (HANDLE_MULTIBYTE)
+static int _rl_col_width PARAMS((char *, int, int));
+static int *_rl_wrapped_line;
+#else
+# define _rl_col_width(l, s, e) (((e) <= (s)) ? 0 : (e) - (s))
+#endif
+
+static int *inv_lbreaks, *vis_lbreaks;
+static int inv_lbsize, vis_lbsize;
+
+/* Heuristic used to decide whether it is faster to move from CUR to NEW
+ by backing up or outputting a carriage return and moving forward. */
+#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
+
+/* **************************************************************** */
+/* */
+/* Display stuff */
+/* */
+/* **************************************************************** */
+
+/* This is the stuff that is hard for me. I never seem to write good
+ display routines in C. Let's see how I do this time. */
+
+/* (PWP) Well... Good for a simple line updater, but totally ignores
+ the problems of input lines longer than the screen width.
+
+ update_line and the code that calls it makes a multiple line,
+ automatically wrapping line update. Careful attention needs
+ to be paid to the vertical position variables. */
+
+/* Keep two buffers; one which reflects the current contents of the
+ screen, and the other to draw what we think the new contents should
+ be. Then compare the buffers, and make whatever changes to the
+ screen itself that we should. Finally, make the buffer that we
+ just drew into be the one which reflects the current contents of the
+ screen, and place the cursor where it belongs.
+
+ Commands that want to can fix the display themselves, and then let
+ this function know that the display has been fixed by setting the
+ RL_DISPLAY_FIXED variable. This is good for efficiency. */
+
+/* Application-specific redisplay function. */
+rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
+
+/* Global variables declared here. */
+/* What YOU turn on when you have handled all redisplay yourself. */
+int rl_display_fixed = 0;
+
+int _rl_suppress_redisplay = 0;
+
+/* The stuff that gets printed out before the actual text of the line.
+ This is usually pointing to rl_prompt. */
+char *rl_display_prompt = (char *)NULL;
+
+/* Pseudo-global variables declared here. */
+/* The visible cursor position. If you print some text, adjust this. */
+int _rl_last_c_pos = 0;
+int _rl_last_v_pos = 0;
+
+/* Number of lines currently on screen minus 1. */
+int _rl_vis_botlin = 0;
+
+/* Variables used only in this file. */
+/* The last left edge of text that was displayed. This is used when
+ doing horizontal scrolling. It shifts in thirds of a screenwidth. */
+static int last_lmargin;
+
+/* The line display buffers. One is the line currently displayed on
+ the screen. The other is the line about to be displayed. */
+static char *visible_line = (char *)NULL;
+static char *invisible_line = (char *)NULL;
+
+/* A buffer for `modeline' messages. */
+static char msg_buf[128];
+
+/* Non-zero forces the redisplay even if we thought it was unnecessary. */
+static int forced_display;
+
+/* Default and initial buffer size. Can grow. */
+static int line_size = 1024;
+
+/* Variables to keep track of the expanded prompt string, which may
+ include invisible characters. */
+
+static char *local_prompt, *local_prompt_prefix;
+static int prompt_visible_length, prompt_prefix_length;
+
+/* The number of invisible characters in the line currently being
+ displayed on the screen. */
+static int visible_wrap_offset;
+
+/* The number of invisible characters in the prompt string. Static so it
+ can be shared between rl_redisplay and update_line */
+static int wrap_offset;
+
+/* The index of the last invisible character in the prompt string. */
+static int prompt_last_invisible;
+
+/* The length (buffer offset) of the first line of the last (possibly
+ multi-line) buffer displayed on the screen. */
+static int visible_first_line_len;
+
+/* Number of invisible characters on the first physical line of the prompt.
+ Only valid when the number of physical characters in the prompt exceeds
+ (or is equal to) _rl_screenwidth. */
+static int prompt_invis_chars_first_line;
+
+static int prompt_last_screen_line;
+
+/* Expand the prompt string S and return the number of visible
+ characters in *LP, if LP is not null. This is currently more-or-less
+ a placeholder for expansion. LIP, if non-null is a place to store the
+ index of the last invisible character in the returned string. NIFLP,
+ if non-zero, is a place to store the number of invisible characters in
+ the first prompt line. */
+
+/* Current implementation:
+ \001 (^A) start non-visible characters
+ \002 (^B) end non-visible characters
+ all characters except \001 and \002 (following a \001) are copied to
+ the returned string; all characters except those between \001 and
+ \002 are assumed to be `visible'. */
+
+static char *
+expand_prompt (pmt, lp, lip, niflp)
+ char *pmt;
+ int *lp, *lip, *niflp;
+{
+ char *r, *ret, *p;
+ int l, rl, last, ignoring, ninvis, invfl;
+
+ /* Short-circuit if we can. */
+ if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
+ {
+ r = savestring (pmt);
+ if (lp)
+ *lp = strlen (r);
+ return r;
+ }
+
+ l = strlen (pmt);
+ r = ret = (char *)xmalloc (l + 1);
+
+ invfl = 0; /* invisible chars in first line of prompt */
+
+ for (rl = ignoring = last = ninvis = 0, p = pmt; p && *p; p++)
+ {
+ /* This code strips the invisible character string markers
+ RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
+ if (*p == RL_PROMPT_START_IGNORE)
+ {
+ ignoring++;
+ continue;
+ }
+ else if (ignoring && *p == RL_PROMPT_END_IGNORE)
+ {
+ ignoring = 0;
+ last = r - ret - 1;
+ continue;
+ }
+ else
+ {
+ *r++ = *p;
+ if (!ignoring)
+ rl++;
+ else
+ ninvis++;
+ if (rl == _rl_screenwidth)
+ invfl = ninvis;
+ }
+ }
+
+ if (rl < _rl_screenwidth)
+ invfl = ninvis;
+
+ *r = '\0';
+ if (lp)
+ *lp = rl;
+ if (lip)
+ *lip = last;
+ if (niflp)
+ *niflp = invfl;
+ return ret;
+}
+
+/* Just strip out RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE from
+ PMT and return the rest of PMT. */
+char *
+_rl_strip_prompt (pmt)
+ char *pmt;
+{
+ char *ret;
+
+ ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL);
+ return ret;
+}
+
+/*
+ * Expand the prompt string into the various display components, if
+ * necessary.
+ *
+ * local_prompt = expanded last line of string in rl_display_prompt
+ * (portion after the final newline)
+ * local_prompt_prefix = portion before last newline of rl_display_prompt,
+ * expanded via expand_prompt
+ * prompt_visible_length = number of visible characters in local_prompt
+ * prompt_prefix_length = number of visible characters in local_prompt_prefix
+ *
+ * This function is called once per call to readline(). It may also be
+ * called arbitrarily to expand the primary prompt.
+ *
+ * The return value is the number of visible characters on the last line
+ * of the (possibly multi-line) prompt.
+ */
+int
+rl_expand_prompt (prompt)
+ char *prompt;
+{
+ char *p, *t;
+ int c;
+
+ /* Clear out any saved values. */
+ FREE (local_prompt);
+ FREE (local_prompt_prefix);
+
+ local_prompt = local_prompt_prefix = (char *)0;
+ prompt_last_invisible = prompt_visible_length = 0;
+
+ if (prompt == 0 || *prompt == 0)
+ return (0);
+
+ p = strrchr (prompt, '\n');
+ if (!p)
+ {
+ /* The prompt is only one logical line, though it might wrap. */
+ local_prompt = expand_prompt (prompt, &prompt_visible_length,
+ &prompt_last_invisible,
+ &prompt_invis_chars_first_line);
+ local_prompt_prefix = (char *)0;
+ return (prompt_visible_length);
+ }
+ else
+ {
+ /* The prompt spans multiple lines. */
+ t = ++p;
+ local_prompt = expand_prompt (p, &prompt_visible_length,
+ &prompt_last_invisible,
+ &prompt_invis_chars_first_line);
+ c = *t; *t = '\0';
+ /* The portion of the prompt string up to and including the
+ final newline is now null-terminated. */
+ local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
+ (int *)NULL,
+ &prompt_invis_chars_first_line);
+ *t = c;
+ return (prompt_prefix_length);
+ }
+}
+
+/* Initialize the VISIBLE_LINE and INVISIBLE_LINE arrays, and their associated
+ arrays of line break markers. MINSIZE is the minimum size of VISIBLE_LINE
+ and INVISIBLE_LINE; if it is greater than LINE_SIZE, LINE_SIZE is
+ increased. If the lines have already been allocated, this ensures that
+ they can hold at least MINSIZE characters. */
+static void
+init_line_structures (minsize)
+ int minsize;
+{
+ register int n;
+
+ if (invisible_line == 0) /* initialize it */
+ {
+ if (line_size < minsize)
+ line_size = minsize;
+ visible_line = (char *)xmalloc (line_size);
+ invisible_line = (char *)xmalloc (line_size);
+ }
+ else if (line_size < minsize) /* ensure it can hold MINSIZE chars */
+ {
+ line_size *= 2;
+ if (line_size < minsize)
+ line_size = minsize;
+ visible_line = (char *)xrealloc (visible_line, line_size);
+ invisible_line = (char *)xrealloc (invisible_line, line_size);
+ }
+
+ for (n = minsize; n < line_size; n++)
+ {
+ visible_line[n] = 0;
+ invisible_line[n] = 1;
+ }
+
+ if (vis_lbreaks == 0)
+ {
+ /* should be enough. */
+ inv_lbsize = vis_lbsize = 256;
+ inv_lbreaks = (int *)xmalloc (inv_lbsize * sizeof (int));
+ vis_lbreaks = (int *)xmalloc (vis_lbsize * sizeof (int));
+#if defined (HANDLE_MULTIBYTE)
+ _rl_wrapped_line = (int *)xmalloc (vis_lbsize * sizeof (int));
+#endif
+ inv_lbreaks[0] = vis_lbreaks[0] = 0;
+ }
+}
+
+/* Basic redisplay algorithm. */
+void
+rl_redisplay ()
+{
+ register int in, out, c, linenum, cursor_linenum;
+ register char *line;
+ int c_pos, inv_botlin, lb_botlin, lb_linenum;
+ int newlines, lpos, temp;
+ char *prompt_this_line;
+#if defined (HANDLE_MULTIBYTE)
+ wchar_t wc;
+ size_t wc_bytes;
+ int wc_width;
+ mbstate_t ps;
+ int _rl_wrapped_multicolumn = 0;
+#endif
+
+ if (!readline_echoing_p)
+ return;
+
+ if (!rl_display_prompt)
+ rl_display_prompt = "";
+
+ if (invisible_line == 0)
+ {
+ init_line_structures (0);
+ rl_on_new_line ();
+ }
+
+ /* Draw the line into the buffer. */
+ c_pos = -1;
+
+ line = invisible_line;
+ out = inv_botlin = 0;
+
+ /* Mark the line as modified or not. We only do this for history
+ lines. */
+ if (_rl_mark_modified_lines && current_history () && rl_undo_list)
+ {
+ line[out++] = '*';
+ line[out] = '\0';
+ }
+
+ /* If someone thought that the redisplay was handled, but the currently
+ visible line has a different modification state than the one about
+ to become visible, then correct the caller's misconception. */
+ if (visible_line[0] != invisible_line[0])
+ rl_display_fixed = 0;
+
+ /* If the prompt to be displayed is the `primary' readline prompt (the
+ one passed to readline()), use the values we have already expanded.
+ If not, use what's already in rl_display_prompt. WRAP_OFFSET is the
+ number of non-visible characters in the prompt string. */
+ if (rl_display_prompt == rl_prompt || local_prompt)
+ {
+ int local_len = local_prompt ? strlen (local_prompt) : 0;
+ if (local_prompt_prefix && forced_display)
+ _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
+
+ if (local_len > 0)
+ {
+ temp = local_len + out + 2;
+ if (temp >= line_size)
+ {
+ line_size = (temp + 1024) - (temp % 1024);
+ visible_line = (char *)xrealloc (visible_line, line_size);
+ line = invisible_line = (char *)xrealloc (invisible_line, line_size);
+ }
+ strncpy (line + out, local_prompt, local_len);
+ out += local_len;
+ }
+ line[out] = '\0';
+ wrap_offset = local_len - prompt_visible_length;
+ }
+ else
+ {
+ int pmtlen;
+ prompt_this_line = strrchr (rl_display_prompt, '\n');
+ if (!prompt_this_line)
+ prompt_this_line = rl_display_prompt;
+ else
+ {
+ prompt_this_line++;
+ pmtlen = prompt_this_line - rl_display_prompt; /* temp var */
+ if (forced_display)
+ {
+ _rl_output_some_chars (rl_display_prompt, pmtlen);
+ /* Make sure we are at column zero even after a newline,
+ regardless of the state of terminal output processing. */
+ if (pmtlen < 2 || prompt_this_line[-2] != '\r')
+ cr ();
+ }
+ }
+
+ pmtlen = strlen (prompt_this_line);
+ temp = pmtlen + out + 2;
+ if (temp >= line_size)
+ {
+ line_size = (temp + 1024) - (temp % 1024);
+ visible_line = (char *)xrealloc (visible_line, line_size);
+ line = invisible_line = (char *)xrealloc (invisible_line, line_size);
+ }
+ strncpy (line + out, prompt_this_line, pmtlen);
+ out += pmtlen;
+ line[out] = '\0';
+ wrap_offset = prompt_invis_chars_first_line = 0;
+ }
+
+#define CHECK_INV_LBREAKS() \
+ do { \
+ if (newlines >= (inv_lbsize - 2)) \
+ { \
+ inv_lbsize *= 2; \
+ inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
+ } \
+ } while (0)
+
+#if defined (HANDLE_MULTIBYTE)
+#define CHECK_LPOS() \
+ do { \
+ lpos++; \
+ if (lpos >= _rl_screenwidth) \
+ { \
+ if (newlines >= (inv_lbsize - 2)) \
+ { \
+ inv_lbsize *= 2; \
+ inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
+ _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \
+ } \
+ inv_lbreaks[++newlines] = out; \
+ _rl_wrapped_line[newlines] = _rl_wrapped_multicolumn; \
+ lpos = 0; \
+ } \
+ } while (0)
+#else
+#define CHECK_LPOS() \
+ do { \
+ lpos++; \
+ if (lpos >= _rl_screenwidth) \
+ { \
+ if (newlines >= (inv_lbsize - 2)) \
+ { \
+ inv_lbsize *= 2; \
+ inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
+ } \
+ inv_lbreaks[++newlines] = out; \
+ lpos = 0; \
+ } \
+ } while (0)
+#endif
+
+ /* inv_lbreaks[i] is where line i starts in the buffer. */
+ inv_lbreaks[newlines = 0] = 0;
+ lpos = out - wrap_offset;
+#if defined (HANDLE_MULTIBYTE)
+ memset (_rl_wrapped_line, 0, vis_lbsize);
+#endif
+
+ /* prompt_invis_chars_first_line is the number of invisible characters in
+ the first physical line of the prompt.
+ wrap_offset - prompt_invis_chars_first_line is the number of invis
+ chars on the second line. */
+
+ /* what if lpos is already >= _rl_screenwidth before we start drawing the
+ contents of the command line? */
+ while (lpos >= _rl_screenwidth)
+ {
+ /* fix from Darin Johnson <darin@acuson.com> for prompt string with
+ invisible characters that is longer than the screen width. The
+ prompt_invis_chars_first_line variable could be made into an array
+ saying how many invisible characters there are per line, but that's
+ probably too much work for the benefit gained. How many people have
+ prompts that exceed two physical lines? */
+ temp = ((newlines + 1) * _rl_screenwidth) +
+#if 0
+ ((newlines == 0) ? prompt_invis_chars_first_line : 0) +
+#else
+ ((newlines == 0 && local_prompt_prefix == 0) ? prompt_invis_chars_first_line : 0) +
+#endif
+ ((newlines == 1) ? wrap_offset : 0);
+
+ inv_lbreaks[++newlines] = temp;
+ lpos -= _rl_screenwidth;
+ }
+
+ prompt_last_screen_line = newlines;
+
+ /* Draw the rest of the line (after the prompt) into invisible_line, keeping
+ track of where the cursor is (c_pos), the number of the line containing
+ the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin).
+ It maintains an array of line breaks for display (inv_lbreaks).
+ This handles expanding tabs for display and displaying meta characters. */
+ lb_linenum = 0;
+#if defined (HANDLE_MULTIBYTE)
+ in = 0;
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ memset (&ps, 0, sizeof (mbstate_t));
+ wc_bytes = mbrtowc (&wc, rl_line_buffer, rl_end, &ps);
+ }
+ else
+ wc_bytes = 1;
+ while (in < rl_end)
+#else
+ for (in = 0; in < rl_end; in++)
+#endif
+ {
+ c = (unsigned char)rl_line_buffer[in];
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ if (wc_bytes == (size_t)-1 || wc_bytes == (size_t)-2)
+ {
+ /* Byte sequence is invalid or shortened. Assume that the
+ first byte represents a character. */
+ wc_bytes = 1;
+ /* Assume that a character occupies a single column. */
+ wc_width = 1;
+ memset (&ps, 0, sizeof (mbstate_t));
+ }
+ else if (wc_bytes == (size_t)0)
+ break; /* Found '\0' */
+ else
+ {
+ temp = wcwidth (wc);
+ wc_width = (temp < 0) ? 1 : temp;
+ }
+ }
+#endif
+
+ if (out + 8 >= line_size) /* XXX - 8 for \t */
+ {
+ line_size *= 2;
+ visible_line = (char *)xrealloc (visible_line, line_size);
+ invisible_line = (char *)xrealloc (invisible_line, line_size);
+ line = invisible_line;
+ }
+
+ if (in == rl_point)
+ {
+ c_pos = out;
+ lb_linenum = newlines;
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ if (META_CHAR (c) && _rl_output_meta_chars == 0) /* XXX - clean up */
+#else
+ if (META_CHAR (c))
+#endif
+ {
+ if (_rl_output_meta_chars == 0)
+ {
+ sprintf (line + out, "\\%o", c);
+
+ if (lpos + 4 >= _rl_screenwidth)
+ {
+ temp = _rl_screenwidth - lpos;
+ CHECK_INV_LBREAKS ();
+ inv_lbreaks[++newlines] = out + temp;
+ lpos = 4 - temp;
+ }
+ else
+ lpos += 4;
+
+ out += 4;
+ }
+ else
+ {
+ line[out++] = c;
+ CHECK_LPOS();
+ }
+ }
+#if defined (DISPLAY_TABS)
+ else if (c == '\t')
+ {
+ register int newout;
+
+#if 0
+ newout = (out | (int)7) + 1;
+#else
+ newout = out + 8 - lpos % 8;
+#endif
+ temp = newout - out;
+ if (lpos + temp >= _rl_screenwidth)
+ {
+ register int temp2;
+ temp2 = _rl_screenwidth - lpos;
+ CHECK_INV_LBREAKS ();
+ inv_lbreaks[++newlines] = out + temp2;
+ lpos = temp - temp2;
+ while (out < newout)
+ line[out++] = ' ';
+ }
+ else
+ {
+ while (out < newout)
+ line[out++] = ' ';
+ lpos += temp;
+ }
+ }
+#endif
+ else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
+ {
+ line[out++] = '\0'; /* XXX - sentinel */
+ CHECK_INV_LBREAKS ();
+ inv_lbreaks[++newlines] = out;
+ lpos = 0;
+ }
+ else if (CTRL_CHAR (c) || c == RUBOUT)
+ {
+ line[out++] = '^';
+ CHECK_LPOS();
+ line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
+ CHECK_LPOS();
+ }
+ else
+ {
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ register int i;
+
+ _rl_wrapped_multicolumn = 0;
+
+ if (_rl_screenwidth < lpos + wc_width)
+ for (i = lpos; i < _rl_screenwidth; i++)
+ {
+ /* The space will be removed in update_line() */
+ line[out++] = ' ';
+ _rl_wrapped_multicolumn++;
+ CHECK_LPOS();
+ }
+ if (in == rl_point)
+ {
+ c_pos = out;
+ lb_linenum = newlines;
+ }
+ for (i = in; i < in+wc_bytes; i++)
+ line[out++] = rl_line_buffer[i];
+ for (i = 0; i < wc_width; i++)
+ CHECK_LPOS();
+ }
+ else
+ {
+ line[out++] = c;
+ CHECK_LPOS();
+ }
+#else
+ line[out++] = c;
+ CHECK_LPOS();
+#endif
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ in += wc_bytes;
+ wc_bytes = mbrtowc (&wc, rl_line_buffer + in, rl_end - in, &ps);
+ }
+ else
+ in++;
+#endif
+
+ }
+ line[out] = '\0';
+ if (c_pos < 0)
+ {
+ c_pos = out;
+ lb_linenum = newlines;
+ }
+
+ inv_botlin = lb_botlin = newlines;
+ CHECK_INV_LBREAKS ();
+ inv_lbreaks[newlines+1] = out;
+ cursor_linenum = lb_linenum;
+
+ /* C_POS == position in buffer where cursor should be placed.
+ CURSOR_LINENUM == line number where the cursor should be placed. */
+
+ /* PWP: now is when things get a bit hairy. The visible and invisible
+ line buffers are really multiple lines, which would wrap every
+ (screenwidth - 1) characters. Go through each in turn, finding
+ the changed region and updating it. The line order is top to bottom. */
+
+ /* If we can move the cursor up and down, then use multiple lines,
+ otherwise, let long lines display in a single terminal line, and
+ horizontally scroll it. */
+
+ if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
+ {
+ int nleft, pos, changed_screen_line;
+
+ if (!rl_display_fixed || forced_display)
+ {
+ forced_display = 0;
+
+ /* If we have more than a screenful of material to display, then
+ only display a screenful. We should display the last screen,
+ not the first. */
+ if (out >= _rl_screenchars)
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ out = _rl_find_prev_mbchar (line, _rl_screenchars, MB_FIND_ANY);
+ else
+ out = _rl_screenchars - 1;
+ }
+
+ /* The first line is at character position 0 in the buffer. The
+ second and subsequent lines start at inv_lbreaks[N], offset by
+ OFFSET (which has already been calculated above). */
+
+#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
+#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
+#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
+#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
+#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
+#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
+
+ /* For each line in the buffer, do the updating display. */
+ for (linenum = 0; linenum <= inv_botlin; linenum++)
+ {
+ update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
+ VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
+
+ /* If this is the line with the prompt, we might need to
+ compensate for invisible characters in the new line. Do
+ this only if there is not more than one new line (which
+ implies that we completely overwrite the old visible line)
+ and the new line is shorter than the old. Make sure we are
+ at the end of the new line before clearing. */
+ if (linenum == 0 &&
+ inv_botlin == 0 && _rl_last_c_pos == out &&
+ (wrap_offset > visible_wrap_offset) &&
+ (_rl_last_c_pos < visible_first_line_len))
+ {
+ nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
+ if (nleft)
+ _rl_clear_to_eol (nleft);
+ }
+
+ /* Since the new first line is now visible, save its length. */
+ if (linenum == 0)
+ visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
+ }
+
+ /* We may have deleted some lines. If so, clear the left over
+ blank ones at the bottom out. */
+ if (_rl_vis_botlin > inv_botlin)
+ {
+ char *tt;
+ for (; linenum <= _rl_vis_botlin; linenum++)
+ {
+ tt = VIS_CHARS (linenum);
+ _rl_move_vert (linenum);
+ _rl_move_cursor_relative (0, tt);
+ _rl_clear_to_eol
+ ((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
+ }
+ }
+ _rl_vis_botlin = inv_botlin;
+
+ /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
+ different screen line during this redisplay. */
+ changed_screen_line = _rl_last_v_pos != cursor_linenum;
+ if (changed_screen_line)
+ {
+ _rl_move_vert (cursor_linenum);
+ /* If we moved up to the line with the prompt using _rl_term_up,
+ the physical cursor position on the screen stays the same,
+ but the buffer position needs to be adjusted to account
+ for invisible characters. */
+ if (cursor_linenum == 0 && wrap_offset)
+ _rl_last_c_pos += wrap_offset;
+ }
+
+ /* We have to reprint the prompt if it contains invisible
+ characters, since it's not generally OK to just reprint
+ the characters from the current cursor position. But we
+ only need to reprint it if the cursor is before the last
+ invisible character in the prompt string. */
+ nleft = prompt_visible_length + wrap_offset;
+ if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
+ _rl_last_c_pos <= prompt_last_invisible && local_prompt)
+ {
+#if defined (__MSDOS__)
+ putc ('\r', rl_outstream);
+#elif defined _WIN32
+ cr ();
+#else
+ if (_rl_term_cr)
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif
+ _rl_output_some_chars (local_prompt, nleft);
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ _rl_last_c_pos = _rl_col_width(local_prompt, 0, nleft);
+ else
+ _rl_last_c_pos = nleft;
+ }
+
+ /* Where on that line? And where does that line start
+ in the buffer? */
+ pos = inv_lbreaks[cursor_linenum];
+ /* nleft == number of characters in the line buffer between the
+ start of the line and the cursor position. */
+ nleft = c_pos - pos;
+
+ /* Since _rl_backspace() doesn't know about invisible characters in the
+ prompt, and there's no good way to tell it, we compensate for
+ those characters here and call _rl_backspace() directly. */
+ if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
+ {
+ _rl_backspace (_rl_last_c_pos - nleft);
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ _rl_last_c_pos = _rl_col_width (&visible_line[pos], 0, nleft);
+ else
+ _rl_last_c_pos = nleft;
+ }
+
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ _rl_move_cursor_relative (nleft, &invisible_line[pos]);
+ else if (nleft != _rl_last_c_pos)
+ _rl_move_cursor_relative (nleft, &invisible_line[pos]);
+ }
+ }
+ else /* Do horizontal scrolling. */
+ {
+#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
+ int lmargin, ndisp, nleft, phys_c_pos, t;
+
+ /* Always at top line. */
+ _rl_last_v_pos = 0;
+
+ /* Compute where in the buffer the displayed line should start. This
+ will be LMARGIN. */
+
+ /* The number of characters that will be displayed before the cursor. */
+ ndisp = c_pos - wrap_offset;
+ nleft = prompt_visible_length + wrap_offset;
+ /* Where the new cursor position will be on the screen. This can be
+ longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
+ phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset);
+ t = _rl_screenwidth / 3;
+
+ /* If the number of characters had already exceeded the screenwidth,
+ last_lmargin will be > 0. */
+
+ /* If the number of characters to be displayed is more than the screen
+ width, compute the starting offset so that the cursor is about
+ two-thirds of the way across the screen. */
+ if (phys_c_pos > _rl_screenwidth - 2)
+ {
+ lmargin = c_pos - (2 * t);
+ if (lmargin < 0)
+ lmargin = 0;
+ /* If the left margin would be in the middle of a prompt with
+ invisible characters, don't display the prompt at all. */
+ if (wrap_offset && lmargin > 0 && lmargin < nleft)
+ lmargin = nleft;
+ }
+ else if (ndisp < _rl_screenwidth - 2) /* XXX - was -1 */
+ lmargin = 0;
+ else if (phys_c_pos < 1)
+ {
+ /* If we are moving back towards the beginning of the line and
+ the last margin is no longer correct, compute a new one. */
+ lmargin = ((c_pos - 1) / t) * t; /* XXX */
+ if (wrap_offset && lmargin > 0 && lmargin < nleft)
+ lmargin = nleft;
+ }
+ else
+ lmargin = last_lmargin;
+
+ /* If the first character on the screen isn't the first character
+ in the display line, indicate this with a special character. */
+ if (lmargin > 0)
+ line[lmargin] = '<';
+
+ /* If SCREENWIDTH characters starting at LMARGIN do not encompass
+ the whole line, indicate that with a special character at the
+ right edge of the screen. If LMARGIN is 0, we need to take the
+ wrap offset into account. */
+ t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
+ if (t < out)
+ line[t - 1] = '>';
+
+ if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
+ {
+ forced_display = 0;
+ update_line (&visible_line[last_lmargin],
+ &invisible_line[lmargin],
+ 0,
+ _rl_screenwidth + visible_wrap_offset,
+ _rl_screenwidth + (lmargin ? 0 : wrap_offset),
+ 0);
+
+ /* If the visible new line is shorter than the old, but the number
+ of invisible characters is greater, and we are at the end of
+ the new line, we need to clear to eol. */
+ t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
+ if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
+ (_rl_last_c_pos == out) &&
+ t < visible_first_line_len)
+ {
+ nleft = _rl_screenwidth - t;
+ _rl_clear_to_eol (nleft);
+ }
+ visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
+ if (visible_first_line_len > _rl_screenwidth)
+ visible_first_line_len = _rl_screenwidth;
+
+ _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
+ last_lmargin = lmargin;
+ }
+ }
+ fflush (rl_outstream);
+
+ /* Swap visible and non-visible lines. */
+ {
+ char *vtemp = visible_line;
+ int *itemp = vis_lbreaks, ntemp = vis_lbsize;
+
+ visible_line = invisible_line;
+ invisible_line = vtemp;
+
+ vis_lbreaks = inv_lbreaks;
+ inv_lbreaks = itemp;
+
+ vis_lbsize = inv_lbsize;
+ inv_lbsize = ntemp;
+
+ rl_display_fixed = 0;
+ /* If we are displaying on a single line, and last_lmargin is > 0, we
+ are not displaying any invisible characters, so set visible_wrap_offset
+ to 0. */
+ if (_rl_horizontal_scroll_mode && last_lmargin)
+ visible_wrap_offset = 0;
+ else
+ visible_wrap_offset = wrap_offset;
+ }
+}
+
+/* PWP: update_line() is based on finding the middle difference of each
+ line on the screen; vis:
+
+ /old first difference
+ /beginning of line | /old last same /old EOL
+ v v v v
+old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
+new: eddie> Oh, my little buggy says to me, as lurgid as
+ ^ ^ ^ ^
+ \beginning of line | \new last same \new end of line
+ \new first difference
+
+ All are character pointers for the sake of speed. Special cases for
+ no differences, as well as for end of line additions must be handled.
+
+ Could be made even smarter, but this works well enough */
+static void
+update_line (old, new, current_line, omax, nmax, inv_botlin)
+ register char *old, *new;
+ int current_line, omax, nmax, inv_botlin;
+{
+ register char *ofd, *ols, *oe, *nfd, *nls, *ne;
+ int temp, lendiff, wsatend, od, nd;
+ int current_invis_chars;
+ int col_lendiff, col_temp;
+#if defined (HANDLE_MULTIBYTE)
+ mbstate_t ps_new, ps_old;
+ int new_offset, old_offset, tmp;
+#endif
+
+ /* If we're at the right edge of a terminal that supports xn, we're
+ ready to wrap around, so do so. This fixes problems with knowing
+ the exact cursor position and cut-and-paste with certain terminal
+ emulators. In this calculation, TEMP is the physical screen
+ position of the cursor. */
+ temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
+ if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
+ && _rl_last_v_pos == current_line - 1)
+ {
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ wchar_t wc;
+ mbstate_t ps;
+ int tempwidth, bytes;
+ size_t ret;
+
+ /* This fixes only double-column characters, but if the wrapped
+ character comsumes more than three columns, spaces will be
+ inserted in the string buffer. */
+ if (_rl_wrapped_line[current_line] > 0)
+ _rl_clear_to_eol (_rl_wrapped_line[current_line]);
+
+ memset (&ps, 0, sizeof (mbstate_t));
+ ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
+ if (ret == (size_t)-1 || ret == (size_t)-2)
+ {
+ tempwidth = 1;
+ ret = 1;
+ }
+ else if (ret == 0)
+ tempwidth = 0;
+ else
+ tempwidth = wcwidth (wc);
+
+ if (tempwidth > 0)
+ {
+ int count;
+ bytes = ret;
+ for (count = 0; count < bytes; count++)
+ putc (new[count], rl_outstream);
+ _rl_last_c_pos = tempwidth;
+ _rl_last_v_pos++;
+ memset (&ps, 0, sizeof (mbstate_t));
+ ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
+ if (ret != 0 && bytes != 0)
+ {
+ if (ret == (size_t)-1 || ret == (size_t)-2)
+ memmove (old+bytes, old+1, strlen (old+1));
+ else
+ memmove (old+bytes, old+ret, strlen (old+ret));
+ memcpy (old, new, bytes);
+ }
+ }
+ else
+ {
+ putc (' ', rl_outstream);
+ _rl_last_c_pos = 1;
+ _rl_last_v_pos++;
+ if (old[0] && new[0])
+ old[0] = new[0];
+ }
+ }
+ else
+#endif
+ {
+ if (new[0])
+ putc (new[0], rl_outstream);
+ else
+ putc (' ', rl_outstream);
+ _rl_last_c_pos = 1; /* XXX */
+ _rl_last_v_pos++;
+ if (old[0] && new[0])
+ old[0] = new[0];
+ }
+ }
+
+
+ /* Find first difference. */
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ memset (&ps_new, 0, sizeof(mbstate_t));
+ memset (&ps_old, 0, sizeof(mbstate_t));
+
+ new_offset = old_offset = 0;
+ for (ofd = old, nfd = new;
+ (ofd - old < omax) && *ofd &&
+ _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
+ {
+ old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
+ new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
+ ofd = old + old_offset;
+ nfd = new + new_offset;
+ }
+ }
+ else
+#endif
+ for (ofd = old, nfd = new;
+ (ofd - old < omax) && *ofd && (*ofd == *nfd);
+ ofd++, nfd++)
+ ;
+
+ /* Move to the end of the screen line. ND and OD are used to keep track
+ of the distance between ne and new and oe and old, respectively, to
+ move a subtraction out of each loop. */
+ for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
+ for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
+
+ /* If no difference, continue to next line. */
+ if (ofd == oe && nfd == ne)
+ return;
+
+ wsatend = 1; /* flag for trailing whitespace */
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
+ nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
+ while ((ols > ofd) && (nls > nfd))
+ {
+ memset (&ps_old, 0, sizeof (mbstate_t));
+ memset (&ps_new, 0, sizeof (mbstate_t));
+
+ _rl_adjust_point (old, ols - old, &ps_old);
+ _rl_adjust_point (new, nls - new, &ps_new);
+
+ if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
+ break;
+
+ if (*ols == ' ')
+ wsatend = 0;
+
+ ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
+ nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
+ }
+ }
+ else
+ {
+#endif /* HANDLE_MULTIBYTE */
+ ols = oe - 1; /* find last same */
+ nls = ne - 1;
+ while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
+ {
+ if (*ols != ' ')
+ wsatend = 0;
+ ols--;
+ nls--;
+ }
+#if defined (HANDLE_MULTIBYTE)
+ }
+#endif
+
+ if (wsatend)
+ {
+ ols = oe;
+ nls = ne;
+ }
+#if defined (HANDLE_MULTIBYTE)
+ /* This may not work for stateful encoding, but who cares? To handle
+ stateful encoding properly, we have to scan each string from the
+ beginning and compare. */
+ else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
+#else
+ else if (*ols != *nls)
+#endif
+ {
+ if (*ols) /* don't step past the NUL */
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ ols = old + _rl_find_next_mbchar (old, ols - old, 1, MB_FIND_ANY);
+ else
+ ols++;
+ }
+ if (*nls)
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ nls = new + _rl_find_next_mbchar (new, nls - new, 1, MB_FIND_ANY);
+ else
+ nls++;
+ }
+ }
+
+ /* count of invisible characters in the current invisible line. */
+ current_invis_chars = W_OFFSET (current_line, wrap_offset);
+ if (_rl_last_v_pos != current_line)
+ {
+ _rl_move_vert (current_line);
+ if (current_line == 0 && visible_wrap_offset)
+ _rl_last_c_pos += visible_wrap_offset;
+ }
+
+ /* If this is the first line and there are invisible characters in the
+ prompt string, and the prompt string has not changed, and the current
+ cursor position is before the last invisible character in the prompt,
+ and the index of the character to move to is past the end of the prompt
+ string, then redraw the entire prompt string. We can only do this
+ reliably if the terminal supports a `cr' capability.
+
+ This is not an efficiency hack -- there is a problem with redrawing
+ portions of the prompt string if they contain terminal escape
+ sequences (like drawing the `unbold' sequence without a corresponding
+ `bold') that manifests itself on certain terminals. */
+
+ lendiff = local_prompt ? strlen (local_prompt) : 0;
+ od = ofd - old; /* index of first difference in visible line */
+ if (current_line == 0 && !_rl_horizontal_scroll_mode &&
+ _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
+ od >= lendiff && _rl_last_c_pos <= prompt_last_invisible)
+ {
+#if defined (__MSDOS__)
+ putc ('\r', rl_outstream);
+#elif defined _WIN32
+ cr();
+#else
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif
+ _rl_output_some_chars (local_prompt, lendiff);
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ _rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff);
+ else
+ _rl_last_c_pos = lendiff;
+ }
+
+ _rl_move_cursor_relative (od, old);
+
+ /* if (len (new) > len (old))
+ lendiff == difference in buffer
+ col_lendiff == difference on screen
+ When not using multibyte characters, these are equal */
+ lendiff = (nls - nfd) - (ols - ofd);
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ col_lendiff = _rl_col_width (new, nfd - new, nls - new) - _rl_col_width (old, ofd - old, ols - old);
+ else
+ col_lendiff = lendiff;
+
+ /* If we are changing the number of invisible characters in a line, and
+ the spot of first difference is before the end of the invisible chars,
+ lendiff needs to be adjusted. */
+ if (current_line == 0 && !_rl_horizontal_scroll_mode &&
+ current_invis_chars != visible_wrap_offset)
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ lendiff += visible_wrap_offset - current_invis_chars;
+ col_lendiff += visible_wrap_offset - current_invis_chars;
+ }
+ else
+ {
+ lendiff += visible_wrap_offset - current_invis_chars;
+ col_lendiff = lendiff;
+ }
+ }
+
+ /* Insert (diff (len (old), len (new)) ch. */
+ temp = ne - nfd;
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ col_temp = _rl_col_width (new, nfd - new, ne - new);
+ else
+ col_temp = temp;
+
+ if (col_lendiff > 0) /* XXX - was lendiff */
+ {
+#if !defined _WIN32
+ /* Non-zero if we're increasing the number of lines. */
+ int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
+ /* Sometimes it is cheaper to print the characters rather than
+ use the terminal's capabilities. If we're growing the number
+ of lines, make sure we actually cause the new line to wrap
+ around on auto-wrapping terminals. */
+ if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
+ {
+ /* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
+ _rl_horizontal_scroll_mode == 1, inserting the characters with
+ _rl_term_IC or _rl_term_ic will screw up the screen because of the
+ invisible characters. We need to just draw them. */
+ if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
+ lendiff <= prompt_visible_length || !current_invis_chars))
+ {
+ insert_some_chars (nfd, lendiff, col_lendiff);
+ _rl_last_c_pos += col_lendiff;
+ }
+ else if (*ols == 0)
+ {
+ /* At the end of a line the characters do not have to
+ be "inserted". They can just be placed on the screen. */
+ /* However, this screws up the rest of this block, which
+ assumes you've done the insert because you can. */
+ _rl_output_some_chars (nfd, lendiff);
+ _rl_last_c_pos += col_lendiff;
+ }
+ else
+ {
+ /* We have horizontal scrolling and we are not inserting at
+ the end. We have invisible characters in this line. This
+ is a dumb update. */
+ _rl_output_some_chars (nfd, temp);
+ _rl_last_c_pos += col_temp;
+ return;
+ }
+ /* Copy (new) chars to screen from first diff to last match. */
+ temp = nls - nfd;
+ if ((temp - lendiff) > 0)
+ {
+ _rl_output_some_chars (nfd + lendiff, temp - lendiff);
+#if 0
+ _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff) - col_lendiff;
+#else
+ _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff);
+#endif
+ }
+ }
+ else
+#endif /* !_WIN32 */
+ {
+ /* cannot insert chars, write to EOL */
+ _rl_output_some_chars (nfd, temp);
+ _rl_last_c_pos += col_temp;
+ }
+ }
+ else /* Delete characters from line. */
+ {
+#if !defined _WIN32
+ /* If possible and inexpensive to use terminal deletion, then do so. */
+ if (_rl_term_dc && (2 * col_temp) >= -col_lendiff)
+ {
+ /* If all we're doing is erasing the invisible characters in the
+ prompt string, don't bother. It screws up the assumptions
+ about what's on the screen. */
+ if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
+ -lendiff == visible_wrap_offset)
+ col_lendiff = 0;
+
+ if (col_lendiff)
+ delete_chars (-col_lendiff); /* delete (diff) characters */
+
+ /* Copy (new) chars to screen from first diff to last match */
+ temp = nls - nfd;
+ if (temp > 0)
+ {
+ _rl_output_some_chars (nfd, temp);
+ _rl_last_c_pos += _rl_col_width (nfd, 0, temp);;
+ }
+ }
+ /* Otherwise, print over the existing material. */
+ else
+#endif /* !_WIN32 */
+ {
+ if (temp > 0)
+ {
+ _rl_output_some_chars (nfd, temp);
+ _rl_last_c_pos += col_temp;
+ }
+ lendiff = (oe - old) - (ne - new);
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ col_lendiff = _rl_col_width (old, 0, oe - old) - _rl_col_width (new, 0, ne - new);
+ else
+ col_lendiff = lendiff;
+
+ if (col_lendiff)
+ {
+ if (_rl_term_autowrap && current_line < inv_botlin)
+ space_to_eol (col_lendiff);
+ else
+ _rl_clear_to_eol (col_lendiff);
+ }
+ }
+ }
+}
+
+/* Tell the update routines that we have moved onto a new (empty) line. */
+int
+rl_on_new_line ()
+{
+ if (visible_line)
+ visible_line[0] = '\0';
+
+ _rl_last_c_pos = _rl_last_v_pos = 0;
+ _rl_vis_botlin = last_lmargin = 0;
+ if (vis_lbreaks)
+ vis_lbreaks[0] = vis_lbreaks[1] = 0;
+ visible_wrap_offset = 0;
+ return 0;
+}
+
+/* Tell the update routines that we have moved onto a new line with the
+ prompt already displayed. Code originally from the version of readline
+ distributed with CLISP. */
+int
+rl_on_new_line_with_prompt ()
+{
+ int prompt_size, i, l, real_screenwidth, newlines;
+ char *prompt_last_line;
+
+ /* Initialize visible_line and invisible_line to ensure that they can hold
+ the already-displayed prompt. */
+ prompt_size = strlen (rl_prompt) + 1;
+ init_line_structures (prompt_size);
+
+ /* Make sure the line structures hold the already-displayed prompt for
+ redisplay. */
+ strcpy (visible_line, rl_prompt);
+ strcpy (invisible_line, rl_prompt);
+
+ /* If the prompt contains newlines, take the last tail. */
+ prompt_last_line = strrchr (rl_prompt, '\n');
+ if (!prompt_last_line)
+ prompt_last_line = rl_prompt;
+
+ l = strlen (prompt_last_line);
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ _rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l);
+ else
+ _rl_last_c_pos = l;
+
+ /* Dissect prompt_last_line into screen lines. Note that here we have
+ to use the real screenwidth. Readline's notion of screenwidth might be
+ one less, see terminal.c. */
+ real_screenwidth = _rl_screenwidth + (_rl_term_autowrap ? 0 : 1);
+ _rl_last_v_pos = l / real_screenwidth;
+ /* If the prompt length is a multiple of real_screenwidth, we don't know
+ whether the cursor is at the end of the last line, or already at the
+ beginning of the next line. Output a newline just to be safe. */
+ if (l > 0 && (l % real_screenwidth) == 0)
+ _rl_output_some_chars ("\n", 1);
+ last_lmargin = 0;
+
+ newlines = 0; i = 0;
+ while (i <= l)
+ {
+ _rl_vis_botlin = newlines;
+ vis_lbreaks[newlines++] = i;
+ i += real_screenwidth;
+ }
+ vis_lbreaks[newlines] = l;
+ visible_wrap_offset = 0;
+
+ return 0;
+}
+
+/* Actually update the display, period. */
+int
+rl_forced_update_display ()
+{
+ if (visible_line)
+ {
+ register char *temp = visible_line;
+
+ while (*temp)
+ *temp++ = '\0';
+ }
+ rl_on_new_line ();
+ forced_display++;
+ (*rl_redisplay_function) ();
+ return 0;
+}
+
+/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
+ DATA is the contents of the screen line of interest; i.e., where
+ the movement is being done. */
+#if !defined _WIN32 /* replace next two functions */
+void
+_rl_move_cursor_relative (new, data)
+ int new;
+ const char *data;
+{
+ register int i;
+
+ /* If we don't have to do anything, then return. */
+#if defined (HANDLE_MULTIBYTE)
+ /* If we have multibyte characters, NEW is indexed by the buffer point in
+ a multibyte string, but _rl_last_c_pos is the display position. In
+ this case, NEW's display position is not obvious. */
+ if ((MB_CUR_MAX == 1 || rl_byte_oriented ) && _rl_last_c_pos == new) return;
+#else
+ if (_rl_last_c_pos == new) return;
+#endif
+
+ /* It may be faster to output a CR, and then move forwards instead
+ of moving backwards. */
+ /* i == current physical cursor position. */
+ i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
+ if (new == 0 || CR_FASTER (new, _rl_last_c_pos) ||
+ (_rl_term_autowrap && i == _rl_screenwidth))
+ {
+#if defined (__MSDOS__)
+ putc ('\r', rl_outstream);
+#else
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif /* !__MSDOS__ */
+ _rl_last_c_pos = 0;
+ }
+
+ if (_rl_last_c_pos < new)
+ {
+ /* Move the cursor forward. We do it by printing the command
+ to move the cursor forward if there is one, else print that
+ portion of the output buffer again. Which is cheaper? */
+
+ /* The above comment is left here for posterity. It is faster
+ to print one character (non-control) than to print a control
+ sequence telling the terminal to move forward one character.
+ That kind of control is for people who don't know what the
+ data is underneath the cursor. */
+#if defined (HACK_TERMCAP_MOTION)
+ if (_rl_term_forward_char)
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ int width;
+ width = _rl_col_width (data, _rl_last_c_pos, new);
+ for (i = 0; i < width; i++)
+ tputs (_rl_term_forward_char, 1, _rl_output_character_function);
+ }
+ else
+ {
+ for (i = _rl_last_c_pos; i < new; i++)
+ tputs (_rl_term_forward_char, 1, _rl_output_character_function);
+ }
+ }
+ else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+ for (i = 0; i < new; i++)
+ putc (data[i], rl_outstream);
+ }
+ else
+ for (i = _rl_last_c_pos; i < new; i++)
+ putc (data[i], rl_outstream);
+
+#else /* !HACK_TERMCAP_MOTION */
+
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+ for (i = 0; i < new; i++)
+ putc (data[i], rl_outstream);
+ }
+ else
+ for (i = _rl_last_c_pos; i < new; i++)
+ putc (data[i], rl_outstream);
+
+#endif /* !HACK_TERMCAP_MOTION */
+
+ }
+#if defined (HANDLE_MULTIBYTE)
+ /* NEW points to the buffer point, but _rl_last_c_pos is the display point.
+ The byte length of the string is probably bigger than the column width
+ of the string, which means that if NEW == _rl_last_c_pos, then NEW's
+ display point is less than _rl_last_c_pos. */
+ else if (_rl_last_c_pos >= new)
+#else
+ else if (_rl_last_c_pos > new)
+#endif
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+ for (i = 0; i < new; i++)
+ putc (data[i], rl_outstream);
+ }
+ else
+ _rl_backspace (_rl_last_c_pos - new);
+ }
+
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ _rl_last_c_pos = _rl_col_width (data, 0, new);
+ else
+ _rl_last_c_pos = new;
+}
+
+/* PWP: move the cursor up or down. */
+void
+_rl_move_vert (to)
+ int to;
+{
+ register int delta, i;
+
+ if (_rl_last_v_pos == to || to > _rl_screenheight)
+ return;
+
+ if ((delta = to - _rl_last_v_pos) > 0)
+ {
+ for (i = 0; i < delta; i++)
+ putc ('\n', rl_outstream);
+#if defined (__MSDOS__)
+ putc ('\r', rl_outstream);
+#else
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif
+ _rl_last_c_pos = 0;
+ }
+ else
+ { /* delta < 0 */
+ if (_rl_term_up && *_rl_term_up)
+ for (i = 0; i < -delta; i++)
+ tputs (_rl_term_up, 1, _rl_output_character_function);
+ }
+
+ _rl_last_v_pos = to; /* Now TO is here */
+}
+
+#else /* _WIN32 */
+
+void
+_rl_move_cursor_relative (new, data)
+ int new;
+ const char *data;
+{
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if ( (_rl_last_c_pos != new)
+ && haveConsole && GetConsoleScreenBufferInfo(hStdout, &csbi) )
+ {
+ csbi.dwCursorPosition.X += new - _rl_last_c_pos;
+ if ( SetConsoleCursorPosition(hStdout, csbi.dwCursorPosition) )
+ _rl_last_c_pos = new;
+ }
+ return;
+}
+
+void
+_rl_move_vert (to)
+ int to;
+{
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if ( (_rl_last_v_pos != to) && (to <= _rl_screenheight)
+ && haveConsole && GetConsoleScreenBufferInfo(hStdout, &csbi) )
+ {
+ csbi.dwCursorPosition.Y += to - _rl_last_v_pos;
+ if ( SetConsoleCursorPosition(hStdout, csbi.dwCursorPosition) )
+ _rl_last_v_pos = to;
+ }
+}
+#endif /* _WIN32 */
+
+/* Physically print C on rl_outstream. This is for functions which know
+ how to optimize the display. Return the number of characters output. */
+int
+rl_show_char (c)
+ int c;
+{
+ int n = 1;
+ if (META_CHAR (c) && (_rl_output_meta_chars == 0))
+ {
+ fprintf (rl_outstream, "M-");
+ n += 2;
+ c = UNMETA (c);
+ }
+
+#if defined (DISPLAY_TABS)
+ if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
+#else
+ if (CTRL_CHAR (c) || c == RUBOUT)
+#endif /* !DISPLAY_TABS */
+ {
+ fprintf (rl_outstream, "C-");
+ n += 2;
+ c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
+ }
+
+ putc (c, rl_outstream);
+ fflush (rl_outstream);
+ return n;
+}
+
+int
+rl_character_len (c, pos)
+ register int c, pos;
+{
+ unsigned char uc;
+
+ uc = (unsigned char)c;
+
+ if (META_CHAR (uc))
+ return ((_rl_output_meta_chars == 0) ? 4 : 1);
+
+ if (uc == '\t')
+ {
+#if defined (DISPLAY_TABS)
+ return (((pos | 7) + 1) - pos);
+#else
+ return (2);
+#endif /* !DISPLAY_TABS */
+ }
+
+ if (CTRL_CHAR (c) || c == RUBOUT)
+ return (2);
+
+ return ((ISPRINT (uc)) ? 1 : 2);
+}
+
+/* How to print things in the "echo-area". The prompt is treated as a
+ mini-modeline. */
+
+#if defined (USE_VARARGS)
+int
+#if defined (PREFER_STDARG)
+rl_message (const char *format, ...)
+#else
+rl_message (va_alist)
+ va_dcl
+#endif
+{
+ va_list args;
+#if defined (PREFER_VARARGS)
+ char *format;
+#endif
+
+#if defined (PREFER_STDARG)
+ va_start (args, format);
+#else
+ va_start (args);
+ format = va_arg (args, char *);
+#endif
+
+#if defined (HAVE_VSNPRINTF)
+ vsnprintf (msg_buf, sizeof (msg_buf) - 1, format, args);
+#else
+ vsprintf (msg_buf, format, args);
+ msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
+#endif
+ va_end (args);
+
+ rl_display_prompt = msg_buf;
+ (*rl_redisplay_function) ();
+ return 0;
+}
+#else /* !USE_VARARGS */
+int
+rl_message (format, arg1, arg2)
+ char *format;
+{
+ sprintf (msg_buf, format, arg1, arg2);
+ msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
+ rl_display_prompt = msg_buf;
+ (*rl_redisplay_function) ();
+ return 0;
+}
+#endif /* !USE_VARARGS */
+
+/* How to clear things from the "echo-area". */
+int
+rl_clear_message ()
+{
+ rl_display_prompt = rl_prompt;
+ (*rl_redisplay_function) ();
+ return 0;
+}
+
+int
+rl_reset_line_state ()
+{
+ rl_on_new_line ();
+
+ rl_display_prompt = rl_prompt ? rl_prompt : "";
+ forced_display = 1;
+ return 0;
+}
+
+static char *saved_local_prompt;
+static char *saved_local_prefix;
+static int saved_last_invisible;
+static int saved_visible_length;
+
+void
+rl_save_prompt ()
+{
+ saved_local_prompt = local_prompt;
+ saved_local_prefix = local_prompt_prefix;
+ saved_last_invisible = prompt_last_invisible;
+ saved_visible_length = prompt_visible_length;
+
+ local_prompt = local_prompt_prefix = (char *)0;
+ prompt_last_invisible = prompt_visible_length = 0;
+}
+
+void
+rl_restore_prompt ()
+{
+ FREE (local_prompt);
+ FREE (local_prompt_prefix);
+
+ local_prompt = saved_local_prompt;
+ local_prompt_prefix = saved_local_prefix;
+ prompt_last_invisible = saved_last_invisible;
+ prompt_visible_length = saved_visible_length;
+}
+
+char *
+_rl_make_prompt_for_search (pchar)
+ int pchar;
+{
+ int len;
+ char *pmt;
+
+ rl_save_prompt ();
+
+ if (saved_local_prompt == 0)
+ {
+ len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
+ pmt = (char *)xmalloc (len + 2);
+ if (len)
+ strcpy (pmt, rl_prompt);
+ pmt[len] = pchar;
+ pmt[len+1] = '\0';
+ }
+ else
+ {
+ len = *saved_local_prompt ? strlen (saved_local_prompt) : 0;
+ pmt = (char *)xmalloc (len + 2);
+ if (len)
+ strcpy (pmt, saved_local_prompt);
+ pmt[len] = pchar;
+ pmt[len+1] = '\0';
+ local_prompt = savestring (pmt);
+ prompt_last_invisible = saved_last_invisible;
+ prompt_visible_length = saved_visible_length + 1;
+ }
+ return pmt;
+}
+
+/* Quick redisplay hack when erasing characters at the end of the line. */
+void
+_rl_erase_at_end_of_line (l)
+ int l;
+{
+ register int i;
+
+ _rl_backspace (l);
+ for (i = 0; i < l; i++)
+ putc (' ', rl_outstream);
+ _rl_backspace (l);
+ for (i = 0; i < l; i++)
+ visible_line[--_rl_last_c_pos] = '\0';
+ rl_display_fixed++;
+}
+
+#if !defined _WIN32
+
+/* Clear to the end of the line. COUNT is the minimum
+ number of character spaces to clear, */
+void
+_rl_clear_to_eol (count)
+ int count;
+{
+ if (_rl_term_clreol)
+ tputs (_rl_term_clreol, 1, _rl_output_character_function);
+ else if (count)
+ space_to_eol (count);
+}
+
+/* Clear to the end of the line using spaces. COUNT is the minimum
+ number of character spaces to clear, */
+static void
+space_to_eol (count)
+ int count;
+{
+ register int i;
+
+ for (i = 0; i < count; i++)
+ putc (' ', rl_outstream);
+
+ _rl_last_c_pos += count;
+}
+
+#else /* _WIN32 */
+
+void
+_rl_clear_to_eol (count)
+ int count;
+{
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (haveConsole && GetConsoleScreenBufferInfo(hStdout, &csbi))
+ {
+ DWORD written;
+ int linear_pos;
+
+ linear_pos = (int)csbi.dwCursorPosition.Y * (int)csbi.dwSize.X
+ + (int)csbi.dwCursorPosition.X;
+#if defined (WITH_MINI_MOUSE)
+ if (linear_pos < rlScreenMax)
+ {
+ rlScreenEnd = csbi.dwCursorPosition;
+ rlScreenMax = linear_pos;
+ }
+#endif /* WITH_MINI_MOUSE */
+ FillConsoleOutputCharacter(hStdout, ' ', count, csbi.dwCursorPosition, &written);
+ }
+ return;
+}
+
+#endif /* _WIN32 */
+
+void
+_rl_clear_screen ()
+{
+#if !defined __MSDOS__ && !defined _WIN32
+ if (_rl_term_clrpag)
+ tputs (_rl_term_clrpag, 1, _rl_output_character_function);
+ else
+#endif
+ rl_crlf ();
+}
+
+#if !defined _WIN32 /* insert_some_chars and delete_chars are too costly with Win32 console */
+/* Insert COUNT characters from STRING to the output stream at column COL. */
+static void
+insert_some_chars (string, count, col)
+ char *string;
+ int count, col;
+{
+ /* DEBUGGING */
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ if (count != col)
+ fprintf(stderr, "readline: debug: insert_some_chars: count (%d) != col (%d)\n", count, col);
+
+ /* If IC is defined, then we do not have to "enter" insert mode. */
+ if (_rl_term_IC)
+ {
+ char *buffer;
+
+ buffer = tgoto (_rl_term_IC, 0, col);
+ tputs (buffer, 1, _rl_output_character_function);
+ _rl_output_some_chars (string, count);
+ }
+ else
+ {
+ register int i;
+
+ /* If we have to turn on insert-mode, then do so. */
+ if (_rl_term_im && *_rl_term_im)
+ tputs (_rl_term_im, 1, _rl_output_character_function);
+
+ /* If there is a special command for inserting characters, then
+ use that first to open up the space. */
+ if (_rl_term_ic && *_rl_term_ic)
+ {
+ for (i = col; i--; )
+ tputs (_rl_term_ic, 1, _rl_output_character_function);
+ }
+
+ /* Print the text. */
+ _rl_output_some_chars (string, count);
+
+ /* If there is a string to turn off insert mode, we had best use
+ it now. */
+ if (_rl_term_ei && *_rl_term_ei)
+ tputs (_rl_term_ei, 1, _rl_output_character_function);
+ }
+}
+
+/* Delete COUNT characters from the display line. */
+static void
+delete_chars (count)
+ int count;
+{
+ if (count > _rl_screenwidth) /* XXX */
+ return;
+
+ if (_rl_term_DC && *_rl_term_DC)
+ {
+ char *buffer;
+ buffer = tgoto (_rl_term_DC, count, count);
+ tputs (buffer, count, _rl_output_character_function);
+ }
+ else
+ {
+ if (_rl_term_dc && *_rl_term_dc)
+ while (count--)
+ tputs (_rl_term_dc, 1, _rl_output_character_function);
+ }
+}
+
+#endif /* !_WIN32 */
+
+void
+_rl_update_final ()
+{
+ int full_lines;
+
+ full_lines = 0;
+ /* If the cursor is the only thing on an otherwise-blank last line,
+ compensate so we don't print an extra CRLF. */
+ if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
+ visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
+ {
+ _rl_vis_botlin--;
+ full_lines = 1;
+ }
+ _rl_move_vert (_rl_vis_botlin);
+ /* If we've wrapped lines, remove the final xterm line-wrap flag. */
+ if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == _rl_screenwidth))
+ {
+ char *last_line;
+
+ last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
+ _rl_move_cursor_relative (_rl_screenwidth - 1, last_line);
+ _rl_clear_to_eol (0);
+ putc (last_line[_rl_screenwidth - 1], rl_outstream);
+ }
+ _rl_vis_botlin = 0;
+ rl_crlf ();
+ fflush (rl_outstream);
+ rl_display_fixed++;
+}
+
+#if !defined _WIN32
+
+/* Move to the start of the current line. */
+static void
+cr ()
+{
+ if (_rl_term_cr)
+ {
+#if defined (__MSDOS__)
+ putc ('\r', rl_outstream);
+#else
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif
+ _rl_last_c_pos = 0;
+ }
+}
+
+#endif
+
+/* Redraw the last line of a multi-line prompt that may possibly contain
+ terminal escape sequences. Called with the cursor at column 0 of the
+ line to draw the prompt on. */
+static void
+redraw_prompt (t)
+ char *t;
+{
+ char *oldp, *oldl, *oldlprefix;
+ int oldlen, oldlast, oldplen, oldninvis;
+
+ /* Geez, I should make this a struct. */
+ oldp = rl_display_prompt;
+ oldl = local_prompt;
+ oldlprefix = local_prompt_prefix;
+ oldlen = prompt_visible_length;
+ oldplen = prompt_prefix_length;
+ oldlast = prompt_last_invisible;
+ oldninvis = prompt_invis_chars_first_line;
+
+ rl_display_prompt = t;
+ local_prompt = expand_prompt (t, &prompt_visible_length,
+ &prompt_last_invisible,
+ &prompt_invis_chars_first_line);
+ local_prompt_prefix = (char *)NULL;
+ rl_forced_update_display ();
+
+ rl_display_prompt = oldp;
+ local_prompt = oldl;
+ local_prompt_prefix = oldlprefix;
+ prompt_visible_length = oldlen;
+ prompt_prefix_length = oldplen;
+ prompt_last_invisible = oldlast;
+ prompt_invis_chars_first_line = oldninvis;
+}
+
+/* Redisplay the current line after a SIGWINCH is received. */
+void
+_rl_redisplay_after_sigwinch ()
+{
+ char *t;
+
+ /* Clear the current line and put the cursor at column 0. Make sure
+ the right thing happens if we have wrapped to a new screen line. */
+ if (_rl_term_cr)
+ {
+#if _WIN32
+ _rl_move_cursor_relative (0, 0);
+ space_to_eol (_rl_screenwidth);
+ _rl_move_cursor_relative (0, 0);
+#else
+# if defined (__MSDOS__)
+ putc ('\r', rl_outstream);
+# else
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+# endif
+ _rl_last_c_pos = 0;
+# if defined (__MSDOS__)
+ space_to_eol (_rl_screenwidth);
+ putc ('\r', rl_outstream);
+# else
+ if (_rl_term_clreol)
+ tputs (_rl_term_clreol, 1, _rl_output_character_function);
+ else
+ {
+ space_to_eol (_rl_screenwidth);
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+ }
+# endif
+#endif
+ if (_rl_last_v_pos > 0)
+ _rl_move_vert (0);
+ }
+ else
+ rl_crlf ();
+
+ /* Redraw only the last line of a multi-line prompt. */
+ t = strrchr (rl_display_prompt, '\n');
+ if (t)
+ redraw_prompt (++t);
+ else
+ rl_forced_update_display ();
+}
+
+void
+_rl_clean_up_for_exit ()
+{
+ if (readline_echoing_p)
+ {
+ _rl_move_vert (_rl_vis_botlin);
+ _rl_vis_botlin = 0;
+ fflush (rl_outstream);
+#if !defined _WIN32
+ rl_restart_output (1, 0);
+#endif
+ }
+}
+
+void
+_rl_erase_entire_line ()
+{
+ cr ();
+ _rl_clear_to_eol (0);
+ cr ();
+ fflush (rl_outstream);
+}
+
+/* return the `current display line' of the cursor -- the number of lines to
+ move up to get to the first screen line of the current readline line. */
+int
+_rl_current_display_line ()
+{
+ int ret, nleft;
+
+ /* Find out whether or not there might be invisible characters in the
+ editing buffer. */
+ if (rl_display_prompt == rl_prompt)
+ nleft = _rl_last_c_pos - _rl_screenwidth - rl_visible_prompt_length;
+ else
+ nleft = _rl_last_c_pos - _rl_screenwidth;
+
+ if (nleft > 0)
+ ret = 1 + nleft / _rl_screenwidth;
+ else
+ ret = 0;
+
+ return ret;
+}
+
+#if defined (HANDLE_MULTIBYTE)
+/* Calculate the number of screen columns occupied by STR from START to END.
+ In the case of multibyte characters with stateful encoding, we have to
+ scan from the beginning of the string to take the state into account. */
+static int
+_rl_col_width (str, start, end)
+ char *str;
+ int start, end;
+{
+ wchar_t wc;
+ mbstate_t ps = {0};
+ int tmp, point, width, max;
+
+ if (end <= start)
+ return 0;
+
+ point = 0;
+ max = end;
+
+ while (point < start)
+ {
+ tmp = mbrlen (str + point, max, &ps);
+ if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2)
+ {
+ /* In this case, the bytes are invalid or too short to compose a
+ multibyte character, so we assume that the first byte represents
+ a single character. */
+ point++;
+ max--;
+
+ /* Clear the state of the byte sequence, because in this case the
+ effect of mbstate is undefined. */
+ memset (&ps, 0, sizeof (mbstate_t));
+ }
+ else if (tmp == 0)
+ break; /* Found '\0' */
+ else
+ {
+ point += tmp;
+ max -= tmp;
+ }
+ }
+
+ /* If START is not a byte that starts a character, then POINT will be
+ greater than START. In this case, assume that (POINT - START) gives
+ a byte count that is the number of columns of difference. */
+ width = point - start;
+
+ while (point < end)
+ {
+ tmp = mbrtowc (&wc, str + point, max, &ps);
+ if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2)
+ {
+ /* In this case, the bytes are invalid or too short to compose a
+ multibyte character, so we assume that the first byte represents
+ a single character. */
+ point++;
+ max--;
+
+ /* and assume that the byte occupies a single column. */
+ width++;
+
+ /* Clear the state of the byte sequence, because in this case the
+ effect of mbstate is undefined. */
+ memset (&ps, 0, sizeof (mbstate_t));
+ }
+ else if (tmp == 0)
+ break; /* Found '\0' */
+ else
+ {
+ point += tmp;
+ max -= tmp;
+ tmp = wcwidth(wc);
+ width += (tmp >= 0) ? tmp : 1;
+ }
+ }
+
+ width += point - end;
+
+ return width;
+}
+#endif /* HANDLE_MULTIBYTE */
+
diff --git a/MSVC/readline/emacs_keymap.c b/MSVC/readline/emacs_keymap.c
index ae1dee2..ca9d134 100644
--- a/MSVC/readline/emacs_keymap.c
+++ b/MSVC/readline/emacs_keymap.c
@@ -1,873 +1,873 @@
-/* emacs_keymap.c -- the keymap for emacs_mode in readline (). */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (BUFSIZ)
-#include <stdio.h>
-#endif /* !BUFSIZ */
-
-#include "readline.h"
-
-/* An array of function pointers, one for each possible key.
- If the type byte is ISKMAP, then the pointer is the address of
- a keymap. */
-
-KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
-
- /* Control keys. */
- { ISFUNC, rl_set_mark }, /* Control-@ */
- { ISFUNC, rl_beg_of_line }, /* Control-a */
- { ISFUNC, rl_backward_char }, /* Control-b */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */
- { ISFUNC, rl_delete }, /* Control-d */
- { ISFUNC, rl_end_of_line }, /* Control-e */
- { ISFUNC, rl_forward_char }, /* Control-f */
- { ISFUNC, rl_abort }, /* Control-g */
- { ISFUNC, rl_rubout }, /* Control-h */
- { ISFUNC, rl_complete }, /* Control-i */
- { ISFUNC, rl_newline }, /* Control-j */
- { ISFUNC, rl_kill_line }, /* Control-k */
- { ISFUNC, rl_clear_screen }, /* Control-l */
- { ISFUNC, rl_newline }, /* Control-m */
- { ISFUNC, rl_get_next_history }, /* Control-n */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */
- { ISFUNC, rl_get_previous_history }, /* Control-p */
- { ISFUNC, rl_quoted_insert }, /* Control-q */
- { ISFUNC, rl_reverse_search_history }, /* Control-r */
- { ISFUNC, rl_forward_search_history }, /* Control-s */
- { ISFUNC, rl_transpose_chars }, /* Control-t */
- { ISFUNC, rl_unix_line_discard }, /* Control-u */
- { ISFUNC, rl_quoted_insert }, /* Control-v */
- { ISFUNC, rl_unix_word_rubout }, /* Control-w */
- { ISKMAP, (rl_command_func_t *)emacs_ctlx_keymap }, /* Control-x */
- { ISFUNC, rl_yank }, /* Control-y */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
- { ISKMAP, (rl_command_func_t *)emacs_meta_keymap }, /* Control-[ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
- { ISFUNC, rl_char_search }, /* Control-] */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
- { ISFUNC, rl_undo_command }, /* Control-_ */
-
- /* The start of printing characters. */
- { ISFUNC, rl_insert }, /* SPACE */
- { ISFUNC, rl_insert }, /* ! */
- { ISFUNC, rl_insert }, /* " */
- { ISFUNC, rl_insert }, /* # */
- { ISFUNC, rl_insert }, /* $ */
- { ISFUNC, rl_insert }, /* % */
- { ISFUNC, rl_insert }, /* & */
- { ISFUNC, rl_insert }, /* ' */
- { ISFUNC, rl_insert }, /* ( */
- { ISFUNC, rl_insert }, /* ) */
- { ISFUNC, rl_insert }, /* * */
- { ISFUNC, rl_insert }, /* + */
- { ISFUNC, rl_insert }, /* , */
- { ISFUNC, rl_insert }, /* - */
- { ISFUNC, rl_insert }, /* . */
- { ISFUNC, rl_insert }, /* / */
-
- /* Regular digits. */
- { ISFUNC, rl_insert }, /* 0 */
- { ISFUNC, rl_insert }, /* 1 */
- { ISFUNC, rl_insert }, /* 2 */
- { ISFUNC, rl_insert }, /* 3 */
- { ISFUNC, rl_insert }, /* 4 */
- { ISFUNC, rl_insert }, /* 5 */
- { ISFUNC, rl_insert }, /* 6 */
- { ISFUNC, rl_insert }, /* 7 */
- { ISFUNC, rl_insert }, /* 8 */
- { ISFUNC, rl_insert }, /* 9 */
-
- /* A little more punctuation. */
- { ISFUNC, rl_insert }, /* : */
- { ISFUNC, rl_insert }, /* ; */
- { ISFUNC, rl_insert }, /* < */
- { ISFUNC, rl_insert }, /* = */
- { ISFUNC, rl_insert }, /* > */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* @ */
-
- /* Uppercase alphabet. */
- { ISFUNC, rl_insert }, /* A */
- { ISFUNC, rl_insert }, /* B */
- { ISFUNC, rl_insert }, /* C */
- { ISFUNC, rl_insert }, /* D */
- { ISFUNC, rl_insert }, /* E */
- { ISFUNC, rl_insert }, /* F */
- { ISFUNC, rl_insert }, /* G */
- { ISFUNC, rl_insert }, /* H */
- { ISFUNC, rl_insert }, /* I */
- { ISFUNC, rl_insert }, /* J */
- { ISFUNC, rl_insert }, /* K */
- { ISFUNC, rl_insert }, /* L */
- { ISFUNC, rl_insert }, /* M */
- { ISFUNC, rl_insert }, /* N */
- { ISFUNC, rl_insert }, /* O */
- { ISFUNC, rl_insert }, /* P */
- { ISFUNC, rl_insert }, /* Q */
- { ISFUNC, rl_insert }, /* R */
- { ISFUNC, rl_insert }, /* S */
- { ISFUNC, rl_insert }, /* T */
- { ISFUNC, rl_insert }, /* U */
- { ISFUNC, rl_insert }, /* V */
- { ISFUNC, rl_insert }, /* W */
- { ISFUNC, rl_insert }, /* X */
- { ISFUNC, rl_insert }, /* Y */
- { ISFUNC, rl_insert }, /* Z */
-
- /* Some more punctuation. */
- { ISFUNC, rl_insert }, /* [ */
- { ISFUNC, rl_insert }, /* \ */
- { ISFUNC, rl_insert }, /* ] */
- { ISFUNC, rl_insert }, /* ^ */
- { ISFUNC, rl_insert }, /* _ */
- { ISFUNC, rl_insert }, /* ` */
-
- /* Lowercase alphabet. */
- { ISFUNC, rl_insert }, /* a */
- { ISFUNC, rl_insert }, /* b */
- { ISFUNC, rl_insert }, /* c */
- { ISFUNC, rl_insert }, /* d */
- { ISFUNC, rl_insert }, /* e */
- { ISFUNC, rl_insert }, /* f */
- { ISFUNC, rl_insert }, /* g */
- { ISFUNC, rl_insert }, /* h */
- { ISFUNC, rl_insert }, /* i */
- { ISFUNC, rl_insert }, /* j */
- { ISFUNC, rl_insert }, /* k */
- { ISFUNC, rl_insert }, /* l */
- { ISFUNC, rl_insert }, /* m */
- { ISFUNC, rl_insert }, /* n */
- { ISFUNC, rl_insert }, /* o */
- { ISFUNC, rl_insert }, /* p */
- { ISFUNC, rl_insert }, /* q */
- { ISFUNC, rl_insert }, /* r */
- { ISFUNC, rl_insert }, /* s */
- { ISFUNC, rl_insert }, /* t */
- { ISFUNC, rl_insert }, /* u */
- { ISFUNC, rl_insert }, /* v */
- { ISFUNC, rl_insert }, /* w */
- { ISFUNC, rl_insert }, /* x */
- { ISFUNC, rl_insert }, /* y */
- { ISFUNC, rl_insert }, /* z */
-
- /* Final punctuation. */
- { ISFUNC, rl_insert }, /* { */
- { ISFUNC, rl_insert }, /* | */
- { ISFUNC, rl_insert }, /* } */
- { ISFUNC, rl_insert }, /* ~ */
- { ISFUNC, rl_rubout }, /* RUBOUT */
-
-#if KEYMAP_SIZE > 128
- /* Pure 8-bit characters (128 - 159).
- These might be used in some
- character sets. */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
-
- /* ISO Latin-1 characters (160 - 255) */
- { ISFUNC, rl_insert }, /* No-break space */
- { ISFUNC, rl_insert }, /* Inverted exclamation mark */
- { ISFUNC, rl_insert }, /* Cent sign */
- { ISFUNC, rl_insert }, /* Pound sign */
- { ISFUNC, rl_insert }, /* Currency sign */
- { ISFUNC, rl_insert }, /* Yen sign */
- { ISFUNC, rl_insert }, /* Broken bar */
- { ISFUNC, rl_insert }, /* Section sign */
- { ISFUNC, rl_insert }, /* Diaeresis */
- { ISFUNC, rl_insert }, /* Copyright sign */
- { ISFUNC, rl_insert }, /* Feminine ordinal indicator */
- { ISFUNC, rl_insert }, /* Left pointing double angle quotation mark */
- { ISFUNC, rl_insert }, /* Not sign */
- { ISFUNC, rl_insert }, /* Soft hyphen */
- { ISFUNC, rl_insert }, /* Registered sign */
- { ISFUNC, rl_insert }, /* Macron */
- { ISFUNC, rl_insert }, /* Degree sign */
- { ISFUNC, rl_insert }, /* Plus-minus sign */
- { ISFUNC, rl_insert }, /* Superscript two */
- { ISFUNC, rl_insert }, /* Superscript three */
- { ISFUNC, rl_insert }, /* Acute accent */
- { ISFUNC, rl_insert }, /* Micro sign */
- { ISFUNC, rl_insert }, /* Pilcrow sign */
- { ISFUNC, rl_insert }, /* Middle dot */
- { ISFUNC, rl_insert }, /* Cedilla */
- { ISFUNC, rl_insert }, /* Superscript one */
- { ISFUNC, rl_insert }, /* Masculine ordinal indicator */
- { ISFUNC, rl_insert }, /* Right pointing double angle quotation mark */
- { ISFUNC, rl_insert }, /* Vulgar fraction one quarter */
- { ISFUNC, rl_insert }, /* Vulgar fraction one half */
- { ISFUNC, rl_insert }, /* Vulgar fraction three quarters */
- { ISFUNC, rl_insert }, /* Inverted questionk mark */
- { ISFUNC, rl_insert }, /* Latin capital letter a with grave */
- { ISFUNC, rl_insert }, /* Latin capital letter a with acute */
- { ISFUNC, rl_insert }, /* Latin capital letter a with circumflex */
- { ISFUNC, rl_insert }, /* Latin capital letter a with tilde */
- { ISFUNC, rl_insert }, /* Latin capital letter a with diaeresis */
- { ISFUNC, rl_insert }, /* Latin capital letter a with ring above */
- { ISFUNC, rl_insert }, /* Latin capital letter ae */
- { ISFUNC, rl_insert }, /* Latin capital letter c with cedilla */
- { ISFUNC, rl_insert }, /* Latin capital letter e with grave */
- { ISFUNC, rl_insert }, /* Latin capital letter e with acute */
- { ISFUNC, rl_insert }, /* Latin capital letter e with circumflex */
- { ISFUNC, rl_insert }, /* Latin capital letter e with diaeresis */
- { ISFUNC, rl_insert }, /* Latin capital letter i with grave */
- { ISFUNC, rl_insert }, /* Latin capital letter i with acute */
- { ISFUNC, rl_insert }, /* Latin capital letter i with circumflex */
- { ISFUNC, rl_insert }, /* Latin capital letter i with diaeresis */
- { ISFUNC, rl_insert }, /* Latin capital letter eth (Icelandic) */
- { ISFUNC, rl_insert }, /* Latin capital letter n with tilde */
- { ISFUNC, rl_insert }, /* Latin capital letter o with grave */
- { ISFUNC, rl_insert }, /* Latin capital letter o with acute */
- { ISFUNC, rl_insert }, /* Latin capital letter o with circumflex */
- { ISFUNC, rl_insert }, /* Latin capital letter o with tilde */
- { ISFUNC, rl_insert }, /* Latin capital letter o with diaeresis */
- { ISFUNC, rl_insert }, /* Multiplication sign */
- { ISFUNC, rl_insert }, /* Latin capital letter o with stroke */
- { ISFUNC, rl_insert }, /* Latin capital letter u with grave */
- { ISFUNC, rl_insert }, /* Latin capital letter u with acute */
- { ISFUNC, rl_insert }, /* Latin capital letter u with circumflex */
- { ISFUNC, rl_insert }, /* Latin capital letter u with diaeresis */
- { ISFUNC, rl_insert }, /* Latin capital letter Y with acute */
- { ISFUNC, rl_insert }, /* Latin capital letter thorn (Icelandic) */
- { ISFUNC, rl_insert }, /* Latin small letter sharp s (German) */
- { ISFUNC, rl_insert }, /* Latin small letter a with grave */
- { ISFUNC, rl_insert }, /* Latin small letter a with acute */
- { ISFUNC, rl_insert }, /* Latin small letter a with circumflex */
- { ISFUNC, rl_insert }, /* Latin small letter a with tilde */
- { ISFUNC, rl_insert }, /* Latin small letter a with diaeresis */
- { ISFUNC, rl_insert }, /* Latin small letter a with ring above */
- { ISFUNC, rl_insert }, /* Latin small letter ae */
- { ISFUNC, rl_insert }, /* Latin small letter c with cedilla */
- { ISFUNC, rl_insert }, /* Latin small letter e with grave */
- { ISFUNC, rl_insert }, /* Latin small letter e with acute */
- { ISFUNC, rl_insert }, /* Latin small letter e with circumflex */
- { ISFUNC, rl_insert }, /* Latin small letter e with diaeresis */
- { ISFUNC, rl_insert }, /* Latin small letter i with grave */
- { ISFUNC, rl_insert }, /* Latin small letter i with acute */
- { ISFUNC, rl_insert }, /* Latin small letter i with circumflex */
- { ISFUNC, rl_insert }, /* Latin small letter i with diaeresis */
- { ISFUNC, rl_insert }, /* Latin small letter eth (Icelandic) */
- { ISFUNC, rl_insert }, /* Latin small letter n with tilde */
- { ISFUNC, rl_insert }, /* Latin small letter o with grave */
- { ISFUNC, rl_insert }, /* Latin small letter o with acute */
- { ISFUNC, rl_insert }, /* Latin small letter o with circumflex */
- { ISFUNC, rl_insert }, /* Latin small letter o with tilde */
- { ISFUNC, rl_insert }, /* Latin small letter o with diaeresis */
- { ISFUNC, rl_insert }, /* Division sign */
- { ISFUNC, rl_insert }, /* Latin small letter o with stroke */
- { ISFUNC, rl_insert }, /* Latin small letter u with grave */
- { ISFUNC, rl_insert }, /* Latin small letter u with acute */
- { ISFUNC, rl_insert }, /* Latin small letter u with circumflex */
- { ISFUNC, rl_insert }, /* Latin small letter u with diaeresis */
- { ISFUNC, rl_insert }, /* Latin small letter y with acute */
- { ISFUNC, rl_insert }, /* Latin small letter thorn (Icelandic) */
- { ISFUNC, rl_insert } /* Latin small letter y with diaeresis */
-#endif /* KEYMAP_SIZE > 128 */
-};
-
-KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
-
- /* Meta keys. Just like above, but the high bit is set. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-@ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-a */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-b */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-c */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-d */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-e */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-f */
- { ISFUNC, rl_abort }, /* Meta-Control-g */
- { ISFUNC, rl_backward_kill_word }, /* Meta-Control-h */
- { ISFUNC, rl_tab_insert }, /* Meta-Control-i */
- { ISFUNC, rl_vi_editing_mode }, /* Meta-Control-j */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-k */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-l */
- { ISFUNC, rl_vi_editing_mode }, /* Meta-Control-m */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-n */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-o */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-p */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-q */
- { ISFUNC, rl_revert_line }, /* Meta-Control-r */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-s */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-t */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-u */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-v */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-w */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-x */
- { ISFUNC, rl_yank_nth_arg }, /* Meta-Control-y */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-z */
-
- { ISFUNC, rl_complete }, /* Meta-Control-[ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-\ */
- { ISFUNC, rl_backward_char_search }, /* Meta-Control-] */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-^ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-_ */
-
- /* The start of printing characters. */
- { ISFUNC, rl_set_mark }, /* Meta-SPACE */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-! */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-" */
- { ISFUNC, rl_insert_comment }, /* Meta-# */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-$ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-% */
- { ISFUNC, rl_tilde_expand }, /* Meta-& */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-' */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-( */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-) */
- { ISFUNC, rl_insert_completions }, /* Meta-* */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-+ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-, */
- { ISFUNC, rl_digit_argument }, /* Meta-- */
- { ISFUNC, rl_yank_last_arg}, /* Meta-. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-/ */
-
- /* Regular digits. */
- { ISFUNC, rl_digit_argument }, /* Meta-0 */
- { ISFUNC, rl_digit_argument }, /* Meta-1 */
- { ISFUNC, rl_digit_argument }, /* Meta-2 */
- { ISFUNC, rl_digit_argument }, /* Meta-3 */
- { ISFUNC, rl_digit_argument }, /* Meta-4 */
- { ISFUNC, rl_digit_argument }, /* Meta-5 */
- { ISFUNC, rl_digit_argument }, /* Meta-6 */
- { ISFUNC, rl_digit_argument }, /* Meta-7 */
- { ISFUNC, rl_digit_argument }, /* Meta-8 */
- { ISFUNC, rl_digit_argument }, /* Meta-9 */
-
- /* A little more punctuation. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-: */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-; */
- { ISFUNC, rl_beginning_of_history }, /* Meta-< */
- { ISFUNC, rl_possible_completions }, /* Meta-= */
- { ISFUNC, rl_end_of_history }, /* Meta-> */
- { ISFUNC, rl_possible_completions }, /* Meta-? */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-@ */
-
- /* Uppercase alphabet. */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-A */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-B */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-C */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-D */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-E */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-F */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-G */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-H */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-I */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-J */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-K */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-L */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-M */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-N */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-O */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-P */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-Q */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-R */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-S */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-T */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-U */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-V */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-W */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-X */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-Y */
- { ISFUNC, rl_do_lowercase_version }, /* Meta-Z */
-
- /* Some more punctuation. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-[ */ /* was rl_arrow_keys */
- { ISFUNC, rl_delete_horizontal_space }, /* Meta-\ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-] */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-^ */
- { ISFUNC, rl_yank_last_arg }, /* Meta-_ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-` */
-
- /* Lowercase alphabet. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-a */
- { ISFUNC, rl_backward_word }, /* Meta-b */
- { ISFUNC, rl_capitalize_word }, /* Meta-c */
- { ISFUNC, rl_kill_word }, /* Meta-d */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-e */
- { ISFUNC, rl_forward_word }, /* Meta-f */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-g */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-h */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-i */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-j */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-k */
- { ISFUNC, rl_downcase_word }, /* Meta-l */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-m */
- { ISFUNC, rl_noninc_forward_search }, /* Meta-n */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-o */ /* was rl_arrow_keys */
- { ISFUNC, rl_noninc_reverse_search }, /* Meta-p */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-q */
- { ISFUNC, rl_revert_line }, /* Meta-r */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-s */
- { ISFUNC, rl_transpose_words }, /* Meta-t */
- { ISFUNC, rl_upcase_word }, /* Meta-u */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-v */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-w */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-x */
- { ISFUNC, rl_yank_pop }, /* Meta-y */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-z */
-
- /* Final punctuation. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-{ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-| */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-} */
- { ISFUNC, rl_tilde_expand }, /* Meta-~ */
- { ISFUNC, rl_backward_kill_word }, /* Meta-rubout */
-
-#if KEYMAP_SIZE > 128
- /* Undefined keys. */
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 }
-#endif /* KEYMAP_SIZE > 128 */
-};
-
-KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = {
-
- /* Control keys. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-d */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-e */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */
- { ISFUNC, rl_abort }, /* Control-g */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-h */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-i */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-j */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-k */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-l */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-m */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-n */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-p */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-q */
- { ISFUNC, rl_re_read_init_file }, /* Control-r */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-s */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-t */
- { ISFUNC, rl_undo_command }, /* Control-u */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-v */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-w */
- { ISFUNC, rl_exchange_point_and_mark }, /* Control-x */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-y */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-[ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-_ */
-
- /* The start of printing characters. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* SPACE */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* " */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* # */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* $ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* % */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* & */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */
- { ISFUNC, rl_start_kbd_macro }, /* ( */
- { ISFUNC, rl_end_kbd_macro }, /* ) */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* * */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* + */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* , */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* - */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* . */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* / */
-
- /* Regular digits. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* 0 */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* 1 */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* 2 */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* 3 */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* 4 */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* 5 */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* 6 */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* 7 */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* 8 */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* 9 */
-
- /* A little more punctuation. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* : */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ; */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* < */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* = */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* > */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ? */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */
-
- /* Uppercase alphabet. */
- { ISFUNC, rl_do_lowercase_version }, /* A */
- { ISFUNC, rl_do_lowercase_version }, /* B */
- { ISFUNC, rl_do_lowercase_version }, /* C */
- { ISFUNC, rl_do_lowercase_version }, /* D */
- { ISFUNC, rl_do_lowercase_version }, /* E */
- { ISFUNC, rl_do_lowercase_version }, /* F */
- { ISFUNC, rl_do_lowercase_version }, /* G */
- { ISFUNC, rl_do_lowercase_version }, /* H */
- { ISFUNC, rl_do_lowercase_version }, /* I */
- { ISFUNC, rl_do_lowercase_version }, /* J */
- { ISFUNC, rl_do_lowercase_version }, /* K */
- { ISFUNC, rl_do_lowercase_version }, /* L */
- { ISFUNC, rl_do_lowercase_version }, /* M */
- { ISFUNC, rl_do_lowercase_version }, /* N */
- { ISFUNC, rl_do_lowercase_version }, /* O */
- { ISFUNC, rl_do_lowercase_version }, /* P */
- { ISFUNC, rl_do_lowercase_version }, /* Q */
- { ISFUNC, rl_do_lowercase_version }, /* R */
- { ISFUNC, rl_do_lowercase_version }, /* S */
- { ISFUNC, rl_do_lowercase_version }, /* T */
- { ISFUNC, rl_do_lowercase_version }, /* U */
- { ISFUNC, rl_do_lowercase_version }, /* V */
- { ISFUNC, rl_do_lowercase_version }, /* W */
- { ISFUNC, rl_do_lowercase_version }, /* X */
- { ISFUNC, rl_do_lowercase_version }, /* Y */
- { ISFUNC, rl_do_lowercase_version }, /* Z */
-
- /* Some more punctuation. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* [ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* \ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ^ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* _ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ` */
-
- /* Lowercase alphabet. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* a */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* b */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* c */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* d */
- { ISFUNC, rl_call_last_kbd_macro }, /* e */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* f */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* g */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* h */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* i */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* j */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* k */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* l */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* m */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* n */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* o */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* p */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* q */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* r */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* s */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* t */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* u */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* v */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* w */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* x */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* y */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* z */
-
- /* Final punctuation. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* { */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* | */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* } */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ~ */
- { ISFUNC, rl_backward_kill_line }, /* RUBOUT */
-
-#if KEYMAP_SIZE > 128
- /* Undefined keys. */
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 }
-#endif /* KEYMAP_SIZE > 128 */
-};
+/* emacs_keymap.c -- the keymap for emacs_mode in readline (). */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (BUFSIZ)
+#include <stdio.h>
+#endif /* !BUFSIZ */
+
+#include "readline.h"
+
+/* An array of function pointers, one for each possible key.
+ If the type byte is ISKMAP, then the pointer is the address of
+ a keymap. */
+
+KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
+
+ /* Control keys. */
+ { ISFUNC, rl_set_mark }, /* Control-@ */
+ { ISFUNC, rl_beg_of_line }, /* Control-a */
+ { ISFUNC, rl_backward_char }, /* Control-b */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */
+ { ISFUNC, rl_delete }, /* Control-d */
+ { ISFUNC, rl_end_of_line }, /* Control-e */
+ { ISFUNC, rl_forward_char }, /* Control-f */
+ { ISFUNC, rl_abort }, /* Control-g */
+ { ISFUNC, rl_rubout }, /* Control-h */
+ { ISFUNC, rl_complete }, /* Control-i */
+ { ISFUNC, rl_newline }, /* Control-j */
+ { ISFUNC, rl_kill_line }, /* Control-k */
+ { ISFUNC, rl_clear_screen }, /* Control-l */
+ { ISFUNC, rl_newline }, /* Control-m */
+ { ISFUNC, rl_get_next_history }, /* Control-n */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */
+ { ISFUNC, rl_get_previous_history }, /* Control-p */
+ { ISFUNC, rl_quoted_insert }, /* Control-q */
+ { ISFUNC, rl_reverse_search_history }, /* Control-r */
+ { ISFUNC, rl_forward_search_history }, /* Control-s */
+ { ISFUNC, rl_transpose_chars }, /* Control-t */
+ { ISFUNC, rl_unix_line_discard }, /* Control-u */
+ { ISFUNC, rl_quoted_insert }, /* Control-v */
+ { ISFUNC, rl_unix_word_rubout }, /* Control-w */
+ { ISKMAP, (rl_command_func_t *)emacs_ctlx_keymap }, /* Control-x */
+ { ISFUNC, rl_yank }, /* Control-y */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
+ { ISKMAP, (rl_command_func_t *)emacs_meta_keymap }, /* Control-[ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
+ { ISFUNC, rl_char_search }, /* Control-] */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
+ { ISFUNC, rl_undo_command }, /* Control-_ */
+
+ /* The start of printing characters. */
+ { ISFUNC, rl_insert }, /* SPACE */
+ { ISFUNC, rl_insert }, /* ! */
+ { ISFUNC, rl_insert }, /* " */
+ { ISFUNC, rl_insert }, /* # */
+ { ISFUNC, rl_insert }, /* $ */
+ { ISFUNC, rl_insert }, /* % */
+ { ISFUNC, rl_insert }, /* & */
+ { ISFUNC, rl_insert }, /* ' */
+ { ISFUNC, rl_insert }, /* ( */
+ { ISFUNC, rl_insert }, /* ) */
+ { ISFUNC, rl_insert }, /* * */
+ { ISFUNC, rl_insert }, /* + */
+ { ISFUNC, rl_insert }, /* , */
+ { ISFUNC, rl_insert }, /* - */
+ { ISFUNC, rl_insert }, /* . */
+ { ISFUNC, rl_insert }, /* / */
+
+ /* Regular digits. */
+ { ISFUNC, rl_insert }, /* 0 */
+ { ISFUNC, rl_insert }, /* 1 */
+ { ISFUNC, rl_insert }, /* 2 */
+ { ISFUNC, rl_insert }, /* 3 */
+ { ISFUNC, rl_insert }, /* 4 */
+ { ISFUNC, rl_insert }, /* 5 */
+ { ISFUNC, rl_insert }, /* 6 */
+ { ISFUNC, rl_insert }, /* 7 */
+ { ISFUNC, rl_insert }, /* 8 */
+ { ISFUNC, rl_insert }, /* 9 */
+
+ /* A little more punctuation. */
+ { ISFUNC, rl_insert }, /* : */
+ { ISFUNC, rl_insert }, /* ; */
+ { ISFUNC, rl_insert }, /* < */
+ { ISFUNC, rl_insert }, /* = */
+ { ISFUNC, rl_insert }, /* > */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* @ */
+
+ /* Uppercase alphabet. */
+ { ISFUNC, rl_insert }, /* A */
+ { ISFUNC, rl_insert }, /* B */
+ { ISFUNC, rl_insert }, /* C */
+ { ISFUNC, rl_insert }, /* D */
+ { ISFUNC, rl_insert }, /* E */
+ { ISFUNC, rl_insert }, /* F */
+ { ISFUNC, rl_insert }, /* G */
+ { ISFUNC, rl_insert }, /* H */
+ { ISFUNC, rl_insert }, /* I */
+ { ISFUNC, rl_insert }, /* J */
+ { ISFUNC, rl_insert }, /* K */
+ { ISFUNC, rl_insert }, /* L */
+ { ISFUNC, rl_insert }, /* M */
+ { ISFUNC, rl_insert }, /* N */
+ { ISFUNC, rl_insert }, /* O */
+ { ISFUNC, rl_insert }, /* P */
+ { ISFUNC, rl_insert }, /* Q */
+ { ISFUNC, rl_insert }, /* R */
+ { ISFUNC, rl_insert }, /* S */
+ { ISFUNC, rl_insert }, /* T */
+ { ISFUNC, rl_insert }, /* U */
+ { ISFUNC, rl_insert }, /* V */
+ { ISFUNC, rl_insert }, /* W */
+ { ISFUNC, rl_insert }, /* X */
+ { ISFUNC, rl_insert }, /* Y */
+ { ISFUNC, rl_insert }, /* Z */
+
+ /* Some more punctuation. */
+ { ISFUNC, rl_insert }, /* [ */
+ { ISFUNC, rl_insert }, /* \ */
+ { ISFUNC, rl_insert }, /* ] */
+ { ISFUNC, rl_insert }, /* ^ */
+ { ISFUNC, rl_insert }, /* _ */
+ { ISFUNC, rl_insert }, /* ` */
+
+ /* Lowercase alphabet. */
+ { ISFUNC, rl_insert }, /* a */
+ { ISFUNC, rl_insert }, /* b */
+ { ISFUNC, rl_insert }, /* c */
+ { ISFUNC, rl_insert }, /* d */
+ { ISFUNC, rl_insert }, /* e */
+ { ISFUNC, rl_insert }, /* f */
+ { ISFUNC, rl_insert }, /* g */
+ { ISFUNC, rl_insert }, /* h */
+ { ISFUNC, rl_insert }, /* i */
+ { ISFUNC, rl_insert }, /* j */
+ { ISFUNC, rl_insert }, /* k */
+ { ISFUNC, rl_insert }, /* l */
+ { ISFUNC, rl_insert }, /* m */
+ { ISFUNC, rl_insert }, /* n */
+ { ISFUNC, rl_insert }, /* o */
+ { ISFUNC, rl_insert }, /* p */
+ { ISFUNC, rl_insert }, /* q */
+ { ISFUNC, rl_insert }, /* r */
+ { ISFUNC, rl_insert }, /* s */
+ { ISFUNC, rl_insert }, /* t */
+ { ISFUNC, rl_insert }, /* u */
+ { ISFUNC, rl_insert }, /* v */
+ { ISFUNC, rl_insert }, /* w */
+ { ISFUNC, rl_insert }, /* x */
+ { ISFUNC, rl_insert }, /* y */
+ { ISFUNC, rl_insert }, /* z */
+
+ /* Final punctuation. */
+ { ISFUNC, rl_insert }, /* { */
+ { ISFUNC, rl_insert }, /* | */
+ { ISFUNC, rl_insert }, /* } */
+ { ISFUNC, rl_insert }, /* ~ */
+ { ISFUNC, rl_rubout }, /* RUBOUT */
+
+#if KEYMAP_SIZE > 128
+ /* Pure 8-bit characters (128 - 159).
+ These might be used in some
+ character sets. */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+
+ /* ISO Latin-1 characters (160 - 255) */
+ { ISFUNC, rl_insert }, /* No-break space */
+ { ISFUNC, rl_insert }, /* Inverted exclamation mark */
+ { ISFUNC, rl_insert }, /* Cent sign */
+ { ISFUNC, rl_insert }, /* Pound sign */
+ { ISFUNC, rl_insert }, /* Currency sign */
+ { ISFUNC, rl_insert }, /* Yen sign */
+ { ISFUNC, rl_insert }, /* Broken bar */
+ { ISFUNC, rl_insert }, /* Section sign */
+ { ISFUNC, rl_insert }, /* Diaeresis */
+ { ISFUNC, rl_insert }, /* Copyright sign */
+ { ISFUNC, rl_insert }, /* Feminine ordinal indicator */
+ { ISFUNC, rl_insert }, /* Left pointing double angle quotation mark */
+ { ISFUNC, rl_insert }, /* Not sign */
+ { ISFUNC, rl_insert }, /* Soft hyphen */
+ { ISFUNC, rl_insert }, /* Registered sign */
+ { ISFUNC, rl_insert }, /* Macron */
+ { ISFUNC, rl_insert }, /* Degree sign */
+ { ISFUNC, rl_insert }, /* Plus-minus sign */
+ { ISFUNC, rl_insert }, /* Superscript two */
+ { ISFUNC, rl_insert }, /* Superscript three */
+ { ISFUNC, rl_insert }, /* Acute accent */
+ { ISFUNC, rl_insert }, /* Micro sign */
+ { ISFUNC, rl_insert }, /* Pilcrow sign */
+ { ISFUNC, rl_insert }, /* Middle dot */
+ { ISFUNC, rl_insert }, /* Cedilla */
+ { ISFUNC, rl_insert }, /* Superscript one */
+ { ISFUNC, rl_insert }, /* Masculine ordinal indicator */
+ { ISFUNC, rl_insert }, /* Right pointing double angle quotation mark */
+ { ISFUNC, rl_insert }, /* Vulgar fraction one quarter */
+ { ISFUNC, rl_insert }, /* Vulgar fraction one half */
+ { ISFUNC, rl_insert }, /* Vulgar fraction three quarters */
+ { ISFUNC, rl_insert }, /* Inverted questionk mark */
+ { ISFUNC, rl_insert }, /* Latin capital letter a with grave */
+ { ISFUNC, rl_insert }, /* Latin capital letter a with acute */
+ { ISFUNC, rl_insert }, /* Latin capital letter a with circumflex */
+ { ISFUNC, rl_insert }, /* Latin capital letter a with tilde */
+ { ISFUNC, rl_insert }, /* Latin capital letter a with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin capital letter a with ring above */
+ { ISFUNC, rl_insert }, /* Latin capital letter ae */
+ { ISFUNC, rl_insert }, /* Latin capital letter c with cedilla */
+ { ISFUNC, rl_insert }, /* Latin capital letter e with grave */
+ { ISFUNC, rl_insert }, /* Latin capital letter e with acute */
+ { ISFUNC, rl_insert }, /* Latin capital letter e with circumflex */
+ { ISFUNC, rl_insert }, /* Latin capital letter e with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin capital letter i with grave */
+ { ISFUNC, rl_insert }, /* Latin capital letter i with acute */
+ { ISFUNC, rl_insert }, /* Latin capital letter i with circumflex */
+ { ISFUNC, rl_insert }, /* Latin capital letter i with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin capital letter eth (Icelandic) */
+ { ISFUNC, rl_insert }, /* Latin capital letter n with tilde */
+ { ISFUNC, rl_insert }, /* Latin capital letter o with grave */
+ { ISFUNC, rl_insert }, /* Latin capital letter o with acute */
+ { ISFUNC, rl_insert }, /* Latin capital letter o with circumflex */
+ { ISFUNC, rl_insert }, /* Latin capital letter o with tilde */
+ { ISFUNC, rl_insert }, /* Latin capital letter o with diaeresis */
+ { ISFUNC, rl_insert }, /* Multiplication sign */
+ { ISFUNC, rl_insert }, /* Latin capital letter o with stroke */
+ { ISFUNC, rl_insert }, /* Latin capital letter u with grave */
+ { ISFUNC, rl_insert }, /* Latin capital letter u with acute */
+ { ISFUNC, rl_insert }, /* Latin capital letter u with circumflex */
+ { ISFUNC, rl_insert }, /* Latin capital letter u with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin capital letter Y with acute */
+ { ISFUNC, rl_insert }, /* Latin capital letter thorn (Icelandic) */
+ { ISFUNC, rl_insert }, /* Latin small letter sharp s (German) */
+ { ISFUNC, rl_insert }, /* Latin small letter a with grave */
+ { ISFUNC, rl_insert }, /* Latin small letter a with acute */
+ { ISFUNC, rl_insert }, /* Latin small letter a with circumflex */
+ { ISFUNC, rl_insert }, /* Latin small letter a with tilde */
+ { ISFUNC, rl_insert }, /* Latin small letter a with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin small letter a with ring above */
+ { ISFUNC, rl_insert }, /* Latin small letter ae */
+ { ISFUNC, rl_insert }, /* Latin small letter c with cedilla */
+ { ISFUNC, rl_insert }, /* Latin small letter e with grave */
+ { ISFUNC, rl_insert }, /* Latin small letter e with acute */
+ { ISFUNC, rl_insert }, /* Latin small letter e with circumflex */
+ { ISFUNC, rl_insert }, /* Latin small letter e with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin small letter i with grave */
+ { ISFUNC, rl_insert }, /* Latin small letter i with acute */
+ { ISFUNC, rl_insert }, /* Latin small letter i with circumflex */
+ { ISFUNC, rl_insert }, /* Latin small letter i with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin small letter eth (Icelandic) */
+ { ISFUNC, rl_insert }, /* Latin small letter n with tilde */
+ { ISFUNC, rl_insert }, /* Latin small letter o with grave */
+ { ISFUNC, rl_insert }, /* Latin small letter o with acute */
+ { ISFUNC, rl_insert }, /* Latin small letter o with circumflex */
+ { ISFUNC, rl_insert }, /* Latin small letter o with tilde */
+ { ISFUNC, rl_insert }, /* Latin small letter o with diaeresis */
+ { ISFUNC, rl_insert }, /* Division sign */
+ { ISFUNC, rl_insert }, /* Latin small letter o with stroke */
+ { ISFUNC, rl_insert }, /* Latin small letter u with grave */
+ { ISFUNC, rl_insert }, /* Latin small letter u with acute */
+ { ISFUNC, rl_insert }, /* Latin small letter u with circumflex */
+ { ISFUNC, rl_insert }, /* Latin small letter u with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin small letter y with acute */
+ { ISFUNC, rl_insert }, /* Latin small letter thorn (Icelandic) */
+ { ISFUNC, rl_insert } /* Latin small letter y with diaeresis */
+#endif /* KEYMAP_SIZE > 128 */
+};
+
+KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
+
+ /* Meta keys. Just like above, but the high bit is set. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-@ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-a */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-b */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-c */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-d */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-e */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-f */
+ { ISFUNC, rl_abort }, /* Meta-Control-g */
+ { ISFUNC, rl_backward_kill_word }, /* Meta-Control-h */
+ { ISFUNC, rl_tab_insert }, /* Meta-Control-i */
+ { ISFUNC, rl_vi_editing_mode }, /* Meta-Control-j */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-k */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-l */
+ { ISFUNC, rl_vi_editing_mode }, /* Meta-Control-m */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-n */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-o */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-p */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-q */
+ { ISFUNC, rl_revert_line }, /* Meta-Control-r */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-s */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-t */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-u */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-v */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-w */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-x */
+ { ISFUNC, rl_yank_nth_arg }, /* Meta-Control-y */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-z */
+
+ { ISFUNC, rl_complete }, /* Meta-Control-[ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-\ */
+ { ISFUNC, rl_backward_char_search }, /* Meta-Control-] */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-^ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-_ */
+
+ /* The start of printing characters. */
+ { ISFUNC, rl_set_mark }, /* Meta-SPACE */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-! */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-" */
+ { ISFUNC, rl_insert_comment }, /* Meta-# */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-$ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-% */
+ { ISFUNC, rl_tilde_expand }, /* Meta-& */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-' */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-( */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-) */
+ { ISFUNC, rl_insert_completions }, /* Meta-* */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-+ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-, */
+ { ISFUNC, rl_digit_argument }, /* Meta-- */
+ { ISFUNC, rl_yank_last_arg}, /* Meta-. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-/ */
+
+ /* Regular digits. */
+ { ISFUNC, rl_digit_argument }, /* Meta-0 */
+ { ISFUNC, rl_digit_argument }, /* Meta-1 */
+ { ISFUNC, rl_digit_argument }, /* Meta-2 */
+ { ISFUNC, rl_digit_argument }, /* Meta-3 */
+ { ISFUNC, rl_digit_argument }, /* Meta-4 */
+ { ISFUNC, rl_digit_argument }, /* Meta-5 */
+ { ISFUNC, rl_digit_argument }, /* Meta-6 */
+ { ISFUNC, rl_digit_argument }, /* Meta-7 */
+ { ISFUNC, rl_digit_argument }, /* Meta-8 */
+ { ISFUNC, rl_digit_argument }, /* Meta-9 */
+
+ /* A little more punctuation. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-: */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-; */
+ { ISFUNC, rl_beginning_of_history }, /* Meta-< */
+ { ISFUNC, rl_possible_completions }, /* Meta-= */
+ { ISFUNC, rl_end_of_history }, /* Meta-> */
+ { ISFUNC, rl_possible_completions }, /* Meta-? */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-@ */
+
+ /* Uppercase alphabet. */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-A */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-B */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-C */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-D */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-E */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-F */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-G */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-H */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-I */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-J */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-K */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-L */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-M */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-N */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-O */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-P */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-Q */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-R */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-S */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-T */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-U */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-V */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-W */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-X */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-Y */
+ { ISFUNC, rl_do_lowercase_version }, /* Meta-Z */
+
+ /* Some more punctuation. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-[ */ /* was rl_arrow_keys */
+ { ISFUNC, rl_delete_horizontal_space }, /* Meta-\ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-] */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-^ */
+ { ISFUNC, rl_yank_last_arg }, /* Meta-_ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-` */
+
+ /* Lowercase alphabet. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-a */
+ { ISFUNC, rl_backward_word }, /* Meta-b */
+ { ISFUNC, rl_capitalize_word }, /* Meta-c */
+ { ISFUNC, rl_kill_word }, /* Meta-d */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-e */
+ { ISFUNC, rl_forward_word }, /* Meta-f */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-g */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-h */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-i */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-j */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-k */
+ { ISFUNC, rl_downcase_word }, /* Meta-l */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-m */
+ { ISFUNC, rl_noninc_forward_search }, /* Meta-n */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-o */ /* was rl_arrow_keys */
+ { ISFUNC, rl_noninc_reverse_search }, /* Meta-p */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-q */
+ { ISFUNC, rl_revert_line }, /* Meta-r */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-s */
+ { ISFUNC, rl_transpose_words }, /* Meta-t */
+ { ISFUNC, rl_upcase_word }, /* Meta-u */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-v */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-w */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-x */
+ { ISFUNC, rl_yank_pop }, /* Meta-y */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-z */
+
+ /* Final punctuation. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-{ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-| */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-} */
+ { ISFUNC, rl_tilde_expand }, /* Meta-~ */
+ { ISFUNC, rl_backward_kill_word }, /* Meta-rubout */
+
+#if KEYMAP_SIZE > 128
+ /* Undefined keys. */
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 }
+#endif /* KEYMAP_SIZE > 128 */
+};
+
+KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = {
+
+ /* Control keys. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-d */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-e */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */
+ { ISFUNC, rl_abort }, /* Control-g */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-h */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-i */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-j */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-k */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-l */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-m */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-n */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-p */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-q */
+ { ISFUNC, rl_re_read_init_file }, /* Control-r */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-s */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-t */
+ { ISFUNC, rl_undo_command }, /* Control-u */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-v */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-w */
+ { ISFUNC, rl_exchange_point_and_mark }, /* Control-x */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-y */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-[ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-_ */
+
+ /* The start of printing characters. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* SPACE */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* " */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* # */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* $ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* % */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* & */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */
+ { ISFUNC, rl_start_kbd_macro }, /* ( */
+ { ISFUNC, rl_end_kbd_macro }, /* ) */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* * */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* + */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* , */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* - */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* . */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* / */
+
+ /* Regular digits. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* 0 */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* 1 */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* 2 */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* 3 */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* 4 */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* 5 */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* 6 */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* 7 */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* 8 */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* 9 */
+
+ /* A little more punctuation. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* : */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ; */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* < */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* = */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* > */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ? */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */
+
+ /* Uppercase alphabet. */
+ { ISFUNC, rl_do_lowercase_version }, /* A */
+ { ISFUNC, rl_do_lowercase_version }, /* B */
+ { ISFUNC, rl_do_lowercase_version }, /* C */
+ { ISFUNC, rl_do_lowercase_version }, /* D */
+ { ISFUNC, rl_do_lowercase_version }, /* E */
+ { ISFUNC, rl_do_lowercase_version }, /* F */
+ { ISFUNC, rl_do_lowercase_version }, /* G */
+ { ISFUNC, rl_do_lowercase_version }, /* H */
+ { ISFUNC, rl_do_lowercase_version }, /* I */
+ { ISFUNC, rl_do_lowercase_version }, /* J */
+ { ISFUNC, rl_do_lowercase_version }, /* K */
+ { ISFUNC, rl_do_lowercase_version }, /* L */
+ { ISFUNC, rl_do_lowercase_version }, /* M */
+ { ISFUNC, rl_do_lowercase_version }, /* N */
+ { ISFUNC, rl_do_lowercase_version }, /* O */
+ { ISFUNC, rl_do_lowercase_version }, /* P */
+ { ISFUNC, rl_do_lowercase_version }, /* Q */
+ { ISFUNC, rl_do_lowercase_version }, /* R */
+ { ISFUNC, rl_do_lowercase_version }, /* S */
+ { ISFUNC, rl_do_lowercase_version }, /* T */
+ { ISFUNC, rl_do_lowercase_version }, /* U */
+ { ISFUNC, rl_do_lowercase_version }, /* V */
+ { ISFUNC, rl_do_lowercase_version }, /* W */
+ { ISFUNC, rl_do_lowercase_version }, /* X */
+ { ISFUNC, rl_do_lowercase_version }, /* Y */
+ { ISFUNC, rl_do_lowercase_version }, /* Z */
+
+ /* Some more punctuation. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* [ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* \ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ^ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* _ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ` */
+
+ /* Lowercase alphabet. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* a */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* b */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* c */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* d */
+ { ISFUNC, rl_call_last_kbd_macro }, /* e */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* f */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* g */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* h */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* i */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* j */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* k */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* l */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* m */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* n */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* o */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* p */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* q */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* r */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* s */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* t */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* u */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* v */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* w */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* x */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* y */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* z */
+
+ /* Final punctuation. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* { */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* | */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* } */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ~ */
+ { ISFUNC, rl_backward_kill_line }, /* RUBOUT */
+
+#if KEYMAP_SIZE > 128
+ /* Undefined keys. */
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 }
+#endif /* KEYMAP_SIZE > 128 */
+};
diff --git a/MSVC/readline/funmap.c b/MSVC/readline/funmap.c
index 277ad27..36c30bc 100644
--- a/MSVC/readline/funmap.c
+++ b/MSVC/readline/funmap.c
@@ -1,251 +1,251 @@
-/* funmap.c -- attach names to functions. */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#if !defined (BUFSIZ)
-#include <stdio.h>
-#endif /* BUFSIZ */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include "rlconf.h"
-#include "readline.h"
-
-#include "xmalloc.h"
-
-#if defined __STDC__ || defined _MSC_VER
-typedef int QSFUNC (const void *, const void *);
-#else
-typedef int QSFUNC ();
-#endif
-
-extern int _rl_qsort_string_compare PARAMS((char **, char **));
-
-FUNMAP **funmap;
-static int funmap_size;
-static int funmap_entry;
-
-/* After initializing the function map, this is the index of the first
- program specific function. */
-int funmap_program_specific_entry_start;
-
-static FUNMAP default_funmap[] = {
- { "abort", rl_abort },
- { "accept-line", rl_newline },
- { "arrow-key-prefix", rl_arrow_keys },
- { "backward-byte", rl_backward_byte },
- { "backward-char", rl_backward_char },
- { "backward-delete-char", rl_rubout },
- { "backward-kill-line", rl_backward_kill_line },
- { "backward-kill-word", rl_backward_kill_word },
- { "backward-word", rl_backward_word },
- { "beginning-of-history", rl_beginning_of_history },
- { "beginning-of-line", rl_beg_of_line },
- { "call-last-kbd-macro", rl_call_last_kbd_macro },
- { "capitalize-word", rl_capitalize_word },
- { "character-search", rl_char_search },
- { "character-search-backward", rl_backward_char_search },
- { "clear-screen", rl_clear_screen },
- { "complete", rl_complete },
- { "copy-backward-word", rl_copy_backward_word },
- { "copy-forward-word", rl_copy_forward_word },
- { "copy-region-as-kill", rl_copy_region_to_kill },
- { "delete-char", rl_delete },
- { "delete-char-or-list", rl_delete_or_show_completions },
- { "delete-horizontal-space", rl_delete_horizontal_space },
- { "digit-argument", rl_digit_argument },
- { "do-lowercase-version", rl_do_lowercase_version },
- { "downcase-word", rl_downcase_word },
- { "dump-functions", rl_dump_functions },
- { "dump-macros", rl_dump_macros },
- { "dump-variables", rl_dump_variables },
- { "emacs-editing-mode", rl_emacs_editing_mode },
- { "end-kbd-macro", rl_end_kbd_macro },
- { "end-of-history", rl_end_of_history },
- { "end-of-line", rl_end_of_line },
- { "exchange-point-and-mark", rl_exchange_point_and_mark },
- { "forward-backward-delete-char", rl_rubout_or_delete },
- { "forward-byte", rl_forward_byte },
- { "forward-char", rl_forward_char },
- { "forward-search-history", rl_forward_search_history },
- { "forward-word", rl_forward_word },
- { "history-search-backward", rl_history_search_backward },
- { "history-search-forward", rl_history_search_forward },
- { "insert-comment", rl_insert_comment },
- { "insert-completions", rl_insert_completions },
- { "kill-whole-line", rl_kill_full_line },
- { "kill-line", rl_kill_line },
- { "kill-region", rl_kill_region },
- { "kill-word", rl_kill_word },
- { "menu-complete", rl_menu_complete },
- { "next-history", rl_get_next_history },
- { "non-incremental-forward-search-history", rl_noninc_forward_search },
- { "non-incremental-reverse-search-history", rl_noninc_reverse_search },
- { "non-incremental-forward-search-history-again", rl_noninc_forward_search_again },
- { "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again },
- { "overwrite-mode", rl_overwrite_mode },
-#if defined __CYGWIN__ || defined _WIN32
- { "paste-from-clipboard", rl_paste_from_clipboard },
-#endif
- { "possible-completions", rl_possible_completions },
- { "previous-history", rl_get_previous_history },
- { "quoted-insert", rl_quoted_insert },
- { "re-read-init-file", rl_re_read_init_file },
- { "redraw-current-line", rl_refresh_line},
- { "reverse-search-history", rl_reverse_search_history },
- { "revert-line", rl_revert_line },
- { "self-insert", rl_insert },
- { "set-mark", rl_set_mark },
- { "start-kbd-macro", rl_start_kbd_macro },
- { "tab-insert", rl_tab_insert },
- { "tilde-expand", rl_tilde_expand },
- { "transpose-chars", rl_transpose_chars },
- { "transpose-words", rl_transpose_words },
- { "tty-status", rl_tty_status },
- { "undo", rl_undo_command },
- { "universal-argument", rl_universal_argument },
- { "unix-line-discard", rl_unix_line_discard },
- { "unix-word-rubout", rl_unix_word_rubout },
- { "upcase-word", rl_upcase_word },
- { "yank", rl_yank },
- { "yank-last-arg", rl_yank_last_arg },
- { "yank-nth-arg", rl_yank_nth_arg },
- { "yank-pop", rl_yank_pop },
-
-#if defined (VI_MODE)
- { "vi-append-eol", rl_vi_append_eol },
- { "vi-append-mode", rl_vi_append_mode },
- { "vi-arg-digit", rl_vi_arg_digit },
- { "vi-back-to-indent", rl_vi_back_to_indent },
- { "vi-bWord", rl_vi_bWord },
- { "vi-bword", rl_vi_bword },
- { "vi-change-case", rl_vi_change_case },
- { "vi-change-char", rl_vi_change_char },
- { "vi-change-to", rl_vi_change_to },
- { "vi-char-search", rl_vi_char_search },
- { "vi-column", rl_vi_column },
- { "vi-complete", rl_vi_complete },
- { "vi-delete", rl_vi_delete },
- { "vi-delete-to", rl_vi_delete_to },
- { "vi-eWord", rl_vi_eWord },
- { "vi-editing-mode", rl_vi_editing_mode },
- { "vi-end-word", rl_vi_end_word },
- { "vi-eof-maybe", rl_vi_eof_maybe },
- { "vi-eword", rl_vi_eword },
- { "vi-fWord", rl_vi_fWord },
- { "vi-fetch-history", rl_vi_fetch_history },
- { "vi-first-print", rl_vi_first_print },
- { "vi-fword", rl_vi_fword },
- { "vi-goto-mark", rl_vi_goto_mark },
- { "vi-insert-beg", rl_vi_insert_beg },
- { "vi-insertion-mode", rl_vi_insertion_mode },
- { "vi-match", rl_vi_match },
- { "vi-movement-mode", rl_vi_movement_mode },
- { "vi-next-word", rl_vi_next_word },
- { "vi-overstrike", rl_vi_overstrike },
- { "vi-overstrike-delete", rl_vi_overstrike_delete },
- { "vi-prev-word", rl_vi_prev_word },
- { "vi-put", rl_vi_put },
- { "vi-redo", rl_vi_redo },
- { "vi-replace", rl_vi_replace },
- { "vi-search", rl_vi_search },
- { "vi-search-again", rl_vi_search_again },
- { "vi-set-mark", rl_vi_set_mark },
- { "vi-subst", rl_vi_subst },
- { "vi-tilde-expand", rl_vi_tilde_expand },
- { "vi-yank-arg", rl_vi_yank_arg },
- { "vi-yank-to", rl_vi_yank_to },
-#endif /* VI_MODE */
-
- {(char *)NULL, (rl_command_func_t *)NULL }
-};
-
-int
-rl_add_funmap_entry (name, function)
- const char *name;
- rl_command_func_t *function;
-{
- if (funmap_entry + 2 >= funmap_size)
- {
- funmap_size += 64;
- funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *));
- }
-
- funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
- funmap[funmap_entry]->name = name;
- funmap[funmap_entry]->function = function;
-
- funmap[++funmap_entry] = (FUNMAP *)NULL;
- return funmap_entry;
-}
-
-static int funmap_initialized;
-
-/* Make the funmap contain all of the default entries. */
-void
-rl_initialize_funmap ()
-{
- register int i;
-
- if (funmap_initialized)
- return;
-
- for (i = 0; default_funmap[i].name; i++)
- rl_add_funmap_entry (default_funmap[i].name, default_funmap[i].function);
-
- funmap_initialized = 1;
- funmap_program_specific_entry_start = i;
-}
-
-/* Produce a NULL terminated array of known function names. The array
- is sorted. The array itself is allocated, but not the strings inside.
- You should free () the array when you done, but not the pointrs. */
-const char **
-rl_funmap_names ()
-{
- const char **result;
- int result_size, result_index;
-
- /* Make sure that the function map has been initialized. */
- rl_initialize_funmap ();
-
- for (result_index = result_size = 0, result = (const char **)NULL; funmap[result_index]; result_index++)
- {
- if (result_index + 2 > result_size)
- {
- result_size += 20;
- result = (const char **)xrealloc ((void *)result, result_size * sizeof (char *));
- }
-
- result[result_index] = funmap[result_index]->name;
- result[result_index + 1] = (char *)NULL;
- }
-
- qsort ((void *)result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
- return (result);
-}
+/* funmap.c -- attach names to functions. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#if !defined (BUFSIZ)
+#include <stdio.h>
+#endif /* BUFSIZ */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include "rlconf.h"
+#include "readline.h"
+
+#include "xmalloc.h"
+
+#if defined __STDC__ || defined _MSC_VER
+typedef int QSFUNC (const void *, const void *);
+#else
+typedef int QSFUNC ();
+#endif
+
+extern int _rl_qsort_string_compare PARAMS((char **, char **));
+
+FUNMAP **funmap;
+static int funmap_size;
+static int funmap_entry;
+
+/* After initializing the function map, this is the index of the first
+ program specific function. */
+int funmap_program_specific_entry_start;
+
+static FUNMAP default_funmap[] = {
+ { "abort", rl_abort },
+ { "accept-line", rl_newline },
+ { "arrow-key-prefix", rl_arrow_keys },
+ { "backward-byte", rl_backward_byte },
+ { "backward-char", rl_backward_char },
+ { "backward-delete-char", rl_rubout },
+ { "backward-kill-line", rl_backward_kill_line },
+ { "backward-kill-word", rl_backward_kill_word },
+ { "backward-word", rl_backward_word },
+ { "beginning-of-history", rl_beginning_of_history },
+ { "beginning-of-line", rl_beg_of_line },
+ { "call-last-kbd-macro", rl_call_last_kbd_macro },
+ { "capitalize-word", rl_capitalize_word },
+ { "character-search", rl_char_search },
+ { "character-search-backward", rl_backward_char_search },
+ { "clear-screen", rl_clear_screen },
+ { "complete", rl_complete },
+ { "copy-backward-word", rl_copy_backward_word },
+ { "copy-forward-word", rl_copy_forward_word },
+ { "copy-region-as-kill", rl_copy_region_to_kill },
+ { "delete-char", rl_delete },
+ { "delete-char-or-list", rl_delete_or_show_completions },
+ { "delete-horizontal-space", rl_delete_horizontal_space },
+ { "digit-argument", rl_digit_argument },
+ { "do-lowercase-version", rl_do_lowercase_version },
+ { "downcase-word", rl_downcase_word },
+ { "dump-functions", rl_dump_functions },
+ { "dump-macros", rl_dump_macros },
+ { "dump-variables", rl_dump_variables },
+ { "emacs-editing-mode", rl_emacs_editing_mode },
+ { "end-kbd-macro", rl_end_kbd_macro },
+ { "end-of-history", rl_end_of_history },
+ { "end-of-line", rl_end_of_line },
+ { "exchange-point-and-mark", rl_exchange_point_and_mark },
+ { "forward-backward-delete-char", rl_rubout_or_delete },
+ { "forward-byte", rl_forward_byte },
+ { "forward-char", rl_forward_char },
+ { "forward-search-history", rl_forward_search_history },
+ { "forward-word", rl_forward_word },
+ { "history-search-backward", rl_history_search_backward },
+ { "history-search-forward", rl_history_search_forward },
+ { "insert-comment", rl_insert_comment },
+ { "insert-completions", rl_insert_completions },
+ { "kill-whole-line", rl_kill_full_line },
+ { "kill-line", rl_kill_line },
+ { "kill-region", rl_kill_region },
+ { "kill-word", rl_kill_word },
+ { "menu-complete", rl_menu_complete },
+ { "next-history", rl_get_next_history },
+ { "non-incremental-forward-search-history", rl_noninc_forward_search },
+ { "non-incremental-reverse-search-history", rl_noninc_reverse_search },
+ { "non-incremental-forward-search-history-again", rl_noninc_forward_search_again },
+ { "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again },
+ { "overwrite-mode", rl_overwrite_mode },
+#if defined __CYGWIN__ || defined _WIN32
+ { "paste-from-clipboard", rl_paste_from_clipboard },
+#endif
+ { "possible-completions", rl_possible_completions },
+ { "previous-history", rl_get_previous_history },
+ { "quoted-insert", rl_quoted_insert },
+ { "re-read-init-file", rl_re_read_init_file },
+ { "redraw-current-line", rl_refresh_line},
+ { "reverse-search-history", rl_reverse_search_history },
+ { "revert-line", rl_revert_line },
+ { "self-insert", rl_insert },
+ { "set-mark", rl_set_mark },
+ { "start-kbd-macro", rl_start_kbd_macro },
+ { "tab-insert", rl_tab_insert },
+ { "tilde-expand", rl_tilde_expand },
+ { "transpose-chars", rl_transpose_chars },
+ { "transpose-words", rl_transpose_words },
+ { "tty-status", rl_tty_status },
+ { "undo", rl_undo_command },
+ { "universal-argument", rl_universal_argument },
+ { "unix-line-discard", rl_unix_line_discard },
+ { "unix-word-rubout", rl_unix_word_rubout },
+ { "upcase-word", rl_upcase_word },
+ { "yank", rl_yank },
+ { "yank-last-arg", rl_yank_last_arg },
+ { "yank-nth-arg", rl_yank_nth_arg },
+ { "yank-pop", rl_yank_pop },
+
+#if defined (VI_MODE)
+ { "vi-append-eol", rl_vi_append_eol },
+ { "vi-append-mode", rl_vi_append_mode },
+ { "vi-arg-digit", rl_vi_arg_digit },
+ { "vi-back-to-indent", rl_vi_back_to_indent },
+ { "vi-bWord", rl_vi_bWord },
+ { "vi-bword", rl_vi_bword },
+ { "vi-change-case", rl_vi_change_case },
+ { "vi-change-char", rl_vi_change_char },
+ { "vi-change-to", rl_vi_change_to },
+ { "vi-char-search", rl_vi_char_search },
+ { "vi-column", rl_vi_column },
+ { "vi-complete", rl_vi_complete },
+ { "vi-delete", rl_vi_delete },
+ { "vi-delete-to", rl_vi_delete_to },
+ { "vi-eWord", rl_vi_eWord },
+ { "vi-editing-mode", rl_vi_editing_mode },
+ { "vi-end-word", rl_vi_end_word },
+ { "vi-eof-maybe", rl_vi_eof_maybe },
+ { "vi-eword", rl_vi_eword },
+ { "vi-fWord", rl_vi_fWord },
+ { "vi-fetch-history", rl_vi_fetch_history },
+ { "vi-first-print", rl_vi_first_print },
+ { "vi-fword", rl_vi_fword },
+ { "vi-goto-mark", rl_vi_goto_mark },
+ { "vi-insert-beg", rl_vi_insert_beg },
+ { "vi-insertion-mode", rl_vi_insertion_mode },
+ { "vi-match", rl_vi_match },
+ { "vi-movement-mode", rl_vi_movement_mode },
+ { "vi-next-word", rl_vi_next_word },
+ { "vi-overstrike", rl_vi_overstrike },
+ { "vi-overstrike-delete", rl_vi_overstrike_delete },
+ { "vi-prev-word", rl_vi_prev_word },
+ { "vi-put", rl_vi_put },
+ { "vi-redo", rl_vi_redo },
+ { "vi-replace", rl_vi_replace },
+ { "vi-search", rl_vi_search },
+ { "vi-search-again", rl_vi_search_again },
+ { "vi-set-mark", rl_vi_set_mark },
+ { "vi-subst", rl_vi_subst },
+ { "vi-tilde-expand", rl_vi_tilde_expand },
+ { "vi-yank-arg", rl_vi_yank_arg },
+ { "vi-yank-to", rl_vi_yank_to },
+#endif /* VI_MODE */
+
+ {(char *)NULL, (rl_command_func_t *)NULL }
+};
+
+int
+rl_add_funmap_entry (name, function)
+ const char *name;
+ rl_command_func_t *function;
+{
+ if (funmap_entry + 2 >= funmap_size)
+ {
+ funmap_size += 64;
+ funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *));
+ }
+
+ funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
+ funmap[funmap_entry]->name = name;
+ funmap[funmap_entry]->function = function;
+
+ funmap[++funmap_entry] = (FUNMAP *)NULL;
+ return funmap_entry;
+}
+
+static int funmap_initialized;
+
+/* Make the funmap contain all of the default entries. */
+void
+rl_initialize_funmap ()
+{
+ register int i;
+
+ if (funmap_initialized)
+ return;
+
+ for (i = 0; default_funmap[i].name; i++)
+ rl_add_funmap_entry (default_funmap[i].name, default_funmap[i].function);
+
+ funmap_initialized = 1;
+ funmap_program_specific_entry_start = i;
+}
+
+/* Produce a NULL terminated array of known function names. The array
+ is sorted. The array itself is allocated, but not the strings inside.
+ You should free () the array when you done, but not the pointrs. */
+const char **
+rl_funmap_names ()
+{
+ const char **result;
+ int result_size, result_index;
+
+ /* Make sure that the function map has been initialized. */
+ rl_initialize_funmap ();
+
+ for (result_index = result_size = 0, result = (const char **)NULL; funmap[result_index]; result_index++)
+ {
+ if (result_index + 2 > result_size)
+ {
+ result_size += 20;
+ result = (const char **)xrealloc ((void *)result, result_size * sizeof (char *));
+ }
+
+ result[result_index] = funmap[result_index]->name;
+ result[result_index + 1] = (char *)NULL;
+ }
+
+ qsort ((void *)result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
+ return (result);
+}
diff --git a/MSVC/readline/histexpand.c b/MSVC/readline/histexpand.c
index a90d9b2..dc2a89f 100644
--- a/MSVC/readline/histexpand.c
+++ b/MSVC/readline/histexpand.c
@@ -1,1489 +1,1489 @@
-/* histexpand.c -- history expansion. */
-
-/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
-
- This file contains the GNU History Library (the Library), a set of
- routines for managing the text of previously typed lines.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <stdio.h>
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_UNISTD_H)
-# ifndef _MINIX
-# include <sys/types.h>
-# endif
-# include <unistd.h>
-#endif
-
-#include "rlmbutil.h"
-
-#include "history.h"
-#include "histlib.h"
-
-#include "rlshell.h"
-#include "xmalloc.h"
-
-#define HISTORY_WORD_DELIMITERS " \t\n;&()|<>"
-#define HISTORY_QUOTE_CHARACTERS "\"'`"
-
-typedef int _hist_search_func_t PARAMS((const char *, int));
-
-extern int rl_byte_oriented; /* declared in mbutil.c */
-
-static char error_pointer;
-
-static char *subst_lhs;
-static char *subst_rhs;
-static int subst_lhs_len;
-static int subst_rhs_len;
-
-static char *get_history_word_specifier PARAMS((char *, char *, int *));
-static char *history_find_word PARAMS((char *, int));
-
-static char *quote_breaks PARAMS((char *));
-
-/* Variables exported by this file. */
-/* The character that represents the start of a history expansion
- request. This is usually `!'. */
-char history_expansion_char = '!';
-
-/* The character that invokes word substitution if found at the start of
- a line. This is usually `^'. */
-char history_subst_char = '^';
-
-/* During tokenization, if this character is seen as the first character
- of a word, then it, and all subsequent characters upto a newline are
- ignored. For a Bourne shell, this should be '#'. Bash special cases
- the interactive comment character to not be a comment delimiter. */
-char history_comment_char = '\0';
-
-/* The list of characters which inhibit the expansion of text if found
- immediately following history_expansion_char. */
-char *history_no_expand_chars = " \t\n\r=";
-
-/* If set to a non-zero value, single quotes inhibit history expansion.
- The default is 0. */
-int history_quotes_inhibit_expansion = 0;
-
-/* Used to split words by history_tokenize_internal. */
-char *history_word_delimiters = HISTORY_WORD_DELIMITERS;
-
-/* If set, this points to a function that is called to verify that a
- particular history expansion should be performed. */
-rl_linebuf_func_t *history_inhibit_expansion_function;
-
-/* **************************************************************** */
-/* */
-/* History Expansion */
-/* */
-/* **************************************************************** */
-
-/* Hairy history expansion on text, not tokens. This is of general
- use, and thus belongs in this library. */
-
-/* The last string searched for by a !?string? search. */
-static char *search_string;
-
-/* The last string matched by a !?string? search. */
-static char *search_match;
-
-/* Return the event specified at TEXT + OFFSET modifying OFFSET to
- point to after the event specifier. Just a pointer to the history
- line is returned; NULL is returned in the event of a bad specifier.
- You pass STRING with *INDEX equal to the history_expansion_char that
- begins this specification.
- DELIMITING_QUOTE is a character that is allowed to end the string
- specification for what to search for in addition to the normal
- characters `:', ` ', `\t', `\n', and sometimes `?'.
- So you might call this function like:
- line = get_history_event ("!echo:p", &index, 0); */
-char *
-get_history_event (string, caller_index, delimiting_quote)
- const char *string;
- int *caller_index;
- int delimiting_quote;
-{
- register int i;
- register char c;
- HIST_ENTRY *entry;
- int which, sign, local_index, substring_okay;
- _hist_search_func_t *search_func;
- char *temp;
-
- /* The event can be specified in a number of ways.
-
- !! the previous command
- !n command line N
- !-n current command-line minus N
- !str the most recent command starting with STR
- !?str[?]
- the most recent command containing STR
-
- All values N are determined via HISTORY_BASE. */
-
- i = *caller_index;
-
- if (string[i] != history_expansion_char)
- return ((char *)NULL);
-
- /* Move on to the specification. */
- i++;
-
- sign = 1;
- substring_okay = 0;
-
-#define RETURN_ENTRY(e, w) \
- return ((e = history_get (w)) ? e->line : (char *)NULL)
-
- /* Handle !! case. */
- if (string[i] == history_expansion_char)
- {
- i++;
- which = history_base + (history_length - 1);
- *caller_index = i;
- RETURN_ENTRY (entry, which);
- }
-
- /* Hack case of numeric line specification. */
- if (string[i] == '-')
- {
- sign = -1;
- i++;
- }
-
- if (_rl_digit_p (string[i]))
- {
- /* Get the extent of the digits and compute the value. */
- for (which = 0; _rl_digit_p (string[i]); i++)
- which = (which * 10) + _rl_digit_value (string[i]);
-
- *caller_index = i;
-
- if (sign < 0)
- which = (history_length + history_base) - which;
-
- RETURN_ENTRY (entry, which);
- }
-
- /* This must be something to search for. If the spec begins with
- a '?', then the string may be anywhere on the line. Otherwise,
- the string must be found at the start of a line. */
- if (string[i] == '?')
- {
- substring_okay++;
- i++;
- }
-
- /* Only a closing `?' or a newline delimit a substring search string. */
- for (local_index = i; c = string[i]; i++)
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- int v;
- mbstate_t ps;
-
- memset (&ps, 0, sizeof (mbstate_t));
- /* These produce warnings because we're passing a const string to a
- function that takes a non-const string. */
- _rl_adjust_point (string, i, &ps);
- if ((v = _rl_get_char_len (string + i, &ps)) > 1)
- {
- i += v - 1;
- continue;
- }
- }
- else
-#endif /* HANDLE_MULTIBYTE */
- if ((!substring_okay && (whitespace (c) || c == ':' ||
- (history_search_delimiter_chars && member (c, history_search_delimiter_chars)) ||
- string[i] == delimiting_quote)) ||
- string[i] == '\n' ||
- (substring_okay && string[i] == '?'))
- break;
-
- which = i - local_index;
- temp = (char *)xmalloc (1 + which);
- if (which)
- strncpy (temp, string + local_index, which);
- temp[which] = '\0';
-
- if (substring_okay && string[i] == '?')
- i++;
-
- *caller_index = i;
-
-#define FAIL_SEARCH() \
- do { \
- history_offset = history_length; free (temp) ; return (char *)NULL; \
- } while (0)
-
- /* If there is no search string, try to use the previous search string,
- if one exists. If not, fail immediately. */
- if (*temp == '\0' && substring_okay)
- {
- if (search_string)
- {
- free (temp);
- temp = savestring (search_string);
- }
- else
- FAIL_SEARCH ();
- }
-
- search_func = substring_okay ? history_search : history_search_prefix;
- while (1)
- {
- local_index = (*search_func) (temp, -1);
-
- if (local_index < 0)
- FAIL_SEARCH ();
-
- if (local_index == 0 || substring_okay)
- {
- entry = current_history ();
- history_offset = history_length;
-
- /* If this was a substring search, then remember the
- string that we matched for word substitution. */
- if (substring_okay)
- {
- FREE (search_string);
- search_string = temp;
-
- FREE (search_match);
- search_match = history_find_word (entry->line, local_index);
- }
- else
- free (temp);
-
- return (entry->line);
- }
-
- if (history_offset)
- history_offset--;
- else
- FAIL_SEARCH ();
- }
-#undef FAIL_SEARCH
-#undef RETURN_ENTRY
-}
-
-/* Function for extracting single-quoted strings. Used for inhibiting
- history expansion within single quotes. */
-
-/* Extract the contents of STRING as if it is enclosed in single quotes.
- SINDEX, when passed in, is the offset of the character immediately
- following the opening single quote; on exit, SINDEX is left pointing
- to the closing single quote. */
-static void
-hist_string_extract_single_quoted (string, sindex)
- char *string;
- int *sindex;
-{
- register int i;
-
- for (i = *sindex; string[i] && string[i] != '\''; i++)
- ;
-
- *sindex = i;
-}
-
-static char *
-quote_breaks (s)
- char *s;
-{
- register char *p, *r;
- char *ret;
- int len = 3;
-
- for (p = s; p && *p; p++, len++)
- {
- if (*p == '\'')
- len += 3;
- else if (whitespace (*p) || *p == '\n')
- len += 2;
- }
-
- r = ret = (char *)xmalloc (len);
- *r++ = '\'';
- for (p = s; p && *p; )
- {
- if (*p == '\'')
- {
- *r++ = '\'';
- *r++ = '\\';
- *r++ = '\'';
- *r++ = '\'';
- p++;
- }
- else if (whitespace (*p) || *p == '\n')
- {
- *r++ = '\'';
- *r++ = *p++;
- *r++ = '\'';
- }
- else
- *r++ = *p++;
- }
- *r++ = '\'';
- *r = '\0';
- return ret;
-}
-
-static char *
-hist_error(s, start, current, errtype)
- char *s;
- int start, current, errtype;
-{
- char *temp;
- const char *emsg;
- int ll, elen;
-
- ll = current - start;
-
- switch (errtype)
- {
- case EVENT_NOT_FOUND:
- emsg = "event not found";
- elen = 15;
- break;
- case BAD_WORD_SPEC:
- emsg = "bad word specifier";
- elen = 18;
- break;
- case SUBST_FAILED:
- emsg = "substitution failed";
- elen = 19;
- break;
- case BAD_MODIFIER:
- emsg = "unrecognized history modifier";
- elen = 29;
- break;
- case NO_PREV_SUBST:
- emsg = "no previous substitution";
- elen = 24;
- break;
- default:
- emsg = "unknown expansion error";
- elen = 23;
- break;
- }
-
- temp = (char *)xmalloc (ll + elen + 3);
- strncpy (temp, s + start, ll);
- temp[ll] = ':';
- temp[ll + 1] = ' ';
- strcpy (temp + ll + 2, emsg);
- return (temp);
-}
-
-/* Get a history substitution string from STR starting at *IPTR
- and return it. The length is returned in LENPTR.
-
- A backslash can quote the delimiter. If the string is the
- empty string, the previous pattern is used. If there is
- no previous pattern for the lhs, the last history search
- string is used.
-
- If IS_RHS is 1, we ignore empty strings and set the pattern
- to "" anyway. subst_lhs is not changed if the lhs is empty;
- subst_rhs is allowed to be set to the empty string. */
-
-static char *
-get_subst_pattern (str, iptr, delimiter, is_rhs, lenptr)
- char *str;
- int *iptr, delimiter, is_rhs, *lenptr;
-{
- register int si, i, j, k;
- char *s;
-#if defined (HANDLE_MULTIBYTE)
- mbstate_t ps;
-#endif
-
- s = (char *)NULL;
- i = *iptr;
-
-#if defined (HANDLE_MULTIBYTE)
- memset (&ps, 0, sizeof (mbstate_t));
- _rl_adjust_point (str, i, &ps);
-#endif
-
- for (si = i; str[si] && str[si] != delimiter; si++)
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- int v;
- if ((v = _rl_get_char_len (str + si, &ps)) > 1)
- si += v - 1;
- else if (str[si] == '\\' && str[si + 1] == delimiter)
- si++;
- }
- else
-#endif /* HANDLE_MULTIBYTE */
- if (str[si] == '\\' && str[si + 1] == delimiter)
- si++;
-
- if (si > i || is_rhs)
- {
- s = (char *)xmalloc (si - i + 1);
- for (j = 0, k = i; k < si; j++, k++)
- {
- /* Remove a backslash quoting the search string delimiter. */
- if (str[k] == '\\' && str[k + 1] == delimiter)
- k++;
- s[j] = str[k];
- }
- s[j] = '\0';
- if (lenptr)
- *lenptr = j;
- }
-
- i = si;
- if (str[i])
- i++;
- *iptr = i;
-
- return s;
-}
-
-static void
-postproc_subst_rhs ()
-{
- char *new;
- int i, j, new_size;
-
- new = (char *)xmalloc (new_size = subst_rhs_len + subst_lhs_len);
- for (i = j = 0; i < subst_rhs_len; i++)
- {
- if (subst_rhs[i] == '&')
- {
- if (j + subst_lhs_len >= new_size)
- new = (char *)xrealloc (new, (new_size = new_size * 2 + subst_lhs_len));
- strcpy (new + j, subst_lhs);
- j += subst_lhs_len;
- }
- else
- {
- /* a single backslash protects the `&' from lhs interpolation */
- if (subst_rhs[i] == '\\' && subst_rhs[i + 1] == '&')
- i++;
- if (j >= new_size)
- new = (char *)xrealloc (new, new_size *= 2);
- new[j++] = subst_rhs[i];
- }
- }
- new[j] = '\0';
- free (subst_rhs);
- subst_rhs = new;
- subst_rhs_len = j;
-}
-
-/* Expand the bulk of a history specifier starting at STRING[START].
- Returns 0 if everything is OK, -1 if an error occurred, and 1
- if the `p' modifier was supplied and the caller should just print
- the returned string. Returns the new index into string in
- *END_INDEX_PTR, and the expanded specifier in *RET_STRING. */
-static int
-history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
- char *string;
- int start, *end_index_ptr;
- char **ret_string;
- char *current_line; /* for !# */
-{
- int i, n, starting_index;
- int substitute_globally, want_quotes, print_only;
- char *event, *temp, *result, *tstr, *t, c, *word_spec;
- int result_len;
-#if defined (HANDLE_MULTIBYTE)
- mbstate_t ps;
-
- memset (&ps, 0, sizeof (mbstate_t));
-#endif
-
- result = (char *)xmalloc (result_len = 128);
-
- i = start;
-
- /* If it is followed by something that starts a word specifier,
- then !! is implied as the event specifier. */
-
- if (member (string[i + 1], ":$*%^"))
- {
- char fake_s[3];
- int fake_i = 0;
- i++;
- fake_s[0] = fake_s[1] = history_expansion_char;
- fake_s[2] = '\0';
- event = get_history_event (fake_s, &fake_i, 0);
- }
- else if (string[i + 1] == '#')
- {
- i += 2;
- event = current_line;
- }
- else
- {
- int quoted_search_delimiter = 0;
-
- /* If the character before this `!' is a double or single
- quote, then this expansion takes place inside of the
- quoted string. If we have to search for some text ("!foo"),
- allow the delimiter to end the search string. */
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- int c, l;
- l = _rl_find_prev_mbchar (string, i, MB_FIND_ANY);
- c = string[l];
- /* XXX - original patch had i - 1 ??? If i == 0 it would fail. */
- if (i && (c == '\'' || c == '"'))
- quoted_search_delimiter = c;
- }
- else
-#endif /* HANDLE_MULTIBYTE */
- if (i && (string[i - 1] == '\'' || string[i - 1] == '"'))
- quoted_search_delimiter = string[i - 1];
-
- event = get_history_event (string, &i, quoted_search_delimiter);
- }
-
- if (event == 0)
- {
- *ret_string = hist_error (string, start, i, EVENT_NOT_FOUND);
- free (result);
- return (-1);
- }
-
- /* If a word specifier is found, then do what that requires. */
- starting_index = i;
- word_spec = get_history_word_specifier (string, event, &i);
-
- /* There is no such thing as a `malformed word specifier'. However,
- it is possible for a specifier that has no match. In that case,
- we complain. */
- if (word_spec == (char *)&error_pointer)
- {
- *ret_string = hist_error (string, starting_index, i, BAD_WORD_SPEC);
- free (result);
- return (-1);
- }
-
- /* If no word specifier, than the thing of interest was the event. */
- temp = word_spec ? savestring (word_spec) : savestring (event);
- FREE (word_spec);
-
- /* Perhaps there are other modifiers involved. Do what they say. */
- want_quotes = substitute_globally = print_only = 0;
- starting_index = i;
-
- while (string[i] == ':')
- {
- c = string[i + 1];
-
- if (c == 'g')
- {
- substitute_globally = 1;
- i++;
- c = string[i + 1];
- }
-
- switch (c)
- {
- default:
- *ret_string = hist_error (string, i+1, i+2, BAD_MODIFIER);
- free (result);
- free (temp);
- return -1;
-
- case 'q':
- want_quotes = 'q';
- break;
-
- case 'x':
- want_quotes = 'x';
- break;
-
- /* :p means make this the last executed line. So we
- return an error state after adding this line to the
- history. */
- case 'p':
- print_only++;
- break;
-
- /* :t discards all but the last part of the pathname. */
- case 't':
- tstr = strrchr (temp, '/');
- if (tstr)
- {
- tstr++;
- t = savestring (tstr);
- free (temp);
- temp = t;
- }
- break;
-
- /* :h discards the last part of a pathname. */
- case 'h':
- tstr = strrchr (temp, '/');
- if (tstr)
- *tstr = '\0';
- break;
-
- /* :r discards the suffix. */
- case 'r':
- tstr = strrchr (temp, '.');
- if (tstr)
- *tstr = '\0';
- break;
-
- /* :e discards everything but the suffix. */
- case 'e':
- tstr = strrchr (temp, '.');
- if (tstr)
- {
- t = savestring (tstr);
- free (temp);
- temp = t;
- }
- break;
-
- /* :s/this/that substitutes `that' for the first
- occurrence of `this'. :gs/this/that substitutes `that'
- for each occurrence of `this'. :& repeats the last
- substitution. :g& repeats the last substitution
- globally. */
-
- case '&':
- case 's':
- {
- char *new_event;
- int delimiter, failed, si, l_temp;
-
- if (c == 's')
- {
- if (i + 2 < (int)strlen (string))
- {
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- _rl_adjust_point (string, i + 2, &ps);
- if (_rl_get_char_len (string + i + 2, &ps) > 1)
- delimiter = 0;
- else
- delimiter = string[i + 2];
- }
- else
-#endif /* HANDLE_MULTIBYTE */
- delimiter = string[i + 2];
- }
- else
- break; /* no search delimiter */
-
- i += 3;
-
- t = get_subst_pattern (string, &i, delimiter, 0, &subst_lhs_len);
- /* An empty substitution lhs with no previous substitution
- uses the last search string as the lhs. */
- if (t)
- {
- FREE (subst_lhs);
- subst_lhs = t;
- }
- else if (!subst_lhs)
- {
- if (search_string && *search_string)
- {
- subst_lhs = savestring (search_string);
- subst_lhs_len = strlen (subst_lhs);
- }
- else
- {
- subst_lhs = (char *) NULL;
- subst_lhs_len = 0;
- }
- }
-
- FREE (subst_rhs);
- subst_rhs = get_subst_pattern (string, &i, delimiter, 1, &subst_rhs_len);
-
- /* If `&' appears in the rhs, it's supposed to be replaced
- with the lhs. */
- if (member ('&', subst_rhs))
- postproc_subst_rhs ();
- }
- else
- i += 2;
-
- /* If there is no lhs, the substitution can't succeed. */
- if (subst_lhs_len == 0)
- {
- *ret_string = hist_error (string, starting_index, i, NO_PREV_SUBST);
- free (result);
- free (temp);
- return -1;
- }
-
- l_temp = strlen (temp);
- /* Ignore impossible cases. */
- if (subst_lhs_len > l_temp)
- {
- *ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
- free (result);
- free (temp);
- return (-1);
- }
-
- /* Find the first occurrence of THIS in TEMP. */
- si = 0;
- for (failed = 1; (si + subst_lhs_len) <= l_temp; si++)
- if (STREQN (temp+si, subst_lhs, subst_lhs_len))
- {
- int len = subst_rhs_len - subst_lhs_len + l_temp;
- new_event = (char *)xmalloc (1 + len);
- strncpy (new_event, temp, si);
- strncpy (new_event + si, subst_rhs, subst_rhs_len);
- strncpy (new_event + si + subst_rhs_len,
- temp + si + subst_lhs_len,
- l_temp - (si + subst_lhs_len));
- new_event[len] = '\0';
- free (temp);
- temp = new_event;
-
- failed = 0;
-
- if (substitute_globally)
- {
- si += subst_rhs_len;
- l_temp = strlen (temp);
- substitute_globally++;
- continue;
- }
- else
- break;
- }
-
- if (substitute_globally > 1)
- {
- substitute_globally = 0;
- continue; /* don't want to increment i */
- }
-
- if (failed == 0)
- continue; /* don't want to increment i */
-
- *ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
- free (result);
- free (temp);
- return (-1);
- }
- }
- i += 2;
- }
- /* Done with modfiers. */
- /* Believe it or not, we have to back the pointer up by one. */
- --i;
-
- if (want_quotes)
- {
- char *x;
-
- if (want_quotes == 'q')
- x = sh_single_quote (temp);
- else if (want_quotes == 'x')
- x = quote_breaks (temp);
- else
- x = savestring (temp);
-
- free (temp);
- temp = x;
- }
-
- n = strlen (temp);
- if (n >= result_len)
- result = (char *)xrealloc (result, n + 2);
- strcpy (result, temp);
- free (temp);
-
- *end_index_ptr = i;
- *ret_string = result;
- return (print_only);
-}
-
-/* Expand the string STRING, placing the result into OUTPUT, a pointer
- to a string. Returns:
-
- -1) If there was an error in expansion.
- 0) If no expansions took place (or, if the only change in
- the text was the de-slashifying of the history expansion
- character)
- 1) If expansions did take place
- 2) If the `p' modifier was given and the caller should print the result
-
- If an error ocurred in expansion, then OUTPUT contains a descriptive
- error message. */
-
-#define ADD_STRING(s) \
- do \
- { \
- int sl = strlen (s); \
- j += sl; \
- if (j >= result_len) \
- { \
- while (j >= result_len) \
- result_len += 128; \
- result = (char *)xrealloc (result, result_len); \
- } \
- strcpy (result + j - sl, s); \
- } \
- while (0)
-
-#define ADD_CHAR(c) \
- do \
- { \
- if (j >= result_len - 1) \
- result = (char *)xrealloc (result, result_len += 64); \
- result[j++] = c; \
- result[j] = '\0'; \
- } \
- while (0)
-
-int
-history_expand (hstring, output)
- char *hstring;
- char **output;
-{
- register int j;
- int i, r, l, passc, cc, modified, eindex, only_printing;
- char *string;
-
- /* The output string, and its length. */
- int result_len;
- char *result;
-
-#if defined (HANDLE_MULTIBYTE)
- char mb[MB_LEN_MAX];
- mbstate_t ps;
-#endif
-
- /* Used when adding the string. */
- char *temp;
-
- if (output == 0)
- return 0;
-
- /* Setting the history expansion character to 0 inhibits all
- history expansion. */
- if (history_expansion_char == 0)
- {
- *output = savestring (hstring);
- return (0);
- }
-
- /* Prepare the buffer for printing error messages. */
- result = (char *)xmalloc (result_len = 256);
- result[0] = '\0';
-
- only_printing = modified = 0;
- l = strlen (hstring);
-
- /* Grovel the string. Only backslash and single quotes can quote the
- history escape character. We also handle arg specifiers. */
-
- /* Before we grovel forever, see if the history_expansion_char appears
- anywhere within the text. */
-
- /* The quick substitution character is a history expansion all right. That
- is to say, "^this^that^" is equivalent to "!!:s^this^that^", and in fact,
- that is the substitution that we do. */
- if (hstring[0] == history_subst_char)
- {
- string = (char *)xmalloc (l + 5);
-
- string[0] = string[1] = history_expansion_char;
- string[2] = ':';
- string[3] = 's';
- strcpy (string + 4, hstring);
- l += 4;
- }
- else
- {
-#if defined (HANDLE_MULTIBYTE)
- memset (&ps, 0, sizeof (mbstate_t));
-#endif
-
- string = hstring;
- /* If not quick substitution, still maybe have to do expansion. */
-
- /* `!' followed by one of the characters in history_no_expand_chars
- is NOT an expansion. */
- for (i = 0; string[i]; i++)
- {
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- int v;
- v = _rl_get_char_len (string + i, &ps);
- if (v > 1)
- {
- i += v - 1;
- continue;
- }
- }
-#endif /* HANDLE_MULTIBYTE */
-
- cc = string[i + 1];
- /* The history_comment_char, if set, appearing at the beginning
- of a word signifies that the rest of the line should not have
- history expansion performed on it.
- Skip the rest of the line and break out of the loop. */
- if (history_comment_char && string[i] == history_comment_char &&
- (i == 0 || member (string[i - 1], history_word_delimiters)))
- {
- while (string[i])
- i++;
- break;
- }
- else if (string[i] == history_expansion_char)
- {
- if (!cc || member (cc, history_no_expand_chars))
- continue;
- /* If the calling application has set
- history_inhibit_expansion_function to a function that checks
- for special cases that should not be history expanded,
- call the function and skip the expansion if it returns a
- non-zero value. */
- else if (history_inhibit_expansion_function &&
- (*history_inhibit_expansion_function) (string, i))
- continue;
- else
- break;
- }
- /* XXX - at some point, might want to extend this to handle
- double quotes as well. */
- else if (history_quotes_inhibit_expansion && string[i] == '\'')
- {
- /* If this is bash, single quotes inhibit history expansion. */
- i++;
- hist_string_extract_single_quoted (string, &i);
- }
- else if (history_quotes_inhibit_expansion && string[i] == '\\')
- {
- /* If this is bash, allow backslashes to quote single
- quotes and the history expansion character. */
- if (cc == '\'' || cc == history_expansion_char)
- i++;
- }
- }
-
- if (string[i] != history_expansion_char)
- {
- free (result);
- *output = savestring (string);
- return (0);
- }
- }
-
- /* Extract and perform the substitution. */
- for (passc = i = j = 0; i < l; i++)
- {
- int tchar = string[i];
-
- if (passc)
- {
- passc = 0;
- ADD_CHAR (tchar);
- continue;
- }
-
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- int k, c;
-
- c = tchar;
- memset (mb, 0, sizeof (mb));
- for (k = 0; k < MB_LEN_MAX; k++)
- {
- mb[k] = (char)c;
- memset (&ps, 0, sizeof (mbstate_t));
- if (_rl_get_char_len (mb, &ps) == -2)
- c = string[++i];
- else
- break;
- }
- if (strlen (mb) > 1)
- {
- ADD_STRING (mb);
- break;
- }
- }
-#endif /* HANDLE_MULTIBYTE */
-
- if (tchar == history_expansion_char)
- tchar = -3;
- else if (tchar == history_comment_char)
- tchar = -2;
-
- switch (tchar)
- {
- default:
- ADD_CHAR (string[i]);
- break;
-
- case '\\':
- passc++;
- ADD_CHAR (tchar);
- break;
-
- case '\'':
- {
- /* If history_quotes_inhibit_expansion is set, single quotes
- inhibit history expansion. */
- if (history_quotes_inhibit_expansion)
- {
- int quote, slen;
-
- quote = i++;
- hist_string_extract_single_quoted (string, &i);
-
- slen = i - quote + 2;
- temp = (char *)xmalloc (slen);
- strncpy (temp, string + quote, slen);
- temp[slen - 1] = '\0';
- ADD_STRING (temp);
- free (temp);
- }
- else
- ADD_CHAR (string[i]);
- break;
- }
-
- case -2: /* history_comment_char */
- if (i == 0 || member (string[i - 1], history_word_delimiters))
- {
- temp = (char *)xmalloc (l - i + 1);
- strcpy (temp, string + i);
- ADD_STRING (temp);
- free (temp);
- i = l;
- }
- else
- ADD_CHAR (string[i]);
- break;
-
- case -3: /* history_expansion_char */
- cc = string[i + 1];
-
- /* If the history_expansion_char is followed by one of the
- characters in history_no_expand_chars, then it is not a
- candidate for expansion of any kind. */
- if (member (cc, history_no_expand_chars))
- {
- ADD_CHAR (string[i]);
- break;
- }
-
-#if defined (NO_BANG_HASH_MODIFIERS)
- /* There is something that is listed as a `word specifier' in csh
- documentation which means `the expanded text to this point'.
- That is not a word specifier, it is an event specifier. If we
- don't want to allow modifiers with `!#', just stick the current
- output line in again. */
- if (cc == '#')
- {
- if (result)
- {
- temp = (char *)xmalloc (1 + strlen (result));
- strcpy (temp, result);
- ADD_STRING (temp);
- free (temp);
- }
- i++;
- break;
- }
-#endif
-
- r = history_expand_internal (string, i, &eindex, &temp, result);
- if (r < 0)
- {
- *output = temp;
- free (result);
- if (string != hstring)
- free (string);
- return -1;
- }
- else
- {
- if (temp)
- {
- modified++;
- if (*temp)
- ADD_STRING (temp);
- free (temp);
- }
- only_printing = r == 1;
- i = eindex;
- }
- break;
- }
- }
-
- *output = result;
- if (string != hstring)
- free (string);
-
- if (only_printing)
- {
- add_history (result);
- return (2);
- }
-
- return (modified != 0);
-}
-
-/* Return a consed string which is the word specified in SPEC, and found
- in FROM. NULL is returned if there is no spec. The address of
- ERROR_POINTER is returned if the word specified cannot be found.
- CALLER_INDEX is the offset in SPEC to start looking; it is updated
- to point to just after the last character parsed. */
-static char *
-get_history_word_specifier (spec, from, caller_index)
- char *spec, *from;
- int *caller_index;
-{
- register int i = *caller_index;
- int first, last;
- int expecting_word_spec = 0;
- char *result;
-
- /* The range of words to return doesn't exist yet. */
- first = last = 0;
- result = (char *)NULL;
-
- /* If we found a colon, then this *must* be a word specification. If
- it isn't, then it is an error. */
- if (spec[i] == ':')
- {
- i++;
- expecting_word_spec++;
- }
-
- /* Handle special cases first. */
-
- /* `%' is the word last searched for. */
- if (spec[i] == '%')
- {
- *caller_index = i + 1;
- return (search_match ? savestring (search_match) : savestring (""));
- }
-
- /* `*' matches all of the arguments, but not the command. */
- if (spec[i] == '*')
- {
- *caller_index = i + 1;
- result = history_arg_extract (1, '$', from);
- return (result ? result : savestring (""));
- }
-
- /* `$' is last arg. */
- if (spec[i] == '$')
- {
- *caller_index = i + 1;
- return (history_arg_extract ('$', '$', from));
- }
-
- /* Try to get FIRST and LAST figured out. */
-
- if (spec[i] == '-')
- first = 0;
- else if (spec[i] == '^')
- first = 1;
- else if (_rl_digit_p (spec[i]) && expecting_word_spec)
- {
- for (first = 0; _rl_digit_p (spec[i]); i++)
- first = (first * 10) + _rl_digit_value (spec[i]);
- }
- else
- return ((char *)NULL); /* no valid `first' for word specifier */
-
- if (spec[i] == '^' || spec[i] == '*')
- {
- last = (spec[i] == '^') ? 1 : '$'; /* x* abbreviates x-$ */
- i++;
- }
- else if (spec[i] != '-')
- last = first;
- else
- {
- i++;
-
- if (_rl_digit_p (spec[i]))
- {
- for (last = 0; _rl_digit_p (spec[i]); i++)
- last = (last * 10) + _rl_digit_value (spec[i]);
- }
- else if (spec[i] == '$')
- {
- i++;
- last = '$';
- }
-#if 0
- else if (!spec[i] || spec[i] == ':')
- /* check against `:' because there could be a modifier separator */
-#else
- else
- /* csh seems to allow anything to terminate the word spec here,
- leaving it as an abbreviation. */
-#endif
- last = -1; /* x- abbreviates x-$ omitting word `$' */
- }
-
- *caller_index = i;
-
- if (last >= first || last == '$' || last < 0)
- result = history_arg_extract (first, last, from);
-
- return (result ? result : (char *)&error_pointer);
-}
-
-/* Extract the args specified, starting at FIRST, and ending at LAST.
- The args are taken from STRING. If either FIRST or LAST is < 0,
- then make that arg count from the right (subtract from the number of
- tokens, so that FIRST = -1 means the next to last token on the line).
- If LAST is `$' the last arg from STRING is used. */
-char *
-history_arg_extract (first, last, string)
- int first, last;
- const char *string;
-{
- register int i, len;
- char *result;
- int size, offset;
- char **list;
-
- /* XXX - think about making history_tokenize return a struct array,
- each struct in array being a string and a length to avoid the
- calls to strlen below. */
- if ((list = history_tokenize (string)) == NULL)
- return ((char *)NULL);
-
- for (len = 0; list[len]; len++)
- ;
-
- if (last < 0)
- last = len + last - 1;
-
- if (first < 0)
- first = len + first - 1;
-
- if (last == '$')
- last = len - 1;
-
- if (first == '$')
- first = len - 1;
-
- last++;
-
- if (first >= len || last > len || first < 0 || last < 0 || first > last)
- result = ((char *)NULL);
- else
- {
- for (size = 0, i = first; i < last; i++)
- size += strlen (list[i]) + 1;
- result = (char *)xmalloc (size + 1);
- result[0] = '\0';
-
- for (i = first, offset = 0; i < last; i++)
- {
- strcpy (result + offset, list[i]);
- offset += strlen (list[i]);
- if (i + 1 < last)
- {
- result[offset++] = ' ';
- result[offset] = 0;
- }
- }
- }
-
- for (i = 0; i < len; i++)
- free (list[i]);
- free (list);
-
- return (result);
-}
-
-#define slashify_in_quotes "\\`\"$"
-
-/* Parse STRING into tokens and return an array of strings. If WIND is
- not -1 and INDP is not null, we also want the word surrounding index
- WIND. The position in the returned array of strings is returned in
- *INDP. */
-static char **
-history_tokenize_internal (string, wind, indp)
- const char *string;
- int wind, *indp;
-{
- char **result;
- register int i, start, result_index, size;
- int len, delimiter;
-
- /* If we're searching for a string that's not part of a word (e.g., " "),
- make sure we set *INDP to a reasonable value. */
- if (indp && wind != -1)
- *indp = -1;
-
- /* Get a token, and stuff it into RESULT. The tokens are split
- exactly where the shell would split them. */
- for (i = result_index = size = 0, result = (char **)NULL; string[i]; )
- {
- delimiter = 0;
-
- /* Skip leading whitespace. */
- for (; string[i] && whitespace (string[i]); i++)
- ;
- if (string[i] == 0 || string[i] == history_comment_char)
- return (result);
-
- start = i;
-
- if (member (string[i], "()\n"))
- {
- i++;
- goto got_token;
- }
-
- if (member (string[i], "<>;&|$"))
- {
- int peek = string[i + 1];
-
- if (peek == string[i] && peek != '$')
- {
- if (peek == '<' && string[i + 2] == '-')
- i++;
- i += 2;
- goto got_token;
- }
- else
- {
- if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
- ((peek == '>') && (string[i] == '&')) ||
- ((peek == '(') && (string[i] == '$')))
- {
- i += 2;
- goto got_token;
- }
- }
- if (string[i] != '$')
- {
- i++;
- goto got_token;
- }
- }
-
- /* Get word from string + i; */
-
- if (member (string[i], HISTORY_QUOTE_CHARACTERS))
- delimiter = string[i++];
-
- for (; string[i]; i++)
- {
- if (string[i] == '\\' && string[i + 1] == '\n')
- {
- i++;
- continue;
- }
-
- if (string[i] == '\\' && delimiter != '\'' &&
- (delimiter != '"' || member (string[i], slashify_in_quotes)))
- {
- i++;
- continue;
- }
-
- if (delimiter && string[i] == delimiter)
- {
- delimiter = 0;
- continue;
- }
-
- if (!delimiter && (member (string[i], history_word_delimiters)))
- break;
-
- if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS))
- delimiter = string[i];
- }
-
- got_token:
-
- /* If we are looking for the word in which the character at a
- particular index falls, remember it. */
- if (indp && wind != -1 && wind >= start && wind < i)
- *indp = result_index;
-
- len = i - start;
- if (result_index + 2 >= size)
- result = (char **)xrealloc (result, ((size += 10) * sizeof (char *)));
- result[result_index] = (char *)xmalloc (1 + len);
- strncpy (result[result_index], string + start, len);
- result[result_index][len] = '\0';
- result[++result_index] = (char *)NULL;
- }
-
- return (result);
-}
-
-/* Return an array of tokens, much as the shell might. The tokens are
- parsed out of STRING. */
-char **
-history_tokenize (string)
- const char *string;
-{
- return (history_tokenize_internal (string, -1, (int *)NULL));
-}
-
-/* Find and return the word which contains the character at index IND
- in the history line LINE. Used to save the word matched by the
- last history !?string? search. */
-static char *
-history_find_word (line, ind)
- char *line;
- int ind;
-{
- char **words, *s;
- int i, wind;
-
- words = history_tokenize_internal (line, ind, &wind);
- if (wind == -1 || words == 0)
- return ((char *)NULL);
- s = words[wind];
- for (i = 0; i < wind; i++)
- free (words[i]);
- for (i = wind + 1; words[i]; i++)
- free (words[i]);
- free (words);
- return s;
-}
+/* histexpand.c -- history expansion. */
+
+/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
+
+ This file contains the GNU History Library (the Library), a set of
+ routines for managing the text of previously typed lines.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <stdio.h>
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_UNISTD_H)
+# ifndef _MINIX
+# include <sys/types.h>
+# endif
+# include <unistd.h>
+#endif
+
+#include "rlmbutil.h"
+
+#include "history.h"
+#include "histlib.h"
+
+#include "rlshell.h"
+#include "xmalloc.h"
+
+#define HISTORY_WORD_DELIMITERS " \t\n;&()|<>"
+#define HISTORY_QUOTE_CHARACTERS "\"'`"
+
+typedef int _hist_search_func_t PARAMS((const char *, int));
+
+extern int rl_byte_oriented; /* declared in mbutil.c */
+
+static char error_pointer;
+
+static char *subst_lhs;
+static char *subst_rhs;
+static int subst_lhs_len;
+static int subst_rhs_len;
+
+static char *get_history_word_specifier PARAMS((char *, char *, int *));
+static char *history_find_word PARAMS((char *, int));
+
+static char *quote_breaks PARAMS((char *));
+
+/* Variables exported by this file. */
+/* The character that represents the start of a history expansion
+ request. This is usually `!'. */
+char history_expansion_char = '!';
+
+/* The character that invokes word substitution if found at the start of
+ a line. This is usually `^'. */
+char history_subst_char = '^';
+
+/* During tokenization, if this character is seen as the first character
+ of a word, then it, and all subsequent characters upto a newline are
+ ignored. For a Bourne shell, this should be '#'. Bash special cases
+ the interactive comment character to not be a comment delimiter. */
+char history_comment_char = '\0';
+
+/* The list of characters which inhibit the expansion of text if found
+ immediately following history_expansion_char. */
+char *history_no_expand_chars = " \t\n\r=";
+
+/* If set to a non-zero value, single quotes inhibit history expansion.
+ The default is 0. */
+int history_quotes_inhibit_expansion = 0;
+
+/* Used to split words by history_tokenize_internal. */
+char *history_word_delimiters = HISTORY_WORD_DELIMITERS;
+
+/* If set, this points to a function that is called to verify that a
+ particular history expansion should be performed. */
+rl_linebuf_func_t *history_inhibit_expansion_function;
+
+/* **************************************************************** */
+/* */
+/* History Expansion */
+/* */
+/* **************************************************************** */
+
+/* Hairy history expansion on text, not tokens. This is of general
+ use, and thus belongs in this library. */
+
+/* The last string searched for by a !?string? search. */
+static char *search_string;
+
+/* The last string matched by a !?string? search. */
+static char *search_match;
+
+/* Return the event specified at TEXT + OFFSET modifying OFFSET to
+ point to after the event specifier. Just a pointer to the history
+ line is returned; NULL is returned in the event of a bad specifier.
+ You pass STRING with *INDEX equal to the history_expansion_char that
+ begins this specification.
+ DELIMITING_QUOTE is a character that is allowed to end the string
+ specification for what to search for in addition to the normal
+ characters `:', ` ', `\t', `\n', and sometimes `?'.
+ So you might call this function like:
+ line = get_history_event ("!echo:p", &index, 0); */
+char *
+get_history_event (string, caller_index, delimiting_quote)
+ const char *string;
+ int *caller_index;
+ int delimiting_quote;
+{
+ register int i;
+ register char c;
+ HIST_ENTRY *entry;
+ int which, sign, local_index, substring_okay;
+ _hist_search_func_t *search_func;
+ char *temp;
+
+ /* The event can be specified in a number of ways.
+
+ !! the previous command
+ !n command line N
+ !-n current command-line minus N
+ !str the most recent command starting with STR
+ !?str[?]
+ the most recent command containing STR
+
+ All values N are determined via HISTORY_BASE. */
+
+ i = *caller_index;
+
+ if (string[i] != history_expansion_char)
+ return ((char *)NULL);
+
+ /* Move on to the specification. */
+ i++;
+
+ sign = 1;
+ substring_okay = 0;
+
+#define RETURN_ENTRY(e, w) \
+ return ((e = history_get (w)) ? e->line : (char *)NULL)
+
+ /* Handle !! case. */
+ if (string[i] == history_expansion_char)
+ {
+ i++;
+ which = history_base + (history_length - 1);
+ *caller_index = i;
+ RETURN_ENTRY (entry, which);
+ }
+
+ /* Hack case of numeric line specification. */
+ if (string[i] == '-')
+ {
+ sign = -1;
+ i++;
+ }
+
+ if (_rl_digit_p (string[i]))
+ {
+ /* Get the extent of the digits and compute the value. */
+ for (which = 0; _rl_digit_p (string[i]); i++)
+ which = (which * 10) + _rl_digit_value (string[i]);
+
+ *caller_index = i;
+
+ if (sign < 0)
+ which = (history_length + history_base) - which;
+
+ RETURN_ENTRY (entry, which);
+ }
+
+ /* This must be something to search for. If the spec begins with
+ a '?', then the string may be anywhere on the line. Otherwise,
+ the string must be found at the start of a line. */
+ if (string[i] == '?')
+ {
+ substring_okay++;
+ i++;
+ }
+
+ /* Only a closing `?' or a newline delimit a substring search string. */
+ for (local_index = i; c = string[i]; i++)
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ int v;
+ mbstate_t ps;
+
+ memset (&ps, 0, sizeof (mbstate_t));
+ /* These produce warnings because we're passing a const string to a
+ function that takes a non-const string. */
+ _rl_adjust_point (string, i, &ps);
+ if ((v = _rl_get_char_len (string + i, &ps)) > 1)
+ {
+ i += v - 1;
+ continue;
+ }
+ }
+ else
+#endif /* HANDLE_MULTIBYTE */
+ if ((!substring_okay && (whitespace (c) || c == ':' ||
+ (history_search_delimiter_chars && member (c, history_search_delimiter_chars)) ||
+ string[i] == delimiting_quote)) ||
+ string[i] == '\n' ||
+ (substring_okay && string[i] == '?'))
+ break;
+
+ which = i - local_index;
+ temp = (char *)xmalloc (1 + which);
+ if (which)
+ strncpy (temp, string + local_index, which);
+ temp[which] = '\0';
+
+ if (substring_okay && string[i] == '?')
+ i++;
+
+ *caller_index = i;
+
+#define FAIL_SEARCH() \
+ do { \
+ history_offset = history_length; free (temp) ; return (char *)NULL; \
+ } while (0)
+
+ /* If there is no search string, try to use the previous search string,
+ if one exists. If not, fail immediately. */
+ if (*temp == '\0' && substring_okay)
+ {
+ if (search_string)
+ {
+ free (temp);
+ temp = savestring (search_string);
+ }
+ else
+ FAIL_SEARCH ();
+ }
+
+ search_func = substring_okay ? history_search : history_search_prefix;
+ while (1)
+ {
+ local_index = (*search_func) (temp, -1);
+
+ if (local_index < 0)
+ FAIL_SEARCH ();
+
+ if (local_index == 0 || substring_okay)
+ {
+ entry = current_history ();
+ history_offset = history_length;
+
+ /* If this was a substring search, then remember the
+ string that we matched for word substitution. */
+ if (substring_okay)
+ {
+ FREE (search_string);
+ search_string = temp;
+
+ FREE (search_match);
+ search_match = history_find_word (entry->line, local_index);
+ }
+ else
+ free (temp);
+
+ return (entry->line);
+ }
+
+ if (history_offset)
+ history_offset--;
+ else
+ FAIL_SEARCH ();
+ }
+#undef FAIL_SEARCH
+#undef RETURN_ENTRY
+}
+
+/* Function for extracting single-quoted strings. Used for inhibiting
+ history expansion within single quotes. */
+
+/* Extract the contents of STRING as if it is enclosed in single quotes.
+ SINDEX, when passed in, is the offset of the character immediately
+ following the opening single quote; on exit, SINDEX is left pointing
+ to the closing single quote. */
+static void
+hist_string_extract_single_quoted (string, sindex)
+ char *string;
+ int *sindex;
+{
+ register int i;
+
+ for (i = *sindex; string[i] && string[i] != '\''; i++)
+ ;
+
+ *sindex = i;
+}
+
+static char *
+quote_breaks (s)
+ char *s;
+{
+ register char *p, *r;
+ char *ret;
+ int len = 3;
+
+ for (p = s; p && *p; p++, len++)
+ {
+ if (*p == '\'')
+ len += 3;
+ else if (whitespace (*p) || *p == '\n')
+ len += 2;
+ }
+
+ r = ret = (char *)xmalloc (len);
+ *r++ = '\'';
+ for (p = s; p && *p; )
+ {
+ if (*p == '\'')
+ {
+ *r++ = '\'';
+ *r++ = '\\';
+ *r++ = '\'';
+ *r++ = '\'';
+ p++;
+ }
+ else if (whitespace (*p) || *p == '\n')
+ {
+ *r++ = '\'';
+ *r++ = *p++;
+ *r++ = '\'';
+ }
+ else
+ *r++ = *p++;
+ }
+ *r++ = '\'';
+ *r = '\0';
+ return ret;
+}
+
+static char *
+hist_error(s, start, current, errtype)
+ char *s;
+ int start, current, errtype;
+{
+ char *temp;
+ const char *emsg;
+ int ll, elen;
+
+ ll = current - start;
+
+ switch (errtype)
+ {
+ case EVENT_NOT_FOUND:
+ emsg = "event not found";
+ elen = 15;
+ break;
+ case BAD_WORD_SPEC:
+ emsg = "bad word specifier";
+ elen = 18;
+ break;
+ case SUBST_FAILED:
+ emsg = "substitution failed";
+ elen = 19;
+ break;
+ case BAD_MODIFIER:
+ emsg = "unrecognized history modifier";
+ elen = 29;
+ break;
+ case NO_PREV_SUBST:
+ emsg = "no previous substitution";
+ elen = 24;
+ break;
+ default:
+ emsg = "unknown expansion error";
+ elen = 23;
+ break;
+ }
+
+ temp = (char *)xmalloc (ll + elen + 3);
+ strncpy (temp, s + start, ll);
+ temp[ll] = ':';
+ temp[ll + 1] = ' ';
+ strcpy (temp + ll + 2, emsg);
+ return (temp);
+}
+
+/* Get a history substitution string from STR starting at *IPTR
+ and return it. The length is returned in LENPTR.
+
+ A backslash can quote the delimiter. If the string is the
+ empty string, the previous pattern is used. If there is
+ no previous pattern for the lhs, the last history search
+ string is used.
+
+ If IS_RHS is 1, we ignore empty strings and set the pattern
+ to "" anyway. subst_lhs is not changed if the lhs is empty;
+ subst_rhs is allowed to be set to the empty string. */
+
+static char *
+get_subst_pattern (str, iptr, delimiter, is_rhs, lenptr)
+ char *str;
+ int *iptr, delimiter, is_rhs, *lenptr;
+{
+ register int si, i, j, k;
+ char *s;
+#if defined (HANDLE_MULTIBYTE)
+ mbstate_t ps;
+#endif
+
+ s = (char *)NULL;
+ i = *iptr;
+
+#if defined (HANDLE_MULTIBYTE)
+ memset (&ps, 0, sizeof (mbstate_t));
+ _rl_adjust_point (str, i, &ps);
+#endif
+
+ for (si = i; str[si] && str[si] != delimiter; si++)
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ int v;
+ if ((v = _rl_get_char_len (str + si, &ps)) > 1)
+ si += v - 1;
+ else if (str[si] == '\\' && str[si + 1] == delimiter)
+ si++;
+ }
+ else
+#endif /* HANDLE_MULTIBYTE */
+ if (str[si] == '\\' && str[si + 1] == delimiter)
+ si++;
+
+ if (si > i || is_rhs)
+ {
+ s = (char *)xmalloc (si - i + 1);
+ for (j = 0, k = i; k < si; j++, k++)
+ {
+ /* Remove a backslash quoting the search string delimiter. */
+ if (str[k] == '\\' && str[k + 1] == delimiter)
+ k++;
+ s[j] = str[k];
+ }
+ s[j] = '\0';
+ if (lenptr)
+ *lenptr = j;
+ }
+
+ i = si;
+ if (str[i])
+ i++;
+ *iptr = i;
+
+ return s;
+}
+
+static void
+postproc_subst_rhs ()
+{
+ char *new;
+ int i, j, new_size;
+
+ new = (char *)xmalloc (new_size = subst_rhs_len + subst_lhs_len);
+ for (i = j = 0; i < subst_rhs_len; i++)
+ {
+ if (subst_rhs[i] == '&')
+ {
+ if (j + subst_lhs_len >= new_size)
+ new = (char *)xrealloc (new, (new_size = new_size * 2 + subst_lhs_len));
+ strcpy (new + j, subst_lhs);
+ j += subst_lhs_len;
+ }
+ else
+ {
+ /* a single backslash protects the `&' from lhs interpolation */
+ if (subst_rhs[i] == '\\' && subst_rhs[i + 1] == '&')
+ i++;
+ if (j >= new_size)
+ new = (char *)xrealloc (new, new_size *= 2);
+ new[j++] = subst_rhs[i];
+ }
+ }
+ new[j] = '\0';
+ free (subst_rhs);
+ subst_rhs = new;
+ subst_rhs_len = j;
+}
+
+/* Expand the bulk of a history specifier starting at STRING[START].
+ Returns 0 if everything is OK, -1 if an error occurred, and 1
+ if the `p' modifier was supplied and the caller should just print
+ the returned string. Returns the new index into string in
+ *END_INDEX_PTR, and the expanded specifier in *RET_STRING. */
+static int
+history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
+ char *string;
+ int start, *end_index_ptr;
+ char **ret_string;
+ char *current_line; /* for !# */
+{
+ int i, n, starting_index;
+ int substitute_globally, want_quotes, print_only;
+ char *event, *temp, *result, *tstr, *t, c, *word_spec;
+ int result_len;
+#if defined (HANDLE_MULTIBYTE)
+ mbstate_t ps;
+
+ memset (&ps, 0, sizeof (mbstate_t));
+#endif
+
+ result = (char *)xmalloc (result_len = 128);
+
+ i = start;
+
+ /* If it is followed by something that starts a word specifier,
+ then !! is implied as the event specifier. */
+
+ if (member (string[i + 1], ":$*%^"))
+ {
+ char fake_s[3];
+ int fake_i = 0;
+ i++;
+ fake_s[0] = fake_s[1] = history_expansion_char;
+ fake_s[2] = '\0';
+ event = get_history_event (fake_s, &fake_i, 0);
+ }
+ else if (string[i + 1] == '#')
+ {
+ i += 2;
+ event = current_line;
+ }
+ else
+ {
+ int quoted_search_delimiter = 0;
+
+ /* If the character before this `!' is a double or single
+ quote, then this expansion takes place inside of the
+ quoted string. If we have to search for some text ("!foo"),
+ allow the delimiter to end the search string. */
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ int c, l;
+ l = _rl_find_prev_mbchar (string, i, MB_FIND_ANY);
+ c = string[l];
+ /* XXX - original patch had i - 1 ??? If i == 0 it would fail. */
+ if (i && (c == '\'' || c == '"'))
+ quoted_search_delimiter = c;
+ }
+ else
+#endif /* HANDLE_MULTIBYTE */
+ if (i && (string[i - 1] == '\'' || string[i - 1] == '"'))
+ quoted_search_delimiter = string[i - 1];
+
+ event = get_history_event (string, &i, quoted_search_delimiter);
+ }
+
+ if (event == 0)
+ {
+ *ret_string = hist_error (string, start, i, EVENT_NOT_FOUND);
+ free (result);
+ return (-1);
+ }
+
+ /* If a word specifier is found, then do what that requires. */
+ starting_index = i;
+ word_spec = get_history_word_specifier (string, event, &i);
+
+ /* There is no such thing as a `malformed word specifier'. However,
+ it is possible for a specifier that has no match. In that case,
+ we complain. */
+ if (word_spec == (char *)&error_pointer)
+ {
+ *ret_string = hist_error (string, starting_index, i, BAD_WORD_SPEC);
+ free (result);
+ return (-1);
+ }
+
+ /* If no word specifier, than the thing of interest was the event. */
+ temp = word_spec ? savestring (word_spec) : savestring (event);
+ FREE (word_spec);
+
+ /* Perhaps there are other modifiers involved. Do what they say. */
+ want_quotes = substitute_globally = print_only = 0;
+ starting_index = i;
+
+ while (string[i] == ':')
+ {
+ c = string[i + 1];
+
+ if (c == 'g')
+ {
+ substitute_globally = 1;
+ i++;
+ c = string[i + 1];
+ }
+
+ switch (c)
+ {
+ default:
+ *ret_string = hist_error (string, i+1, i+2, BAD_MODIFIER);
+ free (result);
+ free (temp);
+ return -1;
+
+ case 'q':
+ want_quotes = 'q';
+ break;
+
+ case 'x':
+ want_quotes = 'x';
+ break;
+
+ /* :p means make this the last executed line. So we
+ return an error state after adding this line to the
+ history. */
+ case 'p':
+ print_only++;
+ break;
+
+ /* :t discards all but the last part of the pathname. */
+ case 't':
+ tstr = strrchr (temp, '/');
+ if (tstr)
+ {
+ tstr++;
+ t = savestring (tstr);
+ free (temp);
+ temp = t;
+ }
+ break;
+
+ /* :h discards the last part of a pathname. */
+ case 'h':
+ tstr = strrchr (temp, '/');
+ if (tstr)
+ *tstr = '\0';
+ break;
+
+ /* :r discards the suffix. */
+ case 'r':
+ tstr = strrchr (temp, '.');
+ if (tstr)
+ *tstr = '\0';
+ break;
+
+ /* :e discards everything but the suffix. */
+ case 'e':
+ tstr = strrchr (temp, '.');
+ if (tstr)
+ {
+ t = savestring (tstr);
+ free (temp);
+ temp = t;
+ }
+ break;
+
+ /* :s/this/that substitutes `that' for the first
+ occurrence of `this'. :gs/this/that substitutes `that'
+ for each occurrence of `this'. :& repeats the last
+ substitution. :g& repeats the last substitution
+ globally. */
+
+ case '&':
+ case 's':
+ {
+ char *new_event;
+ int delimiter, failed, si, l_temp;
+
+ if (c == 's')
+ {
+ if (i + 2 < (int)strlen (string))
+ {
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ _rl_adjust_point (string, i + 2, &ps);
+ if (_rl_get_char_len (string + i + 2, &ps) > 1)
+ delimiter = 0;
+ else
+ delimiter = string[i + 2];
+ }
+ else
+#endif /* HANDLE_MULTIBYTE */
+ delimiter = string[i + 2];
+ }
+ else
+ break; /* no search delimiter */
+
+ i += 3;
+
+ t = get_subst_pattern (string, &i, delimiter, 0, &subst_lhs_len);
+ /* An empty substitution lhs with no previous substitution
+ uses the last search string as the lhs. */
+ if (t)
+ {
+ FREE (subst_lhs);
+ subst_lhs = t;
+ }
+ else if (!subst_lhs)
+ {
+ if (search_string && *search_string)
+ {
+ subst_lhs = savestring (search_string);
+ subst_lhs_len = strlen (subst_lhs);
+ }
+ else
+ {
+ subst_lhs = (char *) NULL;
+ subst_lhs_len = 0;
+ }
+ }
+
+ FREE (subst_rhs);
+ subst_rhs = get_subst_pattern (string, &i, delimiter, 1, &subst_rhs_len);
+
+ /* If `&' appears in the rhs, it's supposed to be replaced
+ with the lhs. */
+ if (member ('&', subst_rhs))
+ postproc_subst_rhs ();
+ }
+ else
+ i += 2;
+
+ /* If there is no lhs, the substitution can't succeed. */
+ if (subst_lhs_len == 0)
+ {
+ *ret_string = hist_error (string, starting_index, i, NO_PREV_SUBST);
+ free (result);
+ free (temp);
+ return -1;
+ }
+
+ l_temp = strlen (temp);
+ /* Ignore impossible cases. */
+ if (subst_lhs_len > l_temp)
+ {
+ *ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
+ free (result);
+ free (temp);
+ return (-1);
+ }
+
+ /* Find the first occurrence of THIS in TEMP. */
+ si = 0;
+ for (failed = 1; (si + subst_lhs_len) <= l_temp; si++)
+ if (STREQN (temp+si, subst_lhs, subst_lhs_len))
+ {
+ int len = subst_rhs_len - subst_lhs_len + l_temp;
+ new_event = (char *)xmalloc (1 + len);
+ strncpy (new_event, temp, si);
+ strncpy (new_event + si, subst_rhs, subst_rhs_len);
+ strncpy (new_event + si + subst_rhs_len,
+ temp + si + subst_lhs_len,
+ l_temp - (si + subst_lhs_len));
+ new_event[len] = '\0';
+ free (temp);
+ temp = new_event;
+
+ failed = 0;
+
+ if (substitute_globally)
+ {
+ si += subst_rhs_len;
+ l_temp = strlen (temp);
+ substitute_globally++;
+ continue;
+ }
+ else
+ break;
+ }
+
+ if (substitute_globally > 1)
+ {
+ substitute_globally = 0;
+ continue; /* don't want to increment i */
+ }
+
+ if (failed == 0)
+ continue; /* don't want to increment i */
+
+ *ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
+ free (result);
+ free (temp);
+ return (-1);
+ }
+ }
+ i += 2;
+ }
+ /* Done with modfiers. */
+ /* Believe it or not, we have to back the pointer up by one. */
+ --i;
+
+ if (want_quotes)
+ {
+ char *x;
+
+ if (want_quotes == 'q')
+ x = sh_single_quote (temp);
+ else if (want_quotes == 'x')
+ x = quote_breaks (temp);
+ else
+ x = savestring (temp);
+
+ free (temp);
+ temp = x;
+ }
+
+ n = strlen (temp);
+ if (n >= result_len)
+ result = (char *)xrealloc (result, n + 2);
+ strcpy (result, temp);
+ free (temp);
+
+ *end_index_ptr = i;
+ *ret_string = result;
+ return (print_only);
+}
+
+/* Expand the string STRING, placing the result into OUTPUT, a pointer
+ to a string. Returns:
+
+ -1) If there was an error in expansion.
+ 0) If no expansions took place (or, if the only change in
+ the text was the de-slashifying of the history expansion
+ character)
+ 1) If expansions did take place
+ 2) If the `p' modifier was given and the caller should print the result
+
+ If an error ocurred in expansion, then OUTPUT contains a descriptive
+ error message. */
+
+#define ADD_STRING(s) \
+ do \
+ { \
+ int sl = strlen (s); \
+ j += sl; \
+ if (j >= result_len) \
+ { \
+ while (j >= result_len) \
+ result_len += 128; \
+ result = (char *)xrealloc (result, result_len); \
+ } \
+ strcpy (result + j - sl, s); \
+ } \
+ while (0)
+
+#define ADD_CHAR(c) \
+ do \
+ { \
+ if (j >= result_len - 1) \
+ result = (char *)xrealloc (result, result_len += 64); \
+ result[j++] = c; \
+ result[j] = '\0'; \
+ } \
+ while (0)
+
+int
+history_expand (hstring, output)
+ char *hstring;
+ char **output;
+{
+ register int j;
+ int i, r, l, passc, cc, modified, eindex, only_printing;
+ char *string;
+
+ /* The output string, and its length. */
+ int result_len;
+ char *result;
+
+#if defined (HANDLE_MULTIBYTE)
+ char mb[MB_LEN_MAX];
+ mbstate_t ps;
+#endif
+
+ /* Used when adding the string. */
+ char *temp;
+
+ if (output == 0)
+ return 0;
+
+ /* Setting the history expansion character to 0 inhibits all
+ history expansion. */
+ if (history_expansion_char == 0)
+ {
+ *output = savestring (hstring);
+ return (0);
+ }
+
+ /* Prepare the buffer for printing error messages. */
+ result = (char *)xmalloc (result_len = 256);
+ result[0] = '\0';
+
+ only_printing = modified = 0;
+ l = strlen (hstring);
+
+ /* Grovel the string. Only backslash and single quotes can quote the
+ history escape character. We also handle arg specifiers. */
+
+ /* Before we grovel forever, see if the history_expansion_char appears
+ anywhere within the text. */
+
+ /* The quick substitution character is a history expansion all right. That
+ is to say, "^this^that^" is equivalent to "!!:s^this^that^", and in fact,
+ that is the substitution that we do. */
+ if (hstring[0] == history_subst_char)
+ {
+ string = (char *)xmalloc (l + 5);
+
+ string[0] = string[1] = history_expansion_char;
+ string[2] = ':';
+ string[3] = 's';
+ strcpy (string + 4, hstring);
+ l += 4;
+ }
+ else
+ {
+#if defined (HANDLE_MULTIBYTE)
+ memset (&ps, 0, sizeof (mbstate_t));
+#endif
+
+ string = hstring;
+ /* If not quick substitution, still maybe have to do expansion. */
+
+ /* `!' followed by one of the characters in history_no_expand_chars
+ is NOT an expansion. */
+ for (i = 0; string[i]; i++)
+ {
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ int v;
+ v = _rl_get_char_len (string + i, &ps);
+ if (v > 1)
+ {
+ i += v - 1;
+ continue;
+ }
+ }
+#endif /* HANDLE_MULTIBYTE */
+
+ cc = string[i + 1];
+ /* The history_comment_char, if set, appearing at the beginning
+ of a word signifies that the rest of the line should not have
+ history expansion performed on it.
+ Skip the rest of the line and break out of the loop. */
+ if (history_comment_char && string[i] == history_comment_char &&
+ (i == 0 || member (string[i - 1], history_word_delimiters)))
+ {
+ while (string[i])
+ i++;
+ break;
+ }
+ else if (string[i] == history_expansion_char)
+ {
+ if (!cc || member (cc, history_no_expand_chars))
+ continue;
+ /* If the calling application has set
+ history_inhibit_expansion_function to a function that checks
+ for special cases that should not be history expanded,
+ call the function and skip the expansion if it returns a
+ non-zero value. */
+ else if (history_inhibit_expansion_function &&
+ (*history_inhibit_expansion_function) (string, i))
+ continue;
+ else
+ break;
+ }
+ /* XXX - at some point, might want to extend this to handle
+ double quotes as well. */
+ else if (history_quotes_inhibit_expansion && string[i] == '\'')
+ {
+ /* If this is bash, single quotes inhibit history expansion. */
+ i++;
+ hist_string_extract_single_quoted (string, &i);
+ }
+ else if (history_quotes_inhibit_expansion && string[i] == '\\')
+ {
+ /* If this is bash, allow backslashes to quote single
+ quotes and the history expansion character. */
+ if (cc == '\'' || cc == history_expansion_char)
+ i++;
+ }
+ }
+
+ if (string[i] != history_expansion_char)
+ {
+ free (result);
+ *output = savestring (string);
+ return (0);
+ }
+ }
+
+ /* Extract and perform the substitution. */
+ for (passc = i = j = 0; i < l; i++)
+ {
+ int tchar = string[i];
+
+ if (passc)
+ {
+ passc = 0;
+ ADD_CHAR (tchar);
+ continue;
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ int k, c;
+
+ c = tchar;
+ memset (mb, 0, sizeof (mb));
+ for (k = 0; k < MB_LEN_MAX; k++)
+ {
+ mb[k] = (char)c;
+ memset (&ps, 0, sizeof (mbstate_t));
+ if (_rl_get_char_len (mb, &ps) == -2)
+ c = string[++i];
+ else
+ break;
+ }
+ if (strlen (mb) > 1)
+ {
+ ADD_STRING (mb);
+ break;
+ }
+ }
+#endif /* HANDLE_MULTIBYTE */
+
+ if (tchar == history_expansion_char)
+ tchar = -3;
+ else if (tchar == history_comment_char)
+ tchar = -2;
+
+ switch (tchar)
+ {
+ default:
+ ADD_CHAR (string[i]);
+ break;
+
+ case '\\':
+ passc++;
+ ADD_CHAR (tchar);
+ break;
+
+ case '\'':
+ {
+ /* If history_quotes_inhibit_expansion is set, single quotes
+ inhibit history expansion. */
+ if (history_quotes_inhibit_expansion)
+ {
+ int quote, slen;
+
+ quote = i++;
+ hist_string_extract_single_quoted (string, &i);
+
+ slen = i - quote + 2;
+ temp = (char *)xmalloc (slen);
+ strncpy (temp, string + quote, slen);
+ temp[slen - 1] = '\0';
+ ADD_STRING (temp);
+ free (temp);
+ }
+ else
+ ADD_CHAR (string[i]);
+ break;
+ }
+
+ case -2: /* history_comment_char */
+ if (i == 0 || member (string[i - 1], history_word_delimiters))
+ {
+ temp = (char *)xmalloc (l - i + 1);
+ strcpy (temp, string + i);
+ ADD_STRING (temp);
+ free (temp);
+ i = l;
+ }
+ else
+ ADD_CHAR (string[i]);
+ break;
+
+ case -3: /* history_expansion_char */
+ cc = string[i + 1];
+
+ /* If the history_expansion_char is followed by one of the
+ characters in history_no_expand_chars, then it is not a
+ candidate for expansion of any kind. */
+ if (member (cc, history_no_expand_chars))
+ {
+ ADD_CHAR (string[i]);
+ break;
+ }
+
+#if defined (NO_BANG_HASH_MODIFIERS)
+ /* There is something that is listed as a `word specifier' in csh
+ documentation which means `the expanded text to this point'.
+ That is not a word specifier, it is an event specifier. If we
+ don't want to allow modifiers with `!#', just stick the current
+ output line in again. */
+ if (cc == '#')
+ {
+ if (result)
+ {
+ temp = (char *)xmalloc (1 + strlen (result));
+ strcpy (temp, result);
+ ADD_STRING (temp);
+ free (temp);
+ }
+ i++;
+ break;
+ }
+#endif
+
+ r = history_expand_internal (string, i, &eindex, &temp, result);
+ if (r < 0)
+ {
+ *output = temp;
+ free (result);
+ if (string != hstring)
+ free (string);
+ return -1;
+ }
+ else
+ {
+ if (temp)
+ {
+ modified++;
+ if (*temp)
+ ADD_STRING (temp);
+ free (temp);
+ }
+ only_printing = r == 1;
+ i = eindex;
+ }
+ break;
+ }
+ }
+
+ *output = result;
+ if (string != hstring)
+ free (string);
+
+ if (only_printing)
+ {
+ add_history (result);
+ return (2);
+ }
+
+ return (modified != 0);
+}
+
+/* Return a consed string which is the word specified in SPEC, and found
+ in FROM. NULL is returned if there is no spec. The address of
+ ERROR_POINTER is returned if the word specified cannot be found.
+ CALLER_INDEX is the offset in SPEC to start looking; it is updated
+ to point to just after the last character parsed. */
+static char *
+get_history_word_specifier (spec, from, caller_index)
+ char *spec, *from;
+ int *caller_index;
+{
+ register int i = *caller_index;
+ int first, last;
+ int expecting_word_spec = 0;
+ char *result;
+
+ /* The range of words to return doesn't exist yet. */
+ first = last = 0;
+ result = (char *)NULL;
+
+ /* If we found a colon, then this *must* be a word specification. If
+ it isn't, then it is an error. */
+ if (spec[i] == ':')
+ {
+ i++;
+ expecting_word_spec++;
+ }
+
+ /* Handle special cases first. */
+
+ /* `%' is the word last searched for. */
+ if (spec[i] == '%')
+ {
+ *caller_index = i + 1;
+ return (search_match ? savestring (search_match) : savestring (""));
+ }
+
+ /* `*' matches all of the arguments, but not the command. */
+ if (spec[i] == '*')
+ {
+ *caller_index = i + 1;
+ result = history_arg_extract (1, '$', from);
+ return (result ? result : savestring (""));
+ }
+
+ /* `$' is last arg. */
+ if (spec[i] == '$')
+ {
+ *caller_index = i + 1;
+ return (history_arg_extract ('$', '$', from));
+ }
+
+ /* Try to get FIRST and LAST figured out. */
+
+ if (spec[i] == '-')
+ first = 0;
+ else if (spec[i] == '^')
+ first = 1;
+ else if (_rl_digit_p (spec[i]) && expecting_word_spec)
+ {
+ for (first = 0; _rl_digit_p (spec[i]); i++)
+ first = (first * 10) + _rl_digit_value (spec[i]);
+ }
+ else
+ return ((char *)NULL); /* no valid `first' for word specifier */
+
+ if (spec[i] == '^' || spec[i] == '*')
+ {
+ last = (spec[i] == '^') ? 1 : '$'; /* x* abbreviates x-$ */
+ i++;
+ }
+ else if (spec[i] != '-')
+ last = first;
+ else
+ {
+ i++;
+
+ if (_rl_digit_p (spec[i]))
+ {
+ for (last = 0; _rl_digit_p (spec[i]); i++)
+ last = (last * 10) + _rl_digit_value (spec[i]);
+ }
+ else if (spec[i] == '$')
+ {
+ i++;
+ last = '$';
+ }
+#if 0
+ else if (!spec[i] || spec[i] == ':')
+ /* check against `:' because there could be a modifier separator */
+#else
+ else
+ /* csh seems to allow anything to terminate the word spec here,
+ leaving it as an abbreviation. */
+#endif
+ last = -1; /* x- abbreviates x-$ omitting word `$' */
+ }
+
+ *caller_index = i;
+
+ if (last >= first || last == '$' || last < 0)
+ result = history_arg_extract (first, last, from);
+
+ return (result ? result : (char *)&error_pointer);
+}
+
+/* Extract the args specified, starting at FIRST, and ending at LAST.
+ The args are taken from STRING. If either FIRST or LAST is < 0,
+ then make that arg count from the right (subtract from the number of
+ tokens, so that FIRST = -1 means the next to last token on the line).
+ If LAST is `$' the last arg from STRING is used. */
+char *
+history_arg_extract (first, last, string)
+ int first, last;
+ const char *string;
+{
+ register int i, len;
+ char *result;
+ int size, offset;
+ char **list;
+
+ /* XXX - think about making history_tokenize return a struct array,
+ each struct in array being a string and a length to avoid the
+ calls to strlen below. */
+ if ((list = history_tokenize (string)) == NULL)
+ return ((char *)NULL);
+
+ for (len = 0; list[len]; len++)
+ ;
+
+ if (last < 0)
+ last = len + last - 1;
+
+ if (first < 0)
+ first = len + first - 1;
+
+ if (last == '$')
+ last = len - 1;
+
+ if (first == '$')
+ first = len - 1;
+
+ last++;
+
+ if (first >= len || last > len || first < 0 || last < 0 || first > last)
+ result = ((char *)NULL);
+ else
+ {
+ for (size = 0, i = first; i < last; i++)
+ size += strlen (list[i]) + 1;
+ result = (char *)xmalloc (size + 1);
+ result[0] = '\0';
+
+ for (i = first, offset = 0; i < last; i++)
+ {
+ strcpy (result + offset, list[i]);
+ offset += strlen (list[i]);
+ if (i + 1 < last)
+ {
+ result[offset++] = ' ';
+ result[offset] = 0;
+ }
+ }
+ }
+
+ for (i = 0; i < len; i++)
+ free (list[i]);
+ free (list);
+
+ return (result);
+}
+
+#define slashify_in_quotes "\\`\"$"
+
+/* Parse STRING into tokens and return an array of strings. If WIND is
+ not -1 and INDP is not null, we also want the word surrounding index
+ WIND. The position in the returned array of strings is returned in
+ *INDP. */
+static char **
+history_tokenize_internal (string, wind, indp)
+ const char *string;
+ int wind, *indp;
+{
+ char **result;
+ register int i, start, result_index, size;
+ int len, delimiter;
+
+ /* If we're searching for a string that's not part of a word (e.g., " "),
+ make sure we set *INDP to a reasonable value. */
+ if (indp && wind != -1)
+ *indp = -1;
+
+ /* Get a token, and stuff it into RESULT. The tokens are split
+ exactly where the shell would split them. */
+ for (i = result_index = size = 0, result = (char **)NULL; string[i]; )
+ {
+ delimiter = 0;
+
+ /* Skip leading whitespace. */
+ for (; string[i] && whitespace (string[i]); i++)
+ ;
+ if (string[i] == 0 || string[i] == history_comment_char)
+ return (result);
+
+ start = i;
+
+ if (member (string[i], "()\n"))
+ {
+ i++;
+ goto got_token;
+ }
+
+ if (member (string[i], "<>;&|$"))
+ {
+ int peek = string[i + 1];
+
+ if (peek == string[i] && peek != '$')
+ {
+ if (peek == '<' && string[i + 2] == '-')
+ i++;
+ i += 2;
+ goto got_token;
+ }
+ else
+ {
+ if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
+ ((peek == '>') && (string[i] == '&')) ||
+ ((peek == '(') && (string[i] == '$')))
+ {
+ i += 2;
+ goto got_token;
+ }
+ }
+ if (string[i] != '$')
+ {
+ i++;
+ goto got_token;
+ }
+ }
+
+ /* Get word from string + i; */
+
+ if (member (string[i], HISTORY_QUOTE_CHARACTERS))
+ delimiter = string[i++];
+
+ for (; string[i]; i++)
+ {
+ if (string[i] == '\\' && string[i + 1] == '\n')
+ {
+ i++;
+ continue;
+ }
+
+ if (string[i] == '\\' && delimiter != '\'' &&
+ (delimiter != '"' || member (string[i], slashify_in_quotes)))
+ {
+ i++;
+ continue;
+ }
+
+ if (delimiter && string[i] == delimiter)
+ {
+ delimiter = 0;
+ continue;
+ }
+
+ if (!delimiter && (member (string[i], history_word_delimiters)))
+ break;
+
+ if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS))
+ delimiter = string[i];
+ }
+
+ got_token:
+
+ /* If we are looking for the word in which the character at a
+ particular index falls, remember it. */
+ if (indp && wind != -1 && wind >= start && wind < i)
+ *indp = result_index;
+
+ len = i - start;
+ if (result_index + 2 >= size)
+ result = (char **)xrealloc (result, ((size += 10) * sizeof (char *)));
+ result[result_index] = (char *)xmalloc (1 + len);
+ strncpy (result[result_index], string + start, len);
+ result[result_index][len] = '\0';
+ result[++result_index] = (char *)NULL;
+ }
+
+ return (result);
+}
+
+/* Return an array of tokens, much as the shell might. The tokens are
+ parsed out of STRING. */
+char **
+history_tokenize (string)
+ const char *string;
+{
+ return (history_tokenize_internal (string, -1, (int *)NULL));
+}
+
+/* Find and return the word which contains the character at index IND
+ in the history line LINE. Used to save the word matched by the
+ last history !?string? search. */
+static char *
+history_find_word (line, ind)
+ char *line;
+ int ind;
+{
+ char **words, *s;
+ int i, wind;
+
+ words = history_tokenize_internal (line, ind, &wind);
+ if (wind == -1 || words == 0)
+ return ((char *)NULL);
+ s = words[wind];
+ for (i = 0; i < wind; i++)
+ free (words[i]);
+ for (i = wind + 1; words[i]; i++)
+ free (words[i]);
+ free (words);
+ return s;
+}
diff --git a/MSVC/readline/histfile.c b/MSVC/readline/histfile.c
index 7fae4c1..b0279db 100644
--- a/MSVC/readline/histfile.c
+++ b/MSVC/readline/histfile.c
@@ -1,487 +1,487 @@
-/* histfile.c - functions to manipulate the history file. */
-
-/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
-
- This file contains the GNU History Library (the Library), a set of
- routines for managing the text of previously typed lines.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-/* The goal is to make the implementation transparent, so that you
- don't have to know what data types are used, just what functions
- you can call. I think I have done that. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <stdio.h>
-
-#include <sys/types.h>
-#if !defined _MINIX && !defined _WIN32
-# include <sys/file.h>
-#endif
-#include "posixstat.h"
-#include <fcntl.h>
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif
-
-#if defined (__EMX__) || defined (__CYGWIN__)
-# undef HAVE_MMAP
-#endif
-
-#ifdef HAVE_MMAP
-# include <sys/mman.h>
-
-# ifdef MAP_FILE
-# define MAP_RFLAGS (MAP_FILE|MAP_PRIVATE)
-# define MAP_WFLAGS (MAP_FILE|MAP_SHARED)
-# else
-# define MAP_RFLAGS MAP_PRIVATE
-# define MAP_WFLAGS MAP_SHARED
-# endif
-
-# ifndef MAP_FAILED
-# define MAP_FAILED ((void *)-1)
-# endif
-
-#endif /* HAVE_MMAP */
-
-/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
- on win 95/98/nt), we want to open files with O_BINARY mode so that there
- is no \n -> \r\n conversion performed. On other systems, we don't want to
- mess around with O_BINARY at all, so we ensure that it's defined to 0. */
-#if defined (__EMX__) || defined (__CYGWIN__)
-# ifndef O_BINARY
-# define O_BINARY 0
-# endif
-#else /* !__EMX__ && !__CYGWIN__ */
-# undef O_BINARY
-# define O_BINARY 0
-#endif /* !__EMX__ && !__CYGWIN__ */
-
-#include <errno.h>
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-#if defined _WIN32
-# include "rlconf.h"
-#endif /* _WIN32 */
-
-#include "history.h"
-#include "histlib.h"
-
-#include "rlshell.h"
-#include "xmalloc.h"
-
-/* Return the string that should be used in the place of this
- filename. This only matters when you don't specify the
- filename to read_history (), or write_history (). */
-static char *
-history_filename (filename)
- const char *filename;
-{
- char *return_val;
- const char *home;
- int home_len;
-
- return_val = filename ? savestring (filename) : (char *)NULL;
-
- if (return_val)
- return (return_val);
-
- home = sh_get_env_value ("HOME");
-
- if (home == 0)
- {
-#if defined _WIN32 && defined INITFILES_IN_REGISTRY
- return_val = get_user_registry_string(READLINE_REGKEY, HISTFILE_REGVAL);
- if (return_val)
- return (return_val);
- free(return_val);
-#endif /* _WIN32 ... */
- home = ".";
- home_len = 1;
- }
- else
- home_len = strlen (home);
-
- return_val = (char *)xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */
- strcpy (return_val, home);
- return_val[home_len] = '/';
-#if defined (__MSDOS__)
- strcpy (return_val + home_len + 1, "_history");
-#else
- strcpy (return_val + home_len + 1, ".history");
-#endif
-
- return (return_val);
-}
-
-/* Add the contents of FILENAME to the history list, a line at a time.
- If FILENAME is NULL, then read from ~/.history. Returns 0 if
- successful, or errno if not. */
-int
-read_history (filename)
- const char *filename;
-{
- return (read_history_range (filename, 0, -1));
-}
-
-/* Read a range of lines from FILENAME, adding them to the history list.
- Start reading at the FROM'th line and end at the TO'th. If FROM
- is zero, start at the beginning. If TO is less than FROM, read
- until the end of the file. If FILENAME is NULL, then read from
- ~/.history. Returns 0 if successful, or errno if not. */
-int
-read_history_range (filename, from, to)
- const char *filename;
- int from, to;
-{
- register char *line_start, *line_end;
- char *input, *buffer, *bufend;
- int file, current_line, chars_read;
- struct stat finfo;
- size_t file_size;
-
- buffer = (char *)NULL;
- input = history_filename (filename);
- file = open (input, O_RDONLY|O_BINARY, 0666);
-
- if ((file < 0) || (fstat (file, &finfo) == -1))
- goto error_and_exit;
-
- file_size = (size_t)finfo.st_size;
-
- /* check for overflow on very large files */
- if (file_size != finfo.st_size || file_size + 1 < file_size)
- {
-#if defined (EFBIG)
- errno = EFBIG;
-#elif defined (EOVERFLOW)
- errno = EOVERFLOW;
-#endif
- goto error_and_exit;
- }
-
-#ifdef HAVE_MMAP
- /* We map read/write and private so we can change newlines to NULs without
- affecting the underlying object. */
- buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0);
- if ((void *)buffer == MAP_FAILED)
- goto error_and_exit;
- chars_read = file_size;
-#else
- buffer = (char *)malloc (file_size + 1);
- if (buffer == 0)
- goto error_and_exit;
-
- chars_read = read (file, buffer, file_size);
-#endif
- if (chars_read < 0)
- {
- error_and_exit:
- chars_read = errno;
- if (file >= 0)
- close (file);
-
- FREE (input);
-#ifndef HAVE_MMAP
- FREE (buffer);
-#endif
-
- return (chars_read);
- }
-
- close (file);
-
- /* Set TO to larger than end of file if negative. */
- if (to < 0)
- to = chars_read;
-
- /* Start at beginning of file, work to end. */
- bufend = buffer + chars_read;
- current_line = 0;
-
- /* Skip lines until we are at FROM. */
- for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++)
- if (*line_end == '\n')
- {
- current_line++;
- line_start = line_end + 1;
- }
-
- /* If there are lines left to gobble, then gobble them now. */
- for (line_end = line_start; line_end < bufend; line_end++)
- if (*line_end == '\n')
- {
- *line_end = '\0';
-
- if (*line_start)
- add_history (line_start);
-
- current_line++;
-
- if (current_line >= to)
- break;
-
- line_start = line_end + 1;
- }
-
- FREE (input);
-#ifndef HAVE_MMAP
- FREE (buffer);
-#else
- munmap (buffer, file_size);
-#endif
-
- return (0);
-}
-
-/* Truncate the history file FNAME, leaving only LINES trailing lines.
- If FNAME is NULL, then use ~/.history. Returns 0 on success, errno
- on failure. */
-int
-history_truncate_file (fname, lines)
- const char *fname;
- int lines;
-{
- char *buffer, *filename, *bp;
- int file, chars_read, rv;
- struct stat finfo;
- size_t file_size;
-
- buffer = (char *)NULL;
- filename = history_filename (fname);
- file = open (filename, O_RDONLY|O_BINARY, 0666);
- rv = 0;
-
- /* Don't try to truncate non-regular files. */
- if (file == -1 || fstat (file, &finfo) == -1)
- {
- rv = errno;
- if (file != -1)
- close (file);
- goto truncate_exit;
- }
-
- if (S_ISREG (finfo.st_mode) == 0)
- {
- close (file);
-#ifdef EFTYPE
- rv = EFTYPE;
-#else
- rv = EINVAL;
-#endif
- goto truncate_exit;
- }
-
- file_size = (size_t)finfo.st_size;
-
- /* check for overflow on very large files */
- if (file_size != finfo.st_size || file_size + 1 < file_size)
- {
- close (file);
-#if defined (EFBIG)
- rv = errno = EFBIG;
-#elif defined (EOVERFLOW)
- rv = errno = EOVERFLOW;
-#else
- rv = errno = EINVAL;
-#endif
- goto truncate_exit;
- }
-
- buffer = (char *)malloc (file_size + 1);
- if (buffer == 0)
- {
- close (file);
- goto truncate_exit;
- }
-
- chars_read = read (file, buffer, file_size);
- close (file);
-
- if (chars_read <= 0)
- {
- rv = (chars_read < 0) ? errno : 0;
- goto truncate_exit;
- }
-
- /* Count backwards from the end of buffer until we have passed
- LINES lines. */
- for (bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
- {
- if (*bp == '\n')
- lines--;
- }
-
- /* If this is the first line, then the file contains exactly the
- number of lines we want to truncate to, so we don't need to do
- anything. It's the first line if we don't find a newline between
- the current value of i and 0. Otherwise, write from the start of
- this line until the end of the buffer. */
- for ( ; bp > buffer; bp--)
- if (*bp == '\n')
- {
- bp++;
- break;
- }
-
- /* Write only if there are more lines in the file than we want to
- truncate to. */
- if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1))
- {
- write (file, bp, chars_read - (bp - buffer));
-
-#if defined (__BEOS__)
- /* BeOS ignores O_TRUNC. */
- ftruncate (file, chars_read - (bp - buffer));
-#endif
-
- close (file);
- }
-
- truncate_exit:
-
- FREE (buffer);
-
- free (filename);
- return rv;
-}
-
-/* Workhorse function for writing history. Writes NELEMENT entries
- from the history list to FILENAME. OVERWRITE is non-zero if you
- wish to replace FILENAME with the entries. */
-static int
-history_do_write (filename, nelements, overwrite)
- const char *filename;
- int nelements, overwrite;
-{
- register int i;
- char *output;
- int file, mode, rv;
- size_t cursize;
-
-#ifdef HAVE_MMAP
- mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY;
-#else
- mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
-#endif
- output = history_filename (filename);
- rv = 0;
-
- if ((file = open (output, mode, 0600)) == -1)
- {
- FREE (output);
- return (errno);
- }
-
-#ifdef HAVE_MMAP
- cursize = overwrite ? 0 : lseek (file, 0, SEEK_END);
-#endif
-
- if (nelements > history_length)
- nelements = history_length;
-
- /* Build a buffer of all the lines to write, and write them in one syscall.
- Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */
- {
- HIST_ENTRY **the_history; /* local */
- register int j;
- int buffer_size;
- char *buffer;
-
- the_history = history_list ();
- /* Calculate the total number of bytes to write. */
- for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
- buffer_size += 1 + strlen (the_history[i]->line);
-
- /* Allocate the buffer, and fill it. */
-#ifdef HAVE_MMAP
- if (ftruncate (file, buffer_size+cursize) == -1)
- goto mmap_error;
- buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize);
- if ((void *)buffer == MAP_FAILED)
- {
-mmap_error:
- rv = errno;
- FREE (output);
- close (file);
- return rv;
- }
-#else
- buffer = (char *)malloc (buffer_size);
- if (buffer == 0)
- {
- rv = errno;
- FREE (output);
- close (file);
- return rv;
- }
-#endif
-
- for (j = 0, i = history_length - nelements; i < history_length; i++)
- {
- strcpy (buffer + j, the_history[i]->line);
- j += strlen (the_history[i]->line);
- buffer[j++] = '\n';
- }
-
-#ifdef HAVE_MMAP
- if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0)
- rv = errno;
-#else
- if (write (file, buffer, buffer_size) < 0)
- rv = errno;
- free (buffer);
-#endif
- }
-
- close (file);
-
- FREE (output);
-
- return (rv);
-}
-
-/* Append NELEMENT entries to FILENAME. The entries appended are from
- the end of the list minus NELEMENTs up to the end of the list. */
-int
-append_history (nelements, filename)
- int nelements;
- const char *filename;
-{
- return (history_do_write (filename, nelements, HISTORY_APPEND));
-}
-
-/* Overwrite FILENAME with the current history. If FILENAME is NULL,
- then write the history list to ~/.history. Values returned
- are as in read_history ().*/
-int
-write_history (filename)
- const char *filename;
-{
- return (history_do_write (filename, history_length, HISTORY_OVERWRITE));
-}
+/* histfile.c - functions to manipulate the history file. */
+
+/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
+
+ This file contains the GNU History Library (the Library), a set of
+ routines for managing the text of previously typed lines.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+/* The goal is to make the implementation transparent, so that you
+ don't have to know what data types are used, just what functions
+ you can call. I think I have done that. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include <sys/types.h>
+#if !defined _MINIX && !defined _WIN32
+# include <sys/file.h>
+#endif
+#include "posixstat.h"
+#include <fcntl.h>
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#if defined (__EMX__) || defined (__CYGWIN__)
+# undef HAVE_MMAP
+#endif
+
+#ifdef HAVE_MMAP
+# include <sys/mman.h>
+
+# ifdef MAP_FILE
+# define MAP_RFLAGS (MAP_FILE|MAP_PRIVATE)
+# define MAP_WFLAGS (MAP_FILE|MAP_SHARED)
+# else
+# define MAP_RFLAGS MAP_PRIVATE
+# define MAP_WFLAGS MAP_SHARED
+# endif
+
+# ifndef MAP_FAILED
+# define MAP_FAILED ((void *)-1)
+# endif
+
+#endif /* HAVE_MMAP */
+
+/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
+ on win 95/98/nt), we want to open files with O_BINARY mode so that there
+ is no \n -> \r\n conversion performed. On other systems, we don't want to
+ mess around with O_BINARY at all, so we ensure that it's defined to 0. */
+#if defined (__EMX__) || defined (__CYGWIN__)
+# ifndef O_BINARY
+# define O_BINARY 0
+# endif
+#else /* !__EMX__ && !__CYGWIN__ */
+# undef O_BINARY
+# define O_BINARY 0
+#endif /* !__EMX__ && !__CYGWIN__ */
+
+#include <errno.h>
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+#if defined _WIN32
+# include "rlconf.h"
+#endif /* _WIN32 */
+
+#include "history.h"
+#include "histlib.h"
+
+#include "rlshell.h"
+#include "xmalloc.h"
+
+/* Return the string that should be used in the place of this
+ filename. This only matters when you don't specify the
+ filename to read_history (), or write_history (). */
+static char *
+history_filename (filename)
+ const char *filename;
+{
+ char *return_val;
+ const char *home;
+ int home_len;
+
+ return_val = filename ? savestring (filename) : (char *)NULL;
+
+ if (return_val)
+ return (return_val);
+
+ home = sh_get_env_value ("HOME");
+
+ if (home == 0)
+ {
+#if defined _WIN32 && defined INITFILES_IN_REGISTRY
+ return_val = get_user_registry_string(READLINE_REGKEY, HISTFILE_REGVAL);
+ if (return_val)
+ return (return_val);
+ free(return_val);
+#endif /* _WIN32 ... */
+ home = ".";
+ home_len = 1;
+ }
+ else
+ home_len = strlen (home);
+
+ return_val = (char *)xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */
+ strcpy (return_val, home);
+ return_val[home_len] = '/';
+#if defined (__MSDOS__)
+ strcpy (return_val + home_len + 1, "_history");
+#else
+ strcpy (return_val + home_len + 1, ".history");
+#endif
+
+ return (return_val);
+}
+
+/* Add the contents of FILENAME to the history list, a line at a time.
+ If FILENAME is NULL, then read from ~/.history. Returns 0 if
+ successful, or errno if not. */
+int
+read_history (filename)
+ const char *filename;
+{
+ return (read_history_range (filename, 0, -1));
+}
+
+/* Read a range of lines from FILENAME, adding them to the history list.
+ Start reading at the FROM'th line and end at the TO'th. If FROM
+ is zero, start at the beginning. If TO is less than FROM, read
+ until the end of the file. If FILENAME is NULL, then read from
+ ~/.history. Returns 0 if successful, or errno if not. */
+int
+read_history_range (filename, from, to)
+ const char *filename;
+ int from, to;
+{
+ register char *line_start, *line_end;
+ char *input, *buffer, *bufend;
+ int file, current_line, chars_read;
+ struct stat finfo;
+ size_t file_size;
+
+ buffer = (char *)NULL;
+ input = history_filename (filename);
+ file = open (input, O_RDONLY|O_BINARY, 0666);
+
+ if ((file < 0) || (fstat (file, &finfo) == -1))
+ goto error_and_exit;
+
+ file_size = (size_t)finfo.st_size;
+
+ /* check for overflow on very large files */
+ if (file_size != finfo.st_size || file_size + 1 < file_size)
+ {
+#if defined (EFBIG)
+ errno = EFBIG;
+#elif defined (EOVERFLOW)
+ errno = EOVERFLOW;
+#endif
+ goto error_and_exit;
+ }
+
+#ifdef HAVE_MMAP
+ /* We map read/write and private so we can change newlines to NULs without
+ affecting the underlying object. */
+ buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0);
+ if ((void *)buffer == MAP_FAILED)
+ goto error_and_exit;
+ chars_read = file_size;
+#else
+ buffer = (char *)malloc (file_size + 1);
+ if (buffer == 0)
+ goto error_and_exit;
+
+ chars_read = read (file, buffer, file_size);
+#endif
+ if (chars_read < 0)
+ {
+ error_and_exit:
+ chars_read = errno;
+ if (file >= 0)
+ close (file);
+
+ FREE (input);
+#ifndef HAVE_MMAP
+ FREE (buffer);
+#endif
+
+ return (chars_read);
+ }
+
+ close (file);
+
+ /* Set TO to larger than end of file if negative. */
+ if (to < 0)
+ to = chars_read;
+
+ /* Start at beginning of file, work to end. */
+ bufend = buffer + chars_read;
+ current_line = 0;
+
+ /* Skip lines until we are at FROM. */
+ for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++)
+ if (*line_end == '\n')
+ {
+ current_line++;
+ line_start = line_end + 1;
+ }
+
+ /* If there are lines left to gobble, then gobble them now. */
+ for (line_end = line_start; line_end < bufend; line_end++)
+ if (*line_end == '\n')
+ {
+ *line_end = '\0';
+
+ if (*line_start)
+ add_history (line_start);
+
+ current_line++;
+
+ if (current_line >= to)
+ break;
+
+ line_start = line_end + 1;
+ }
+
+ FREE (input);
+#ifndef HAVE_MMAP
+ FREE (buffer);
+#else
+ munmap (buffer, file_size);
+#endif
+
+ return (0);
+}
+
+/* Truncate the history file FNAME, leaving only LINES trailing lines.
+ If FNAME is NULL, then use ~/.history. Returns 0 on success, errno
+ on failure. */
+int
+history_truncate_file (fname, lines)
+ const char *fname;
+ int lines;
+{
+ char *buffer, *filename, *bp;
+ int file, chars_read, rv;
+ struct stat finfo;
+ size_t file_size;
+
+ buffer = (char *)NULL;
+ filename = history_filename (fname);
+ file = open (filename, O_RDONLY|O_BINARY, 0666);
+ rv = 0;
+
+ /* Don't try to truncate non-regular files. */
+ if (file == -1 || fstat (file, &finfo) == -1)
+ {
+ rv = errno;
+ if (file != -1)
+ close (file);
+ goto truncate_exit;
+ }
+
+ if (S_ISREG (finfo.st_mode) == 0)
+ {
+ close (file);
+#ifdef EFTYPE
+ rv = EFTYPE;
+#else
+ rv = EINVAL;
+#endif
+ goto truncate_exit;
+ }
+
+ file_size = (size_t)finfo.st_size;
+
+ /* check for overflow on very large files */
+ if (file_size != finfo.st_size || file_size + 1 < file_size)
+ {
+ close (file);
+#if defined (EFBIG)
+ rv = errno = EFBIG;
+#elif defined (EOVERFLOW)
+ rv = errno = EOVERFLOW;
+#else
+ rv = errno = EINVAL;
+#endif
+ goto truncate_exit;
+ }
+
+ buffer = (char *)malloc (file_size + 1);
+ if (buffer == 0)
+ {
+ close (file);
+ goto truncate_exit;
+ }
+
+ chars_read = read (file, buffer, file_size);
+ close (file);
+
+ if (chars_read <= 0)
+ {
+ rv = (chars_read < 0) ? errno : 0;
+ goto truncate_exit;
+ }
+
+ /* Count backwards from the end of buffer until we have passed
+ LINES lines. */
+ for (bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
+ {
+ if (*bp == '\n')
+ lines--;
+ }
+
+ /* If this is the first line, then the file contains exactly the
+ number of lines we want to truncate to, so we don't need to do
+ anything. It's the first line if we don't find a newline between
+ the current value of i and 0. Otherwise, write from the start of
+ this line until the end of the buffer. */
+ for ( ; bp > buffer; bp--)
+ if (*bp == '\n')
+ {
+ bp++;
+ break;
+ }
+
+ /* Write only if there are more lines in the file than we want to
+ truncate to. */
+ if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1))
+ {
+ write (file, bp, chars_read - (bp - buffer));
+
+#if defined (__BEOS__)
+ /* BeOS ignores O_TRUNC. */
+ ftruncate (file, chars_read - (bp - buffer));
+#endif
+
+ close (file);
+ }
+
+ truncate_exit:
+
+ FREE (buffer);
+
+ free (filename);
+ return rv;
+}
+
+/* Workhorse function for writing history. Writes NELEMENT entries
+ from the history list to FILENAME. OVERWRITE is non-zero if you
+ wish to replace FILENAME with the entries. */
+static int
+history_do_write (filename, nelements, overwrite)
+ const char *filename;
+ int nelements, overwrite;
+{
+ register int i;
+ char *output;
+ int file, mode, rv;
+ size_t cursize;
+
+#ifdef HAVE_MMAP
+ mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY;
+#else
+ mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
+#endif
+ output = history_filename (filename);
+ rv = 0;
+
+ if ((file = open (output, mode, 0600)) == -1)
+ {
+ FREE (output);
+ return (errno);
+ }
+
+#ifdef HAVE_MMAP
+ cursize = overwrite ? 0 : lseek (file, 0, SEEK_END);
+#endif
+
+ if (nelements > history_length)
+ nelements = history_length;
+
+ /* Build a buffer of all the lines to write, and write them in one syscall.
+ Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */
+ {
+ HIST_ENTRY **the_history; /* local */
+ register int j;
+ int buffer_size;
+ char *buffer;
+
+ the_history = history_list ();
+ /* Calculate the total number of bytes to write. */
+ for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
+ buffer_size += 1 + strlen (the_history[i]->line);
+
+ /* Allocate the buffer, and fill it. */
+#ifdef HAVE_MMAP
+ if (ftruncate (file, buffer_size+cursize) == -1)
+ goto mmap_error;
+ buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize);
+ if ((void *)buffer == MAP_FAILED)
+ {
+mmap_error:
+ rv = errno;
+ FREE (output);
+ close (file);
+ return rv;
+ }
+#else
+ buffer = (char *)malloc (buffer_size);
+ if (buffer == 0)
+ {
+ rv = errno;
+ FREE (output);
+ close (file);
+ return rv;
+ }
+#endif
+
+ for (j = 0, i = history_length - nelements; i < history_length; i++)
+ {
+ strcpy (buffer + j, the_history[i]->line);
+ j += strlen (the_history[i]->line);
+ buffer[j++] = '\n';
+ }
+
+#ifdef HAVE_MMAP
+ if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0)
+ rv = errno;
+#else
+ if (write (file, buffer, buffer_size) < 0)
+ rv = errno;
+ free (buffer);
+#endif
+ }
+
+ close (file);
+
+ FREE (output);
+
+ return (rv);
+}
+
+/* Append NELEMENT entries to FILENAME. The entries appended are from
+ the end of the list minus NELEMENTs up to the end of the list. */
+int
+append_history (nelements, filename)
+ int nelements;
+ const char *filename;
+{
+ return (history_do_write (filename, nelements, HISTORY_APPEND));
+}
+
+/* Overwrite FILENAME with the current history. If FILENAME is NULL,
+ then write the history list to ~/.history. Values returned
+ are as in read_history ().*/
+int
+write_history (filename)
+ const char *filename;
+{
+ return (history_do_write (filename, history_length, HISTORY_OVERWRITE));
+}
diff --git a/MSVC/readline/histlib.h b/MSVC/readline/histlib.h
index 3ca6c25..7c5de45 100644
--- a/MSVC/readline/histlib.h
+++ b/MSVC/readline/histlib.h
@@ -1,82 +1,82 @@
-/* histlib.h -- internal definitions for the history library. */
-/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
-
- This file contains the GNU History Library (the Library), a set of
- routines for managing the text of previously typed lines.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_HISTLIB_H_)
-#define _HISTLIB_H_
-
-#if defined (HAVE_STRING_H)
-# include <string.h>
-#else
-# include <strings.h>
-#endif /* !HAVE_STRING_H */
-
-#if !defined (STREQ)
-#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
-#define STREQN(a, b, n) (((n) == 0) ? (1) \
- : ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
-#endif
-
-#ifndef savestring
-#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
-#endif
-
-#ifndef whitespace
-#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
-#endif
-
-#ifndef _rl_digit_p
-#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
-#endif
-
-#ifndef _rl_digit_value
-#define _rl_digit_value(c) ((c) - '0')
-#endif
-
-#ifndef member
-# if !defined strchr && !defined _MSC_VER
-extern char *strchr ();
-# endif
-#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
-#endif
-
-#ifndef FREE
-# define FREE(x) if (x) free (x)
-#endif
-
-/* Possible history errors passed to hist_error. */
-#define EVENT_NOT_FOUND 0
-#define BAD_WORD_SPEC 1
-#define SUBST_FAILED 2
-#define BAD_MODIFIER 3
-#define NO_PREV_SUBST 4
-
-/* Possible definitions for history starting point specification. */
-#define ANCHORED_SEARCH 1
-#define NON_ANCHORED_SEARCH 0
-
-/* Possible definitions for what style of writing the history file we want. */
-#define HISTORY_APPEND 0
-#define HISTORY_OVERWRITE 1
-
-/* Some variable definitions shared across history source files. */
-extern int history_offset;
-
-#endif /* !_HISTLIB_H_ */
+/* histlib.h -- internal definitions for the history library. */
+/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
+
+ This file contains the GNU History Library (the Library), a set of
+ routines for managing the text of previously typed lines.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_HISTLIB_H_)
+#define _HISTLIB_H_
+
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else
+# include <strings.h>
+#endif /* !HAVE_STRING_H */
+
+#if !defined (STREQ)
+#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
+#define STREQN(a, b, n) (((n) == 0) ? (1) \
+ : ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
+#endif
+
+#ifndef savestring
+#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
+#endif
+
+#ifndef whitespace
+#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
+#endif
+
+#ifndef _rl_digit_p
+#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
+#endif
+
+#ifndef _rl_digit_value
+#define _rl_digit_value(c) ((c) - '0')
+#endif
+
+#ifndef member
+# if !defined strchr && !defined _MSC_VER
+extern char *strchr ();
+# endif
+#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
+#endif
+
+#ifndef FREE
+# define FREE(x) if (x) free (x)
+#endif
+
+/* Possible history errors passed to hist_error. */
+#define EVENT_NOT_FOUND 0
+#define BAD_WORD_SPEC 1
+#define SUBST_FAILED 2
+#define BAD_MODIFIER 3
+#define NO_PREV_SUBST 4
+
+/* Possible definitions for history starting point specification. */
+#define ANCHORED_SEARCH 1
+#define NON_ANCHORED_SEARCH 0
+
+/* Possible definitions for what style of writing the history file we want. */
+#define HISTORY_APPEND 0
+#define HISTORY_OVERWRITE 1
+
+/* Some variable definitions shared across history source files. */
+extern int history_offset;
+
+#endif /* !_HISTLIB_H_ */
diff --git a/MSVC/readline/history.c b/MSVC/readline/history.c
index 0fd5ef1..4f6d6fc 100644
--- a/MSVC/readline/history.c
+++ b/MSVC/readline/history.c
@@ -1,379 +1,379 @@
-/* History.c -- standalone history library */
-
-/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
-
- This file contains the GNU History Library (the Library), a set of
- routines for managing the text of previously typed lines.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-/* The goal is to make the implementation transparent, so that you
- don't have to know what data types are used, just what functions
- you can call. I think I have done that. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <stdio.h>
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_UNISTD_H)
-# ifdef _MINIX
-# include <sys/types.h>
-# endif
-# include <unistd.h>
-#endif
-
-#include "history.h"
-#include "histlib.h"
-
-#include "xmalloc.h"
-
-/* The number of slots to increase the_history by. */
-#define DEFAULT_HISTORY_GROW_SIZE 50
-
-/* **************************************************************** */
-/* */
-/* History Functions */
-/* */
-/* **************************************************************** */
-
-/* An array of HIST_ENTRY. This is where we store the history. */
-static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
-
-/* Non-zero means that we have enforced a limit on the amount of
- history that we save. */
-static int history_stifled;
-
-/* The current number of slots allocated to the input_history. */
-static int history_size;
-
-/* If HISTORY_STIFLED is non-zero, then this is the maximum number of
- entries to remember. */
-int history_max_entries;
-int max_input_history; /* backwards compatibility */
-
-/* The current location of the interactive history pointer. Just makes
- life easier for outside callers. */
-int history_offset;
-
-/* The number of strings currently stored in the history list. */
-int history_length;
-
-/* The logical `base' of the history array. It defaults to 1. */
-int history_base = 1;
-
-/* Return the current HISTORY_STATE of the history. */
-HISTORY_STATE *
-history_get_history_state ()
-{
- HISTORY_STATE *state;
-
- state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
- state->entries = the_history;
- state->offset = history_offset;
- state->length = history_length;
- state->size = history_size;
- state->flags = 0;
- if (history_stifled)
- state->flags |= HS_STIFLED;
-
- return (state);
-}
-
-/* Set the state of the current history array to STATE. */
-void
-history_set_history_state (state)
- HISTORY_STATE *state;
-{
- the_history = state->entries;
- history_offset = state->offset;
- history_length = state->length;
- history_size = state->size;
- if (state->flags & HS_STIFLED)
- history_stifled = 1;
-}
-
-/* Begin a session in which the history functions might be used. This
- initializes interactive variables. */
-void
-using_history ()
-{
- history_offset = history_length;
-}
-
-/* Return the number of bytes that the primary history entries are using.
- This just adds up the lengths of the_history->lines. */
-int
-history_total_bytes ()
-{
- register int i, result;
-
- for (i = result = 0; the_history && the_history[i]; i++)
- result += strlen (the_history[i]->line);
-
- return (result);
-}
-
-/* Returns the magic number which says what history element we are
- looking at now. In this implementation, it returns history_offset. */
-int
-where_history ()
-{
- return (history_offset);
-}
-
-/* Make the current history item be the one at POS, an absolute index.
- Returns zero if POS is out of range, else non-zero. */
-int
-history_set_pos (pos)
- int pos;
-{
- if (pos > history_length || pos < 0 || !the_history)
- return (0);
- history_offset = pos;
- return (1);
-}
-
-/* Return the current history array. The caller has to be carefull, since this
- is the actual array of data, and could be bashed or made corrupt easily.
- The array is terminated with a NULL pointer. */
-HIST_ENTRY **
-history_list ()
-{
- return (the_history);
-}
-
-/* Return the history entry at the current position, as determined by
- history_offset. If there is no entry there, return a NULL pointer. */
-HIST_ENTRY *
-current_history ()
-{
- return ((history_offset == history_length) || the_history == 0)
- ? (HIST_ENTRY *)NULL
- : the_history[history_offset];
-}
-
-/* Back up history_offset to the previous history entry, and return
- a pointer to that entry. If there is no previous entry then return
- a NULL pointer. */
-HIST_ENTRY *
-previous_history ()
-{
- return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
-}
-
-/* Move history_offset forward to the next history entry, and return
- a pointer to that entry. If there is no next entry then return a
- NULL pointer. */
-HIST_ENTRY *
-next_history ()
-{
- return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
-}
-
-/* Return the history entry which is logically at OFFSET in the history array.
- OFFSET is relative to history_base. */
-HIST_ENTRY *
-history_get (offset)
- int offset;
-{
- int local_index;
-
- local_index = offset - history_base;
- return (local_index >= history_length || local_index < 0 || !the_history)
- ? (HIST_ENTRY *)NULL
- : the_history[local_index];
-}
-
-/* Place STRING at the end of the history list. The data field
- is set to NULL. */
-void
-add_history (string)
- const char *string;
-{
- HIST_ENTRY *temp;
-
- if (history_stifled && (history_length == history_max_entries))
- {
- register int i;
-
- /* If the history is stifled, and history_length is zero,
- and it equals history_max_entries, we don't save items. */
- if (history_length == 0)
- return;
-
- /* If there is something in the slot, then remove it. */
- if (the_history[0])
- {
- free (the_history[0]->line);
- free (the_history[0]);
- }
-
- /* Copy the rest of the entries, moving down one slot. */
- for (i = 0; i < history_length; i++)
- the_history[i] = the_history[i + 1];
-
- history_base++;
- }
- else
- {
- if (history_size == 0)
- {
- history_size = DEFAULT_HISTORY_GROW_SIZE;
- the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
- history_length = 1;
- }
- else
- {
- if (history_length == (history_size - 1))
- {
- history_size += DEFAULT_HISTORY_GROW_SIZE;
- the_history = (HIST_ENTRY **)
- xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
- }
- history_length++;
- }
- }
-
- temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
- temp->line = savestring (string);
- temp->data = (char *)NULL;
-
- the_history[history_length] = (HIST_ENTRY *)NULL;
- the_history[history_length - 1] = temp;
-}
-
-/* Make the history entry at WHICH have LINE and DATA. This returns
- the old entry so you can dispose of the data. In the case of an
- invalid WHICH, a NULL pointer is returned. */
-HIST_ENTRY *
-replace_history_entry (which, line, data)
- int which;
- const char *line;
- histdata_t data;
-{
- HIST_ENTRY *temp, *old_value;
-
- if (which >= history_length)
- return ((HIST_ENTRY *)NULL);
-
- temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
- old_value = the_history[which];
-
- temp->line = savestring (line);
- temp->data = data;
- the_history[which] = temp;
-
- return (old_value);
-}
-
-/* Remove history element WHICH from the history. The removed
- element is returned to you so you can free the line, data,
- and containing structure. */
-HIST_ENTRY *
-remove_history (which)
- int which;
-{
- HIST_ENTRY *return_value;
- register int i;
-
- if (which >= history_length || !history_length)
- return_value = (HIST_ENTRY *)NULL;
- else
- {
- return_value = the_history[which];
-
- for (i = which; i < history_length; i++)
- the_history[i] = the_history[i + 1];
-
- history_length--;
- }
-
- return (return_value);
-}
-
-/* Stifle the history list, remembering only MAX number of lines. */
-void
-stifle_history (max)
- int max;
-{
- register int i, j;
-
- if (max < 0)
- max = 0;
-
- if (history_length > max)
- {
- /* This loses because we cannot free the data. */
- for (i = 0, j = history_length - max; i < j; i++)
- {
- free (the_history[i]->line);
- free (the_history[i]);
- }
-
- history_base = i;
- for (j = 0, i = history_length - max; j < max; i++, j++)
- the_history[j] = the_history[i];
- the_history[j] = (HIST_ENTRY *)NULL;
- history_length = j;
- }
-
- history_stifled = 1;
- max_input_history = history_max_entries = max;
-}
-
-/* Stop stifling the history. This returns the previous maximum
- number of history entries. The value is positive if the history
- was stifled, negative if it wasn't. */
-int
-unstifle_history ()
-{
- if (history_stifled)
- {
- history_stifled = 0;
- return (history_max_entries);
- }
- else
- return (-history_max_entries);
-}
-
-int
-history_is_stifled ()
-{
- return (history_stifled);
-}
-
-void
-clear_history ()
-{
- register int i;
-
- /* This loses because we cannot free the data. */
- for (i = 0; i < history_length; i++)
- {
- free (the_history[i]->line);
- free (the_history[i]);
- the_history[i] = (HIST_ENTRY *)NULL;
- }
-
- history_offset = history_length = 0;
-}
+/* History.c -- standalone history library */
+
+/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
+
+ This file contains the GNU History Library (the Library), a set of
+ routines for managing the text of previously typed lines.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+/* The goal is to make the implementation transparent, so that you
+ don't have to know what data types are used, just what functions
+ you can call. I think I have done that. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <stdio.h>
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_UNISTD_H)
+# ifdef _MINIX
+# include <sys/types.h>
+# endif
+# include <unistd.h>
+#endif
+
+#include "history.h"
+#include "histlib.h"
+
+#include "xmalloc.h"
+
+/* The number of slots to increase the_history by. */
+#define DEFAULT_HISTORY_GROW_SIZE 50
+
+/* **************************************************************** */
+/* */
+/* History Functions */
+/* */
+/* **************************************************************** */
+
+/* An array of HIST_ENTRY. This is where we store the history. */
+static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
+
+/* Non-zero means that we have enforced a limit on the amount of
+ history that we save. */
+static int history_stifled;
+
+/* The current number of slots allocated to the input_history. */
+static int history_size;
+
+/* If HISTORY_STIFLED is non-zero, then this is the maximum number of
+ entries to remember. */
+int history_max_entries;
+int max_input_history; /* backwards compatibility */
+
+/* The current location of the interactive history pointer. Just makes
+ life easier for outside callers. */
+int history_offset;
+
+/* The number of strings currently stored in the history list. */
+int history_length;
+
+/* The logical `base' of the history array. It defaults to 1. */
+int history_base = 1;
+
+/* Return the current HISTORY_STATE of the history. */
+HISTORY_STATE *
+history_get_history_state ()
+{
+ HISTORY_STATE *state;
+
+ state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
+ state->entries = the_history;
+ state->offset = history_offset;
+ state->length = history_length;
+ state->size = history_size;
+ state->flags = 0;
+ if (history_stifled)
+ state->flags |= HS_STIFLED;
+
+ return (state);
+}
+
+/* Set the state of the current history array to STATE. */
+void
+history_set_history_state (state)
+ HISTORY_STATE *state;
+{
+ the_history = state->entries;
+ history_offset = state->offset;
+ history_length = state->length;
+ history_size = state->size;
+ if (state->flags & HS_STIFLED)
+ history_stifled = 1;
+}
+
+/* Begin a session in which the history functions might be used. This
+ initializes interactive variables. */
+void
+using_history ()
+{
+ history_offset = history_length;
+}
+
+/* Return the number of bytes that the primary history entries are using.
+ This just adds up the lengths of the_history->lines. */
+int
+history_total_bytes ()
+{
+ register int i, result;
+
+ for (i = result = 0; the_history && the_history[i]; i++)
+ result += strlen (the_history[i]->line);
+
+ return (result);
+}
+
+/* Returns the magic number which says what history element we are
+ looking at now. In this implementation, it returns history_offset. */
+int
+where_history ()
+{
+ return (history_offset);
+}
+
+/* Make the current history item be the one at POS, an absolute index.
+ Returns zero if POS is out of range, else non-zero. */
+int
+history_set_pos (pos)
+ int pos;
+{
+ if (pos > history_length || pos < 0 || !the_history)
+ return (0);
+ history_offset = pos;
+ return (1);
+}
+
+/* Return the current history array. The caller has to be carefull, since this
+ is the actual array of data, and could be bashed or made corrupt easily.
+ The array is terminated with a NULL pointer. */
+HIST_ENTRY **
+history_list ()
+{
+ return (the_history);
+}
+
+/* Return the history entry at the current position, as determined by
+ history_offset. If there is no entry there, return a NULL pointer. */
+HIST_ENTRY *
+current_history ()
+{
+ return ((history_offset == history_length) || the_history == 0)
+ ? (HIST_ENTRY *)NULL
+ : the_history[history_offset];
+}
+
+/* Back up history_offset to the previous history entry, and return
+ a pointer to that entry. If there is no previous entry then return
+ a NULL pointer. */
+HIST_ENTRY *
+previous_history ()
+{
+ return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
+}
+
+/* Move history_offset forward to the next history entry, and return
+ a pointer to that entry. If there is no next entry then return a
+ NULL pointer. */
+HIST_ENTRY *
+next_history ()
+{
+ return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
+}
+
+/* Return the history entry which is logically at OFFSET in the history array.
+ OFFSET is relative to history_base. */
+HIST_ENTRY *
+history_get (offset)
+ int offset;
+{
+ int local_index;
+
+ local_index = offset - history_base;
+ return (local_index >= history_length || local_index < 0 || !the_history)
+ ? (HIST_ENTRY *)NULL
+ : the_history[local_index];
+}
+
+/* Place STRING at the end of the history list. The data field
+ is set to NULL. */
+void
+add_history (string)
+ const char *string;
+{
+ HIST_ENTRY *temp;
+
+ if (history_stifled && (history_length == history_max_entries))
+ {
+ register int i;
+
+ /* If the history is stifled, and history_length is zero,
+ and it equals history_max_entries, we don't save items. */
+ if (history_length == 0)
+ return;
+
+ /* If there is something in the slot, then remove it. */
+ if (the_history[0])
+ {
+ free (the_history[0]->line);
+ free (the_history[0]);
+ }
+
+ /* Copy the rest of the entries, moving down one slot. */
+ for (i = 0; i < history_length; i++)
+ the_history[i] = the_history[i + 1];
+
+ history_base++;
+ }
+ else
+ {
+ if (history_size == 0)
+ {
+ history_size = DEFAULT_HISTORY_GROW_SIZE;
+ the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
+ history_length = 1;
+ }
+ else
+ {
+ if (history_length == (history_size - 1))
+ {
+ history_size += DEFAULT_HISTORY_GROW_SIZE;
+ the_history = (HIST_ENTRY **)
+ xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
+ }
+ history_length++;
+ }
+ }
+
+ temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
+ temp->line = savestring (string);
+ temp->data = (char *)NULL;
+
+ the_history[history_length] = (HIST_ENTRY *)NULL;
+ the_history[history_length - 1] = temp;
+}
+
+/* Make the history entry at WHICH have LINE and DATA. This returns
+ the old entry so you can dispose of the data. In the case of an
+ invalid WHICH, a NULL pointer is returned. */
+HIST_ENTRY *
+replace_history_entry (which, line, data)
+ int which;
+ const char *line;
+ histdata_t data;
+{
+ HIST_ENTRY *temp, *old_value;
+
+ if (which >= history_length)
+ return ((HIST_ENTRY *)NULL);
+
+ temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
+ old_value = the_history[which];
+
+ temp->line = savestring (line);
+ temp->data = data;
+ the_history[which] = temp;
+
+ return (old_value);
+}
+
+/* Remove history element WHICH from the history. The removed
+ element is returned to you so you can free the line, data,
+ and containing structure. */
+HIST_ENTRY *
+remove_history (which)
+ int which;
+{
+ HIST_ENTRY *return_value;
+ register int i;
+
+ if (which >= history_length || !history_length)
+ return_value = (HIST_ENTRY *)NULL;
+ else
+ {
+ return_value = the_history[which];
+
+ for (i = which; i < history_length; i++)
+ the_history[i] = the_history[i + 1];
+
+ history_length--;
+ }
+
+ return (return_value);
+}
+
+/* Stifle the history list, remembering only MAX number of lines. */
+void
+stifle_history (max)
+ int max;
+{
+ register int i, j;
+
+ if (max < 0)
+ max = 0;
+
+ if (history_length > max)
+ {
+ /* This loses because we cannot free the data. */
+ for (i = 0, j = history_length - max; i < j; i++)
+ {
+ free (the_history[i]->line);
+ free (the_history[i]);
+ }
+
+ history_base = i;
+ for (j = 0, i = history_length - max; j < max; i++, j++)
+ the_history[j] = the_history[i];
+ the_history[j] = (HIST_ENTRY *)NULL;
+ history_length = j;
+ }
+
+ history_stifled = 1;
+ max_input_history = history_max_entries = max;
+}
+
+/* Stop stifling the history. This returns the previous maximum
+ number of history entries. The value is positive if the history
+ was stifled, negative if it wasn't. */
+int
+unstifle_history ()
+{
+ if (history_stifled)
+ {
+ history_stifled = 0;
+ return (history_max_entries);
+ }
+ else
+ return (-history_max_entries);
+}
+
+int
+history_is_stifled ()
+{
+ return (history_stifled);
+}
+
+void
+clear_history ()
+{
+ register int i;
+
+ /* This loses because we cannot free the data. */
+ for (i = 0; i < history_length; i++)
+ {
+ free (the_history[i]->line);
+ free (the_history[i]);
+ the_history[i] = (HIST_ENTRY *)NULL;
+ }
+
+ history_offset = history_length = 0;
+}
diff --git a/MSVC/readline/history.h b/MSVC/readline/history.h
index 10e2577..0c983ff 100644
--- a/MSVC/readline/history.h
+++ b/MSVC/readline/history.h
@@ -1,248 +1,248 @@
-/* History.h -- the names of functions that you can call in history. */
-/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
-
- This file contains the GNU History Library (the Library), a set of
- routines for managing the text of previously typed lines.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#ifndef _HISTORY_H_
-#define _HISTORY_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined READLINE_LIBRARY
-# include "rlstdc.h"
-# include "rltypedefs.h"
-#else
-# include <readline/rlstdc.h>
-# include <readline/rltypedefs.h>
-#endif
-
-#ifdef __STDC__
-typedef void *histdata_t;
-#else
-typedef char *histdata_t;
-#endif
-
-#include "rldynlink.h" /* for export / import macros */
-
-/* The structure used to store a history entry. */
-typedef struct _hist_entry {
- char *line;
- histdata_t data;
-} HIST_ENTRY;
-
-/* A structure used to pass the current state of the history stuff around. */
-typedef struct _hist_state {
- HIST_ENTRY **entries; /* Pointer to the entries themselves. */
- int offset; /* The location pointer within this array. */
- int length; /* Number of elements within this array. */
- int size; /* Number of slots allocated to this array. */
- int flags;
-} HISTORY_STATE;
-
-/* Flag values for the `flags' member of HISTORY_STATE. */
-#define HS_STIFLED 0x01
-
-/* Initialization and state management. */
-
-/* Begin a session in which the history functions might be used. This
- just initializes the interactive variables. */
-RL_EXTERN void using_history PARAMS((void));
-
-/* Return the current HISTORY_STATE of the history. */
-RL_EXTERN HISTORY_STATE * history_get_history_state PARAMS((void));
-
-/* Set the state of the current history array to STATE. */
-RL_EXTERN void history_set_history_state PARAMS((HISTORY_STATE *));
-
-/* Manage the history list. */
-
-/* Place STRING at the end of the history list.
- The associated data field (if any) is set to NULL. */
-RL_EXTERN void add_history PARAMS((const char *));
-
-/* A reasonably useless function, only here for completeness. WHICH
- is the magic number that tells us which element to delete. The
- elements are numbered from 0. */
-RL_EXTERN HIST_ENTRY *remove_history PARAMS((int));
-
-/* Make the history entry at WHICH have LINE and DATA. This returns
- the old entry so you can dispose of the data. In the case of an
- invalid WHICH, a NULL pointer is returned. */
-RL_EXTERN HIST_ENTRY *replace_history_entry PARAMS((int, const char *, histdata_t));
-
-/* Clear the history list and start over. */
-RL_EXTERN void clear_history PARAMS((void));
-
-/* Stifle the history list, remembering only MAX number of entries. */
-RL_EXTERN void stifle_history PARAMS((int));
-
-/* Stop stifling the history. This returns the previous amount the
- history was stifled by. The value is positive if the history was
- stifled, negative if it wasn't. */
-RL_EXTERN int unstifle_history PARAMS((void));
-
-/* Return 1 if the history is stifled, 0 if it is not. */
-RL_EXTERN int history_is_stifled PARAMS((void));
-
-/* Information about the history list. */
-
-/* Return a NULL terminated array of HIST_ENTRY which is the current input
- history. Element 0 of this list is the beginning of time. If there
- is no history, return NULL. */
-RL_EXTERN HIST_ENTRY **history_list PARAMS((void));
-
-/* Returns the number which says what history element we are now
- looking at. */
-RL_EXTERN int where_history PARAMS((void));
-
-/* Return the history entry at the current position, as determined by
- history_offset. If there is no entry there, return a NULL pointer. */
-RL_EXTERN HIST_ENTRY *current_history PARAMS((void));
-
-/* Return the history entry which is logically at OFFSET in the history
- array. OFFSET is relative to history_base. */
-RL_EXTERN HIST_ENTRY *history_get PARAMS((int));
-
-/* Return the number of bytes that the primary history entries are using.
- This just adds up the lengths of the_history->lines. */
-RL_EXTERN int history_total_bytes PARAMS((void));
-
-/* Moving around the history list. */
-
-/* Set the position in the history list to POS. */
-RL_EXTERN int history_set_pos PARAMS((int));
-
-/* Back up history_offset to the previous history entry, and return
- a pointer to that entry. If there is no previous entry, return
- a NULL pointer. */
-RL_EXTERN HIST_ENTRY *previous_history PARAMS((void));
-
-/* Move history_offset forward to the next item in the input_history,
- and return the a pointer to that entry. If there is no next entry,
- return a NULL pointer. */
-RL_EXTERN HIST_ENTRY *next_history PARAMS((void));
-
-/* Searching the history list. */
-
-/* Search the history for STRING, starting at history_offset.
- If DIRECTION < 0, then the search is through previous entries,
- else through subsequent. If the string is found, then
- current_history () is the history entry, and the value of this function
- is the offset in the line of that history entry that the string was
- found in. Otherwise, nothing is changed, and a -1 is returned. */
-RL_EXTERN int history_search PARAMS((const char *, int));
-
-/* Search the history for STRING, starting at history_offset.
- The search is anchored: matching lines must begin with string.
- DIRECTION is as in history_search(). */
-RL_EXTERN int history_search_prefix PARAMS((const char *, int));
-
-/* Search for STRING in the history list, starting at POS, an
- absolute index into the list. DIR, if negative, says to search
- backwards from POS, else forwards.
- Returns the absolute index of the history element where STRING
- was found, or -1 otherwise. */
-RL_EXTERN int history_search_pos PARAMS((const char *, int, int));
-
-/* Managing the history file. */
-
-/* Add the contents of FILENAME to the history list, a line at a time.
- If FILENAME is NULL, then read from ~/.history. Returns 0 if
- successful, or errno if not. */
-RL_EXTERN int read_history PARAMS((const char *));
-
-/* Read a range of lines from FILENAME, adding them to the history list.
- Start reading at the FROM'th line and end at the TO'th. If FROM
- is zero, start at the beginning. If TO is less than FROM, read
- until the end of the file. If FILENAME is NULL, then read from
- ~/.history. Returns 0 if successful, or errno if not. */
-RL_EXTERN int read_history_range PARAMS((const char *, int, int));
-
-/* Write the current history to FILENAME. If FILENAME is NULL,
- then write the history list to ~/.history. Values returned
- are as in read_history (). */
-RL_EXTERN int write_history PARAMS((const char *));
-
-/* Append NELEMENT entries to FILENAME. The entries appended are from
- the end of the list minus NELEMENTs up to the end of the list. */
-RL_EXTERN int append_history PARAMS((int, const char *));
-
-/* Truncate the history file, leaving only the last NLINES lines. */
-RL_EXTERN int history_truncate_file PARAMS((const char *, int));
-
-/* History expansion. */
-
-/* Expand the string STRING, placing the result into OUTPUT, a pointer
- to a string. Returns:
-
- 0) If no expansions took place (or, if the only change in
- the text was the de-slashifying of the history expansion
- character)
- 1) If expansions did take place
- -1) If there was an error in expansion.
- 2) If the returned line should just be printed.
-
- If an error ocurred in expansion, then OUTPUT contains a descriptive
- error message. */
-RL_EXTERN int history_expand PARAMS((char *, char **));
-
-/* Extract a string segment consisting of the FIRST through LAST
- arguments present in STRING. Arguments are broken up as in
- the shell. */
-RL_EXTERN char *history_arg_extract PARAMS((int, int, const char *));
-
-/* Return the text of the history event beginning at the current
- offset into STRING. Pass STRING with *INDEX equal to the
- history_expansion_char that begins this specification.
- DELIMITING_QUOTE is a character that is allowed to end the string
- specification for what to search for in addition to the normal
- characters `:', ` ', `\t', `\n', and sometimes `?'. */
-RL_EXTERN char *get_history_event PARAMS((const char *, int *, int));
-
-/* Return an array of tokens, much as the shell might. The tokens are
- parsed out of STRING. */
-RL_EXTERN char **history_tokenize PARAMS((const char *));
-
-/* Exported history variables. */
-RL_EXTERN int history_base;
-RL_EXTERN int history_length;
-RL_EXTERN int history_max_entries;
-RL_EXTERN char history_expansion_char;
-RL_EXTERN char history_subst_char;
-RL_EXTERN char *history_word_delimiters;
-RL_EXTERN char history_comment_char;
-RL_EXTERN char *history_no_expand_chars;
-RL_EXTERN char *history_search_delimiter_chars;
-RL_EXTERN int history_quotes_inhibit_expansion;
-
-/* Backwards compatibility */
-RL_EXTERN int max_input_history;
-
-/* If set, this function is called to decide whether or not a particular
- history expansion should be treated as a special case for the calling
- application and not expanded. */
-RL_EXTERN rl_linebuf_func_t *history_inhibit_expansion_function;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !_HISTORY_H_ */
+/* History.h -- the names of functions that you can call in history. */
+/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
+
+ This file contains the GNU History Library (the Library), a set of
+ routines for managing the text of previously typed lines.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#ifndef _HISTORY_H_
+#define _HISTORY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined READLINE_LIBRARY
+# include "rlstdc.h"
+# include "rltypedefs.h"
+#else
+# include <readline/rlstdc.h>
+# include <readline/rltypedefs.h>
+#endif
+
+#ifdef __STDC__
+typedef void *histdata_t;
+#else
+typedef char *histdata_t;
+#endif
+
+#include "rldynlink.h" /* for export / import macros */
+
+/* The structure used to store a history entry. */
+typedef struct _hist_entry {
+ char *line;
+ histdata_t data;
+} HIST_ENTRY;
+
+/* A structure used to pass the current state of the history stuff around. */
+typedef struct _hist_state {
+ HIST_ENTRY **entries; /* Pointer to the entries themselves. */
+ int offset; /* The location pointer within this array. */
+ int length; /* Number of elements within this array. */
+ int size; /* Number of slots allocated to this array. */
+ int flags;
+} HISTORY_STATE;
+
+/* Flag values for the `flags' member of HISTORY_STATE. */
+#define HS_STIFLED 0x01
+
+/* Initialization and state management. */
+
+/* Begin a session in which the history functions might be used. This
+ just initializes the interactive variables. */
+RL_EXTERN void using_history PARAMS((void));
+
+/* Return the current HISTORY_STATE of the history. */
+RL_EXTERN HISTORY_STATE * history_get_history_state PARAMS((void));
+
+/* Set the state of the current history array to STATE. */
+RL_EXTERN void history_set_history_state PARAMS((HISTORY_STATE *));
+
+/* Manage the history list. */
+
+/* Place STRING at the end of the history list.
+ The associated data field (if any) is set to NULL. */
+RL_EXTERN void add_history PARAMS((const char *));
+
+/* A reasonably useless function, only here for completeness. WHICH
+ is the magic number that tells us which element to delete. The
+ elements are numbered from 0. */
+RL_EXTERN HIST_ENTRY *remove_history PARAMS((int));
+
+/* Make the history entry at WHICH have LINE and DATA. This returns
+ the old entry so you can dispose of the data. In the case of an
+ invalid WHICH, a NULL pointer is returned. */
+RL_EXTERN HIST_ENTRY *replace_history_entry PARAMS((int, const char *, histdata_t));
+
+/* Clear the history list and start over. */
+RL_EXTERN void clear_history PARAMS((void));
+
+/* Stifle the history list, remembering only MAX number of entries. */
+RL_EXTERN void stifle_history PARAMS((int));
+
+/* Stop stifling the history. This returns the previous amount the
+ history was stifled by. The value is positive if the history was
+ stifled, negative if it wasn't. */
+RL_EXTERN int unstifle_history PARAMS((void));
+
+/* Return 1 if the history is stifled, 0 if it is not. */
+RL_EXTERN int history_is_stifled PARAMS((void));
+
+/* Information about the history list. */
+
+/* Return a NULL terminated array of HIST_ENTRY which is the current input
+ history. Element 0 of this list is the beginning of time. If there
+ is no history, return NULL. */
+RL_EXTERN HIST_ENTRY **history_list PARAMS((void));
+
+/* Returns the number which says what history element we are now
+ looking at. */
+RL_EXTERN int where_history PARAMS((void));
+
+/* Return the history entry at the current position, as determined by
+ history_offset. If there is no entry there, return a NULL pointer. */
+RL_EXTERN HIST_ENTRY *current_history PARAMS((void));
+
+/* Return the history entry which is logically at OFFSET in the history
+ array. OFFSET is relative to history_base. */
+RL_EXTERN HIST_ENTRY *history_get PARAMS((int));
+
+/* Return the number of bytes that the primary history entries are using.
+ This just adds up the lengths of the_history->lines. */
+RL_EXTERN int history_total_bytes PARAMS((void));
+
+/* Moving around the history list. */
+
+/* Set the position in the history list to POS. */
+RL_EXTERN int history_set_pos PARAMS((int));
+
+/* Back up history_offset to the previous history entry, and return
+ a pointer to that entry. If there is no previous entry, return
+ a NULL pointer. */
+RL_EXTERN HIST_ENTRY *previous_history PARAMS((void));
+
+/* Move history_offset forward to the next item in the input_history,
+ and return the a pointer to that entry. If there is no next entry,
+ return a NULL pointer. */
+RL_EXTERN HIST_ENTRY *next_history PARAMS((void));
+
+/* Searching the history list. */
+
+/* Search the history for STRING, starting at history_offset.
+ If DIRECTION < 0, then the search is through previous entries,
+ else through subsequent. If the string is found, then
+ current_history () is the history entry, and the value of this function
+ is the offset in the line of that history entry that the string was
+ found in. Otherwise, nothing is changed, and a -1 is returned. */
+RL_EXTERN int history_search PARAMS((const char *, int));
+
+/* Search the history for STRING, starting at history_offset.
+ The search is anchored: matching lines must begin with string.
+ DIRECTION is as in history_search(). */
+RL_EXTERN int history_search_prefix PARAMS((const char *, int));
+
+/* Search for STRING in the history list, starting at POS, an
+ absolute index into the list. DIR, if negative, says to search
+ backwards from POS, else forwards.
+ Returns the absolute index of the history element where STRING
+ was found, or -1 otherwise. */
+RL_EXTERN int history_search_pos PARAMS((const char *, int, int));
+
+/* Managing the history file. */
+
+/* Add the contents of FILENAME to the history list, a line at a time.
+ If FILENAME is NULL, then read from ~/.history. Returns 0 if
+ successful, or errno if not. */
+RL_EXTERN int read_history PARAMS((const char *));
+
+/* Read a range of lines from FILENAME, adding them to the history list.
+ Start reading at the FROM'th line and end at the TO'th. If FROM
+ is zero, start at the beginning. If TO is less than FROM, read
+ until the end of the file. If FILENAME is NULL, then read from
+ ~/.history. Returns 0 if successful, or errno if not. */
+RL_EXTERN int read_history_range PARAMS((const char *, int, int));
+
+/* Write the current history to FILENAME. If FILENAME is NULL,
+ then write the history list to ~/.history. Values returned
+ are as in read_history (). */
+RL_EXTERN int write_history PARAMS((const char *));
+
+/* Append NELEMENT entries to FILENAME. The entries appended are from
+ the end of the list minus NELEMENTs up to the end of the list. */
+RL_EXTERN int append_history PARAMS((int, const char *));
+
+/* Truncate the history file, leaving only the last NLINES lines. */
+RL_EXTERN int history_truncate_file PARAMS((const char *, int));
+
+/* History expansion. */
+
+/* Expand the string STRING, placing the result into OUTPUT, a pointer
+ to a string. Returns:
+
+ 0) If no expansions took place (or, if the only change in
+ the text was the de-slashifying of the history expansion
+ character)
+ 1) If expansions did take place
+ -1) If there was an error in expansion.
+ 2) If the returned line should just be printed.
+
+ If an error ocurred in expansion, then OUTPUT contains a descriptive
+ error message. */
+RL_EXTERN int history_expand PARAMS((char *, char **));
+
+/* Extract a string segment consisting of the FIRST through LAST
+ arguments present in STRING. Arguments are broken up as in
+ the shell. */
+RL_EXTERN char *history_arg_extract PARAMS((int, int, const char *));
+
+/* Return the text of the history event beginning at the current
+ offset into STRING. Pass STRING with *INDEX equal to the
+ history_expansion_char that begins this specification.
+ DELIMITING_QUOTE is a character that is allowed to end the string
+ specification for what to search for in addition to the normal
+ characters `:', ` ', `\t', `\n', and sometimes `?'. */
+RL_EXTERN char *get_history_event PARAMS((const char *, int *, int));
+
+/* Return an array of tokens, much as the shell might. The tokens are
+ parsed out of STRING. */
+RL_EXTERN char **history_tokenize PARAMS((const char *));
+
+/* Exported history variables. */
+RL_EXTERN int history_base;
+RL_EXTERN int history_length;
+RL_EXTERN int history_max_entries;
+RL_EXTERN char history_expansion_char;
+RL_EXTERN char history_subst_char;
+RL_EXTERN char *history_word_delimiters;
+RL_EXTERN char history_comment_char;
+RL_EXTERN char *history_no_expand_chars;
+RL_EXTERN char *history_search_delimiter_chars;
+RL_EXTERN int history_quotes_inhibit_expansion;
+
+/* Backwards compatibility */
+RL_EXTERN int max_input_history;
+
+/* If set, this function is called to decide whether or not a particular
+ history expansion should be treated as a special case for the calling
+ application and not expanded. */
+RL_EXTERN rl_linebuf_func_t *history_inhibit_expansion_function;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_HISTORY_H_ */
diff --git a/MSVC/readline/histsearch.c b/MSVC/readline/histsearch.c
index fc522fa..5077e63 100644
--- a/MSVC/readline/histsearch.c
+++ b/MSVC/readline/histsearch.c
@@ -1,193 +1,193 @@
-/* histsearch.c -- searching the history list. */
-
-/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
-
- This file contains the GNU History Library (the Library), a set of
- routines for managing the text of previously typed lines.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <stdio.h>
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_UNISTD_H)
-# ifdef _MINIX
-# include <sys/types.h>
-# endif
-# include <unistd.h>
-#endif
-
-#include "history.h"
-#include "histlib.h"
-
-/* The list of alternate characters that can delimit a history search
- string. */
-char *history_search_delimiter_chars = (char *)NULL;
-
-static int history_search_internal PARAMS((const char *, int, int));
-
-/* Search the history for STRING, starting at history_offset.
- If DIRECTION < 0, then the search is through previous entries, else
- through subsequent. If ANCHORED is non-zero, the string must
- appear at the beginning of a history line, otherwise, the string
- may appear anywhere in the line. If the string is found, then
- current_history () is the history entry, and the value of this
- function is the offset in the line of that history entry that the
- string was found in. Otherwise, nothing is changed, and a -1 is
- returned. */
-
-static int
-history_search_internal (string, direction, anchored)
- const char *string;
- int direction, anchored;
-{
- register int i, reverse;
- register char *line;
- register int line_index;
- int string_len;
- HIST_ENTRY **the_history; /* local */
-
- i = history_offset;
- reverse = (direction < 0);
-
- /* Take care of trivial cases first. */
- if (string == 0 || *string == '\0')
- return (-1);
-
- if (!history_length || ((i == history_length) && !reverse))
- return (-1);
-
- if (reverse && (i == history_length))
- i--;
-
-#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)
-
- the_history = history_list ();
- string_len = strlen (string);
- while (1)
- {
- /* Search each line in the history list for STRING. */
-
- /* At limit for direction? */
- if ((reverse && i < 0) || (!reverse && i == history_length))
- return (-1);
-
- line = the_history[i]->line;
- line_index = strlen (line);
-
- /* If STRING is longer than line, no match. */
- if (string_len > line_index)
- {
- NEXT_LINE ();
- continue;
- }
-
- /* Handle anchored searches first. */
- if (anchored == ANCHORED_SEARCH)
- {
- if (STREQN (string, line, string_len))
- {
- history_offset = i;
- return (0);
- }
-
- NEXT_LINE ();
- continue;
- }
-
- /* Do substring search. */
- if (reverse)
- {
- line_index -= string_len;
-
- while (line_index >= 0)
- {
- if (STREQN (string, line + line_index, string_len))
- {
- history_offset = i;
- return (line_index);
- }
- line_index--;
- }
- }
- else
- {
- register int limit;
-
- limit = line_index - string_len + 1;
- line_index = 0;
-
- while (line_index < limit)
- {
- if (STREQN (string, line + line_index, string_len))
- {
- history_offset = i;
- return (line_index);
- }
- line_index++;
- }
- }
- NEXT_LINE ();
- }
-}
-
-/* Do a non-anchored search for STRING through the history in DIRECTION. */
-int
-history_search (string, direction)
- const char *string;
- int direction;
-{
- return (history_search_internal (string, direction, NON_ANCHORED_SEARCH));
-}
-
-/* Do an anchored search for string through the history in DIRECTION. */
-int
-history_search_prefix (string, direction)
- const char *string;
- int direction;
-{
- return (history_search_internal (string, direction, ANCHORED_SEARCH));
-}
-
-/* Search for STRING in the history list. DIR is < 0 for searching
- backwards. POS is an absolute index into the history list at
- which point to begin searching. */
-int
-history_search_pos (string, dir, pos)
- const char *string;
- int dir, pos;
-{
- int ret, old;
-
- old = where_history ();
- history_set_pos (pos);
- if (history_search (string, dir) == -1)
- {
- history_set_pos (old);
- return (-1);
- }
- ret = where_history ();
- history_set_pos (old);
- return ret;
-}
+/* histsearch.c -- searching the history list. */
+
+/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
+
+ This file contains the GNU History Library (the Library), a set of
+ routines for managing the text of previously typed lines.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <stdio.h>
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_UNISTD_H)
+# ifdef _MINIX
+# include <sys/types.h>
+# endif
+# include <unistd.h>
+#endif
+
+#include "history.h"
+#include "histlib.h"
+
+/* The list of alternate characters that can delimit a history search
+ string. */
+char *history_search_delimiter_chars = (char *)NULL;
+
+static int history_search_internal PARAMS((const char *, int, int));
+
+/* Search the history for STRING, starting at history_offset.
+ If DIRECTION < 0, then the search is through previous entries, else
+ through subsequent. If ANCHORED is non-zero, the string must
+ appear at the beginning of a history line, otherwise, the string
+ may appear anywhere in the line. If the string is found, then
+ current_history () is the history entry, and the value of this
+ function is the offset in the line of that history entry that the
+ string was found in. Otherwise, nothing is changed, and a -1 is
+ returned. */
+
+static int
+history_search_internal (string, direction, anchored)
+ const char *string;
+ int direction, anchored;
+{
+ register int i, reverse;
+ register char *line;
+ register int line_index;
+ int string_len;
+ HIST_ENTRY **the_history; /* local */
+
+ i = history_offset;
+ reverse = (direction < 0);
+
+ /* Take care of trivial cases first. */
+ if (string == 0 || *string == '\0')
+ return (-1);
+
+ if (!history_length || ((i == history_length) && !reverse))
+ return (-1);
+
+ if (reverse && (i == history_length))
+ i--;
+
+#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)
+
+ the_history = history_list ();
+ string_len = strlen (string);
+ while (1)
+ {
+ /* Search each line in the history list for STRING. */
+
+ /* At limit for direction? */
+ if ((reverse && i < 0) || (!reverse && i == history_length))
+ return (-1);
+
+ line = the_history[i]->line;
+ line_index = strlen (line);
+
+ /* If STRING is longer than line, no match. */
+ if (string_len > line_index)
+ {
+ NEXT_LINE ();
+ continue;
+ }
+
+ /* Handle anchored searches first. */
+ if (anchored == ANCHORED_SEARCH)
+ {
+ if (STREQN (string, line, string_len))
+ {
+ history_offset = i;
+ return (0);
+ }
+
+ NEXT_LINE ();
+ continue;
+ }
+
+ /* Do substring search. */
+ if (reverse)
+ {
+ line_index -= string_len;
+
+ while (line_index >= 0)
+ {
+ if (STREQN (string, line + line_index, string_len))
+ {
+ history_offset = i;
+ return (line_index);
+ }
+ line_index--;
+ }
+ }
+ else
+ {
+ register int limit;
+
+ limit = line_index - string_len + 1;
+ line_index = 0;
+
+ while (line_index < limit)
+ {
+ if (STREQN (string, line + line_index, string_len))
+ {
+ history_offset = i;
+ return (line_index);
+ }
+ line_index++;
+ }
+ }
+ NEXT_LINE ();
+ }
+}
+
+/* Do a non-anchored search for STRING through the history in DIRECTION. */
+int
+history_search (string, direction)
+ const char *string;
+ int direction;
+{
+ return (history_search_internal (string, direction, NON_ANCHORED_SEARCH));
+}
+
+/* Do an anchored search for string through the history in DIRECTION. */
+int
+history_search_prefix (string, direction)
+ const char *string;
+ int direction;
+{
+ return (history_search_internal (string, direction, ANCHORED_SEARCH));
+}
+
+/* Search for STRING in the history list. DIR is < 0 for searching
+ backwards. POS is an absolute index into the history list at
+ which point to begin searching. */
+int
+history_search_pos (string, dir, pos)
+ const char *string;
+ int dir, pos;
+{
+ int ret, old;
+
+ old = where_history ();
+ history_set_pos (pos);
+ if (history_search (string, dir) == -1)
+ {
+ history_set_pos (old);
+ return (-1);
+ }
+ ret = where_history ();
+ history_set_pos (old);
+ return ret;
+}
diff --git a/MSVC/readline/input.c b/MSVC/readline/input.c
index cc7b219..1822fdf 100644
--- a/MSVC/readline/input.c
+++ b/MSVC/readline/input.c
@@ -1,744 +1,744 @@
-/* input.c -- character input functions for readline. */
-
-/* Copyright (C) 1994 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <fcntl.h>
-#if defined (HAVE_SYS_FILE_H)
-# include <sys/file.h>
-#endif /* HAVE_SYS_FILE_H */
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_SELECT)
-# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)
-# if !defined _WIN32
-# include <sys/time.h>
-# endif
-# endif
-#endif /* HAVE_SELECT */
-#if defined (HAVE_SYS_SELECT_H)
-# include <sys/select.h>
-#endif
-
-#if defined (FIONREAD_IN_SYS_IOCTL)
-# include <sys/ioctl.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-
-#include "rlprivate.h"
-#include "rlshell.h"
-#include "xmalloc.h"
-
-/* What kind of non-blocking I/O do we have? */
-#if !defined (O_NDELAY) && defined (O_NONBLOCK)
-# define O_NDELAY O_NONBLOCK /* Posix style */
-#endif
-
-/* Non-null means it is a pointer to a function to run while waiting for
- character input. */
-rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL;
-
-rl_getc_func_t *rl_getc_function = rl_getc;
-
-static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */
-
-static int ibuffer_space PARAMS((void));
-static int rl_get_char PARAMS((int *));
-static int rl_gather_tyi PARAMS((void));
-
-/* **************************************************************** */
-/* */
-/* Character Input Buffering */
-/* */
-/* **************************************************************** */
-
-static int pop_index, push_index;
-static unsigned int ibuffer[512];
-static int ibuffer_len = sizeof ibuffer / sizeof ibuffer[0] - 1;
-
-#define any_typein (push_index != pop_index)
-
-int
-_rl_any_typein ()
-{
- return any_typein;
-}
-
-/* Return the amount of space available in the buffer for stuffing
- characters. */
-static int
-ibuffer_space ()
-{
- if (pop_index > push_index)
- return (pop_index - push_index - 1);
- else
- return (ibuffer_len - (push_index - pop_index));
-}
-
-/* Get a key from the buffer of characters to be read.
- Return the key in KEY.
- Result is KEY if there was a key, or 0 if there wasn't. */
-static int
-rl_get_char (key)
- int *key;
-{
- if (push_index == pop_index)
- return (0);
-
- *key = ibuffer[pop_index++];
-
- if (pop_index >= ibuffer_len)
- pop_index = 0;
-
- return (1);
-}
-
-/* Stuff KEY into the *front* of the input buffer.
- Returns non-zero if successful, zero if there is
- no space left in the buffer. */
-int
-_rl_unget_char (key)
- int key;
-{
- if (ibuffer_space ())
- {
- pop_index--;
- if (pop_index < 0)
- pop_index = ibuffer_len - 1;
- ibuffer[pop_index] = key;
- return (1);
- }
- return (0);
-}
-
-#if !defined _WIN32
-/* If a character is available to be read, then read it and stuff it into
- IBUFFER. Otherwise, just return. Returns number of characters read
- (0 if none available) and -1 on error (EIO). */
-static int
-rl_gather_tyi ()
-{
- int tty;
- register int tem, result;
- int chars_avail;
- char input;
-#if defined(HAVE_SELECT)
- fd_set readfds, exceptfds;
- struct timeval timeout;
-#endif
-
- tty = fileno (rl_instream);
-
-#if defined (HAVE_SELECT)
- FD_ZERO (&readfds);
- FD_ZERO (&exceptfds);
- FD_SET (tty, &readfds);
- FD_SET (tty, &exceptfds);
- timeout.tv_sec = 0;
- timeout.tv_usec = _keyboard_input_timeout;
- result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
- if (result <= 0)
- return 0; /* Nothing to read. */
-#endif
-
- result = -1;
-#if defined (FIONREAD)
- errno = 0;
- result = ioctl (tty, FIONREAD, &chars_avail);
- if (result == -1 && errno == EIO)
- return -1;
-#endif
-
-#if defined (O_NDELAY)
- if (result == -1)
- {
- tem = fcntl (tty, F_GETFL, 0);
-
- fcntl (tty, F_SETFL, (tem | O_NDELAY));
- chars_avail = read (tty, &input, 1);
-
- fcntl (tty, F_SETFL, tem);
- if (chars_avail == -1 && errno == EAGAIN)
- return 0;
- }
-#endif /* O_NDELAY */
-
- /* If there's nothing available, don't waste time trying to read
- something. */
- if (chars_avail <= 0)
- return 0;
-
- tem = ibuffer_space ();
-
- if (chars_avail > tem)
- chars_avail = tem;
-
- /* One cannot read all of the available input. I can only read a single
- character at a time, or else programs which require input can be
- thwarted. If the buffer is larger than one character, I lose.
- Damn! */
- if (tem < ibuffer_len)
- chars_avail = 0;
-
- if (result != -1)
- {
- while (chars_avail--)
- rl_stuff_char ((*rl_getc_function) (rl_instream));
- }
- else
- {
- if (chars_avail)
- rl_stuff_char (input);
- }
-
- return 1;
-}
-
-/* Is there input available to be read on the readline input file
- descriptor? Only works if the system has select(2) or FIONREAD.
- Uses the value of _keyboard_input_timeout as the timeout; if another
- readline function wants to specify a timeout and not leave it up to
- the user, it should use _rl_input_queued(timeout_value_in_microseconds)
- instead. */
-int
-_rl_input_available ()
-{
-#if defined(HAVE_SELECT)
- fd_set readfds, exceptfds;
- struct timeval timeout;
-#endif
-#if !defined (HAVE_SELECT) && defined(FIONREAD)
- int chars_avail;
-#endif
- int tty;
-
- tty = fileno (rl_instream);
-
-#if defined (HAVE_SELECT)
- FD_ZERO (&readfds);
- FD_ZERO (&exceptfds);
- FD_SET (tty, &readfds);
- FD_SET (tty, &exceptfds);
- timeout.tv_sec = 0;
- timeout.tv_usec = _keyboard_input_timeout;
- return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
-#else
-
-#if defined (FIONREAD)
- if (ioctl (tty, FIONREAD, &chars_avail) == 0)
- return (chars_avail);
-#endif
-
-#endif
- return 0;
-}
-#endif /* !_WIN32 */
-
-int
-rl_set_keyboard_input_timeout (u)
- int u;
-{
- int o;
-
- o = _keyboard_input_timeout;
- if (u > 0)
- _keyboard_input_timeout = u;
- return (o);
-}
-
-int
-_rl_input_queued (t)
- int t;
-{
- int old_timeout, r;
-
- old_timeout = rl_set_keyboard_input_timeout (t);
- r = _rl_input_available ();
- rl_set_keyboard_input_timeout (old_timeout);
- return r;
-}
-
-void
-_rl_insert_typein (c)
- int c;
-{
- int key, t, i;
- char *string;
-
- i = key = 0;
- string = (char *)xmalloc (ibuffer_len + 1);
- string[i++] = (char) c;
-
- while ((t = rl_get_char (&key)) &&
- _rl_keymap[key].type == ISFUNC &&
- _rl_keymap[key].function == rl_insert)
- string[i++] = key;
-
- if (t)
- _rl_unget_char (key);
-
- string[i] = '\0';
- rl_insert_text (string);
- free (string);
-}
-
-/* Add KEY to the buffer of characters to be read. Returns 1 if the
- character was stuffed correctly; 0 otherwise. */
-int
-rl_stuff_char (key)
- int key;
-{
- if (ibuffer_space () == 0)
- return 0;
-
- if (key == EOF)
- {
- key = NEWLINE;
- rl_pending_input = EOF;
- RL_SETSTATE (RL_STATE_INPUTPENDING);
- }
- ibuffer[push_index++] = key;
- if (push_index >= ibuffer_len)
- push_index = 0;
-
- return 1;
-}
-
-/* Make C be the next command to be executed. */
-int
-rl_execute_next (c)
- int c;
-{
- rl_pending_input = c;
- RL_SETSTATE (RL_STATE_INPUTPENDING);
- return 0;
-}
-
-/* Clear any pending input pushed with rl_execute_next() */
-int
-rl_clear_pending_input ()
-{
- rl_pending_input = 0;
- RL_UNSETSTATE (RL_STATE_INPUTPENDING);
- return 0;
-}
-
-/* **************************************************************** */
-/* */
-/* Character Input */
-/* */
-/* **************************************************************** */
-
-/* Read a key, including pending input. */
-int
-rl_read_key ()
-{
- int c;
-
- rl_key_sequence_length++;
-
- if (rl_pending_input)
- {
- c = rl_pending_input;
- rl_clear_pending_input ();
- }
- else
- {
- /* If input is coming from a macro, then use that. */
- if ( (c = _rl_next_macro_key ()) )
- return (c);
-
- /* If the user has an event function, then call it periodically. */
- if (rl_event_hook)
- {
- while (rl_event_hook && rl_get_char (&c) == 0)
- {
- (*rl_event_hook) ();
- if (rl_done) /* XXX - experimental */
- return ('\n');
- if (rl_gather_tyi () < 0) /* XXX - EIO */
- {
- rl_done = 1;
- return ('\n');
- }
- }
- }
- else
- {
- if (rl_get_char (&c) == 0)
- c = (*rl_getc_function) (rl_instream);
- }
- }
-
- return (c);
-}
-
-#if !defined _WIN32
-int
-rl_getc (stream)
- FILE *stream;
-{
- int result;
- unsigned char c;
-
- while (1)
- {
- result = read (fileno (stream), &c, sizeof (unsigned char));
-
- if (result == sizeof (unsigned char))
- return (c);
-
- /* If zero characters are returned, then the file that we are
- reading from is empty! Return EOF in that case. */
- if (result == 0)
- return (EOF);
-
-#if defined (__BEOS__)
- if (errno == EINTR)
- continue;
-#endif
-
-#if defined (EWOULDBLOCK)
-# define X_EWOULDBLOCK EWOULDBLOCK
-#else
-# define X_EWOULDBLOCK -99
-#endif
-
-#if defined (EAGAIN)
-# define X_EAGAIN EAGAIN
-#else
-# define X_EAGAIN -99
-#endif
-
- if (errno == X_EWOULDBLOCK || errno == X_EAGAIN)
- {
- if (sh_unset_nodelay_mode (fileno (stream)) < 0)
- return (EOF);
- continue;
- }
-
-#undef X_EWOULDBLOCK
-#undef X_EAGAIN
-
- /* If the error that we received was SIGINT, then try again,
- this is simply an interrupted system call to read ().
- Otherwise, some error ocurred, also signifying EOF. */
- if (errno != EINTR)
- return (EOF);
- }
-}
-
-#else
-
-#include <windows.h>
-#include <ctype.h>
-#include <conio.h>
-
-#define EXT_PREFIX 0x1f8
-
-#define KEV irec.Event.KeyEvent /* to make life easier */
-#define KST irec.Event.KeyEvent.dwControlKeyState
-
-
-static int pending_key = 0;
-static int pending_count = 0;
-static int pending_prefix = 0;
-
-extern int _rl_last_c_pos; /* imported from display.c */
-extern int _rl_last_v_pos;
-extern int rl_dispatching; /* imported from readline.c */
-extern int rl_point;
-extern int rl_done;
-extern int rl_visible_prompt_length;
-
-extern int haveConsole; /* imported from rltty.c */
-extern HANDLE hStdout, hStdin;
-#if defined (WITH_MINI_MOUSE)
- extern COORD rlScreenOrigin, rlScreenEnd;
- extern int rlScreenStart, rlScreenMax;
-
- static void MouseEventProc(MOUSE_EVENT_RECORD kev);
-#endif /* WITH_MINI_MOUSE */
-
-int rl_getc (stream)
- FILE *stream __attribute__((unused));
-{
- int key;
-
- if ( pending_count )
- {
- --pending_count;
- if ( pending_prefix && (pending_count & 1) )
- return pending_prefix;
- else
- return pending_key;
- }
-
- while ( 1 )
- {
- DWORD dummy;
-
- if (WaitForSingleObject(hStdin, WAIT_FOR_INPUT) != WAIT_OBJECT_0)
- {
- if ( rl_done )
- return( 0 );
- else
- continue;
- }
- if ( haveConsole & FOR_INPUT )
- {
- INPUT_RECORD irec;
- ReadConsoleInput(hStdin, &irec, 1, &dummy);
- switch(irec.EventType)
- {
- case KEY_EVENT:
- if ( KEV.bKeyDown
- && ((KEV.wVirtualKeyCode < VK_SHIFT) || (KEV.wVirtualKeyCode > VK_MENU)) )
- {
- int mask = 0;
-
- key = KEV.uChar.AsciiChar & 0xff;
- if ( KST & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED) )
- mask=0x100;
- if ( key )
- {
- /* Ascii direct */
- pending_count = KEV.wRepeatCount - 1;
- pending_key = key;
- pending_prefix = 0;
- if ( mask )
- key = tolower(key) | mask;
- }
- else
- /* Others prefixed */
- {
- key = EXT_PREFIX;
- if ( mask )
- key |= 4;
- if (KST & SHIFT_PRESSED)
- key |= 1;
- if (KST & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
- key |= 2;
- mask |= EXT_PREFIX;
- pending_count = (KEV.wRepeatCount << 1) - 1;
- pending_key = KEV.wVirtualKeyCode;
- pending_prefix = key;
- }
- return key;
- }
- break;
-#if defined (WITH_MINI_MOUSE)
- case MOUSE_EVENT:
- if ( (haveConsole & FOR_OUTPUT) && !rl_dispatching )
- MouseEventProc(irec.Event.MouseEvent);
-#endif /* WITH_MINI_MOUSE */
- default:
- break;
- }
- }
- else
- {
- ReadFile(hStdin, &key, 1, &dummy, NULL);
- return key;
- }
- }
-}
-
-#if defined (WITH_MINI_MOUSE)
-
-void MouseEventProc(MOUSE_EVENT_RECORD mev)
-{
- static DWORD lastButtonState, cstat_flags;
- static COORD lastButtonPos, src_down_pos;
-
-#define RLPOS_CHANGED 1
-#define SELECT_START 2
-
- switch (mev.dwEventFlags )
- {
- case 0 : /* change in button state */
-
- /* Cursor setting:
- LEFT_BUTTON_PRESSED sets cursor anywhere on the screen,
- thereafter, any change in button state will clipp the cursor
- position to the readline range if there has been no cursor
- movement. Otherwhise the cursor is reset to its old position.
- */
- if (mev.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
- {
- if (lastButtonState == 0)
- {
- src_down_pos = mev.dwMousePosition;
- cstat_flags |= RLPOS_CHANGED | SELECT_START;
- SetConsoleCursorPosition(hStdout, mev.dwMousePosition);
- }
- }
- else
- {
- if (cstat_flags & RLPOS_CHANGED)
- {
- if ( (mev.dwMousePosition.X == src_down_pos.X)
- && (mev.dwMousePosition.Y == src_down_pos.Y) )
- {
- int linear_pos = (int)mev.dwMousePosition.Y * _rl_screenwidth
- + (int)mev.dwMousePosition.X;
- if (linear_pos < rlScreenStart + rl_visible_prompt_length)
- {
- linear_pos = rlScreenStart + rl_visible_prompt_length;
- mev.dwMousePosition.X = rlScreenOrigin.X + rl_visible_prompt_length;
- mev.dwMousePosition.Y = rlScreenOrigin.Y;
- }
- if (linear_pos > rlScreenMax)
- {
- linear_pos = rlScreenMax;
- mev.dwMousePosition = rlScreenEnd;
- }
- rl_point = linear_pos - rlScreenStart - rl_visible_prompt_length;
- _rl_last_c_pos = mev.dwMousePosition.X - rlScreenOrigin.X;
- _rl_last_v_pos = mev.dwMousePosition.Y - rlScreenOrigin.Y;
- }
- else
- {
- mev.dwMousePosition.X = rlScreenOrigin.X + _rl_last_c_pos;
- mev.dwMousePosition.Y = rlScreenOrigin.Y + _rl_last_v_pos;
- }
- SetConsoleCursorPosition(hStdout, mev.dwMousePosition);
- cstat_flags &= !RLPOS_CHANGED;
- }
- }
- lastButtonState = mev.dwButtonState;
- lastButtonPos = mev.dwMousePosition;
- break;
- case MOUSE_MOVED: /* the most frequent event */
- default:
- break;
-
- }
-}
-#endif /* WITH_MINI_MOUSE */
-
-int _rl_input_available ()
-{
- return (kbhit());
-}
-
-static int rl_gather_tyi ()
-{
- rl_stuff_char ((*rl_getc_function) (rl_instream));
- return 0;
-}
-
-#endif /* _WIN32 */
-
-#if defined (HANDLE_MULTIBYTE)
-/* read multibyte char */
-int
-_rl_read_mbchar (mbchar, size)
- char *mbchar;
- int size;
-{
- int mb_len = 0;
- size_t mbchar_bytes_length;
- wchar_t wc;
- mbstate_t ps, ps_back;
-
- memset(&ps, 0, sizeof (mbstate_t));
- memset(&ps_back, 0, sizeof (mbstate_t));
-
- while (mb_len < size)
- {
- RL_SETSTATE(RL_STATE_MOREINPUT);
- mbchar[mb_len++] = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
- mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps);
- if (mbchar_bytes_length == (size_t)(-1))
- break; /* invalid byte sequence for the current locale */
- else if (mbchar_bytes_length == (size_t)(-2))
- {
- /* shorted bytes */
- ps = ps_back;
- continue;
- }
- else if (mbchar_bytes_length > (size_t)(0))
- break;
- }
-
- return mb_len;
-}
-
-/* Read a multibyte-character string whose first character is FIRST into
- the buffer MB of length MBLEN. Returns the last character read, which
- may be FIRST. Used by the search functions, among others. Very similar
- to _rl_read_mbchar. */
-int
-_rl_read_mbstring (first, mb, mblen)
- int first;
- char *mb;
- int mblen;
-{
- int i, c;
- mbstate_t ps;
-
- c = first;
- memset (mb, 0, mblen);
- for (i = 0; i < mblen; i++)
- {
- mb[i] = (char)c;
- memset (&ps, 0, sizeof (mbstate_t));
- if (_rl_get_char_len (mb, &ps) == -2)
- {
- /* Read more for multibyte character */
- RL_SETSTATE (RL_STATE_MOREINPUT);
- c = rl_read_key ();
- RL_UNSETSTATE (RL_STATE_MOREINPUT);
- }
- else
- break;
- }
- return c;
-}
-#endif /* HANDLE_MULTIBYTE */
+/* input.c -- character input functions for readline. */
+
+/* Copyright (C) 1994 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#if defined (HAVE_SYS_FILE_H)
+# include <sys/file.h>
+#endif /* HAVE_SYS_FILE_H */
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_SELECT)
+# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)
+# if !defined _WIN32
+# include <sys/time.h>
+# endif
+# endif
+#endif /* HAVE_SELECT */
+#if defined (HAVE_SYS_SELECT_H)
+# include <sys/select.h>
+#endif
+
+#if defined (FIONREAD_IN_SYS_IOCTL)
+# include <sys/ioctl.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+#include "rlmbutil.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+
+#include "rlprivate.h"
+#include "rlshell.h"
+#include "xmalloc.h"
+
+/* What kind of non-blocking I/O do we have? */
+#if !defined (O_NDELAY) && defined (O_NONBLOCK)
+# define O_NDELAY O_NONBLOCK /* Posix style */
+#endif
+
+/* Non-null means it is a pointer to a function to run while waiting for
+ character input. */
+rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL;
+
+rl_getc_func_t *rl_getc_function = rl_getc;
+
+static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */
+
+static int ibuffer_space PARAMS((void));
+static int rl_get_char PARAMS((int *));
+static int rl_gather_tyi PARAMS((void));
+
+/* **************************************************************** */
+/* */
+/* Character Input Buffering */
+/* */
+/* **************************************************************** */
+
+static int pop_index, push_index;
+static unsigned int ibuffer[512];
+static int ibuffer_len = sizeof ibuffer / sizeof ibuffer[0] - 1;
+
+#define any_typein (push_index != pop_index)
+
+int
+_rl_any_typein ()
+{
+ return any_typein;
+}
+
+/* Return the amount of space available in the buffer for stuffing
+ characters. */
+static int
+ibuffer_space ()
+{
+ if (pop_index > push_index)
+ return (pop_index - push_index - 1);
+ else
+ return (ibuffer_len - (push_index - pop_index));
+}
+
+/* Get a key from the buffer of characters to be read.
+ Return the key in KEY.
+ Result is KEY if there was a key, or 0 if there wasn't. */
+static int
+rl_get_char (key)
+ int *key;
+{
+ if (push_index == pop_index)
+ return (0);
+
+ *key = ibuffer[pop_index++];
+
+ if (pop_index >= ibuffer_len)
+ pop_index = 0;
+
+ return (1);
+}
+
+/* Stuff KEY into the *front* of the input buffer.
+ Returns non-zero if successful, zero if there is
+ no space left in the buffer. */
+int
+_rl_unget_char (key)
+ int key;
+{
+ if (ibuffer_space ())
+ {
+ pop_index--;
+ if (pop_index < 0)
+ pop_index = ibuffer_len - 1;
+ ibuffer[pop_index] = key;
+ return (1);
+ }
+ return (0);
+}
+
+#if !defined _WIN32
+/* If a character is available to be read, then read it and stuff it into
+ IBUFFER. Otherwise, just return. Returns number of characters read
+ (0 if none available) and -1 on error (EIO). */
+static int
+rl_gather_tyi ()
+{
+ int tty;
+ register int tem, result;
+ int chars_avail;
+ char input;
+#if defined(HAVE_SELECT)
+ fd_set readfds, exceptfds;
+ struct timeval timeout;
+#endif
+
+ tty = fileno (rl_instream);
+
+#if defined (HAVE_SELECT)
+ FD_ZERO (&readfds);
+ FD_ZERO (&exceptfds);
+ FD_SET (tty, &readfds);
+ FD_SET (tty, &exceptfds);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = _keyboard_input_timeout;
+ result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
+ if (result <= 0)
+ return 0; /* Nothing to read. */
+#endif
+
+ result = -1;
+#if defined (FIONREAD)
+ errno = 0;
+ result = ioctl (tty, FIONREAD, &chars_avail);
+ if (result == -1 && errno == EIO)
+ return -1;
+#endif
+
+#if defined (O_NDELAY)
+ if (result == -1)
+ {
+ tem = fcntl (tty, F_GETFL, 0);
+
+ fcntl (tty, F_SETFL, (tem | O_NDELAY));
+ chars_avail = read (tty, &input, 1);
+
+ fcntl (tty, F_SETFL, tem);
+ if (chars_avail == -1 && errno == EAGAIN)
+ return 0;
+ }
+#endif /* O_NDELAY */
+
+ /* If there's nothing available, don't waste time trying to read
+ something. */
+ if (chars_avail <= 0)
+ return 0;
+
+ tem = ibuffer_space ();
+
+ if (chars_avail > tem)
+ chars_avail = tem;
+
+ /* One cannot read all of the available input. I can only read a single
+ character at a time, or else programs which require input can be
+ thwarted. If the buffer is larger than one character, I lose.
+ Damn! */
+ if (tem < ibuffer_len)
+ chars_avail = 0;
+
+ if (result != -1)
+ {
+ while (chars_avail--)
+ rl_stuff_char ((*rl_getc_function) (rl_instream));
+ }
+ else
+ {
+ if (chars_avail)
+ rl_stuff_char (input);
+ }
+
+ return 1;
+}
+
+/* Is there input available to be read on the readline input file
+ descriptor? Only works if the system has select(2) or FIONREAD.
+ Uses the value of _keyboard_input_timeout as the timeout; if another
+ readline function wants to specify a timeout and not leave it up to
+ the user, it should use _rl_input_queued(timeout_value_in_microseconds)
+ instead. */
+int
+_rl_input_available ()
+{
+#if defined(HAVE_SELECT)
+ fd_set readfds, exceptfds;
+ struct timeval timeout;
+#endif
+#if !defined (HAVE_SELECT) && defined(FIONREAD)
+ int chars_avail;
+#endif
+ int tty;
+
+ tty = fileno (rl_instream);
+
+#if defined (HAVE_SELECT)
+ FD_ZERO (&readfds);
+ FD_ZERO (&exceptfds);
+ FD_SET (tty, &readfds);
+ FD_SET (tty, &exceptfds);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = _keyboard_input_timeout;
+ return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
+#else
+
+#if defined (FIONREAD)
+ if (ioctl (tty, FIONREAD, &chars_avail) == 0)
+ return (chars_avail);
+#endif
+
+#endif
+ return 0;
+}
+#endif /* !_WIN32 */
+
+int
+rl_set_keyboard_input_timeout (u)
+ int u;
+{
+ int o;
+
+ o = _keyboard_input_timeout;
+ if (u > 0)
+ _keyboard_input_timeout = u;
+ return (o);
+}
+
+int
+_rl_input_queued (t)
+ int t;
+{
+ int old_timeout, r;
+
+ old_timeout = rl_set_keyboard_input_timeout (t);
+ r = _rl_input_available ();
+ rl_set_keyboard_input_timeout (old_timeout);
+ return r;
+}
+
+void
+_rl_insert_typein (c)
+ int c;
+{
+ int key, t, i;
+ char *string;
+
+ i = key = 0;
+ string = (char *)xmalloc (ibuffer_len + 1);
+ string[i++] = (char) c;
+
+ while ((t = rl_get_char (&key)) &&
+ _rl_keymap[key].type == ISFUNC &&
+ _rl_keymap[key].function == rl_insert)
+ string[i++] = key;
+
+ if (t)
+ _rl_unget_char (key);
+
+ string[i] = '\0';
+ rl_insert_text (string);
+ free (string);
+}
+
+/* Add KEY to the buffer of characters to be read. Returns 1 if the
+ character was stuffed correctly; 0 otherwise. */
+int
+rl_stuff_char (key)
+ int key;
+{
+ if (ibuffer_space () == 0)
+ return 0;
+
+ if (key == EOF)
+ {
+ key = NEWLINE;
+ rl_pending_input = EOF;
+ RL_SETSTATE (RL_STATE_INPUTPENDING);
+ }
+ ibuffer[push_index++] = key;
+ if (push_index >= ibuffer_len)
+ push_index = 0;
+
+ return 1;
+}
+
+/* Make C be the next command to be executed. */
+int
+rl_execute_next (c)
+ int c;
+{
+ rl_pending_input = c;
+ RL_SETSTATE (RL_STATE_INPUTPENDING);
+ return 0;
+}
+
+/* Clear any pending input pushed with rl_execute_next() */
+int
+rl_clear_pending_input ()
+{
+ rl_pending_input = 0;
+ RL_UNSETSTATE (RL_STATE_INPUTPENDING);
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Character Input */
+/* */
+/* **************************************************************** */
+
+/* Read a key, including pending input. */
+int
+rl_read_key ()
+{
+ int c;
+
+ rl_key_sequence_length++;
+
+ if (rl_pending_input)
+ {
+ c = rl_pending_input;
+ rl_clear_pending_input ();
+ }
+ else
+ {
+ /* If input is coming from a macro, then use that. */
+ if ( (c = _rl_next_macro_key ()) )
+ return (c);
+
+ /* If the user has an event function, then call it periodically. */
+ if (rl_event_hook)
+ {
+ while (rl_event_hook && rl_get_char (&c) == 0)
+ {
+ (*rl_event_hook) ();
+ if (rl_done) /* XXX - experimental */
+ return ('\n');
+ if (rl_gather_tyi () < 0) /* XXX - EIO */
+ {
+ rl_done = 1;
+ return ('\n');
+ }
+ }
+ }
+ else
+ {
+ if (rl_get_char (&c) == 0)
+ c = (*rl_getc_function) (rl_instream);
+ }
+ }
+
+ return (c);
+}
+
+#if !defined _WIN32
+int
+rl_getc (stream)
+ FILE *stream;
+{
+ int result;
+ unsigned char c;
+
+ while (1)
+ {
+ result = read (fileno (stream), &c, sizeof (unsigned char));
+
+ if (result == sizeof (unsigned char))
+ return (c);
+
+ /* If zero characters are returned, then the file that we are
+ reading from is empty! Return EOF in that case. */
+ if (result == 0)
+ return (EOF);
+
+#if defined (__BEOS__)
+ if (errno == EINTR)
+ continue;
+#endif
+
+#if defined (EWOULDBLOCK)
+# define X_EWOULDBLOCK EWOULDBLOCK
+#else
+# define X_EWOULDBLOCK -99
+#endif
+
+#if defined (EAGAIN)
+# define X_EAGAIN EAGAIN
+#else
+# define X_EAGAIN -99
+#endif
+
+ if (errno == X_EWOULDBLOCK || errno == X_EAGAIN)
+ {
+ if (sh_unset_nodelay_mode (fileno (stream)) < 0)
+ return (EOF);
+ continue;
+ }
+
+#undef X_EWOULDBLOCK
+#undef X_EAGAIN
+
+ /* If the error that we received was SIGINT, then try again,
+ this is simply an interrupted system call to read ().
+ Otherwise, some error ocurred, also signifying EOF. */
+ if (errno != EINTR)
+ return (EOF);
+ }
+}
+
+#else
+
+#include <windows.h>
+#include <ctype.h>
+#include <conio.h>
+
+#define EXT_PREFIX 0x1f8
+
+#define KEV irec.Event.KeyEvent /* to make life easier */
+#define KST irec.Event.KeyEvent.dwControlKeyState
+
+
+static int pending_key = 0;
+static int pending_count = 0;
+static int pending_prefix = 0;
+
+extern int _rl_last_c_pos; /* imported from display.c */
+extern int _rl_last_v_pos;
+extern int rl_dispatching; /* imported from readline.c */
+extern int rl_point;
+extern int rl_done;
+extern int rl_visible_prompt_length;
+
+extern int haveConsole; /* imported from rltty.c */
+extern HANDLE hStdout, hStdin;
+#if defined (WITH_MINI_MOUSE)
+ extern COORD rlScreenOrigin, rlScreenEnd;
+ extern int rlScreenStart, rlScreenMax;
+
+ static void MouseEventProc(MOUSE_EVENT_RECORD kev);
+#endif /* WITH_MINI_MOUSE */
+
+int rl_getc (stream)
+ FILE *stream __attribute__((unused));
+{
+ int key;
+
+ if ( pending_count )
+ {
+ --pending_count;
+ if ( pending_prefix && (pending_count & 1) )
+ return pending_prefix;
+ else
+ return pending_key;
+ }
+
+ while ( 1 )
+ {
+ DWORD dummy;
+
+ if (WaitForSingleObject(hStdin, WAIT_FOR_INPUT) != WAIT_OBJECT_0)
+ {
+ if ( rl_done )
+ return( 0 );
+ else
+ continue;
+ }
+ if ( haveConsole & FOR_INPUT )
+ {
+ INPUT_RECORD irec;
+ ReadConsoleInput(hStdin, &irec, 1, &dummy);
+ switch(irec.EventType)
+ {
+ case KEY_EVENT:
+ if ( KEV.bKeyDown
+ && ((KEV.wVirtualKeyCode < VK_SHIFT) || (KEV.wVirtualKeyCode > VK_MENU)) )
+ {
+ int mask = 0;
+
+ key = KEV.uChar.AsciiChar & 0xff;
+ if ( KST & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED) )
+ mask=0x100;
+ if ( key )
+ {
+ /* Ascii direct */
+ pending_count = KEV.wRepeatCount - 1;
+ pending_key = key;
+ pending_prefix = 0;
+ if ( mask )
+ key = tolower(key) | mask;
+ }
+ else
+ /* Others prefixed */
+ {
+ key = EXT_PREFIX;
+ if ( mask )
+ key |= 4;
+ if (KST & SHIFT_PRESSED)
+ key |= 1;
+ if (KST & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
+ key |= 2;
+ mask |= EXT_PREFIX;
+ pending_count = (KEV.wRepeatCount << 1) - 1;
+ pending_key = KEV.wVirtualKeyCode;
+ pending_prefix = key;
+ }
+ return key;
+ }
+ break;
+#if defined (WITH_MINI_MOUSE)
+ case MOUSE_EVENT:
+ if ( (haveConsole & FOR_OUTPUT) && !rl_dispatching )
+ MouseEventProc(irec.Event.MouseEvent);
+#endif /* WITH_MINI_MOUSE */
+ default:
+ break;
+ }
+ }
+ else
+ {
+ ReadFile(hStdin, &key, 1, &dummy, NULL);
+ return key;
+ }
+ }
+}
+
+#if defined (WITH_MINI_MOUSE)
+
+void MouseEventProc(MOUSE_EVENT_RECORD mev)
+{
+ static DWORD lastButtonState, cstat_flags;
+ static COORD lastButtonPos, src_down_pos;
+
+#define RLPOS_CHANGED 1
+#define SELECT_START 2
+
+ switch (mev.dwEventFlags )
+ {
+ case 0 : /* change in button state */
+
+ /* Cursor setting:
+ LEFT_BUTTON_PRESSED sets cursor anywhere on the screen,
+ thereafter, any change in button state will clipp the cursor
+ position to the readline range if there has been no cursor
+ movement. Otherwhise the cursor is reset to its old position.
+ */
+ if (mev.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
+ {
+ if (lastButtonState == 0)
+ {
+ src_down_pos = mev.dwMousePosition;
+ cstat_flags |= RLPOS_CHANGED | SELECT_START;
+ SetConsoleCursorPosition(hStdout, mev.dwMousePosition);
+ }
+ }
+ else
+ {
+ if (cstat_flags & RLPOS_CHANGED)
+ {
+ if ( (mev.dwMousePosition.X == src_down_pos.X)
+ && (mev.dwMousePosition.Y == src_down_pos.Y) )
+ {
+ int linear_pos = (int)mev.dwMousePosition.Y * _rl_screenwidth
+ + (int)mev.dwMousePosition.X;
+ if (linear_pos < rlScreenStart + rl_visible_prompt_length)
+ {
+ linear_pos = rlScreenStart + rl_visible_prompt_length;
+ mev.dwMousePosition.X = rlScreenOrigin.X + rl_visible_prompt_length;
+ mev.dwMousePosition.Y = rlScreenOrigin.Y;
+ }
+ if (linear_pos > rlScreenMax)
+ {
+ linear_pos = rlScreenMax;
+ mev.dwMousePosition = rlScreenEnd;
+ }
+ rl_point = linear_pos - rlScreenStart - rl_visible_prompt_length;
+ _rl_last_c_pos = mev.dwMousePosition.X - rlScreenOrigin.X;
+ _rl_last_v_pos = mev.dwMousePosition.Y - rlScreenOrigin.Y;
+ }
+ else
+ {
+ mev.dwMousePosition.X = rlScreenOrigin.X + _rl_last_c_pos;
+ mev.dwMousePosition.Y = rlScreenOrigin.Y + _rl_last_v_pos;
+ }
+ SetConsoleCursorPosition(hStdout, mev.dwMousePosition);
+ cstat_flags &= !RLPOS_CHANGED;
+ }
+ }
+ lastButtonState = mev.dwButtonState;
+ lastButtonPos = mev.dwMousePosition;
+ break;
+ case MOUSE_MOVED: /* the most frequent event */
+ default:
+ break;
+
+ }
+}
+#endif /* WITH_MINI_MOUSE */
+
+int _rl_input_available ()
+{
+ return (kbhit());
+}
+
+static int rl_gather_tyi ()
+{
+ rl_stuff_char ((*rl_getc_function) (rl_instream));
+ return 0;
+}
+
+#endif /* _WIN32 */
+
+#if defined (HANDLE_MULTIBYTE)
+/* read multibyte char */
+int
+_rl_read_mbchar (mbchar, size)
+ char *mbchar;
+ int size;
+{
+ int mb_len = 0;
+ size_t mbchar_bytes_length;
+ wchar_t wc;
+ mbstate_t ps, ps_back;
+
+ memset(&ps, 0, sizeof (mbstate_t));
+ memset(&ps_back, 0, sizeof (mbstate_t));
+
+ while (mb_len < size)
+ {
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ mbchar[mb_len++] = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+ mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps);
+ if (mbchar_bytes_length == (size_t)(-1))
+ break; /* invalid byte sequence for the current locale */
+ else if (mbchar_bytes_length == (size_t)(-2))
+ {
+ /* shorted bytes */
+ ps = ps_back;
+ continue;
+ }
+ else if (mbchar_bytes_length > (size_t)(0))
+ break;
+ }
+
+ return mb_len;
+}
+
+/* Read a multibyte-character string whose first character is FIRST into
+ the buffer MB of length MBLEN. Returns the last character read, which
+ may be FIRST. Used by the search functions, among others. Very similar
+ to _rl_read_mbchar. */
+int
+_rl_read_mbstring (first, mb, mblen)
+ int first;
+ char *mb;
+ int mblen;
+{
+ int i, c;
+ mbstate_t ps;
+
+ c = first;
+ memset (mb, 0, mblen);
+ for (i = 0; i < mblen; i++)
+ {
+ mb[i] = (char)c;
+ memset (&ps, 0, sizeof (mbstate_t));
+ if (_rl_get_char_len (mb, &ps) == -2)
+ {
+ /* Read more for multibyte character */
+ RL_SETSTATE (RL_STATE_MOREINPUT);
+ c = rl_read_key ();
+ RL_UNSETSTATE (RL_STATE_MOREINPUT);
+ }
+ else
+ break;
+ }
+ return c;
+}
+#endif /* HANDLE_MULTIBYTE */
diff --git a/MSVC/readline/isearch.c b/MSVC/readline/isearch.c
index ebd03ce..a9d28bd 100644
--- a/MSVC/readline/isearch.c
+++ b/MSVC/readline/isearch.c
@@ -1,558 +1,558 @@
-/* **************************************************************** */
-/* */
-/* I-Search and Searching */
-/* */
-/* **************************************************************** */
-
-/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
-
- This file contains the Readline Library (the Library), a set of
- routines for providing Emacs style line input to programs that ask
- for it.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-
-#include <stdio.h>
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif
-
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-/* Variables exported to other files in the readline library. */
-char *_rl_isearch_terminators = (char *)NULL;
-
-/* Variables imported from other files in the readline library. */
-extern HIST_ENTRY *_rl_saved_line_for_history;
-
-/* Forward declarations */
-static int rl_search_history PARAMS((int, int));
-
-/* Last line found by the current incremental search, so we don't `find'
- identical lines many times in a row. */
-static char *prev_line_found;
-
-/* Last search string and its length. */
-static char *last_isearch_string;
-static int last_isearch_string_len;
-
-static char *default_isearch_terminators = "\033\012";
-
-/* Search backwards through the history looking for a string which is typed
- interactively. Start with the current line. */
-int
-rl_reverse_search_history (sign, key)
- int sign, key;
-{
- return (rl_search_history (-sign, key));
-}
-
-/* Search forwards through the history looking for a string which is typed
- interactively. Start with the current line. */
-int
-rl_forward_search_history (sign, key)
- int sign, key;
-{
- return (rl_search_history (sign, key));
-}
-
-/* Display the current state of the search in the echo-area.
- SEARCH_STRING contains the string that is being searched for,
- DIRECTION is zero for forward, or 1 for reverse,
- WHERE is the history list number of the current line. If it is
- -1, then this line is the starting one. */
-static void
-rl_display_search (search_string, reverse_p, where)
- char *search_string;
- int reverse_p, where;
-{
- char *message;
- int msglen, searchlen;
-
- searchlen = (search_string && *search_string) ? strlen (search_string) : 0;
-
- message = (char *)xmalloc (searchlen + 33);
- msglen = 0;
-
-#if defined (NOTDEF)
- if (where != -1)
- {
- sprintf (message, "[%d]", where + history_base);
- msglen = strlen (message);
- }
-#endif /* NOTDEF */
-
- message[msglen++] = '(';
-
- if (reverse_p)
- {
- strcpy (message + msglen, "reverse-");
- msglen += 8;
- }
-
- strcpy (message + msglen, "i-search)`");
- msglen += 10;
-
- if (search_string)
- {
- strcpy (message + msglen, search_string);
- msglen += searchlen;
- }
-
- strcpy (message + msglen, "': ");
-
- rl_message ("%s", message);
- free (message);
- (*rl_redisplay_function) ();
-}
-
-/* Search through the history looking for an interactively typed string.
- This is analogous to i-search. We start the search in the current line.
- DIRECTION is which direction to search; >= 0 means forward, < 0 means
- backwards. */
-static int
-rl_search_history (direction, invoking_key)
- int direction, invoking_key;
-{
- /* The string that the user types in to search for. */
- char *search_string;
-
- /* The current length of SEARCH_STRING. */
- int search_string_index;
-
- /* The amount of space that SEARCH_STRING has allocated to it. */
- int search_string_size;
-
- /* The list of lines to search through. */
- char **lines, *allocated_line;
-
- /* The length of LINES. */
- int hlen;
-
- /* Where we get LINES from. */
- HIST_ENTRY **hlist;
-
- register int i;
- int orig_point, orig_mark, orig_line, last_found_line;
- int c, found, failed, sline_len;
- int n, wstart, wlen;
-#if defined (HANDLE_MULTIBYTE)
- char mb[MB_LEN_MAX];
-#endif
-
- /* The line currently being searched. */
- char *sline;
-
- /* Offset in that line. */
- int line_index;
-
- /* Non-zero if we are doing a reverse search. */
- int reverse;
-
- /* The list of characters which terminate the search, but are not
- subsequently executed. If the variable isearch-terminators has
- been set, we use that value, otherwise we use ESC and C-J. */
- char *isearch_terminators;
-
- RL_SETSTATE(RL_STATE_ISEARCH);
- orig_point = rl_point;
- orig_mark = rl_mark;
- last_found_line = orig_line = where_history ();
- reverse = direction < 0;
- hlist = history_list ();
- allocated_line = (char *)NULL;
-
- isearch_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
- : default_isearch_terminators;
-
- /* Create an arrary of pointers to the lines that we want to search. */
- rl_maybe_replace_line ();
- i = 0;
- if (hlist)
- for (i = 0; hlist[i]; i++);
-
- /* Allocate space for this many lines, +1 for the current input line,
- and remember those lines. */
- lines = (char **)xmalloc ((1 + (hlen = i)) * sizeof (char *));
- for (i = 0; i < hlen; i++)
- lines[i] = hlist[i]->line;
-
- if (_rl_saved_line_for_history)
- lines[i] = _rl_saved_line_for_history->line;
- else
- {
- /* Keep track of this so we can free it. */
- allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
- strcpy (allocated_line, &rl_line_buffer[0]);
- lines[i] = allocated_line;
- }
-
- hlen++;
-
- /* The line where we start the search. */
- i = orig_line;
-
- rl_save_prompt ();
-
- /* Initialize search parameters. */
- search_string = (char *)xmalloc (search_string_size = 128);
- *search_string = '\0';
- search_string_index = 0;
- prev_line_found = (char *)0; /* XXX */
-
- /* Normalize DIRECTION into 1 or -1. */
- direction = (direction >= 0) ? 1 : -1;
-
- rl_display_search (search_string, reverse, -1);
-
- sline = rl_line_buffer;
- sline_len = strlen (sline);
- line_index = rl_point;
-
- found = failed = 0;
- for (;;)
- {
- rl_command_func_t *f = (rl_command_func_t *)NULL;
-
- /* Read a key and decide how to proceed. */
- RL_SETSTATE(RL_STATE_MOREINPUT);
- c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
-#endif
-
- /* Translate the keys we do something with to opcodes. */
- if (c >= 0 && _rl_keymap[c].type == ISFUNC)
- {
- f = _rl_keymap[c].function;
-
- if (f == rl_reverse_search_history)
- c = reverse ? -1 : -2;
- else if (f == rl_forward_search_history)
- c = !reverse ? -1 : -2;
- else if (f == rl_rubout)
- c = -3;
- else if (c == CTRL ('G'))
- c = -4;
- else if (c == CTRL ('W')) /* XXX */
- c = -5;
- else if (c == CTRL ('Y')) /* XXX */
- c = -6;
- }
-
- /* The characters in isearch_terminators (set from the user-settable
- variable isearch-terminators) are used to terminate the search but
- not subsequently execute the character as a command. The default
- value is "\033\012" (ESC and C-J). */
- if (strchr (isearch_terminators, c))
- {
- /* ESC still terminates the search, but if there is pending
- input or if input arrives within 0.1 seconds (on systems
- with select(2)) it is used as a prefix character
- with rl_execute_next. WATCH OUT FOR THIS! This is intended
- to allow the arrow keys to be used like ^F and ^B are used
- to terminate the search and execute the movement command.
- XXX - since _rl_input_available depends on the application-
- settable keyboard timeout value, this could alternatively
- use _rl_input_queued(100000) */
- if (c == ESC && _rl_input_available ())
- rl_execute_next (ESC);
- break;
- }
-
-#define ENDSRCH_CHAR(c) \
- ((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G')))
-
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- if (c >= 0 && strlen (mb) == 1 && ENDSRCH_CHAR (c))
- {
- /* This sets rl_pending_input to c; it will be picked up the next
- time rl_read_key is called. */
- rl_execute_next (c);
- break;
- }
- }
- else
-#endif
- if (c >= 0 && ENDSRCH_CHAR (c))
- {
- /* This sets rl_pending_input to c; it will be picked up the next
- time rl_read_key is called. */
- rl_execute_next (c);
- break;
- }
-
- switch (c)
- {
- case -1:
- if (search_string_index == 0)
- {
- if (last_isearch_string)
- {
- search_string_size = 64 + last_isearch_string_len;
- search_string = (char *)xrealloc (search_string, search_string_size);
- strcpy (search_string, last_isearch_string);
- search_string_index = last_isearch_string_len;
- rl_display_search (search_string, reverse, -1);
- break;
- }
- continue;
- }
- else if (reverse)
- --line_index;
- else if (line_index != sline_len)
- ++line_index;
- else
- rl_ding ();
- break;
-
- /* switch directions */
- case -2:
- direction = -direction;
- reverse = direction < 0;
- break;
-
- /* delete character from search string. */
- case -3: /* C-H, DEL */
- /* This is tricky. To do this right, we need to keep a
- stack of search positions for the current search, with
- sentinels marking the beginning and end. But this will
- do until we have a real isearch-undo. */
- if (search_string_index == 0)
- rl_ding ();
- else
- search_string[--search_string_index] = '\0';
-
- break;
-
- case -4: /* C-G */
- rl_replace_line (lines[orig_line], 0);
- rl_point = orig_point;
- rl_mark = orig_mark;
- rl_restore_prompt();
- rl_clear_message ();
- if (allocated_line)
- free (allocated_line);
- free (lines);
- RL_UNSETSTATE(RL_STATE_ISEARCH);
- return 0;
-
- case -5: /* C-W */
- /* skip over portion of line we already matched */
- wstart = rl_point + search_string_index;
- if (wstart >= rl_end)
- {
- rl_ding ();
- break;
- }
-
- /* if not in a word, move to one. */
- if (rl_alphabetic(rl_line_buffer[wstart]) == 0)
- {
- rl_ding ();
- break;
- }
- n = wstart;
- while (n < rl_end && rl_alphabetic(rl_line_buffer[n]))
- n++;
- wlen = n - wstart + 1;
- if (search_string_index + wlen + 1 >= search_string_size)
- {
- search_string_size += wlen + 1;
- search_string = (char *)xrealloc (search_string, search_string_size);
- }
- for (; wstart < n; wstart++)
- search_string[search_string_index++] = rl_line_buffer[wstart];
- search_string[search_string_index] = '\0';
- break;
-
- case -6: /* C-Y */
- /* skip over portion of line we already matched */
- wstart = rl_point + search_string_index;
- if (wstart >= rl_end)
- {
- rl_ding ();
- break;
- }
- n = rl_end - wstart + 1;
- if (search_string_index + n + 1 >= search_string_size)
- {
- search_string_size += n + 1;
- search_string = (char *)xrealloc (search_string, search_string_size);
- }
- for (n = wstart; n < rl_end; n++)
- search_string[search_string_index++] = rl_line_buffer[n];
- search_string[search_string_index] = '\0';
- break;
-
- default:
- /* Add character to search string and continue search. */
- if (search_string_index + 2 >= search_string_size)
- {
- search_string_size += 128;
- search_string = (char *)xrealloc (search_string, search_string_size);
- }
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- int j, l;
- for (j = 0, l = strlen (mb); j < l; )
- search_string[search_string_index++] = mb[j++];
- }
- else
-#endif
- search_string[search_string_index++] = c;
- search_string[search_string_index] = '\0';
- break;
- }
-
- for (found = failed = 0;;)
- {
- int limit = sline_len - search_string_index + 1;
-
- /* Search the current line. */
- while (reverse ? (line_index >= 0) : (line_index < limit))
- {
- if (STREQN (search_string, sline + line_index, search_string_index))
- {
- found++;
- break;
- }
- else
- line_index += direction;
- }
- if (found)
- break;
-
- /* Move to the next line, but skip new copies of the line
- we just found and lines shorter than the string we're
- searching for. */
- do
- {
- /* Move to the next line. */
- i += direction;
-
- /* At limit for direction? */
- if (reverse ? (i < 0) : (i == hlen))
- {
- failed++;
- break;
- }
-
- /* We will need these later. */
- sline = lines[i];
- sline_len = strlen (sline);
- }
- while ((prev_line_found && STREQ (prev_line_found, lines[i])) ||
- (search_string_index > sline_len));
-
- if (failed)
- break;
-
- /* Now set up the line for searching... */
- line_index = reverse ? sline_len - search_string_index : 0;
- }
-
- if (failed)
- {
- /* We cannot find the search string. Ding the bell. */
- rl_ding ();
- i = last_found_line;
- continue; /* XXX - was break */
- }
-
- /* We have found the search string. Just display it. But don't
- actually move there in the history list until the user accepts
- the location. */
- if (found)
- {
- prev_line_found = lines[i];
- rl_replace_line (lines[i], 0);
- rl_point = line_index;
- last_found_line = i;
- rl_display_search (search_string, reverse, (i == orig_line) ? -1 : i);
- }
- }
-
- /* The searching is over. The user may have found the string that she
- was looking for, or else she may have exited a failing search. If
- LINE_INDEX is -1, then that shows that the string searched for was
- not found. We use this to determine where to place rl_point. */
-
- /* First put back the original state. */
- strcpy (rl_line_buffer, lines[orig_line]);
-
- rl_restore_prompt ();
-
- /* Save the search string for possible later use. */
- FREE (last_isearch_string);
- last_isearch_string = search_string;
- last_isearch_string_len = search_string_index;
-
- if (last_found_line < orig_line)
- rl_get_previous_history (orig_line - last_found_line, 0);
- else
- rl_get_next_history (last_found_line - orig_line, 0);
-
- /* If the string was not found, put point at the end of the last matching
- line. If last_found_line == orig_line, we didn't find any matching
- history lines at all, so put point back in its original position. */
- if (line_index < 0)
- {
- if (last_found_line == orig_line)
- line_index = orig_point;
- else
- line_index = strlen (rl_line_buffer);
- rl_mark = orig_mark;
- }
-
- rl_point = line_index;
- /* Don't worry about where to put the mark here; rl_get_previous_history
- and rl_get_next_history take care of it. */
-
- rl_clear_message ();
-
- FREE (allocated_line);
- free (lines);
-
- RL_UNSETSTATE(RL_STATE_ISEARCH);
-
- return 0;
-}
+/* **************************************************************** */
+/* */
+/* I-Search and Searching */
+/* */
+/* **************************************************************** */
+
+/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
+
+ This file contains the Readline Library (the Library), a set of
+ routines for providing Emacs style line input to programs that ask
+ for it.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif
+
+#include "rldefs.h"
+#include "rlmbutil.h"
+
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "xmalloc.h"
+
+/* Variables exported to other files in the readline library. */
+char *_rl_isearch_terminators = (char *)NULL;
+
+/* Variables imported from other files in the readline library. */
+extern HIST_ENTRY *_rl_saved_line_for_history;
+
+/* Forward declarations */
+static int rl_search_history PARAMS((int, int));
+
+/* Last line found by the current incremental search, so we don't `find'
+ identical lines many times in a row. */
+static char *prev_line_found;
+
+/* Last search string and its length. */
+static char *last_isearch_string;
+static int last_isearch_string_len;
+
+static char *default_isearch_terminators = "\033\012";
+
+/* Search backwards through the history looking for a string which is typed
+ interactively. Start with the current line. */
+int
+rl_reverse_search_history (sign, key)
+ int sign, key;
+{
+ return (rl_search_history (-sign, key));
+}
+
+/* Search forwards through the history looking for a string which is typed
+ interactively. Start with the current line. */
+int
+rl_forward_search_history (sign, key)
+ int sign, key;
+{
+ return (rl_search_history (sign, key));
+}
+
+/* Display the current state of the search in the echo-area.
+ SEARCH_STRING contains the string that is being searched for,
+ DIRECTION is zero for forward, or 1 for reverse,
+ WHERE is the history list number of the current line. If it is
+ -1, then this line is the starting one. */
+static void
+rl_display_search (search_string, reverse_p, where)
+ char *search_string;
+ int reverse_p, where;
+{
+ char *message;
+ int msglen, searchlen;
+
+ searchlen = (search_string && *search_string) ? strlen (search_string) : 0;
+
+ message = (char *)xmalloc (searchlen + 33);
+ msglen = 0;
+
+#if defined (NOTDEF)
+ if (where != -1)
+ {
+ sprintf (message, "[%d]", where + history_base);
+ msglen = strlen (message);
+ }
+#endif /* NOTDEF */
+
+ message[msglen++] = '(';
+
+ if (reverse_p)
+ {
+ strcpy (message + msglen, "reverse-");
+ msglen += 8;
+ }
+
+ strcpy (message + msglen, "i-search)`");
+ msglen += 10;
+
+ if (search_string)
+ {
+ strcpy (message + msglen, search_string);
+ msglen += searchlen;
+ }
+
+ strcpy (message + msglen, "': ");
+
+ rl_message ("%s", message);
+ free (message);
+ (*rl_redisplay_function) ();
+}
+
+/* Search through the history looking for an interactively typed string.
+ This is analogous to i-search. We start the search in the current line.
+ DIRECTION is which direction to search; >= 0 means forward, < 0 means
+ backwards. */
+static int
+rl_search_history (direction, invoking_key)
+ int direction, invoking_key;
+{
+ /* The string that the user types in to search for. */
+ char *search_string;
+
+ /* The current length of SEARCH_STRING. */
+ int search_string_index;
+
+ /* The amount of space that SEARCH_STRING has allocated to it. */
+ int search_string_size;
+
+ /* The list of lines to search through. */
+ char **lines, *allocated_line;
+
+ /* The length of LINES. */
+ int hlen;
+
+ /* Where we get LINES from. */
+ HIST_ENTRY **hlist;
+
+ register int i;
+ int orig_point, orig_mark, orig_line, last_found_line;
+ int c, found, failed, sline_len;
+ int n, wstart, wlen;
+#if defined (HANDLE_MULTIBYTE)
+ char mb[MB_LEN_MAX];
+#endif
+
+ /* The line currently being searched. */
+ char *sline;
+
+ /* Offset in that line. */
+ int line_index;
+
+ /* Non-zero if we are doing a reverse search. */
+ int reverse;
+
+ /* The list of characters which terminate the search, but are not
+ subsequently executed. If the variable isearch-terminators has
+ been set, we use that value, otherwise we use ESC and C-J. */
+ char *isearch_terminators;
+
+ RL_SETSTATE(RL_STATE_ISEARCH);
+ orig_point = rl_point;
+ orig_mark = rl_mark;
+ last_found_line = orig_line = where_history ();
+ reverse = direction < 0;
+ hlist = history_list ();
+ allocated_line = (char *)NULL;
+
+ isearch_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
+ : default_isearch_terminators;
+
+ /* Create an arrary of pointers to the lines that we want to search. */
+ rl_maybe_replace_line ();
+ i = 0;
+ if (hlist)
+ for (i = 0; hlist[i]; i++);
+
+ /* Allocate space for this many lines, +1 for the current input line,
+ and remember those lines. */
+ lines = (char **)xmalloc ((1 + (hlen = i)) * sizeof (char *));
+ for (i = 0; i < hlen; i++)
+ lines[i] = hlist[i]->line;
+
+ if (_rl_saved_line_for_history)
+ lines[i] = _rl_saved_line_for_history->line;
+ else
+ {
+ /* Keep track of this so we can free it. */
+ allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
+ strcpy (allocated_line, &rl_line_buffer[0]);
+ lines[i] = allocated_line;
+ }
+
+ hlen++;
+
+ /* The line where we start the search. */
+ i = orig_line;
+
+ rl_save_prompt ();
+
+ /* Initialize search parameters. */
+ search_string = (char *)xmalloc (search_string_size = 128);
+ *search_string = '\0';
+ search_string_index = 0;
+ prev_line_found = (char *)0; /* XXX */
+
+ /* Normalize DIRECTION into 1 or -1. */
+ direction = (direction >= 0) ? 1 : -1;
+
+ rl_display_search (search_string, reverse, -1);
+
+ sline = rl_line_buffer;
+ sline_len = strlen (sline);
+ line_index = rl_point;
+
+ found = failed = 0;
+ for (;;)
+ {
+ rl_command_func_t *f = (rl_command_func_t *)NULL;
+
+ /* Read a key and decide how to proceed. */
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
+#endif
+
+ /* Translate the keys we do something with to opcodes. */
+ if (c >= 0 && _rl_keymap[c].type == ISFUNC)
+ {
+ f = _rl_keymap[c].function;
+
+ if (f == rl_reverse_search_history)
+ c = reverse ? -1 : -2;
+ else if (f == rl_forward_search_history)
+ c = !reverse ? -1 : -2;
+ else if (f == rl_rubout)
+ c = -3;
+ else if (c == CTRL ('G'))
+ c = -4;
+ else if (c == CTRL ('W')) /* XXX */
+ c = -5;
+ else if (c == CTRL ('Y')) /* XXX */
+ c = -6;
+ }
+
+ /* The characters in isearch_terminators (set from the user-settable
+ variable isearch-terminators) are used to terminate the search but
+ not subsequently execute the character as a command. The default
+ value is "\033\012" (ESC and C-J). */
+ if (strchr (isearch_terminators, c))
+ {
+ /* ESC still terminates the search, but if there is pending
+ input or if input arrives within 0.1 seconds (on systems
+ with select(2)) it is used as a prefix character
+ with rl_execute_next. WATCH OUT FOR THIS! This is intended
+ to allow the arrow keys to be used like ^F and ^B are used
+ to terminate the search and execute the movement command.
+ XXX - since _rl_input_available depends on the application-
+ settable keyboard timeout value, this could alternatively
+ use _rl_input_queued(100000) */
+ if (c == ESC && _rl_input_available ())
+ rl_execute_next (ESC);
+ break;
+ }
+
+#define ENDSRCH_CHAR(c) \
+ ((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G')))
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ if (c >= 0 && strlen (mb) == 1 && ENDSRCH_CHAR (c))
+ {
+ /* This sets rl_pending_input to c; it will be picked up the next
+ time rl_read_key is called. */
+ rl_execute_next (c);
+ break;
+ }
+ }
+ else
+#endif
+ if (c >= 0 && ENDSRCH_CHAR (c))
+ {
+ /* This sets rl_pending_input to c; it will be picked up the next
+ time rl_read_key is called. */
+ rl_execute_next (c);
+ break;
+ }
+
+ switch (c)
+ {
+ case -1:
+ if (search_string_index == 0)
+ {
+ if (last_isearch_string)
+ {
+ search_string_size = 64 + last_isearch_string_len;
+ search_string = (char *)xrealloc (search_string, search_string_size);
+ strcpy (search_string, last_isearch_string);
+ search_string_index = last_isearch_string_len;
+ rl_display_search (search_string, reverse, -1);
+ break;
+ }
+ continue;
+ }
+ else if (reverse)
+ --line_index;
+ else if (line_index != sline_len)
+ ++line_index;
+ else
+ rl_ding ();
+ break;
+
+ /* switch directions */
+ case -2:
+ direction = -direction;
+ reverse = direction < 0;
+ break;
+
+ /* delete character from search string. */
+ case -3: /* C-H, DEL */
+ /* This is tricky. To do this right, we need to keep a
+ stack of search positions for the current search, with
+ sentinels marking the beginning and end. But this will
+ do until we have a real isearch-undo. */
+ if (search_string_index == 0)
+ rl_ding ();
+ else
+ search_string[--search_string_index] = '\0';
+
+ break;
+
+ case -4: /* C-G */
+ rl_replace_line (lines[orig_line], 0);
+ rl_point = orig_point;
+ rl_mark = orig_mark;
+ rl_restore_prompt();
+ rl_clear_message ();
+ if (allocated_line)
+ free (allocated_line);
+ free (lines);
+ RL_UNSETSTATE(RL_STATE_ISEARCH);
+ return 0;
+
+ case -5: /* C-W */
+ /* skip over portion of line we already matched */
+ wstart = rl_point + search_string_index;
+ if (wstart >= rl_end)
+ {
+ rl_ding ();
+ break;
+ }
+
+ /* if not in a word, move to one. */
+ if (rl_alphabetic(rl_line_buffer[wstart]) == 0)
+ {
+ rl_ding ();
+ break;
+ }
+ n = wstart;
+ while (n < rl_end && rl_alphabetic(rl_line_buffer[n]))
+ n++;
+ wlen = n - wstart + 1;
+ if (search_string_index + wlen + 1 >= search_string_size)
+ {
+ search_string_size += wlen + 1;
+ search_string = (char *)xrealloc (search_string, search_string_size);
+ }
+ for (; wstart < n; wstart++)
+ search_string[search_string_index++] = rl_line_buffer[wstart];
+ search_string[search_string_index] = '\0';
+ break;
+
+ case -6: /* C-Y */
+ /* skip over portion of line we already matched */
+ wstart = rl_point + search_string_index;
+ if (wstart >= rl_end)
+ {
+ rl_ding ();
+ break;
+ }
+ n = rl_end - wstart + 1;
+ if (search_string_index + n + 1 >= search_string_size)
+ {
+ search_string_size += n + 1;
+ search_string = (char *)xrealloc (search_string, search_string_size);
+ }
+ for (n = wstart; n < rl_end; n++)
+ search_string[search_string_index++] = rl_line_buffer[n];
+ search_string[search_string_index] = '\0';
+ break;
+
+ default:
+ /* Add character to search string and continue search. */
+ if (search_string_index + 2 >= search_string_size)
+ {
+ search_string_size += 128;
+ search_string = (char *)xrealloc (search_string, search_string_size);
+ }
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ int j, l;
+ for (j = 0, l = strlen (mb); j < l; )
+ search_string[search_string_index++] = mb[j++];
+ }
+ else
+#endif
+ search_string[search_string_index++] = c;
+ search_string[search_string_index] = '\0';
+ break;
+ }
+
+ for (found = failed = 0;;)
+ {
+ int limit = sline_len - search_string_index + 1;
+
+ /* Search the current line. */
+ while (reverse ? (line_index >= 0) : (line_index < limit))
+ {
+ if (STREQN (search_string, sline + line_index, search_string_index))
+ {
+ found++;
+ break;
+ }
+ else
+ line_index += direction;
+ }
+ if (found)
+ break;
+
+ /* Move to the next line, but skip new copies of the line
+ we just found and lines shorter than the string we're
+ searching for. */
+ do
+ {
+ /* Move to the next line. */
+ i += direction;
+
+ /* At limit for direction? */
+ if (reverse ? (i < 0) : (i == hlen))
+ {
+ failed++;
+ break;
+ }
+
+ /* We will need these later. */
+ sline = lines[i];
+ sline_len = strlen (sline);
+ }
+ while ((prev_line_found && STREQ (prev_line_found, lines[i])) ||
+ (search_string_index > sline_len));
+
+ if (failed)
+ break;
+
+ /* Now set up the line for searching... */
+ line_index = reverse ? sline_len - search_string_index : 0;
+ }
+
+ if (failed)
+ {
+ /* We cannot find the search string. Ding the bell. */
+ rl_ding ();
+ i = last_found_line;
+ continue; /* XXX - was break */
+ }
+
+ /* We have found the search string. Just display it. But don't
+ actually move there in the history list until the user accepts
+ the location. */
+ if (found)
+ {
+ prev_line_found = lines[i];
+ rl_replace_line (lines[i], 0);
+ rl_point = line_index;
+ last_found_line = i;
+ rl_display_search (search_string, reverse, (i == orig_line) ? -1 : i);
+ }
+ }
+
+ /* The searching is over. The user may have found the string that she
+ was looking for, or else she may have exited a failing search. If
+ LINE_INDEX is -1, then that shows that the string searched for was
+ not found. We use this to determine where to place rl_point. */
+
+ /* First put back the original state. */
+ strcpy (rl_line_buffer, lines[orig_line]);
+
+ rl_restore_prompt ();
+
+ /* Save the search string for possible later use. */
+ FREE (last_isearch_string);
+ last_isearch_string = search_string;
+ last_isearch_string_len = search_string_index;
+
+ if (last_found_line < orig_line)
+ rl_get_previous_history (orig_line - last_found_line, 0);
+ else
+ rl_get_next_history (last_found_line - orig_line, 0);
+
+ /* If the string was not found, put point at the end of the last matching
+ line. If last_found_line == orig_line, we didn't find any matching
+ history lines at all, so put point back in its original position. */
+ if (line_index < 0)
+ {
+ if (last_found_line == orig_line)
+ line_index = orig_point;
+ else
+ line_index = strlen (rl_line_buffer);
+ rl_mark = orig_mark;
+ }
+
+ rl_point = line_index;
+ /* Don't worry about where to put the mark here; rl_get_previous_history
+ and rl_get_next_history take care of it. */
+
+ rl_clear_message ();
+
+ FREE (allocated_line);
+ free (lines);
+
+ RL_UNSETSTATE(RL_STATE_ISEARCH);
+
+ return 0;
+}
diff --git a/MSVC/readline/keymaps.c b/MSVC/readline/keymaps.c
index 10f7b4b..e16f150 100644
--- a/MSVC/readline/keymaps.c
+++ b/MSVC/readline/keymaps.c
@@ -1,148 +1,148 @@
-/* keymaps.c -- Functions and keymaps for the GNU Readline library. */
-
-/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
-
- This file is part of GNU Readline, a library for reading lines
- of text with interactive input and history editing.
-
- Readline 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, or (at your option) any
- later version.
-
- Readline 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 Readline; see the file COPYING. If not, write to the Free
- Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h> /* for FILE * definition for readline.h */
-
-#include "readline.h"
-#include "rlconf.h"
-
-#include "emacs_keymap.c"
-
-#if defined (VI_MODE)
-#include "vi_keymap.c"
-#endif
-
-#include "xmalloc.h"
-
-/* **************************************************************** */
-/* */
-/* Functions for manipulating Keymaps. */
-/* */
-/* **************************************************************** */
-
-
-/* Return a new, empty keymap.
- Free it with free() when you are done. */
-Keymap
-rl_make_bare_keymap ()
-{
- register int i;
- Keymap keymap = (Keymap)xmalloc (KEYMAP_SIZE * sizeof (KEYMAP_ENTRY));
-
- for (i = 0; i < KEYMAP_SIZE; i++)
- {
- keymap[i].type = ISFUNC;
- keymap[i].function = (rl_command_func_t *)NULL;
- }
-
- for (i = 'A'; i < ('Z' + 1); i++)
- {
- keymap[i].type = ISFUNC;
- keymap[i].function = rl_do_lowercase_version;
- }
-
- return (keymap);
-}
-
-/* Return a new keymap which is a copy of MAP. */
-Keymap
-rl_copy_keymap (map)
- Keymap map;
-{
- register int i;
- Keymap temp = rl_make_bare_keymap ();
-
- for (i = 0; i < KEYMAP_SIZE; i++)
- {
- temp[i].type = map[i].type;
- temp[i].function = map[i].function;
- }
- return (temp);
-}
-
-/* Return a new keymap with the printing characters bound to rl_insert,
- the uppercase Meta characters bound to run their lowercase equivalents,
- and the Meta digits bound to produce numeric arguments. */
-Keymap
-rl_make_keymap ()
-{
- register int i;
- Keymap newmap;
-
- newmap = rl_make_bare_keymap ();
-
- /* All ASCII printing characters are self-inserting. */
- for (i = ' '; i < 127; i++)
- newmap[i].function = rl_insert;
-
- newmap[TAB].function = rl_insert;
- newmap[RUBOUT].function = rl_rubout; /* RUBOUT == 127 */
- newmap[CTRL('H')].function = rl_rubout;
-
-#if KEYMAP_SIZE > 128
- /* Printing characters in some 8-bit character sets. */
- for (i = 128; i < 160; i++)
- newmap[i].function = rl_insert;
-
- /* ISO Latin-1 printing characters should self-insert. */
- for (i = 160; i < 256; i++)
- newmap[i].function = rl_insert;
-#endif /* KEYMAP_SIZE > 128 */
-
- return (newmap);
-}
-
-/* Free the storage associated with MAP. */
-void
-rl_discard_keymap (map)
- Keymap map;
-{
- int i;
-
- if (!map)
- return;
-
- for (i = 0; i < KEYMAP_SIZE; i++)
- {
- switch (map[i].type)
- {
- case ISFUNC:
- break;
-
- case ISKMAP:
- rl_discard_keymap ((Keymap)map[i].function);
- break;
-
- case ISMACR:
- free ((char *)map[i].function);
- break;
- }
- }
-}
+/* keymaps.c -- Functions and keymaps for the GNU Readline library. */
+
+/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
+
+ This file is part of GNU Readline, a library for reading lines
+ of text with interactive input and history editing.
+
+ Readline 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, or (at your option) any
+ later version.
+
+ Readline 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 Readline; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <stdio.h> /* for FILE * definition for readline.h */
+
+#include "readline.h"
+#include "rlconf.h"
+
+#include "emacs_keymap.c"
+
+#if defined (VI_MODE)
+#include "vi_keymap.c"
+#endif
+
+#include "xmalloc.h"
+
+/* **************************************************************** */
+/* */
+/* Functions for manipulating Keymaps. */
+/* */
+/* **************************************************************** */
+
+
+/* Return a new, empty keymap.
+ Free it with free() when you are done. */
+Keymap
+rl_make_bare_keymap ()
+{
+ register int i;
+ Keymap keymap = (Keymap)xmalloc (KEYMAP_SIZE * sizeof (KEYMAP_ENTRY));
+
+ for (i = 0; i < KEYMAP_SIZE; i++)
+ {
+ keymap[i].type = ISFUNC;
+ keymap[i].function = (rl_command_func_t *)NULL;
+ }
+
+ for (i = 'A'; i < ('Z' + 1); i++)
+ {
+ keymap[i].type = ISFUNC;
+ keymap[i].function = rl_do_lowercase_version;
+ }
+
+ return (keymap);
+}
+
+/* Return a new keymap which is a copy of MAP. */
+Keymap
+rl_copy_keymap (map)
+ Keymap map;
+{
+ register int i;
+ Keymap temp = rl_make_bare_keymap ();
+
+ for (i = 0; i < KEYMAP_SIZE; i++)
+ {
+ temp[i].type = map[i].type;
+ temp[i].function = map[i].function;
+ }
+ return (temp);
+}
+
+/* Return a new keymap with the printing characters bound to rl_insert,
+ the uppercase Meta characters bound to run their lowercase equivalents,
+ and the Meta digits bound to produce numeric arguments. */
+Keymap
+rl_make_keymap ()
+{
+ register int i;
+ Keymap newmap;
+
+ newmap = rl_make_bare_keymap ();
+
+ /* All ASCII printing characters are self-inserting. */
+ for (i = ' '; i < 127; i++)
+ newmap[i].function = rl_insert;
+
+ newmap[TAB].function = rl_insert;
+ newmap[RUBOUT].function = rl_rubout; /* RUBOUT == 127 */
+ newmap[CTRL('H')].function = rl_rubout;
+
+#if KEYMAP_SIZE > 128
+ /* Printing characters in some 8-bit character sets. */
+ for (i = 128; i < 160; i++)
+ newmap[i].function = rl_insert;
+
+ /* ISO Latin-1 printing characters should self-insert. */
+ for (i = 160; i < 256; i++)
+ newmap[i].function = rl_insert;
+#endif /* KEYMAP_SIZE > 128 */
+
+ return (newmap);
+}
+
+/* Free the storage associated with MAP. */
+void
+rl_discard_keymap (map)
+ Keymap map;
+{
+ int i;
+
+ if (!map)
+ return;
+
+ for (i = 0; i < KEYMAP_SIZE; i++)
+ {
+ switch (map[i].type)
+ {
+ case ISFUNC:
+ break;
+
+ case ISKMAP:
+ rl_discard_keymap ((Keymap)map[i].function);
+ break;
+
+ case ISMACR:
+ free ((char *)map[i].function);
+ break;
+ }
+ }
+}
diff --git a/MSVC/readline/keymaps.h b/MSVC/readline/keymaps.h
index c256881..d5c950c 100644
--- a/MSVC/readline/keymaps.h
+++ b/MSVC/readline/keymaps.h
@@ -1,108 +1,108 @@
-/* keymaps.h -- Manipulation of readline keymaps. */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#ifndef _KEYMAPS_H_
-#define _KEYMAPS_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined (READLINE_LIBRARY)
-# include "rlstdc.h"
-# include "chardefs.h"
-# include "rltypedefs.h"
-#else
-# include <readline/rlstdc.h>
-# include <readline/chardefs.h>
-# include <readline/rltypedefs.h>
-#endif
-
-#include "rldynlink.h" /* for export / import macros */
-
-/* A keymap contains one entry for each key in the ASCII set.
- Each entry consists of a type and a pointer.
- FUNCTION is the address of a function to run, or the
- address of a keymap to indirect through.
- TYPE says which kind of thing FUNCTION is. */
-typedef struct _keymap_entry {
- char type;
- rl_command_func_t *function;
-} KEYMAP_ENTRY;
-
-/* This must be large enough to hold bindings for all of the characters
- in a desired character set (e.g, 128 for ASCII, 256 for ISO Latin-x,
- and so on) plus one for subsequence matching. */
-#define KEYMAP_SIZE 257
-#define ANYOTHERKEY KEYMAP_SIZE-1
-
-/* I wanted to make the above structure contain a union of:
- union { rl_command_func_t *function; struct _keymap_entry *keymap; } value;
- but this made it impossible for me to create a static array.
- Maybe I need C lessons. */
-
-typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE];
-typedef KEYMAP_ENTRY *Keymap;
-
-/* The values that TYPE can have in a keymap entry. */
-#define ISFUNC 0
-#define ISKMAP 1
-#define ISMACR 2
-
-RL_EXTERN KEYMAP_ENTRY_ARRAY emacs_standard_keymap;
-RL_EXTERN KEYMAP_ENTRY_ARRAY emacs_meta_keymap;
-RL_EXTERN KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap;
-RL_EXTERN KEYMAP_ENTRY_ARRAY vi_insertion_keymap;
-RL_EXTERN KEYMAP_ENTRY_ARRAY vi_movement_keymap;
-
-/* Return a new, empty keymap.
- Free it with free() when you are done. */
-RL_EXTERN Keymap rl_make_bare_keymap PARAMS((void));
-
-/* Return a new keymap which is a copy of MAP. */
-RL_EXTERN Keymap rl_copy_keymap PARAMS((Keymap));
-
-/* Return a new keymap with the printing characters bound to rl_insert,
- the lowercase Meta characters bound to run their equivalents, and
- the Meta digits bound to produce numeric arguments. */
-RL_EXTERN Keymap rl_make_keymap PARAMS((void));
-
-/* Free the storage associated with a keymap. */
-RL_EXTERN void rl_discard_keymap PARAMS((Keymap));
-
-/* These functions actually appear in bind.c */
-
-/* Return the keymap corresponding to a given name. Names look like
- `emacs' or `emacs-meta' or `vi-insert'. */
-RL_EXTERN Keymap rl_get_keymap_by_name PARAMS((const char *));
-
-/* Return the current keymap. */
-RL_EXTERN Keymap rl_get_keymap PARAMS((void));
-
-/* Set the current keymap to MAP. */
-RL_EXTERN void rl_set_keymap PARAMS((Keymap));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _KEYMAPS_H_ */
+/* keymaps.h -- Manipulation of readline keymaps. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#ifndef _KEYMAPS_H_
+#define _KEYMAPS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined (READLINE_LIBRARY)
+# include "rlstdc.h"
+# include "chardefs.h"
+# include "rltypedefs.h"
+#else
+# include <readline/rlstdc.h>
+# include <readline/chardefs.h>
+# include <readline/rltypedefs.h>
+#endif
+
+#include "rldynlink.h" /* for export / import macros */
+
+/* A keymap contains one entry for each key in the ASCII set.
+ Each entry consists of a type and a pointer.
+ FUNCTION is the address of a function to run, or the
+ address of a keymap to indirect through.
+ TYPE says which kind of thing FUNCTION is. */
+typedef struct _keymap_entry {
+ char type;
+ rl_command_func_t *function;
+} KEYMAP_ENTRY;
+
+/* This must be large enough to hold bindings for all of the characters
+ in a desired character set (e.g, 128 for ASCII, 256 for ISO Latin-x,
+ and so on) plus one for subsequence matching. */
+#define KEYMAP_SIZE 257
+#define ANYOTHERKEY KEYMAP_SIZE-1
+
+/* I wanted to make the above structure contain a union of:
+ union { rl_command_func_t *function; struct _keymap_entry *keymap; } value;
+ but this made it impossible for me to create a static array.
+ Maybe I need C lessons. */
+
+typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE];
+typedef KEYMAP_ENTRY *Keymap;
+
+/* The values that TYPE can have in a keymap entry. */
+#define ISFUNC 0
+#define ISKMAP 1
+#define ISMACR 2
+
+RL_EXTERN KEYMAP_ENTRY_ARRAY emacs_standard_keymap;
+RL_EXTERN KEYMAP_ENTRY_ARRAY emacs_meta_keymap;
+RL_EXTERN KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap;
+RL_EXTERN KEYMAP_ENTRY_ARRAY vi_insertion_keymap;
+RL_EXTERN KEYMAP_ENTRY_ARRAY vi_movement_keymap;
+
+/* Return a new, empty keymap.
+ Free it with free() when you are done. */
+RL_EXTERN Keymap rl_make_bare_keymap PARAMS((void));
+
+/* Return a new keymap which is a copy of MAP. */
+RL_EXTERN Keymap rl_copy_keymap PARAMS((Keymap));
+
+/* Return a new keymap with the printing characters bound to rl_insert,
+ the lowercase Meta characters bound to run their equivalents, and
+ the Meta digits bound to produce numeric arguments. */
+RL_EXTERN Keymap rl_make_keymap PARAMS((void));
+
+/* Free the storage associated with a keymap. */
+RL_EXTERN void rl_discard_keymap PARAMS((Keymap));
+
+/* These functions actually appear in bind.c */
+
+/* Return the keymap corresponding to a given name. Names look like
+ `emacs' or `emacs-meta' or `vi-insert'. */
+RL_EXTERN Keymap rl_get_keymap_by_name PARAMS((const char *));
+
+/* Return the current keymap. */
+RL_EXTERN Keymap rl_get_keymap PARAMS((void));
+
+/* Set the current keymap to MAP. */
+RL_EXTERN void rl_set_keymap PARAMS((Keymap));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KEYMAPS_H_ */
diff --git a/MSVC/readline/kill.c b/MSVC/readline/kill.c
index 87e13fe..4dc3b16 100644
--- a/MSVC/readline/kill.c
+++ b/MSVC/readline/kill.c
@@ -1,650 +1,650 @@
-/* kill.c -- kill ring management. */
-
-/* Copyright (C) 1994 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h> /* for _POSIX_VERSION */
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-/* **************************************************************** */
-/* */
-/* Killing Mechanism */
-/* */
-/* **************************************************************** */
-
-/* What we assume for a max number of kills. */
-#define DEFAULT_MAX_KILLS 10
-
-/* The real variable to look at to find out when to flush kills. */
-static int rl_max_kills = DEFAULT_MAX_KILLS;
-
-/* Where to store killed text. */
-static char **rl_kill_ring = (char **)NULL;
-
-/* Where we are in the kill ring. */
-static int rl_kill_index;
-
-/* How many slots we have in the kill ring. */
-static int rl_kill_ring_length;
-
-static int _rl_copy_to_kill_ring PARAMS((char *, int));
-static int region_kill_internal PARAMS((int));
-static int _rl_copy_word_as_kill PARAMS((int, int));
-static int rl_yank_nth_arg_internal PARAMS((int, int, int));
-
-/* How to say that you only want to save a certain amount
- of kill material. */
-int
-rl_set_retained_kills (num)
- int num;
-{
- return 0;
-}
-
-/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
- This uses TEXT directly, so the caller must not free it. If APPEND is
- non-zero, and the last command was a kill, the text is appended to the
- current kill ring slot, otherwise prepended. */
-static int
-_rl_copy_to_kill_ring (text, append)
- char *text;
- int append;
-{
- char *old, *new;
- int slot;
-
- /* First, find the slot to work with. */
- if (_rl_last_command_was_kill == 0)
- {
- /* Get a new slot. */
- if (rl_kill_ring == 0)
- {
- /* If we don't have any defined, then make one. */
- rl_kill_ring = (char **)
- xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
- rl_kill_ring[slot = 0] = (char *)NULL;
- }
- else
- {
- /* We have to add a new slot on the end, unless we have
- exceeded the max limit for remembering kills. */
- slot = rl_kill_ring_length;
- if (slot == rl_max_kills)
- {
- register int i;
- free (rl_kill_ring[0]);
- for (i = 0; i < slot; i++)
- rl_kill_ring[i] = rl_kill_ring[i + 1];
- }
- else
- {
- slot = rl_kill_ring_length += 1;
- rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
- }
- rl_kill_ring[--slot] = (char *)NULL;
- }
- }
- else
- slot = rl_kill_ring_length - 1;
-
- /* If the last command was a kill, prepend or append. */
- if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
- {
- old = rl_kill_ring[slot];
- new = (char *)xmalloc (1 + strlen (old) + strlen (text));
-
- if (append)
- {
- strcpy (new, old);
- strcat (new, text);
- }
- else
- {
- strcpy (new, text);
- strcat (new, old);
- }
- free (old);
- free (text);
- rl_kill_ring[slot] = new;
- }
- else
- rl_kill_ring[slot] = text;
-
- rl_kill_index = slot;
- return 0;
-}
-
-/* The way to kill something. This appends or prepends to the last
- kill, if the last command was a kill command. if FROM is less
- than TO, then the text is appended, otherwise prepended. If the
- last command was not a kill command, then a new slot is made for
- this kill. */
-int
-rl_kill_text (from, to)
- int from, to;
-{
- char *text;
-
- /* Is there anything to kill? */
- if (from == to)
- {
- _rl_last_command_was_kill++;
- return 0;
- }
-
- text = rl_copy_text (from, to);
-
- /* Delete the copied text from the line. */
- rl_delete_text (from, to);
-
- _rl_copy_to_kill_ring (text, from < to);
-
- _rl_last_command_was_kill++;
- return 0;
-}
-
-/* Now REMEMBER! In order to do prepending or appending correctly, kill
- commands always make rl_point's original position be the FROM argument,
- and rl_point's extent be the TO argument. */
-
-/* **************************************************************** */
-/* */
-/* Killing Commands */
-/* */
-/* **************************************************************** */
-
-/* Delete the word at point, saving the text in the kill ring. */
-int
-rl_kill_word (count, key)
- int count, key;
-{
- int orig_point;
-
- if (count < 0)
- return (rl_backward_kill_word (-count, key));
- else
- {
- orig_point = rl_point;
- rl_forward_word (count, key);
-
- if (rl_point != orig_point)
- rl_kill_text (orig_point, rl_point);
-
- rl_point = orig_point;
- if (rl_editing_mode == emacs_mode)
- rl_mark = rl_point;
- }
- return 0;
-}
-
-/* Rubout the word before point, placing it on the kill ring. */
-int
-rl_backward_kill_word (count, ignore)
- int count, ignore;
-{
- int orig_point;
-
- if (count < 0)
- return (rl_kill_word (-count, ignore));
- else
- {
- orig_point = rl_point;
- rl_backward_word (count, ignore);
-
- if (rl_point != orig_point)
- rl_kill_text (orig_point, rl_point);
-
- if (rl_editing_mode == emacs_mode)
- rl_mark = rl_point;
- }
- return 0;
-}
-
-/* Kill from here to the end of the line. If DIRECTION is negative, kill
- back to the line start instead. */
-int
-rl_kill_line (direction, ignore)
- int direction, ignore;
-{
- int orig_point;
-
- if (direction < 0)
- return (rl_backward_kill_line (1, ignore));
- else
- {
- orig_point = rl_point;
- rl_end_of_line (1, ignore);
- if (orig_point != rl_point)
- rl_kill_text (orig_point, rl_point);
- rl_point = orig_point;
- if (rl_editing_mode == emacs_mode)
- rl_mark = rl_point;
- }
- return 0;
-}
-
-/* Kill backwards to the start of the line. If DIRECTION is negative, kill
- forwards to the line end instead. */
-int
-rl_backward_kill_line (direction, ignore)
- int direction, ignore;
-{
- int orig_point;
-
- if (direction < 0)
- return (rl_kill_line (1, ignore));
- else
- {
- if (!rl_point)
- rl_ding ();
- else
- {
- orig_point = rl_point;
- rl_beg_of_line (1, ignore);
- if (rl_point != orig_point)
- rl_kill_text (orig_point, rl_point);
- if (rl_editing_mode == emacs_mode)
- rl_mark = rl_point;
- }
- }
- return 0;
-}
-
-/* Kill the whole line, no matter where point is. */
-int
-rl_kill_full_line (count, ignore)
- int count, ignore;
-{
- rl_begin_undo_group ();
- rl_point = 0;
- rl_kill_text (rl_point, rl_end);
- rl_mark = 0;
- rl_end_undo_group ();
- return 0;
-}
-
-/* The next two functions mimic unix line editing behaviour, except they
- save the deleted text on the kill ring. This is safer than not saving
- it, and since we have a ring, nobody should get screwed. */
-
-/* This does what C-w does in Unix. We can't prevent people from
- using behaviour that they expect. */
-int
-rl_unix_word_rubout (count, key)
- int count, key;
-{
- int orig_point;
-
- if (rl_point == 0)
- rl_ding ();
- else
- {
- orig_point = rl_point;
- if (count <= 0)
- count = 1;
-
- while (count--)
- {
- while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
- rl_point--;
-
- while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
- rl_point--;
- }
-
- rl_kill_text (orig_point, rl_point);
- if (rl_editing_mode == emacs_mode)
- rl_mark = rl_point;
- }
- return 0;
-}
-
-/* Here is C-u doing what Unix does. You don't *have* to use these
- key-bindings. We have a choice of killing the entire line, or
- killing from where we are to the start of the line. We choose the
- latter, because if you are a Unix weenie, then you haven't backspaced
- into the line at all, and if you aren't, then you know what you are
- doing. */
-int
-rl_unix_line_discard (count, key)
- int count, key;
-{
- if (rl_point == 0)
- rl_ding ();
- else
- {
- rl_kill_text (rl_point, 0);
- rl_point = 0;
- if (rl_editing_mode == emacs_mode)
- rl_mark = rl_point;
- }
- return 0;
-}
-
-/* Copy the text in the `region' to the kill ring. If DELETE is non-zero,
- delete the text from the line as well. */
-static int
-region_kill_internal (delete)
- int delete;
-{
- char *text;
-
- if (rl_mark != rl_point)
- {
- text = rl_copy_text (rl_point, rl_mark);
- if (delete)
- rl_delete_text (rl_point, rl_mark);
- _rl_copy_to_kill_ring (text, rl_point < rl_mark);
- }
-
- _rl_last_command_was_kill++;
- return 0;
-}
-
-/* Copy the text in the region to the kill ring. */
-int
-rl_copy_region_to_kill (count, ignore)
- int count, ignore;
-{
- return (region_kill_internal (0));
-}
-
-/* Kill the text between the point and mark. */
-int
-rl_kill_region (count, ignore)
- int count, ignore;
-{
- int r, npoint;
-
- npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
- r = region_kill_internal (1);
- _rl_fix_point (1);
- rl_point = npoint;
- return r;
-}
-
-/* Copy COUNT words to the kill ring. DIR says which direction we look
- to find the words. */
-static int
-_rl_copy_word_as_kill (count, dir)
- int count, dir;
-{
- int om, op, r;
-
- om = rl_mark;
- op = rl_point;
-
- if (dir > 0)
- rl_forward_word (count, 0);
- else
- rl_backward_word (count, 0);
-
- rl_mark = rl_point;
-
- if (dir > 0)
- rl_backward_word (count, 0);
- else
- rl_forward_word (count, 0);
-
- r = region_kill_internal (0);
-
- rl_mark = om;
- rl_point = op;
-
- return r;
-}
-
-int
-rl_copy_forward_word (count, key)
- int count, key;
-{
- if (count < 0)
- return (rl_copy_backward_word (-count, key));
-
- return (_rl_copy_word_as_kill (count, 1));
-}
-
-int
-rl_copy_backward_word (count, key)
- int count, key;
-{
- if (count < 0)
- return (rl_copy_forward_word (-count, key));
-
- return (_rl_copy_word_as_kill (count, -1));
-}
-
-/* Yank back the last killed text. This ignores arguments. */
-int
-rl_yank (count, ignore)
- int count, ignore;
-{
- if (rl_kill_ring == 0)
- {
- _rl_abort_internal ();
- return -1;
- }
-
- _rl_set_mark_at_pos (rl_point);
- rl_insert_text (rl_kill_ring[rl_kill_index]);
- return 0;
-}
-
-/* If the last command was yank, or yank_pop, and the text just
- before point is identical to the current kill item, then
- delete that text from the line, rotate the index down, and
- yank back some other text. */
-int
-rl_yank_pop (count, key)
- int count, key;
-{
- int l, n;
-
- if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
- !rl_kill_ring)
- {
- _rl_abort_internal ();
- return -1;
- }
-
- l = strlen (rl_kill_ring[rl_kill_index]);
- n = rl_point - l;
- if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
- {
- rl_delete_text (n, rl_point);
- rl_point = n;
- rl_kill_index--;
- if (rl_kill_index < 0)
- rl_kill_index = rl_kill_ring_length - 1;
- rl_yank (1, 0);
- return 0;
- }
- else
- {
- _rl_abort_internal ();
- return -1;
- }
-}
-
-/* Yank the COUNTh argument from the previous history line, skipping
- HISTORY_SKIP lines before looking for the `previous line'. */
-static int
-rl_yank_nth_arg_internal (count, ignore, history_skip)
- int count, ignore, history_skip;
-{
- register HIST_ENTRY *entry;
- char *arg;
- int i, pos;
-
- pos = where_history ();
-
- if (history_skip)
- {
- for (i = 0; i < history_skip; i++)
- entry = previous_history ();
- }
-
- entry = previous_history ();
-
- history_set_pos (pos);
-
- if (entry == 0)
- {
- rl_ding ();
- return -1;
- }
-
- arg = history_arg_extract (count, count, entry->line);
- if (!arg || !*arg)
- {
- rl_ding ();
- return -1;
- }
-
- rl_begin_undo_group ();
-
- _rl_set_mark_at_pos (rl_point);
-
-#if defined (VI_MODE)
- /* Vi mode always inserts a space before yanking the argument, and it
- inserts it right *after* rl_point. */
- if (rl_editing_mode == vi_mode)
- {
- rl_vi_append_mode (1, ignore);
- rl_insert_text (" ");
- }
-#endif /* VI_MODE */
-
- rl_insert_text (arg);
- free (arg);
-
- rl_end_undo_group ();
- return 0;
-}
-
-/* Yank the COUNTth argument from the previous history line. */
-int
-rl_yank_nth_arg (count, ignore)
- int count, ignore;
-{
- return (rl_yank_nth_arg_internal (count, ignore, 0));
-}
-
-/* Yank the last argument from the previous history line. This `knows'
- how rl_yank_nth_arg treats a count of `$'. With an argument, this
- behaves the same as rl_yank_nth_arg. */
-int
-rl_yank_last_arg (count, key)
- int count, key;
-{
- static int history_skip = 0;
- static int explicit_arg_p = 0;
- static int count_passed = 1;
- static int direction = 1;
- static int undo_needed = 0;
- int retval;
-
- if (rl_last_func != rl_yank_last_arg)
- {
- history_skip = 0;
- explicit_arg_p = rl_explicit_arg;
- count_passed = count;
- direction = 1;
- }
- else
- {
- if (undo_needed)
- rl_do_undo ();
- if (count < 1)
- direction = -direction;
- history_skip += direction;
- if (history_skip < 0)
- history_skip = 0;
- }
-
- if (explicit_arg_p)
- retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
- else
- retval = rl_yank_nth_arg_internal ('$', key, history_skip);
-
- undo_needed = retval == 0;
- return retval;
-}
-
-/* A special paste command for users of Cygnus's cygwin32. */
-#if defined __CYGWIN__ || defined _WIN32
-#include <windows.h>
-
-int
-rl_paste_from_clipboard (count, key)
- int count, key;
-{
- char *data, *ptr;
- int len;
-
- if (OpenClipboard (NULL) == 0)
- return (0);
-
- data = (char *)GetClipboardData (CF_TEXT);
- if (data)
- {
- ptr = strchr (data, '\r');
- if (ptr)
- {
- len = ptr - data;
- ptr = (char *)xmalloc (len + 1);
- ptr[len] = '\0';
- strncpy (ptr, data, len);
- }
- else
- ptr = data;
- _rl_set_mark_at_pos (rl_point);
- rl_insert_text (ptr);
- if (ptr != data)
- free (ptr);
- CloseClipboard ();
- }
- return (0);
-}
-#endif /* __CYGWIN__ */
+/* kill.c -- kill ring management. */
+
+/* Copyright (C) 1994 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h> /* for _POSIX_VERSION */
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <stdio.h>
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "xmalloc.h"
+
+/* **************************************************************** */
+/* */
+/* Killing Mechanism */
+/* */
+/* **************************************************************** */
+
+/* What we assume for a max number of kills. */
+#define DEFAULT_MAX_KILLS 10
+
+/* The real variable to look at to find out when to flush kills. */
+static int rl_max_kills = DEFAULT_MAX_KILLS;
+
+/* Where to store killed text. */
+static char **rl_kill_ring = (char **)NULL;
+
+/* Where we are in the kill ring. */
+static int rl_kill_index;
+
+/* How many slots we have in the kill ring. */
+static int rl_kill_ring_length;
+
+static int _rl_copy_to_kill_ring PARAMS((char *, int));
+static int region_kill_internal PARAMS((int));
+static int _rl_copy_word_as_kill PARAMS((int, int));
+static int rl_yank_nth_arg_internal PARAMS((int, int, int));
+
+/* How to say that you only want to save a certain amount
+ of kill material. */
+int
+rl_set_retained_kills (num)
+ int num;
+{
+ return 0;
+}
+
+/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
+ This uses TEXT directly, so the caller must not free it. If APPEND is
+ non-zero, and the last command was a kill, the text is appended to the
+ current kill ring slot, otherwise prepended. */
+static int
+_rl_copy_to_kill_ring (text, append)
+ char *text;
+ int append;
+{
+ char *old, *new;
+ int slot;
+
+ /* First, find the slot to work with. */
+ if (_rl_last_command_was_kill == 0)
+ {
+ /* Get a new slot. */
+ if (rl_kill_ring == 0)
+ {
+ /* If we don't have any defined, then make one. */
+ rl_kill_ring = (char **)
+ xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
+ rl_kill_ring[slot = 0] = (char *)NULL;
+ }
+ else
+ {
+ /* We have to add a new slot on the end, unless we have
+ exceeded the max limit for remembering kills. */
+ slot = rl_kill_ring_length;
+ if (slot == rl_max_kills)
+ {
+ register int i;
+ free (rl_kill_ring[0]);
+ for (i = 0; i < slot; i++)
+ rl_kill_ring[i] = rl_kill_ring[i + 1];
+ }
+ else
+ {
+ slot = rl_kill_ring_length += 1;
+ rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
+ }
+ rl_kill_ring[--slot] = (char *)NULL;
+ }
+ }
+ else
+ slot = rl_kill_ring_length - 1;
+
+ /* If the last command was a kill, prepend or append. */
+ if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
+ {
+ old = rl_kill_ring[slot];
+ new = (char *)xmalloc (1 + strlen (old) + strlen (text));
+
+ if (append)
+ {
+ strcpy (new, old);
+ strcat (new, text);
+ }
+ else
+ {
+ strcpy (new, text);
+ strcat (new, old);
+ }
+ free (old);
+ free (text);
+ rl_kill_ring[slot] = new;
+ }
+ else
+ rl_kill_ring[slot] = text;
+
+ rl_kill_index = slot;
+ return 0;
+}
+
+/* The way to kill something. This appends or prepends to the last
+ kill, if the last command was a kill command. if FROM is less
+ than TO, then the text is appended, otherwise prepended. If the
+ last command was not a kill command, then a new slot is made for
+ this kill. */
+int
+rl_kill_text (from, to)
+ int from, to;
+{
+ char *text;
+
+ /* Is there anything to kill? */
+ if (from == to)
+ {
+ _rl_last_command_was_kill++;
+ return 0;
+ }
+
+ text = rl_copy_text (from, to);
+
+ /* Delete the copied text from the line. */
+ rl_delete_text (from, to);
+
+ _rl_copy_to_kill_ring (text, from < to);
+
+ _rl_last_command_was_kill++;
+ return 0;
+}
+
+/* Now REMEMBER! In order to do prepending or appending correctly, kill
+ commands always make rl_point's original position be the FROM argument,
+ and rl_point's extent be the TO argument. */
+
+/* **************************************************************** */
+/* */
+/* Killing Commands */
+/* */
+/* **************************************************************** */
+
+/* Delete the word at point, saving the text in the kill ring. */
+int
+rl_kill_word (count, key)
+ int count, key;
+{
+ int orig_point;
+
+ if (count < 0)
+ return (rl_backward_kill_word (-count, key));
+ else
+ {
+ orig_point = rl_point;
+ rl_forward_word (count, key);
+
+ if (rl_point != orig_point)
+ rl_kill_text (orig_point, rl_point);
+
+ rl_point = orig_point;
+ if (rl_editing_mode == emacs_mode)
+ rl_mark = rl_point;
+ }
+ return 0;
+}
+
+/* Rubout the word before point, placing it on the kill ring. */
+int
+rl_backward_kill_word (count, ignore)
+ int count, ignore;
+{
+ int orig_point;
+
+ if (count < 0)
+ return (rl_kill_word (-count, ignore));
+ else
+ {
+ orig_point = rl_point;
+ rl_backward_word (count, ignore);
+
+ if (rl_point != orig_point)
+ rl_kill_text (orig_point, rl_point);
+
+ if (rl_editing_mode == emacs_mode)
+ rl_mark = rl_point;
+ }
+ return 0;
+}
+
+/* Kill from here to the end of the line. If DIRECTION is negative, kill
+ back to the line start instead. */
+int
+rl_kill_line (direction, ignore)
+ int direction, ignore;
+{
+ int orig_point;
+
+ if (direction < 0)
+ return (rl_backward_kill_line (1, ignore));
+ else
+ {
+ orig_point = rl_point;
+ rl_end_of_line (1, ignore);
+ if (orig_point != rl_point)
+ rl_kill_text (orig_point, rl_point);
+ rl_point = orig_point;
+ if (rl_editing_mode == emacs_mode)
+ rl_mark = rl_point;
+ }
+ return 0;
+}
+
+/* Kill backwards to the start of the line. If DIRECTION is negative, kill
+ forwards to the line end instead. */
+int
+rl_backward_kill_line (direction, ignore)
+ int direction, ignore;
+{
+ int orig_point;
+
+ if (direction < 0)
+ return (rl_kill_line (1, ignore));
+ else
+ {
+ if (!rl_point)
+ rl_ding ();
+ else
+ {
+ orig_point = rl_point;
+ rl_beg_of_line (1, ignore);
+ if (rl_point != orig_point)
+ rl_kill_text (orig_point, rl_point);
+ if (rl_editing_mode == emacs_mode)
+ rl_mark = rl_point;
+ }
+ }
+ return 0;
+}
+
+/* Kill the whole line, no matter where point is. */
+int
+rl_kill_full_line (count, ignore)
+ int count, ignore;
+{
+ rl_begin_undo_group ();
+ rl_point = 0;
+ rl_kill_text (rl_point, rl_end);
+ rl_mark = 0;
+ rl_end_undo_group ();
+ return 0;
+}
+
+/* The next two functions mimic unix line editing behaviour, except they
+ save the deleted text on the kill ring. This is safer than not saving
+ it, and since we have a ring, nobody should get screwed. */
+
+/* This does what C-w does in Unix. We can't prevent people from
+ using behaviour that they expect. */
+int
+rl_unix_word_rubout (count, key)
+ int count, key;
+{
+ int orig_point;
+
+ if (rl_point == 0)
+ rl_ding ();
+ else
+ {
+ orig_point = rl_point;
+ if (count <= 0)
+ count = 1;
+
+ while (count--)
+ {
+ while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
+ rl_point--;
+
+ while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
+ rl_point--;
+ }
+
+ rl_kill_text (orig_point, rl_point);
+ if (rl_editing_mode == emacs_mode)
+ rl_mark = rl_point;
+ }
+ return 0;
+}
+
+/* Here is C-u doing what Unix does. You don't *have* to use these
+ key-bindings. We have a choice of killing the entire line, or
+ killing from where we are to the start of the line. We choose the
+ latter, because if you are a Unix weenie, then you haven't backspaced
+ into the line at all, and if you aren't, then you know what you are
+ doing. */
+int
+rl_unix_line_discard (count, key)
+ int count, key;
+{
+ if (rl_point == 0)
+ rl_ding ();
+ else
+ {
+ rl_kill_text (rl_point, 0);
+ rl_point = 0;
+ if (rl_editing_mode == emacs_mode)
+ rl_mark = rl_point;
+ }
+ return 0;
+}
+
+/* Copy the text in the `region' to the kill ring. If DELETE is non-zero,
+ delete the text from the line as well. */
+static int
+region_kill_internal (delete)
+ int delete;
+{
+ char *text;
+
+ if (rl_mark != rl_point)
+ {
+ text = rl_copy_text (rl_point, rl_mark);
+ if (delete)
+ rl_delete_text (rl_point, rl_mark);
+ _rl_copy_to_kill_ring (text, rl_point < rl_mark);
+ }
+
+ _rl_last_command_was_kill++;
+ return 0;
+}
+
+/* Copy the text in the region to the kill ring. */
+int
+rl_copy_region_to_kill (count, ignore)
+ int count, ignore;
+{
+ return (region_kill_internal (0));
+}
+
+/* Kill the text between the point and mark. */
+int
+rl_kill_region (count, ignore)
+ int count, ignore;
+{
+ int r, npoint;
+
+ npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
+ r = region_kill_internal (1);
+ _rl_fix_point (1);
+ rl_point = npoint;
+ return r;
+}
+
+/* Copy COUNT words to the kill ring. DIR says which direction we look
+ to find the words. */
+static int
+_rl_copy_word_as_kill (count, dir)
+ int count, dir;
+{
+ int om, op, r;
+
+ om = rl_mark;
+ op = rl_point;
+
+ if (dir > 0)
+ rl_forward_word (count, 0);
+ else
+ rl_backward_word (count, 0);
+
+ rl_mark = rl_point;
+
+ if (dir > 0)
+ rl_backward_word (count, 0);
+ else
+ rl_forward_word (count, 0);
+
+ r = region_kill_internal (0);
+
+ rl_mark = om;
+ rl_point = op;
+
+ return r;
+}
+
+int
+rl_copy_forward_word (count, key)
+ int count, key;
+{
+ if (count < 0)
+ return (rl_copy_backward_word (-count, key));
+
+ return (_rl_copy_word_as_kill (count, 1));
+}
+
+int
+rl_copy_backward_word (count, key)
+ int count, key;
+{
+ if (count < 0)
+ return (rl_copy_forward_word (-count, key));
+
+ return (_rl_copy_word_as_kill (count, -1));
+}
+
+/* Yank back the last killed text. This ignores arguments. */
+int
+rl_yank (count, ignore)
+ int count, ignore;
+{
+ if (rl_kill_ring == 0)
+ {
+ _rl_abort_internal ();
+ return -1;
+ }
+
+ _rl_set_mark_at_pos (rl_point);
+ rl_insert_text (rl_kill_ring[rl_kill_index]);
+ return 0;
+}
+
+/* If the last command was yank, or yank_pop, and the text just
+ before point is identical to the current kill item, then
+ delete that text from the line, rotate the index down, and
+ yank back some other text. */
+int
+rl_yank_pop (count, key)
+ int count, key;
+{
+ int l, n;
+
+ if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
+ !rl_kill_ring)
+ {
+ _rl_abort_internal ();
+ return -1;
+ }
+
+ l = strlen (rl_kill_ring[rl_kill_index]);
+ n = rl_point - l;
+ if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
+ {
+ rl_delete_text (n, rl_point);
+ rl_point = n;
+ rl_kill_index--;
+ if (rl_kill_index < 0)
+ rl_kill_index = rl_kill_ring_length - 1;
+ rl_yank (1, 0);
+ return 0;
+ }
+ else
+ {
+ _rl_abort_internal ();
+ return -1;
+ }
+}
+
+/* Yank the COUNTh argument from the previous history line, skipping
+ HISTORY_SKIP lines before looking for the `previous line'. */
+static int
+rl_yank_nth_arg_internal (count, ignore, history_skip)
+ int count, ignore, history_skip;
+{
+ register HIST_ENTRY *entry;
+ char *arg;
+ int i, pos;
+
+ pos = where_history ();
+
+ if (history_skip)
+ {
+ for (i = 0; i < history_skip; i++)
+ entry = previous_history ();
+ }
+
+ entry = previous_history ();
+
+ history_set_pos (pos);
+
+ if (entry == 0)
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ arg = history_arg_extract (count, count, entry->line);
+ if (!arg || !*arg)
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ rl_begin_undo_group ();
+
+ _rl_set_mark_at_pos (rl_point);
+
+#if defined (VI_MODE)
+ /* Vi mode always inserts a space before yanking the argument, and it
+ inserts it right *after* rl_point. */
+ if (rl_editing_mode == vi_mode)
+ {
+ rl_vi_append_mode (1, ignore);
+ rl_insert_text (" ");
+ }
+#endif /* VI_MODE */
+
+ rl_insert_text (arg);
+ free (arg);
+
+ rl_end_undo_group ();
+ return 0;
+}
+
+/* Yank the COUNTth argument from the previous history line. */
+int
+rl_yank_nth_arg (count, ignore)
+ int count, ignore;
+{
+ return (rl_yank_nth_arg_internal (count, ignore, 0));
+}
+
+/* Yank the last argument from the previous history line. This `knows'
+ how rl_yank_nth_arg treats a count of `$'. With an argument, this
+ behaves the same as rl_yank_nth_arg. */
+int
+rl_yank_last_arg (count, key)
+ int count, key;
+{
+ static int history_skip = 0;
+ static int explicit_arg_p = 0;
+ static int count_passed = 1;
+ static int direction = 1;
+ static int undo_needed = 0;
+ int retval;
+
+ if (rl_last_func != rl_yank_last_arg)
+ {
+ history_skip = 0;
+ explicit_arg_p = rl_explicit_arg;
+ count_passed = count;
+ direction = 1;
+ }
+ else
+ {
+ if (undo_needed)
+ rl_do_undo ();
+ if (count < 1)
+ direction = -direction;
+ history_skip += direction;
+ if (history_skip < 0)
+ history_skip = 0;
+ }
+
+ if (explicit_arg_p)
+ retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
+ else
+ retval = rl_yank_nth_arg_internal ('$', key, history_skip);
+
+ undo_needed = retval == 0;
+ return retval;
+}
+
+/* A special paste command for users of Cygnus's cygwin32. */
+#if defined __CYGWIN__ || defined _WIN32
+#include <windows.h>
+
+int
+rl_paste_from_clipboard (count, key)
+ int count, key;
+{
+ char *data, *ptr;
+ int len;
+
+ if (OpenClipboard (NULL) == 0)
+ return (0);
+
+ data = (char *)GetClipboardData (CF_TEXT);
+ if (data)
+ {
+ ptr = strchr (data, '\r');
+ if (ptr)
+ {
+ len = ptr - data;
+ ptr = (char *)xmalloc (len + 1);
+ ptr[len] = '\0';
+ strncpy (ptr, data, len);
+ }
+ else
+ ptr = data;
+ _rl_set_mark_at_pos (rl_point);
+ rl_insert_text (ptr);
+ if (ptr != data)
+ free (ptr);
+ CloseClipboard ();
+ }
+ return (0);
+}
+#endif /* __CYGWIN__ */
diff --git a/MSVC/readline/macro.c b/MSVC/readline/macro.c
index 5fe9dc0..08be5f2 100644
--- a/MSVC/readline/macro.c
+++ b/MSVC/readline/macro.c
@@ -1,260 +1,260 @@
-/* macro.c -- keyboard macros for readline. */
-
-/* Copyright (C) 1994 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h> /* for _POSIX_VERSION */
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-/* **************************************************************** */
-/* */
-/* Hacking Keyboard Macros */
-/* */
-/* **************************************************************** */
-
-/* The currently executing macro string. If this is non-zero,
- then it is a malloc ()'ed string where input is coming from. */
-char *rl_executing_macro = (char *)NULL;
-
-/* The offset in the above string to the next character to be read. */
-static int executing_macro_index;
-
-/* The current macro string being built. Characters get stuffed
- in here by add_macro_char (). */
-static char *current_macro = (char *)NULL;
-
-/* The size of the buffer allocated to current_macro. */
-static int current_macro_size;
-
-/* The index at which characters are being added to current_macro. */
-static int current_macro_index;
-
-/* A structure used to save nested macro strings.
- It is a linked list of string/index for each saved macro. */
-struct saved_macro {
- struct saved_macro *next;
- char *string;
- int sindex;
-};
-
-/* The list of saved macros. */
-static struct saved_macro *macro_list = (struct saved_macro *)NULL;
-
-/* Set up to read subsequent input from STRING.
- STRING is free ()'ed when we are done with it. */
-void
-_rl_with_macro_input (string)
- char *string;
-{
- _rl_push_executing_macro ();
- rl_executing_macro = string;
- executing_macro_index = 0;
- RL_SETSTATE(RL_STATE_MACROINPUT);
-}
-
-/* Return the next character available from a macro, or 0 if
- there are no macro characters. */
-int
-_rl_next_macro_key ()
-{
- if (rl_executing_macro == 0)
- return (0);
-
- if (rl_executing_macro[executing_macro_index] == 0)
- {
- _rl_pop_executing_macro ();
- return (_rl_next_macro_key ());
- }
-
- return (rl_executing_macro[executing_macro_index++]);
-}
-
-/* Save the currently executing macro on a stack of saved macros. */
-void
-_rl_push_executing_macro ()
-{
- struct saved_macro *saver;
-
- saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
- saver->next = macro_list;
- saver->sindex = executing_macro_index;
- saver->string = rl_executing_macro;
-
- macro_list = saver;
-}
-
-/* Discard the current macro, replacing it with the one
- on the top of the stack of saved macros. */
-void
-_rl_pop_executing_macro ()
-{
- struct saved_macro *macro;
-
- FREE (rl_executing_macro);
- rl_executing_macro = (char *)NULL;
- executing_macro_index = 0;
-
- if (macro_list)
- {
- macro = macro_list;
- rl_executing_macro = macro_list->string;
- executing_macro_index = macro_list->sindex;
- macro_list = macro_list->next;
- free (macro);
- }
-
- if (rl_executing_macro == 0)
- RL_UNSETSTATE(RL_STATE_MACROINPUT);
-}
-
-/* Add a character to the macro being built. */
-void
-_rl_add_macro_char (c)
- int c;
-{
- if (current_macro_index + 1 >= current_macro_size)
- {
- if (current_macro == 0)
- current_macro = (char *)xmalloc (current_macro_size = 25);
- else
- current_macro = (char *)xrealloc (current_macro, current_macro_size += 25);
- }
-
- current_macro[current_macro_index++] = c;
- current_macro[current_macro_index] = '\0';
-}
-
-void
-_rl_kill_kbd_macro ()
-{
- if (current_macro)
- {
- free (current_macro);
- current_macro = (char *) NULL;
- }
- current_macro_size = current_macro_index = 0;
-
- FREE (rl_executing_macro);
- rl_executing_macro = (char *) NULL;
- executing_macro_index = 0;
-
- RL_UNSETSTATE(RL_STATE_MACRODEF);
-}
-
-/* Begin defining a keyboard macro.
- Keystrokes are recorded as they are executed.
- End the definition with rl_end_kbd_macro ().
- If a numeric argument was explicitly typed, then append this
- definition to the end of the existing macro, and start by
- re-executing the existing macro. */
-int
-rl_start_kbd_macro (ignore1, ignore2)
- int ignore1, ignore2;
-{
- if (RL_ISSTATE (RL_STATE_MACRODEF))
- {
- _rl_abort_internal ();
- return -1;
- }
-
- if (rl_explicit_arg)
- {
- if (current_macro)
- _rl_with_macro_input (savestring (current_macro));
- }
- else
- current_macro_index = 0;
-
- RL_SETSTATE(RL_STATE_MACRODEF);
- return 0;
-}
-
-/* Stop defining a keyboard macro.
- A numeric argument says to execute the macro right now,
- that many times, counting the definition as the first time. */
-int
-rl_end_kbd_macro (count, ignore)
- int count, ignore;
-{
- if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
- {
- _rl_abort_internal ();
- return -1;
- }
-
- current_macro_index -= rl_key_sequence_length - 1;
- current_macro[current_macro_index] = '\0';
-
- RL_UNSETSTATE(RL_STATE_MACRODEF);
-
- return (rl_call_last_kbd_macro (--count, 0));
-}
-
-/* Execute the most recently defined keyboard macro.
- COUNT says how many times to execute it. */
-int
-rl_call_last_kbd_macro (count, ignore)
- int count, ignore;
-{
- if (current_macro == 0)
- _rl_abort_internal ();
-
- if (RL_ISSTATE (RL_STATE_MACRODEF))
- {
- rl_ding (); /* no recursive macros */
- current_macro[--current_macro_index] = '\0'; /* erase this char */
- return 0;
- }
-
- while (count--)
- _rl_with_macro_input (savestring (current_macro));
- return 0;
-}
-
-void
-rl_push_macro_input (macro)
- char *macro;
-{
- _rl_with_macro_input (macro);
-}
+/* macro.c -- keyboard macros for readline. */
+
+/* Copyright (C) 1994 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h> /* for _POSIX_VERSION */
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <stdio.h>
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "xmalloc.h"
+
+/* **************************************************************** */
+/* */
+/* Hacking Keyboard Macros */
+/* */
+/* **************************************************************** */
+
+/* The currently executing macro string. If this is non-zero,
+ then it is a malloc ()'ed string where input is coming from. */
+char *rl_executing_macro = (char *)NULL;
+
+/* The offset in the above string to the next character to be read. */
+static int executing_macro_index;
+
+/* The current macro string being built. Characters get stuffed
+ in here by add_macro_char (). */
+static char *current_macro = (char *)NULL;
+
+/* The size of the buffer allocated to current_macro. */
+static int current_macro_size;
+
+/* The index at which characters are being added to current_macro. */
+static int current_macro_index;
+
+/* A structure used to save nested macro strings.
+ It is a linked list of string/index for each saved macro. */
+struct saved_macro {
+ struct saved_macro *next;
+ char *string;
+ int sindex;
+};
+
+/* The list of saved macros. */
+static struct saved_macro *macro_list = (struct saved_macro *)NULL;
+
+/* Set up to read subsequent input from STRING.
+ STRING is free ()'ed when we are done with it. */
+void
+_rl_with_macro_input (string)
+ char *string;
+{
+ _rl_push_executing_macro ();
+ rl_executing_macro = string;
+ executing_macro_index = 0;
+ RL_SETSTATE(RL_STATE_MACROINPUT);
+}
+
+/* Return the next character available from a macro, or 0 if
+ there are no macro characters. */
+int
+_rl_next_macro_key ()
+{
+ if (rl_executing_macro == 0)
+ return (0);
+
+ if (rl_executing_macro[executing_macro_index] == 0)
+ {
+ _rl_pop_executing_macro ();
+ return (_rl_next_macro_key ());
+ }
+
+ return (rl_executing_macro[executing_macro_index++]);
+}
+
+/* Save the currently executing macro on a stack of saved macros. */
+void
+_rl_push_executing_macro ()
+{
+ struct saved_macro *saver;
+
+ saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
+ saver->next = macro_list;
+ saver->sindex = executing_macro_index;
+ saver->string = rl_executing_macro;
+
+ macro_list = saver;
+}
+
+/* Discard the current macro, replacing it with the one
+ on the top of the stack of saved macros. */
+void
+_rl_pop_executing_macro ()
+{
+ struct saved_macro *macro;
+
+ FREE (rl_executing_macro);
+ rl_executing_macro = (char *)NULL;
+ executing_macro_index = 0;
+
+ if (macro_list)
+ {
+ macro = macro_list;
+ rl_executing_macro = macro_list->string;
+ executing_macro_index = macro_list->sindex;
+ macro_list = macro_list->next;
+ free (macro);
+ }
+
+ if (rl_executing_macro == 0)
+ RL_UNSETSTATE(RL_STATE_MACROINPUT);
+}
+
+/* Add a character to the macro being built. */
+void
+_rl_add_macro_char (c)
+ int c;
+{
+ if (current_macro_index + 1 >= current_macro_size)
+ {
+ if (current_macro == 0)
+ current_macro = (char *)xmalloc (current_macro_size = 25);
+ else
+ current_macro = (char *)xrealloc (current_macro, current_macro_size += 25);
+ }
+
+ current_macro[current_macro_index++] = c;
+ current_macro[current_macro_index] = '\0';
+}
+
+void
+_rl_kill_kbd_macro ()
+{
+ if (current_macro)
+ {
+ free (current_macro);
+ current_macro = (char *) NULL;
+ }
+ current_macro_size = current_macro_index = 0;
+
+ FREE (rl_executing_macro);
+ rl_executing_macro = (char *) NULL;
+ executing_macro_index = 0;
+
+ RL_UNSETSTATE(RL_STATE_MACRODEF);
+}
+
+/* Begin defining a keyboard macro.
+ Keystrokes are recorded as they are executed.
+ End the definition with rl_end_kbd_macro ().
+ If a numeric argument was explicitly typed, then append this
+ definition to the end of the existing macro, and start by
+ re-executing the existing macro. */
+int
+rl_start_kbd_macro (ignore1, ignore2)
+ int ignore1, ignore2;
+{
+ if (RL_ISSTATE (RL_STATE_MACRODEF))
+ {
+ _rl_abort_internal ();
+ return -1;
+ }
+
+ if (rl_explicit_arg)
+ {
+ if (current_macro)
+ _rl_with_macro_input (savestring (current_macro));
+ }
+ else
+ current_macro_index = 0;
+
+ RL_SETSTATE(RL_STATE_MACRODEF);
+ return 0;
+}
+
+/* Stop defining a keyboard macro.
+ A numeric argument says to execute the macro right now,
+ that many times, counting the definition as the first time. */
+int
+rl_end_kbd_macro (count, ignore)
+ int count, ignore;
+{
+ if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
+ {
+ _rl_abort_internal ();
+ return -1;
+ }
+
+ current_macro_index -= rl_key_sequence_length - 1;
+ current_macro[current_macro_index] = '\0';
+
+ RL_UNSETSTATE(RL_STATE_MACRODEF);
+
+ return (rl_call_last_kbd_macro (--count, 0));
+}
+
+/* Execute the most recently defined keyboard macro.
+ COUNT says how many times to execute it. */
+int
+rl_call_last_kbd_macro (count, ignore)
+ int count, ignore;
+{
+ if (current_macro == 0)
+ _rl_abort_internal ();
+
+ if (RL_ISSTATE (RL_STATE_MACRODEF))
+ {
+ rl_ding (); /* no recursive macros */
+ current_macro[--current_macro_index] = '\0'; /* erase this char */
+ return 0;
+ }
+
+ while (count--)
+ _rl_with_macro_input (savestring (current_macro));
+ return 0;
+}
+
+void
+rl_push_macro_input (macro)
+ char *macro;
+{
+ _rl_with_macro_input (macro);
+}
diff --git a/MSVC/readline/mbutil.c b/MSVC/readline/mbutil.c
index a0df9f4..a955778 100644
--- a/MSVC/readline/mbutil.c
+++ b/MSVC/readline/mbutil.c
@@ -1,345 +1,345 @@
-/* mbutil.c -- readline multibyte character utility functions */
-
-/* Copyright (C) 2001 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include "posixjmp.h"
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h> /* for _POSIX_VERSION */
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-#include <ctype.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-#if defined (TIOCSTAT_IN_SYS_IOCTL)
-# include <sys/ioctl.h>
-#endif /* TIOCSTAT_IN_SYS_IOCTL */
-
-/* Some standard library routines. */
-#include "readline.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-/* Declared here so it can be shared between the readline and history
- libraries. */
-#if defined (HANDLE_MULTIBYTE)
-int rl_byte_oriented = 0;
-#else
-int rl_byte_oriented = 1;
-#endif
-
-/* **************************************************************** */
-/* */
-/* Multibyte Character Utility Functions */
-/* */
-/* **************************************************************** */
-
-#if defined(HANDLE_MULTIBYTE)
-
-int
-wcwidth (wchar_t wc)
-{
- if (wc == 0)
- return 0;
- else if (0xff < wc)
- return 2;
- return -1;
-}
-
-static int
-_rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
- char *string;
- int seed, count, find_non_zero;
-{
- size_t tmp = 0;
- mbstate_t ps;
- int point = 0;
- wchar_t wc;
-
- memset(&ps, 0, sizeof (mbstate_t));
- if (seed < 0)
- seed = 0;
- if (count <= 0)
- return seed;
-
- point = seed + _rl_adjust_point(string, seed, &ps);
- /* if this is true, means that seed was not pointed character
- started byte. So correct the point and consume count */
- if (seed < point)
- count --;
-
- while (count > 0)
- {
- tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps);
- if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
- {
- /* invalid bytes. asume a byte represents a character */
- point++;
- count--;
- /* reset states. */
- memset(&ps, 0, sizeof(mbstate_t));
- }
- else if (tmp == (size_t)0)
- /* found '\0' char */
- break;
- else
- {
- /* valid bytes */
- point += tmp;
- if (find_non_zero)
- {
- if (wcwidth (wc) == 0)
- continue;
- else
- count--;
- }
- else
- count--;
- }
- }
-
- if (find_non_zero)
- {
- tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
- while (wcwidth (wc) == 0)
- {
- point += tmp;
- tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
- if (tmp == (size_t)(0) || tmp == (size_t)(-1) || tmp == (size_t)(-2))
- break;
- }
- }
- return point;
-}
-
-static int
-_rl_find_prev_mbchar_internal (string, seed, find_non_zero)
- char *string;
- int seed, find_non_zero;
-{
- mbstate_t ps;
- int prev, non_zero_prev, point, length;
- size_t tmp;
- wchar_t wc;
-
- memset(&ps, 0, sizeof(mbstate_t));
- length = strlen(string);
-
- if (seed < 0)
- return 0;
- else if (length < seed)
- return length;
-
- prev = non_zero_prev = point = 0;
- while (point < seed)
- {
- tmp = mbrtowc (&wc, string + point, length - point, &ps);
- if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
- {
- /* in this case, bytes are invalid or shorted to compose
- multibyte char, so assume that the first byte represents
- a single character anyway. */
- tmp = 1;
- /* clear the state of the byte sequence, because
- in this case effect of mbstate is undefined */
- memset(&ps, 0, sizeof (mbstate_t));
- }
- else if (tmp == 0)
- break; /* Found '\0' char. Can this happen? */
- else
- {
- if (find_non_zero)
- {
- if (wcwidth (wc) != 0)
- prev = point;
- }
- else
- prev = point;
- }
-
- point += tmp;
- }
-
- return prev;
-}
-
-/* return the number of bytes parsed from the multibyte sequence starting
- at src, if a non-L'\0' wide character was recognized. It returns 0,
- if a L'\0' wide character was recognized. It returns (size_t)(-1),
- if an invalid multibyte sequence was encountered. It returns (size_t)(-2)
- if it couldn't parse a complete multibyte character. */
-int
-_rl_get_char_len (src, ps)
- char *src;
- mbstate_t *ps;
-{
- size_t tmp;
-
- tmp = mbrlen((const char *)src, (size_t)strlen (src), ps);
- if (tmp == (size_t)(-2))
- {
- /* shorted to compose multibyte char */
- memset (ps, 0, sizeof(mbstate_t));
- return -2;
- }
- else if (tmp == (size_t)(-1))
- {
- /* invalid to compose multibyte char */
- /* initialize the conversion state */
- memset (ps, 0, sizeof(mbstate_t));
- return -1;
- }
- else if (tmp == (size_t)0)
- return 0;
- else
- return (int)tmp;
-}
-
-/* compare the specified two characters. If the characters matched,
- return 1. Otherwise return 0. */
-int
-_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2)
- char *buf1, *buf2;
- mbstate_t *ps1, *ps2;
- int pos1, pos2;
-{
- int i, w1, w2;
-
- if ((w1 = _rl_get_char_len (&buf1[pos1], ps1)) <= 0 ||
- (w2 = _rl_get_char_len (&buf2[pos2], ps2)) <= 0 ||
- (w1 != w2) ||
- (buf1[pos1] != buf2[pos2]))
- return 0;
-
- for (i = 1; i < w1; i++)
- if (buf1[pos1+i] != buf2[pos2+i])
- return 0;
-
- return 1;
-}
-
-/* adjust pointed byte and find mbstate of the point of string.
- adjusted point will be point <= adjusted_point, and returns
- differences of the byte(adjusted_point - point).
- if point is invalied (point < 0 || more than string length),
- it returns -1 */
-int
-_rl_adjust_point(string, point, ps)
- char *string;
- int point;
- mbstate_t *ps;
-{
- size_t tmp = 0;
- int length;
- int pos = 0;
-
- length = strlen(string);
- if (point < 0)
- return -1;
- if (length < point)
- return -1;
-
- while (pos < point)
- {
- tmp = mbrlen (string + pos, length - pos, ps);
- if((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
- {
- /* in this case, bytes are invalid or shorted to compose
- multibyte char, so assume that the first byte represents
- a single character anyway. */
- pos++;
- /* clear the state of the byte sequence, because
- in this case effect of mbstate is undefined */
- memset (ps, 0, sizeof (mbstate_t));
- }
- else
- pos += tmp;
- }
-
- return (pos - point);
-}
-
-int
-_rl_is_mbchar_matched (string, seed, end, mbchar, length)
- char *string;
- int seed, end;
- char *mbchar;
- int length;
-{
- int i;
-
- if ((end - seed) < length)
- return 0;
-
- for (i = 0; i < length; i++)
- if (string[seed + i] != mbchar[i])
- return 0;
- return 1;
-}
-#endif /* HANDLE_MULTIBYTE */
-
-/* Find next `count' characters started byte point of the specified seed.
- If flags is MB_FIND_NONZERO, we look for non-zero-width multibyte
- characters. */
-#undef _rl_find_next_mbchar
-int
-_rl_find_next_mbchar (string, seed, count, flags)
- char *string;
- int seed, count, flags;
-{
-#if defined (HANDLE_MULTIBYTE)
- return _rl_find_next_mbchar_internal (string, seed, count, flags);
-#else
- return (seed + count);
-#endif
-}
-
-/* Find previous character started byte point of the specified seed.
- Returned point will be point <= seed. If flags is MB_FIND_NONZERO,
- we look for non-zero-width multibyte characters. */
-#undef _rl_find_prev_mbchar
-int
-_rl_find_prev_mbchar (string, seed, flags)
- char *string;
- int seed, flags;
-{
-#if defined (HANDLE_MULTIBYTE)
- return _rl_find_prev_mbchar_internal (string, seed, flags);
-#else
- return ((seed == 0) ? seed : seed - 1);
-#endif
-}
+/* mbutil.c -- readline multibyte character utility functions */
+
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "posixjmp.h"
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h> /* for _POSIX_VERSION */
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <stdio.h>
+#include <ctype.h>
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+#include "rlmbutil.h"
+
+#if defined (TIOCSTAT_IN_SYS_IOCTL)
+# include <sys/ioctl.h>
+#endif /* TIOCSTAT_IN_SYS_IOCTL */
+
+/* Some standard library routines. */
+#include "readline.h"
+
+#include "rlprivate.h"
+#include "xmalloc.h"
+
+/* Declared here so it can be shared between the readline and history
+ libraries. */
+#if defined (HANDLE_MULTIBYTE)
+int rl_byte_oriented = 0;
+#else
+int rl_byte_oriented = 1;
+#endif
+
+/* **************************************************************** */
+/* */
+/* Multibyte Character Utility Functions */
+/* */
+/* **************************************************************** */
+
+#if defined(HANDLE_MULTIBYTE)
+
+int
+wcwidth (wchar_t wc)
+{
+ if (wc == 0)
+ return 0;
+ else if (0xff < wc)
+ return 2;
+ return -1;
+}
+
+static int
+_rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
+ char *string;
+ int seed, count, find_non_zero;
+{
+ size_t tmp = 0;
+ mbstate_t ps;
+ int point = 0;
+ wchar_t wc;
+
+ memset(&ps, 0, sizeof (mbstate_t));
+ if (seed < 0)
+ seed = 0;
+ if (count <= 0)
+ return seed;
+
+ point = seed + _rl_adjust_point(string, seed, &ps);
+ /* if this is true, means that seed was not pointed character
+ started byte. So correct the point and consume count */
+ if (seed < point)
+ count --;
+
+ while (count > 0)
+ {
+ tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps);
+ if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
+ {
+ /* invalid bytes. asume a byte represents a character */
+ point++;
+ count--;
+ /* reset states. */
+ memset(&ps, 0, sizeof(mbstate_t));
+ }
+ else if (tmp == (size_t)0)
+ /* found '\0' char */
+ break;
+ else
+ {
+ /* valid bytes */
+ point += tmp;
+ if (find_non_zero)
+ {
+ if (wcwidth (wc) == 0)
+ continue;
+ else
+ count--;
+ }
+ else
+ count--;
+ }
+ }
+
+ if (find_non_zero)
+ {
+ tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
+ while (wcwidth (wc) == 0)
+ {
+ point += tmp;
+ tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
+ if (tmp == (size_t)(0) || tmp == (size_t)(-1) || tmp == (size_t)(-2))
+ break;
+ }
+ }
+ return point;
+}
+
+static int
+_rl_find_prev_mbchar_internal (string, seed, find_non_zero)
+ char *string;
+ int seed, find_non_zero;
+{
+ mbstate_t ps;
+ int prev, non_zero_prev, point, length;
+ size_t tmp;
+ wchar_t wc;
+
+ memset(&ps, 0, sizeof(mbstate_t));
+ length = strlen(string);
+
+ if (seed < 0)
+ return 0;
+ else if (length < seed)
+ return length;
+
+ prev = non_zero_prev = point = 0;
+ while (point < seed)
+ {
+ tmp = mbrtowc (&wc, string + point, length - point, &ps);
+ if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
+ {
+ /* in this case, bytes are invalid or shorted to compose
+ multibyte char, so assume that the first byte represents
+ a single character anyway. */
+ tmp = 1;
+ /* clear the state of the byte sequence, because
+ in this case effect of mbstate is undefined */
+ memset(&ps, 0, sizeof (mbstate_t));
+ }
+ else if (tmp == 0)
+ break; /* Found '\0' char. Can this happen? */
+ else
+ {
+ if (find_non_zero)
+ {
+ if (wcwidth (wc) != 0)
+ prev = point;
+ }
+ else
+ prev = point;
+ }
+
+ point += tmp;
+ }
+
+ return prev;
+}
+
+/* return the number of bytes parsed from the multibyte sequence starting
+ at src, if a non-L'\0' wide character was recognized. It returns 0,
+ if a L'\0' wide character was recognized. It returns (size_t)(-1),
+ if an invalid multibyte sequence was encountered. It returns (size_t)(-2)
+ if it couldn't parse a complete multibyte character. */
+int
+_rl_get_char_len (src, ps)
+ char *src;
+ mbstate_t *ps;
+{
+ size_t tmp;
+
+ tmp = mbrlen((const char *)src, (size_t)strlen (src), ps);
+ if (tmp == (size_t)(-2))
+ {
+ /* shorted to compose multibyte char */
+ memset (ps, 0, sizeof(mbstate_t));
+ return -2;
+ }
+ else if (tmp == (size_t)(-1))
+ {
+ /* invalid to compose multibyte char */
+ /* initialize the conversion state */
+ memset (ps, 0, sizeof(mbstate_t));
+ return -1;
+ }
+ else if (tmp == (size_t)0)
+ return 0;
+ else
+ return (int)tmp;
+}
+
+/* compare the specified two characters. If the characters matched,
+ return 1. Otherwise return 0. */
+int
+_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2)
+ char *buf1, *buf2;
+ mbstate_t *ps1, *ps2;
+ int pos1, pos2;
+{
+ int i, w1, w2;
+
+ if ((w1 = _rl_get_char_len (&buf1[pos1], ps1)) <= 0 ||
+ (w2 = _rl_get_char_len (&buf2[pos2], ps2)) <= 0 ||
+ (w1 != w2) ||
+ (buf1[pos1] != buf2[pos2]))
+ return 0;
+
+ for (i = 1; i < w1; i++)
+ if (buf1[pos1+i] != buf2[pos2+i])
+ return 0;
+
+ return 1;
+}
+
+/* adjust pointed byte and find mbstate of the point of string.
+ adjusted point will be point <= adjusted_point, and returns
+ differences of the byte(adjusted_point - point).
+ if point is invalied (point < 0 || more than string length),
+ it returns -1 */
+int
+_rl_adjust_point(string, point, ps)
+ char *string;
+ int point;
+ mbstate_t *ps;
+{
+ size_t tmp = 0;
+ int length;
+ int pos = 0;
+
+ length = strlen(string);
+ if (point < 0)
+ return -1;
+ if (length < point)
+ return -1;
+
+ while (pos < point)
+ {
+ tmp = mbrlen (string + pos, length - pos, ps);
+ if((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
+ {
+ /* in this case, bytes are invalid or shorted to compose
+ multibyte char, so assume that the first byte represents
+ a single character anyway. */
+ pos++;
+ /* clear the state of the byte sequence, because
+ in this case effect of mbstate is undefined */
+ memset (ps, 0, sizeof (mbstate_t));
+ }
+ else
+ pos += tmp;
+ }
+
+ return (pos - point);
+}
+
+int
+_rl_is_mbchar_matched (string, seed, end, mbchar, length)
+ char *string;
+ int seed, end;
+ char *mbchar;
+ int length;
+{
+ int i;
+
+ if ((end - seed) < length)
+ return 0;
+
+ for (i = 0; i < length; i++)
+ if (string[seed + i] != mbchar[i])
+ return 0;
+ return 1;
+}
+#endif /* HANDLE_MULTIBYTE */
+
+/* Find next `count' characters started byte point of the specified seed.
+ If flags is MB_FIND_NONZERO, we look for non-zero-width multibyte
+ characters. */
+#undef _rl_find_next_mbchar
+int
+_rl_find_next_mbchar (string, seed, count, flags)
+ char *string;
+ int seed, count, flags;
+{
+#if defined (HANDLE_MULTIBYTE)
+ return _rl_find_next_mbchar_internal (string, seed, count, flags);
+#else
+ return (seed + count);
+#endif
+}
+
+/* Find previous character started byte point of the specified seed.
+ Returned point will be point <= seed. If flags is MB_FIND_NONZERO,
+ we look for non-zero-width multibyte characters. */
+#undef _rl_find_prev_mbchar
+int
+_rl_find_prev_mbchar (string, seed, flags)
+ char *string;
+ int seed, flags;
+{
+#if defined (HANDLE_MULTIBYTE)
+ return _rl_find_prev_mbchar_internal (string, seed, flags);
+#else
+ return ((seed == 0) ? seed : seed - 1);
+#endif
+}
diff --git a/MSVC/readline/misc.c b/MSVC/readline/misc.c
index 2eeac38..d8be28b 100644
--- a/MSVC/readline/misc.c
+++ b/MSVC/readline/misc.c
@@ -1,494 +1,494 @@
-/* misc.c -- miscellaneous bindable readline functions. */
-
-/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_LOCALE_H)
-# include <locale.h>
-#endif
-
-#include <stdio.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "rlshell.h"
-#include "xmalloc.h"
-
-static int rl_digit_loop PARAMS((void));
-static void _rl_history_set_point PARAMS((void));
-
-/* Forward declarations used in this file */
-void _rl_free_history_entry PARAMS((HIST_ENTRY *));
-
-/* If non-zero, rl_get_previous_history and rl_get_next_history attempt
- to preserve the value of rl_point from line to line. */
-int _rl_history_preserve_point = 0;
-
-/* Saved target point for when _rl_history_preserve_point is set. Special
- value of -1 means that point is at the end of the line. */
-int _rl_history_saved_point = -1;
-
-/* **************************************************************** */
-/* */
-/* Numeric Arguments */
-/* */
-/* **************************************************************** */
-
-/* Handle C-u style numeric args, as well as M--, and M-digits. */
-static int
-rl_digit_loop ()
-{
- int key, c, sawminus, sawdigits;
-
- rl_save_prompt ();
-
- RL_SETSTATE(RL_STATE_NUMERICARG);
- sawminus = sawdigits = 0;
- while (1)
- {
- if (rl_numeric_arg > 1000000)
- {
- sawdigits = rl_explicit_arg = rl_numeric_arg = 0;
- rl_ding ();
- rl_restore_prompt ();
- rl_clear_message ();
- RL_UNSETSTATE(RL_STATE_NUMERICARG);
- return 1;
- }
- rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
- RL_SETSTATE(RL_STATE_MOREINPUT);
- key = c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
- if (c < 0)
- {
- _rl_abort_internal ();
- return -1;
- }
-
- /* If we see a key bound to `universal-argument' after seeing digits,
- it ends the argument but is otherwise ignored. */
- if (_rl_keymap[c].type == ISFUNC &&
- _rl_keymap[c].function == rl_universal_argument)
- {
- if (sawdigits == 0)
- {
- rl_numeric_arg *= 4;
- continue;
- }
- else
- {
- RL_SETSTATE(RL_STATE_MOREINPUT);
- key = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
- rl_restore_prompt ();
- rl_clear_message ();
- RL_UNSETSTATE(RL_STATE_NUMERICARG);
- return (_rl_dispatch (key, _rl_keymap));
- }
- }
-
- c = UNMETA (c);
-
- if (_rl_digit_p (c))
- {
- rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + c - '0' : c - '0';
- sawdigits = rl_explicit_arg = 1;
- }
- else if (c == '-' && rl_explicit_arg == 0)
- {
- rl_numeric_arg = sawminus = 1;
- rl_arg_sign = -1;
- }
- else
- {
- /* Make M-- command equivalent to M--1 command. */
- if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0)
- rl_explicit_arg = 1;
- rl_restore_prompt ();
- rl_clear_message ();
- RL_UNSETSTATE(RL_STATE_NUMERICARG);
- return (_rl_dispatch (key, _rl_keymap));
- }
- }
-
- /*NOTREACHED*/
-}
-
-/* Add the current digit to the argument in progress. */
-int
-rl_digit_argument (ignore, key)
- int ignore, key;
-{
- rl_execute_next (key);
- return (rl_digit_loop ());
-}
-
-/* What to do when you abort reading an argument. */
-int
-rl_discard_argument ()
-{
- rl_ding ();
- rl_clear_message ();
- _rl_init_argument ();
- return 0;
-}
-
-/* Create a default argument. */
-int
-_rl_init_argument ()
-{
- rl_numeric_arg = rl_arg_sign = 1;
- rl_explicit_arg = 0;
- return 0;
-}
-
-/* C-u, universal argument. Multiply the current argument by 4.
- Read a key. If the key has nothing to do with arguments, then
- dispatch on it. If the key is the abort character then abort. */
-int
-rl_universal_argument (count, key)
- int count, key;
-{
- rl_numeric_arg *= 4;
- return (rl_digit_loop ());
-}
-
-/* **************************************************************** */
-/* */
-/* History Utilities */
-/* */
-/* **************************************************************** */
-
-/* We already have a history library, and that is what we use to control
- the history features of readline. This is our local interface to
- the history mechanism. */
-
-/* While we are editing the history, this is the saved
- version of the original line. */
-HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
-
-/* Set the history pointer back to the last entry in the history. */
-void
-_rl_start_using_history ()
-{
- using_history ();
- if (_rl_saved_line_for_history)
- _rl_free_history_entry (_rl_saved_line_for_history);
-
- _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
-}
-
-/* Free the contents (and containing structure) of a HIST_ENTRY. */
-void
-_rl_free_history_entry (entry)
- HIST_ENTRY *entry;
-{
- if (entry == 0)
- return;
- if (entry->line)
- free (entry->line);
- free (entry);
-}
-
-/* Perhaps put back the current line if it has changed. */
-int
-rl_maybe_replace_line ()
-{
- HIST_ENTRY *temp;
-
- temp = current_history ();
- /* If the current line has changed, save the changes. */
- if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
- {
- temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
- free (temp->line);
- free (temp);
- }
- return 0;
-}
-
-/* Restore the _rl_saved_line_for_history if there is one. */
-int
-rl_maybe_unsave_line ()
-{
- if (_rl_saved_line_for_history)
- {
- rl_replace_line (_rl_saved_line_for_history->line, 0);
- rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
- _rl_free_history_entry (_rl_saved_line_for_history);
- _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
- rl_point = rl_end; /* rl_replace_line sets rl_end */
- }
- else
- rl_ding ();
- return 0;
-}
-
-/* Save the current line in _rl_saved_line_for_history. */
-int
-rl_maybe_save_line ()
-{
- if (_rl_saved_line_for_history == 0)
- {
- _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
- _rl_saved_line_for_history->line = savestring (rl_line_buffer);
- _rl_saved_line_for_history->data = (char *)rl_undo_list;
- }
- return 0;
-}
-
-int
-_rl_free_saved_history_line ()
-{
- if (_rl_saved_line_for_history)
- {
- _rl_free_history_entry (_rl_saved_line_for_history);
- _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
- }
- return 0;
-}
-
-static void
-_rl_history_set_point ()
-{
- rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
- ? _rl_history_saved_point
- : rl_end;
- if (rl_point > rl_end)
- rl_point = rl_end;
-
-#if defined (VI_MODE)
- if (rl_editing_mode == vi_mode)
- rl_point = 0;
-#endif /* VI_MODE */
-
- if (rl_editing_mode == emacs_mode)
- rl_mark = (rl_point == rl_end ? 0 : rl_end);
-}
-
-void
-rl_replace_from_history (entry, flags)
- HIST_ENTRY *entry;
- int flags; /* currently unused */
-{
- rl_replace_line (entry->line, 0);
- rl_undo_list = (UNDO_LIST *)entry->data;
- rl_point = rl_end;
- rl_mark = 0;
-
-#if defined (VI_MODE)
- if (rl_editing_mode == vi_mode)
- {
- rl_point = 0;
- rl_mark = rl_end;
- }
-#endif
-}
-
-/* **************************************************************** */
-/* */
-/* History Commands */
-/* */
-/* **************************************************************** */
-
-/* Meta-< goes to the start of the history. */
-int
-rl_beginning_of_history (count, key)
- int count, key;
-{
- return (rl_get_previous_history (1 + where_history (), key));
-}
-
-/* Meta-> goes to the end of the history. (The current line). */
-int
-rl_end_of_history (count, key)
- int count, key;
-{
- rl_maybe_replace_line ();
- using_history ();
- rl_maybe_unsave_line ();
- return 0;
-}
-
-/* Move down to the next history line. */
-int
-rl_get_next_history (count, key)
- int count, key;
-{
- HIST_ENTRY *temp;
-
- if (count < 0)
- return (rl_get_previous_history (-count, key));
-
- if (count == 0)
- return 0;
-
- rl_maybe_replace_line ();
-
- /* either not saved by rl_newline or at end of line, so set appropriately. */
- if (_rl_history_saved_point == -1 && (rl_point || rl_end))
- _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
-
- temp = (HIST_ENTRY *)NULL;
- while (count)
- {
- temp = next_history ();
- if (!temp)
- break;
- --count;
- }
-
- if (temp == 0)
- rl_maybe_unsave_line ();
- else
- {
- rl_replace_from_history (temp, 0);
- _rl_history_set_point ();
- }
- return 0;
-}
-
-/* Get the previous item out of our interactive history, making it the current
- line. If there is no previous history, just ding. */
-int
-rl_get_previous_history (count, key)
- int count, key;
-{
- HIST_ENTRY *old_temp, *temp;
-
- if (count < 0)
- return (rl_get_next_history (-count, key));
-
- if (count == 0)
- return 0;
-
- /* either not saved by rl_newline or at end of line, so set appropriately. */
- if (_rl_history_saved_point == -1 && (rl_point || rl_end))
- _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
-
- /* If we don't have a line saved, then save this one. */
- rl_maybe_save_line ();
-
- /* If the current line has changed, save the changes. */
- rl_maybe_replace_line ();
-
- temp = old_temp = (HIST_ENTRY *)NULL;
- while (count)
- {
- temp = previous_history ();
- if (temp == 0)
- break;
-
- old_temp = temp;
- --count;
- }
-
- /* If there was a large argument, and we moved back to the start of the
- history, that is not an error. So use the last value found. */
- if (!temp && old_temp)
- temp = old_temp;
-
- if (temp == 0)
- rl_ding ();
- else
- {
- rl_replace_from_history (temp, 0);
- _rl_history_set_point ();
- }
- return 0;
-}
-
-/* **************************************************************** */
-/* */
-/* Editing Modes */
-/* */
-/* **************************************************************** */
-/* How to toggle back and forth between editing modes. */
-int
-rl_vi_editing_mode (count, key)
- int count, key;
-{
-#if defined (VI_MODE)
- _rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */
- rl_editing_mode = vi_mode;
- rl_vi_insertion_mode (1, key);
-#endif /* VI_MODE */
-
- return 0;
-}
-
-int
-rl_emacs_editing_mode (count, key)
- int count, key;
-{
- rl_editing_mode = emacs_mode;
- _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
- _rl_keymap = emacs_standard_keymap;
- return 0;
-}
-
-/* Function for the rest of the library to use to set insert/overwrite mode. */
-void
-_rl_set_insert_mode (im, force)
- int im, force;
-{
-#ifdef CURSOR_MODE
- _rl_set_cursor (im, force);
-#endif
-
- rl_insert_mode = im;
-}
-
-/* Toggle overwrite mode. A positive explicit argument selects overwrite
- mode. A negative or zero explicit argument selects insert mode. */
-int
-rl_overwrite_mode (count, key)
- int count, key;
-{
- if (rl_explicit_arg == 0)
- _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
- else if (count > 0)
- _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
- else
- _rl_set_insert_mode (RL_IM_INSERT, 0);
-
- return 0;
-}
+/* misc.c -- miscellaneous bindable readline functions. */
+
+/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_LOCALE_H)
+# include <locale.h>
+#endif
+
+#include <stdio.h>
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+#include "rlmbutil.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "rlshell.h"
+#include "xmalloc.h"
+
+static int rl_digit_loop PARAMS((void));
+static void _rl_history_set_point PARAMS((void));
+
+/* Forward declarations used in this file */
+void _rl_free_history_entry PARAMS((HIST_ENTRY *));
+
+/* If non-zero, rl_get_previous_history and rl_get_next_history attempt
+ to preserve the value of rl_point from line to line. */
+int _rl_history_preserve_point = 0;
+
+/* Saved target point for when _rl_history_preserve_point is set. Special
+ value of -1 means that point is at the end of the line. */
+int _rl_history_saved_point = -1;
+
+/* **************************************************************** */
+/* */
+/* Numeric Arguments */
+/* */
+/* **************************************************************** */
+
+/* Handle C-u style numeric args, as well as M--, and M-digits. */
+static int
+rl_digit_loop ()
+{
+ int key, c, sawminus, sawdigits;
+
+ rl_save_prompt ();
+
+ RL_SETSTATE(RL_STATE_NUMERICARG);
+ sawminus = sawdigits = 0;
+ while (1)
+ {
+ if (rl_numeric_arg > 1000000)
+ {
+ sawdigits = rl_explicit_arg = rl_numeric_arg = 0;
+ rl_ding ();
+ rl_restore_prompt ();
+ rl_clear_message ();
+ RL_UNSETSTATE(RL_STATE_NUMERICARG);
+ return 1;
+ }
+ rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ key = c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+ if (c < 0)
+ {
+ _rl_abort_internal ();
+ return -1;
+ }
+
+ /* If we see a key bound to `universal-argument' after seeing digits,
+ it ends the argument but is otherwise ignored. */
+ if (_rl_keymap[c].type == ISFUNC &&
+ _rl_keymap[c].function == rl_universal_argument)
+ {
+ if (sawdigits == 0)
+ {
+ rl_numeric_arg *= 4;
+ continue;
+ }
+ else
+ {
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ key = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+ rl_restore_prompt ();
+ rl_clear_message ();
+ RL_UNSETSTATE(RL_STATE_NUMERICARG);
+ return (_rl_dispatch (key, _rl_keymap));
+ }
+ }
+
+ c = UNMETA (c);
+
+ if (_rl_digit_p (c))
+ {
+ rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + c - '0' : c - '0';
+ sawdigits = rl_explicit_arg = 1;
+ }
+ else if (c == '-' && rl_explicit_arg == 0)
+ {
+ rl_numeric_arg = sawminus = 1;
+ rl_arg_sign = -1;
+ }
+ else
+ {
+ /* Make M-- command equivalent to M--1 command. */
+ if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0)
+ rl_explicit_arg = 1;
+ rl_restore_prompt ();
+ rl_clear_message ();
+ RL_UNSETSTATE(RL_STATE_NUMERICARG);
+ return (_rl_dispatch (key, _rl_keymap));
+ }
+ }
+
+ /*NOTREACHED*/
+}
+
+/* Add the current digit to the argument in progress. */
+int
+rl_digit_argument (ignore, key)
+ int ignore, key;
+{
+ rl_execute_next (key);
+ return (rl_digit_loop ());
+}
+
+/* What to do when you abort reading an argument. */
+int
+rl_discard_argument ()
+{
+ rl_ding ();
+ rl_clear_message ();
+ _rl_init_argument ();
+ return 0;
+}
+
+/* Create a default argument. */
+int
+_rl_init_argument ()
+{
+ rl_numeric_arg = rl_arg_sign = 1;
+ rl_explicit_arg = 0;
+ return 0;
+}
+
+/* C-u, universal argument. Multiply the current argument by 4.
+ Read a key. If the key has nothing to do with arguments, then
+ dispatch on it. If the key is the abort character then abort. */
+int
+rl_universal_argument (count, key)
+ int count, key;
+{
+ rl_numeric_arg *= 4;
+ return (rl_digit_loop ());
+}
+
+/* **************************************************************** */
+/* */
+/* History Utilities */
+/* */
+/* **************************************************************** */
+
+/* We already have a history library, and that is what we use to control
+ the history features of readline. This is our local interface to
+ the history mechanism. */
+
+/* While we are editing the history, this is the saved
+ version of the original line. */
+HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
+
+/* Set the history pointer back to the last entry in the history. */
+void
+_rl_start_using_history ()
+{
+ using_history ();
+ if (_rl_saved_line_for_history)
+ _rl_free_history_entry (_rl_saved_line_for_history);
+
+ _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
+}
+
+/* Free the contents (and containing structure) of a HIST_ENTRY. */
+void
+_rl_free_history_entry (entry)
+ HIST_ENTRY *entry;
+{
+ if (entry == 0)
+ return;
+ if (entry->line)
+ free (entry->line);
+ free (entry);
+}
+
+/* Perhaps put back the current line if it has changed. */
+int
+rl_maybe_replace_line ()
+{
+ HIST_ENTRY *temp;
+
+ temp = current_history ();
+ /* If the current line has changed, save the changes. */
+ if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
+ {
+ temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
+ free (temp->line);
+ free (temp);
+ }
+ return 0;
+}
+
+/* Restore the _rl_saved_line_for_history if there is one. */
+int
+rl_maybe_unsave_line ()
+{
+ if (_rl_saved_line_for_history)
+ {
+ rl_replace_line (_rl_saved_line_for_history->line, 0);
+ rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
+ _rl_free_history_entry (_rl_saved_line_for_history);
+ _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
+ rl_point = rl_end; /* rl_replace_line sets rl_end */
+ }
+ else
+ rl_ding ();
+ return 0;
+}
+
+/* Save the current line in _rl_saved_line_for_history. */
+int
+rl_maybe_save_line ()
+{
+ if (_rl_saved_line_for_history == 0)
+ {
+ _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
+ _rl_saved_line_for_history->line = savestring (rl_line_buffer);
+ _rl_saved_line_for_history->data = (char *)rl_undo_list;
+ }
+ return 0;
+}
+
+int
+_rl_free_saved_history_line ()
+{
+ if (_rl_saved_line_for_history)
+ {
+ _rl_free_history_entry (_rl_saved_line_for_history);
+ _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
+ }
+ return 0;
+}
+
+static void
+_rl_history_set_point ()
+{
+ rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
+ ? _rl_history_saved_point
+ : rl_end;
+ if (rl_point > rl_end)
+ rl_point = rl_end;
+
+#if defined (VI_MODE)
+ if (rl_editing_mode == vi_mode)
+ rl_point = 0;
+#endif /* VI_MODE */
+
+ if (rl_editing_mode == emacs_mode)
+ rl_mark = (rl_point == rl_end ? 0 : rl_end);
+}
+
+void
+rl_replace_from_history (entry, flags)
+ HIST_ENTRY *entry;
+ int flags; /* currently unused */
+{
+ rl_replace_line (entry->line, 0);
+ rl_undo_list = (UNDO_LIST *)entry->data;
+ rl_point = rl_end;
+ rl_mark = 0;
+
+#if defined (VI_MODE)
+ if (rl_editing_mode == vi_mode)
+ {
+ rl_point = 0;
+ rl_mark = rl_end;
+ }
+#endif
+}
+
+/* **************************************************************** */
+/* */
+/* History Commands */
+/* */
+/* **************************************************************** */
+
+/* Meta-< goes to the start of the history. */
+int
+rl_beginning_of_history (count, key)
+ int count, key;
+{
+ return (rl_get_previous_history (1 + where_history (), key));
+}
+
+/* Meta-> goes to the end of the history. (The current line). */
+int
+rl_end_of_history (count, key)
+ int count, key;
+{
+ rl_maybe_replace_line ();
+ using_history ();
+ rl_maybe_unsave_line ();
+ return 0;
+}
+
+/* Move down to the next history line. */
+int
+rl_get_next_history (count, key)
+ int count, key;
+{
+ HIST_ENTRY *temp;
+
+ if (count < 0)
+ return (rl_get_previous_history (-count, key));
+
+ if (count == 0)
+ return 0;
+
+ rl_maybe_replace_line ();
+
+ /* either not saved by rl_newline or at end of line, so set appropriately. */
+ if (_rl_history_saved_point == -1 && (rl_point || rl_end))
+ _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
+
+ temp = (HIST_ENTRY *)NULL;
+ while (count)
+ {
+ temp = next_history ();
+ if (!temp)
+ break;
+ --count;
+ }
+
+ if (temp == 0)
+ rl_maybe_unsave_line ();
+ else
+ {
+ rl_replace_from_history (temp, 0);
+ _rl_history_set_point ();
+ }
+ return 0;
+}
+
+/* Get the previous item out of our interactive history, making it the current
+ line. If there is no previous history, just ding. */
+int
+rl_get_previous_history (count, key)
+ int count, key;
+{
+ HIST_ENTRY *old_temp, *temp;
+
+ if (count < 0)
+ return (rl_get_next_history (-count, key));
+
+ if (count == 0)
+ return 0;
+
+ /* either not saved by rl_newline or at end of line, so set appropriately. */
+ if (_rl_history_saved_point == -1 && (rl_point || rl_end))
+ _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
+
+ /* If we don't have a line saved, then save this one. */
+ rl_maybe_save_line ();
+
+ /* If the current line has changed, save the changes. */
+ rl_maybe_replace_line ();
+
+ temp = old_temp = (HIST_ENTRY *)NULL;
+ while (count)
+ {
+ temp = previous_history ();
+ if (temp == 0)
+ break;
+
+ old_temp = temp;
+ --count;
+ }
+
+ /* If there was a large argument, and we moved back to the start of the
+ history, that is not an error. So use the last value found. */
+ if (!temp && old_temp)
+ temp = old_temp;
+
+ if (temp == 0)
+ rl_ding ();
+ else
+ {
+ rl_replace_from_history (temp, 0);
+ _rl_history_set_point ();
+ }
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Editing Modes */
+/* */
+/* **************************************************************** */
+/* How to toggle back and forth between editing modes. */
+int
+rl_vi_editing_mode (count, key)
+ int count, key;
+{
+#if defined (VI_MODE)
+ _rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */
+ rl_editing_mode = vi_mode;
+ rl_vi_insertion_mode (1, key);
+#endif /* VI_MODE */
+
+ return 0;
+}
+
+int
+rl_emacs_editing_mode (count, key)
+ int count, key;
+{
+ rl_editing_mode = emacs_mode;
+ _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
+ _rl_keymap = emacs_standard_keymap;
+ return 0;
+}
+
+/* Function for the rest of the library to use to set insert/overwrite mode. */
+void
+_rl_set_insert_mode (im, force)
+ int im, force;
+{
+#ifdef CURSOR_MODE
+ _rl_set_cursor (im, force);
+#endif
+
+ rl_insert_mode = im;
+}
+
+/* Toggle overwrite mode. A positive explicit argument selects overwrite
+ mode. A negative or zero explicit argument selects insert mode. */
+int
+rl_overwrite_mode (count, key)
+ int count, key;
+{
+ if (rl_explicit_arg == 0)
+ _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
+ else if (count > 0)
+ _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
+ else
+ _rl_set_insert_mode (RL_IM_INSERT, 0);
+
+ return 0;
+}
diff --git a/MSVC/readline/nls.c b/MSVC/readline/nls.c
index 40c3e45..27c834a 100644
--- a/MSVC/readline/nls.c
+++ b/MSVC/readline/nls.c
@@ -1,228 +1,228 @@
-/* nls.c -- skeletal internationalization code. */
-
-/* Copyright (C) 1996 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-
-#include <stdio.h>
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_LOCALE_H)
-# include <locale.h>
-#endif
-
-#include <ctype.h>
-
-#include "rldefs.h"
-#include "readline.h"
-#include "rlshell.h"
-#include "rlprivate.h"
-
-#if !defined (HAVE_SETLOCALE)
-/* A list of legal values for the LANG or LC_CTYPE environment variables.
- If a locale name in this list is the value for the LC_ALL, LC_CTYPE,
- or LANG environment variable (using the first of those with a value),
- readline eight-bit mode is enabled. */
-static char *legal_lang_values[] =
-{
- "iso88591",
- "iso88592",
- "iso88593",
- "iso88594",
- "iso88595",
- "iso88596",
- "iso88597",
- "iso88598",
- "iso88599",
- "iso885910",
- "koi8r",
- 0
-};
-
-static char *normalize_codeset PARAMS((char *));
-static char *find_codeset PARAMS((char *, size_t *));
-#endif /* !HAVE_SETLOCALE */
-
-/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
- to decide the defaults for 8-bit character input and output. Returns
- 1 if we set eight-bit mode. */
-int
-_rl_init_eightbit ()
-{
-/* If we have setlocale(3), just check the current LC_CTYPE category
- value, and go into eight-bit mode if it's not C or POSIX. */
-#if defined (HAVE_SETLOCALE)
- char *t;
-
-#ifndef _WIN32
- /* Set the LC_CTYPE locale category from environment variables. */
- t = setlocale (LC_CTYPE, "");
- if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0))
- {
-#endif
- _rl_meta_flag = 1;
- _rl_convert_meta_chars_to_ascii = 1;
- _rl_output_meta_chars = 1;
- return (1);
-#ifndef _WIN32
- }
- else
- return (0);
-#endif
-
-#else /* !HAVE_SETLOCALE */
- char *lspec, *t;
- int i;
-
- /* We don't have setlocale. Finesse it. Check the environment for the
- appropriate variables and set eight-bit mode if they have the right
- values. */
- lspec = sh_get_env_value ("LC_ALL");
- if (lspec == 0) lspec = sh_get_env_value ("LC_CTYPE");
- if (lspec == 0) lspec = sh_get_env_value ("LANG");
- if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
- return (0);
- for (i = 0; t && legal_lang_values[i]; i++)
- if (STREQ (t, legal_lang_values[i]))
- {
- _rl_meta_flag = 1;
- _rl_convert_meta_chars_to_ascii = 0;
- _rl_output_meta_chars = 1;
- break;
- }
- free (t);
- return (legal_lang_values[i] ? 1 : 0);
-
-#endif /* !HAVE_SETLOCALE */
-}
-
-#if !defined (HAVE_SETLOCALE)
-static char *
-normalize_codeset (codeset)
- char *codeset;
-{
- size_t namelen, i;
- int len, all_digits;
- char *wp, *retval;
-
- codeset = find_codeset (codeset, &namelen);
-
- if (codeset == 0)
- return (codeset);
-
- all_digits = 1;
- for (len = 0, i = 0; i < namelen; i++)
- {
- if (ISALNUM ((unsigned char)codeset[i]))
- {
- len++;
- all_digits &= _rl_digit_p (codeset[i]);
- }
- }
-
- retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1);
- if (retval == 0)
- return ((char *)0);
-
- wp = retval;
- /* Add `iso' to beginning of an all-digit codeset */
- if (all_digits)
- {
- *wp++ = 'i';
- *wp++ = 's';
- *wp++ = 'o';
- }
-
- for (i = 0; i < namelen; i++)
- if (ISALPHA ((unsigned char)codeset[i]))
- *wp++ = _rl_to_lower (codeset[i]);
- else if (_rl_digit_p (codeset[i]))
- *wp++ = codeset[i];
- *wp = '\0';
-
- return retval;
-}
-
-/* Isolate codeset portion of locale specification. */
-static char *
-find_codeset (name, lenp)
- char *name;
- size_t *lenp;
-{
- char *cp, *language, *result;
-
- cp = language = name;
- result = (char *)0;
-
- while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',')
- cp++;
-
- /* This does not make sense: language has to be specified. As
- an exception we allow the variable to contain only the codeset
- name. Perhaps there are funny codeset names. */
- if (language == cp)
- {
- *lenp = strlen (language);
- result = language;
- }
- else
- {
- /* Next is the territory. */
- if (*cp == '_')
- do
- ++cp;
- while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_');
-
- /* Now, finally, is the codeset. */
- result = cp;
- if (*cp == '.')
- do
- ++cp;
- while (*cp && *cp != '@');
-
- if (cp - result > 2)
- {
- result++;
- *lenp = cp - result;
- }
- else
- {
- *lenp = strlen (language);
- result = language;
- }
- }
-
- return result;
-}
-#endif /* !HAVE_SETLOCALE */
-
+/* nls.c -- skeletal internationalization code. */
+
+/* Copyright (C) 1996 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_LOCALE_H)
+# include <locale.h>
+#endif
+
+#include <ctype.h>
+
+#include "rldefs.h"
+#include "readline.h"
+#include "rlshell.h"
+#include "rlprivate.h"
+
+#if !defined (HAVE_SETLOCALE)
+/* A list of legal values for the LANG or LC_CTYPE environment variables.
+ If a locale name in this list is the value for the LC_ALL, LC_CTYPE,
+ or LANG environment variable (using the first of those with a value),
+ readline eight-bit mode is enabled. */
+static char *legal_lang_values[] =
+{
+ "iso88591",
+ "iso88592",
+ "iso88593",
+ "iso88594",
+ "iso88595",
+ "iso88596",
+ "iso88597",
+ "iso88598",
+ "iso88599",
+ "iso885910",
+ "koi8r",
+ 0
+};
+
+static char *normalize_codeset PARAMS((char *));
+static char *find_codeset PARAMS((char *, size_t *));
+#endif /* !HAVE_SETLOCALE */
+
+/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
+ to decide the defaults for 8-bit character input and output. Returns
+ 1 if we set eight-bit mode. */
+int
+_rl_init_eightbit ()
+{
+/* If we have setlocale(3), just check the current LC_CTYPE category
+ value, and go into eight-bit mode if it's not C or POSIX. */
+#if defined (HAVE_SETLOCALE)
+ char *t;
+
+#ifndef _WIN32
+ /* Set the LC_CTYPE locale category from environment variables. */
+ t = setlocale (LC_CTYPE, "");
+ if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0))
+ {
+#endif
+ _rl_meta_flag = 1;
+ _rl_convert_meta_chars_to_ascii = 1;
+ _rl_output_meta_chars = 1;
+ return (1);
+#ifndef _WIN32
+ }
+ else
+ return (0);
+#endif
+
+#else /* !HAVE_SETLOCALE */
+ char *lspec, *t;
+ int i;
+
+ /* We don't have setlocale. Finesse it. Check the environment for the
+ appropriate variables and set eight-bit mode if they have the right
+ values. */
+ lspec = sh_get_env_value ("LC_ALL");
+ if (lspec == 0) lspec = sh_get_env_value ("LC_CTYPE");
+ if (lspec == 0) lspec = sh_get_env_value ("LANG");
+ if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
+ return (0);
+ for (i = 0; t && legal_lang_values[i]; i++)
+ if (STREQ (t, legal_lang_values[i]))
+ {
+ _rl_meta_flag = 1;
+ _rl_convert_meta_chars_to_ascii = 0;
+ _rl_output_meta_chars = 1;
+ break;
+ }
+ free (t);
+ return (legal_lang_values[i] ? 1 : 0);
+
+#endif /* !HAVE_SETLOCALE */
+}
+
+#if !defined (HAVE_SETLOCALE)
+static char *
+normalize_codeset (codeset)
+ char *codeset;
+{
+ size_t namelen, i;
+ int len, all_digits;
+ char *wp, *retval;
+
+ codeset = find_codeset (codeset, &namelen);
+
+ if (codeset == 0)
+ return (codeset);
+
+ all_digits = 1;
+ for (len = 0, i = 0; i < namelen; i++)
+ {
+ if (ISALNUM ((unsigned char)codeset[i]))
+ {
+ len++;
+ all_digits &= _rl_digit_p (codeset[i]);
+ }
+ }
+
+ retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1);
+ if (retval == 0)
+ return ((char *)0);
+
+ wp = retval;
+ /* Add `iso' to beginning of an all-digit codeset */
+ if (all_digits)
+ {
+ *wp++ = 'i';
+ *wp++ = 's';
+ *wp++ = 'o';
+ }
+
+ for (i = 0; i < namelen; i++)
+ if (ISALPHA ((unsigned char)codeset[i]))
+ *wp++ = _rl_to_lower (codeset[i]);
+ else if (_rl_digit_p (codeset[i]))
+ *wp++ = codeset[i];
+ *wp = '\0';
+
+ return retval;
+}
+
+/* Isolate codeset portion of locale specification. */
+static char *
+find_codeset (name, lenp)
+ char *name;
+ size_t *lenp;
+{
+ char *cp, *language, *result;
+
+ cp = language = name;
+ result = (char *)0;
+
+ while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',')
+ cp++;
+
+ /* This does not make sense: language has to be specified. As
+ an exception we allow the variable to contain only the codeset
+ name. Perhaps there are funny codeset names. */
+ if (language == cp)
+ {
+ *lenp = strlen (language);
+ result = language;
+ }
+ else
+ {
+ /* Next is the territory. */
+ if (*cp == '_')
+ do
+ ++cp;
+ while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_');
+
+ /* Now, finally, is the codeset. */
+ result = cp;
+ if (*cp == '.')
+ do
+ ++cp;
+ while (*cp && *cp != '@');
+
+ if (cp - result > 2)
+ {
+ result++;
+ *lenp = cp - result;
+ }
+ else
+ {
+ *lenp = strlen (language);
+ result = language;
+ }
+ }
+
+ return result;
+}
+#endif /* !HAVE_SETLOCALE */
+
diff --git a/MSVC/readline/parens.c b/MSVC/readline/parens.c
index 1e4d54e..5b79b31 100644
--- a/MSVC/readline/parens.c
+++ b/MSVC/readline/parens.c
@@ -1,177 +1,177 @@
-/* parens.c -- Implementation of matching parentheses feature. */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "rlconf.h"
-
-#include "config.h"
-
-#include <stdio.h>
-#include <sys/types.h>
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif
-
-#if defined (FD_SET) && !defined (HAVE_SELECT)
-# define HAVE_SELECT
-#endif
-
-#if defined HAVE_SELECT && !defined _WIN32
-# include <sys/time.h>
-#endif /* HAVE_SELECT */
-#if defined (HAVE_SYS_SELECT_H)
-# include <sys/select.h>
-#endif
-
-#if defined (HAVE_STRING_H)
-# include <string.h>
-#else /* !HAVE_STRING_H */
-# include <strings.h>
-#endif /* !HAVE_STRING_H */
-
-#if !defined (strchr) && !defined (__STDC__) && !defined _MSC_VER
-extern char *strchr (), *strrchr ();
-#endif /* !strchr && !__STDC__ */
-
-#include "readline.h"
-#include "rlprivate.h"
-
-static int find_matching_open PARAMS((char *, int, int));
-
-/* Non-zero means try to blink the matching open parenthesis when the
- close parenthesis is inserted. */
-#if defined (HAVE_SELECT)
-int rl_blink_matching_paren = 1;
-#else /* !HAVE_SELECT */
-int rl_blink_matching_paren = 0;
-#endif /* !HAVE_SELECT */
-
-static int _paren_blink_usec = 500000;
-
-/* Change emacs_standard_keymap to have bindings for paren matching when
- ON_OR_OFF is 1, change them back to self_insert when ON_OR_OFF == 0. */
-void
-_rl_enable_paren_matching (on_or_off)
- int on_or_off;
-{
- if (on_or_off)
- { /* ([{ */
- rl_bind_key_in_map (')', rl_insert_close, emacs_standard_keymap);
- rl_bind_key_in_map (']', rl_insert_close, emacs_standard_keymap);
- rl_bind_key_in_map ('}', rl_insert_close, emacs_standard_keymap);
- }
- else
- { /* ([{ */
- rl_bind_key_in_map (')', rl_insert, emacs_standard_keymap);
- rl_bind_key_in_map (']', rl_insert, emacs_standard_keymap);
- rl_bind_key_in_map ('}', rl_insert, emacs_standard_keymap);
- }
-}
-
-int
-rl_set_paren_blink_timeout (u)
- int u;
-{
- int o;
-
- o = _paren_blink_usec;
- if (u > 0)
- _paren_blink_usec = u;
- return (o);
-}
-
-int
-rl_insert_close (count, invoking_key)
- int count, invoking_key;
-{
- if (rl_explicit_arg || !rl_blink_matching_paren)
- _rl_insert_char (count, invoking_key);
- else
- {
-#if defined HAVE_SELECT && !defined _WIN32
- int orig_point, match_point, ready;
- struct timeval timer;
- fd_set readfds;
-
- _rl_insert_char (1, invoking_key);
- (*rl_redisplay_function) ();
- match_point =
- find_matching_open (rl_line_buffer, rl_point - 2, invoking_key);
-
- /* Emacs might message or ring the bell here, but I don't. */
- if (match_point < 0)
- return -1;
-
- FD_ZERO (&readfds);
- FD_SET (fileno (rl_instream), &readfds);
- timer.tv_sec = 0;
- timer.tv_usec = _paren_blink_usec;
-
- orig_point = rl_point;
- rl_point = match_point;
- (*rl_redisplay_function) ();
- ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
- rl_point = orig_point;
-#else /* !HAVE_SELECT */
- _rl_insert_char (count, invoking_key);
-#endif /* !HAVE_SELECT */
- }
- return 0;
-}
-
-static int
-find_matching_open (string, from, closer)
- char *string;
- int from, closer;
-{
- register int i;
- int opener, level, delimiter;
-
- switch (closer)
- {
- case ']': opener = '['; break;
- case '}': opener = '{'; break;
- case ')': opener = '('; break;
- default:
- return (-1);
- }
-
- level = 1; /* The closer passed in counts as 1. */
- delimiter = 0; /* Delimited state unknown. */
-
- for (i = from; i > -1; i--)
- {
- if (delimiter && (string[i] == delimiter))
- delimiter = 0;
- else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i]))
- delimiter = string[i];
- else if (!delimiter && (string[i] == closer))
- level++;
- else if (!delimiter && (string[i] == opener))
- level--;
-
- if (!level)
- break;
- }
- return (i);
-}
+/* parens.c -- Implementation of matching parentheses feature. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "rlconf.h"
+
+#include "config.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#if defined (FD_SET) && !defined (HAVE_SELECT)
+# define HAVE_SELECT
+#endif
+
+#if defined HAVE_SELECT && !defined _WIN32
+# include <sys/time.h>
+#endif /* HAVE_SELECT */
+#if defined (HAVE_SYS_SELECT_H)
+# include <sys/select.h>
+#endif
+
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else /* !HAVE_STRING_H */
+# include <strings.h>
+#endif /* !HAVE_STRING_H */
+
+#if !defined (strchr) && !defined (__STDC__) && !defined _MSC_VER
+extern char *strchr (), *strrchr ();
+#endif /* !strchr && !__STDC__ */
+
+#include "readline.h"
+#include "rlprivate.h"
+
+static int find_matching_open PARAMS((char *, int, int));
+
+/* Non-zero means try to blink the matching open parenthesis when the
+ close parenthesis is inserted. */
+#if defined (HAVE_SELECT)
+int rl_blink_matching_paren = 1;
+#else /* !HAVE_SELECT */
+int rl_blink_matching_paren = 0;
+#endif /* !HAVE_SELECT */
+
+static int _paren_blink_usec = 500000;
+
+/* Change emacs_standard_keymap to have bindings for paren matching when
+ ON_OR_OFF is 1, change them back to self_insert when ON_OR_OFF == 0. */
+void
+_rl_enable_paren_matching (on_or_off)
+ int on_or_off;
+{
+ if (on_or_off)
+ { /* ([{ */
+ rl_bind_key_in_map (')', rl_insert_close, emacs_standard_keymap);
+ rl_bind_key_in_map (']', rl_insert_close, emacs_standard_keymap);
+ rl_bind_key_in_map ('}', rl_insert_close, emacs_standard_keymap);
+ }
+ else
+ { /* ([{ */
+ rl_bind_key_in_map (')', rl_insert, emacs_standard_keymap);
+ rl_bind_key_in_map (']', rl_insert, emacs_standard_keymap);
+ rl_bind_key_in_map ('}', rl_insert, emacs_standard_keymap);
+ }
+}
+
+int
+rl_set_paren_blink_timeout (u)
+ int u;
+{
+ int o;
+
+ o = _paren_blink_usec;
+ if (u > 0)
+ _paren_blink_usec = u;
+ return (o);
+}
+
+int
+rl_insert_close (count, invoking_key)
+ int count, invoking_key;
+{
+ if (rl_explicit_arg || !rl_blink_matching_paren)
+ _rl_insert_char (count, invoking_key);
+ else
+ {
+#if defined HAVE_SELECT && !defined _WIN32
+ int orig_point, match_point, ready;
+ struct timeval timer;
+ fd_set readfds;
+
+ _rl_insert_char (1, invoking_key);
+ (*rl_redisplay_function) ();
+ match_point =
+ find_matching_open (rl_line_buffer, rl_point - 2, invoking_key);
+
+ /* Emacs might message or ring the bell here, but I don't. */
+ if (match_point < 0)
+ return -1;
+
+ FD_ZERO (&readfds);
+ FD_SET (fileno (rl_instream), &readfds);
+ timer.tv_sec = 0;
+ timer.tv_usec = _paren_blink_usec;
+
+ orig_point = rl_point;
+ rl_point = match_point;
+ (*rl_redisplay_function) ();
+ ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
+ rl_point = orig_point;
+#else /* !HAVE_SELECT */
+ _rl_insert_char (count, invoking_key);
+#endif /* !HAVE_SELECT */
+ }
+ return 0;
+}
+
+static int
+find_matching_open (string, from, closer)
+ char *string;
+ int from, closer;
+{
+ register int i;
+ int opener, level, delimiter;
+
+ switch (closer)
+ {
+ case ']': opener = '['; break;
+ case '}': opener = '{'; break;
+ case ')': opener = '('; break;
+ default:
+ return (-1);
+ }
+
+ level = 1; /* The closer passed in counts as 1. */
+ delimiter = 0; /* Delimited state unknown. */
+
+ for (i = from; i > -1; i--)
+ {
+ if (delimiter && (string[i] == delimiter))
+ delimiter = 0;
+ else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i]))
+ delimiter = string[i];
+ else if (!delimiter && (string[i] == closer))
+ level++;
+ else if (!delimiter && (string[i] == opener))
+ level--;
+
+ if (!level)
+ break;
+ }
+ return (i);
+}
diff --git a/MSVC/readline/posixdir.h b/MSVC/readline/posixdir.h
index b75259a..25c5836 100644
--- a/MSVC/readline/posixdir.h
+++ b/MSVC/readline/posixdir.h
@@ -1,57 +1,57 @@
-/* posixdir.h -- Posix directory reading includes and defines. */
-
-/* Copyright (C) 1987,1991 Free Software Foundation, Inc.
-
- This file is part of GNU Bash, the Bourne Again SHell.
-
- Bash 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, or (at your option)
- any later version.
-
- Bash 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 Bash; see the file COPYING. If not, write to the Free
- Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-/* This file should be included instead of <dirent.h> or <sys/dir.h>. */
-
-#if !defined (_POSIXDIR_H_)
-#define _POSIXDIR_H_
-
-#if defined (HAVE_DIRENT_H)
-# include "dirent.h"
-# define D_NAMLEN(d) (strlen ((d)->d_name))
-#else
-# if defined (HAVE_SYS_NDIR_H)
-# include <sys/ndir.h>
-# endif
-# if defined (HAVE_SYS_DIR_H)
-# include <sys/dir.h>
-# endif
-# if defined (HAVE_NDIR_H)
-# include <ndir.h>
-# endif
-# if !defined (dirent)
-# define dirent direct
-# endif /* !dirent */
-# define D_NAMLEN(d) ((d)->d_namlen)
-#endif /* !HAVE_DIRENT_H */
-
-#if defined (STRUCT_DIRENT_HAS_D_INO) && !defined (STRUCT_DIRENT_HAS_D_FILENO)
-# define d_fileno d_ino
-#endif
-
-#if defined (_POSIX_SOURCE) && (!defined (STRUCT_DIRENT_HAS_D_INO) || defined (BROKEN_DIRENT_D_INO))
-/* Posix does not require that the d_ino field be present, and some
- systems do not provide it. */
-# define REAL_DIR_ENTRY(dp) 1
-#else
-# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
-#endif /* _POSIX_SOURCE */
-
-#endif /* !_POSIXDIR_H_ */
+/* posixdir.h -- Posix directory reading includes and defines. */
+
+/* Copyright (C) 1987,1991 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ Bash 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, or (at your option)
+ any later version.
+
+ Bash 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 Bash; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+/* This file should be included instead of <dirent.h> or <sys/dir.h>. */
+
+#if !defined (_POSIXDIR_H_)
+#define _POSIXDIR_H_
+
+#if defined (HAVE_DIRENT_H)
+# include "dirent.h"
+# define D_NAMLEN(d) (strlen ((d)->d_name))
+#else
+# if defined (HAVE_SYS_NDIR_H)
+# include <sys/ndir.h>
+# endif
+# if defined (HAVE_SYS_DIR_H)
+# include <sys/dir.h>
+# endif
+# if defined (HAVE_NDIR_H)
+# include <ndir.h>
+# endif
+# if !defined (dirent)
+# define dirent direct
+# endif /* !dirent */
+# define D_NAMLEN(d) ((d)->d_namlen)
+#endif /* !HAVE_DIRENT_H */
+
+#if defined (STRUCT_DIRENT_HAS_D_INO) && !defined (STRUCT_DIRENT_HAS_D_FILENO)
+# define d_fileno d_ino
+#endif
+
+#if defined (_POSIX_SOURCE) && (!defined (STRUCT_DIRENT_HAS_D_INO) || defined (BROKEN_DIRENT_D_INO))
+/* Posix does not require that the d_ino field be present, and some
+ systems do not provide it. */
+# define REAL_DIR_ENTRY(dp) 1
+#else
+# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
+#endif /* _POSIX_SOURCE */
+
+#endif /* !_POSIXDIR_H_ */
diff --git a/MSVC/readline/posixjmp.h b/MSVC/readline/posixjmp.h
index 6a05ea7..b52aa00 100644
--- a/MSVC/readline/posixjmp.h
+++ b/MSVC/readline/posixjmp.h
@@ -1,40 +1,40 @@
-/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */
-
-/* Copyright (C) 1987,1991 Free Software Foundation, Inc.
-
- This file is part of GNU Bash, the Bourne Again SHell.
-
- Bash 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, or (at your option)
- any later version.
-
- Bash 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 Bash; see the file COPYING. If not, write to the Free
- Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#ifndef _POSIXJMP_H_
-#define _POSIXJMP_H_
-
-#include <setjmp.h>
-
-/* This *must* be included *after* config.h */
-
-#if defined (HAVE_POSIX_SIGSETJMP)
-# define procenv_t sigjmp_buf
-# if !defined (__OPENNT)
-# undef setjmp
-# define setjmp(x) sigsetjmp((x), 1)
-# undef longjmp
-# define longjmp(x, n) siglongjmp((x), (n))
-# endif /* !__OPENNT */
-#else
-# define procenv_t jmp_buf
-#endif
-
-#endif /* _POSIXJMP_H_ */
+/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */
+
+/* Copyright (C) 1987,1991 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ Bash 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, or (at your option)
+ any later version.
+
+ Bash 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 Bash; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#ifndef _POSIXJMP_H_
+#define _POSIXJMP_H_
+
+#include <setjmp.h>
+
+/* This *must* be included *after* config.h */
+
+#if defined (HAVE_POSIX_SIGSETJMP)
+# define procenv_t sigjmp_buf
+# if !defined (__OPENNT)
+# undef setjmp
+# define setjmp(x) sigsetjmp((x), 1)
+# undef longjmp
+# define longjmp(x, n) siglongjmp((x), (n))
+# endif /* !__OPENNT */
+#else
+# define procenv_t jmp_buf
+#endif
+
+#endif /* _POSIXJMP_H_ */
diff --git a/MSVC/readline/posixstat.h b/MSVC/readline/posixstat.h
index 1ba6aef..c93b528 100644
--- a/MSVC/readline/posixstat.h
+++ b/MSVC/readline/posixstat.h
@@ -1,142 +1,142 @@
-/* posixstat.h -- Posix stat(2) definitions for systems that
- don't have them. */
-
-/* Copyright (C) 1987,1991 Free Software Foundation, Inc.
-
- This file is part of GNU Bash, the Bourne Again SHell.
-
- Bash 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, or (at your option)
- any later version.
-
- Bash 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 Bash; see the file COPYING. If not, write to the Free
- Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-/* This file should be included instead of <sys/stat.h>.
- It relies on the local sys/stat.h to work though. */
-#if !defined (_POSIXSTAT_H_)
-#define _POSIXSTAT_H_
-
-#include <sys/stat.h>
-
-#if defined (STAT_MACROS_BROKEN)
-# undef S_ISBLK
-# undef S_ISCHR
-# undef S_ISDIR
-# undef S_ISFIFO
-# undef S_ISREG
-# undef S_ISLNK
-#endif /* STAT_MACROS_BROKEN */
-
-/* These are guaranteed to work only on isc386 */
-#if !defined (S_IFDIR) && !defined (S_ISDIR)
-# define S_IFDIR 0040000
-#endif /* !S_IFDIR && !S_ISDIR */
-#if !defined (S_IFMT)
-# define S_IFMT 0170000
-#endif /* !S_IFMT */
-
-/* Posix 1003.1 5.6.1.1 <sys/stat.h> file types */
-
-/* Some Posix-wannabe systems define _S_IF* macros instead of S_IF*, but
- do not provide the S_IS* macros that Posix requires. */
-
-#if defined (_S_IFMT) && !defined (S_IFMT)
-#define S_IFMT _S_IFMT
-#endif
-#if defined (_S_IFIFO) && !defined (S_IFIFO)
-#define S_IFIFO _S_IFIFO
-#endif
-#if defined (_S_IFCHR) && !defined (S_IFCHR)
-#define S_IFCHR _S_IFCHR
-#endif
-#if defined (_S_IFDIR) && !defined (S_IFDIR)
-#define S_IFDIR _S_IFDIR
-#endif
-#if defined (_S_IFBLK) && !defined (S_IFBLK)
-#define S_IFBLK _S_IFBLK
-#endif
-#if defined (_S_IFREG) && !defined (S_IFREG)
-#define S_IFREG _S_IFREG
-#endif
-#if defined (_S_IFLNK) && !defined (S_IFLNK)
-#define S_IFLNK _S_IFLNK
-#endif
-#if defined (_S_IFSOCK) && !defined (S_IFSOCK)
-#define S_IFSOCK _S_IFSOCK
-#endif
-
-/* Test for each symbol individually and define the ones necessary (some
- systems claiming Posix compatibility define some but not all). */
-
-#if defined (S_IFBLK) && !defined (S_ISBLK)
-#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* block device */
-#endif
-
-#if defined (S_IFCHR) && !defined (S_ISCHR)
-#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* character device */
-#endif
-
-#if defined (S_IFDIR) && !defined (S_ISDIR)
-#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* directory */
-#endif
-
-#if defined (S_IFREG) && !defined (S_ISREG)
-#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) /* file */
-#endif
-
-#if defined (S_IFIFO) && !defined (S_ISFIFO)
-#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) /* fifo - named pipe */
-#endif
-
-#if defined (S_IFLNK) && !defined (S_ISLNK)
-#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* symbolic link */
-#endif
-
-#if defined (S_IFSOCK) && !defined (S_ISSOCK)
-#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) /* socket */
-#endif
-
-/*
- * POSIX 1003.1 5.6.1.2 <sys/stat.h> File Modes
- */
-
-#if !defined (S_IRWXU)
-# if !defined (S_IREAD)
-# define S_IREAD 00400
-# define S_IWRITE 00200
-# define S_IEXEC 00100
-# endif /* S_IREAD */
-
-# if !defined (S_IRUSR)
-# define S_IRUSR S_IREAD /* read, owner */
-# define S_IWUSR S_IWRITE /* write, owner */
-# define S_IXUSR S_IEXEC /* execute, owner */
-
-# define S_IRGRP (S_IREAD >> 3) /* read, group */
-# define S_IWGRP (S_IWRITE >> 3) /* write, group */
-# define S_IXGRP (S_IEXEC >> 3) /* execute, group */
-
-# define S_IROTH (S_IREAD >> 6) /* read, other */
-# define S_IWOTH (S_IWRITE >> 6) /* write, other */
-# define S_IXOTH (S_IEXEC >> 6) /* execute, other */
-# endif /* !S_IRUSR */
-
-# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
-# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
-# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
-#endif /* !S_IRWXU */
-
-/* These are non-standard, but are used in builtins.c$symbolic_umask() */
-#define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH)
-#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH)
-#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
-
-#endif /* _POSIXSTAT_H_ */
+/* posixstat.h -- Posix stat(2) definitions for systems that
+ don't have them. */
+
+/* Copyright (C) 1987,1991 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ Bash 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, or (at your option)
+ any later version.
+
+ Bash 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 Bash; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+/* This file should be included instead of <sys/stat.h>.
+ It relies on the local sys/stat.h to work though. */
+#if !defined (_POSIXSTAT_H_)
+#define _POSIXSTAT_H_
+
+#include <sys/stat.h>
+
+#if defined (STAT_MACROS_BROKEN)
+# undef S_ISBLK
+# undef S_ISCHR
+# undef S_ISDIR
+# undef S_ISFIFO
+# undef S_ISREG
+# undef S_ISLNK
+#endif /* STAT_MACROS_BROKEN */
+
+/* These are guaranteed to work only on isc386 */
+#if !defined (S_IFDIR) && !defined (S_ISDIR)
+# define S_IFDIR 0040000
+#endif /* !S_IFDIR && !S_ISDIR */
+#if !defined (S_IFMT)
+# define S_IFMT 0170000
+#endif /* !S_IFMT */
+
+/* Posix 1003.1 5.6.1.1 <sys/stat.h> file types */
+
+/* Some Posix-wannabe systems define _S_IF* macros instead of S_IF*, but
+ do not provide the S_IS* macros that Posix requires. */
+
+#if defined (_S_IFMT) && !defined (S_IFMT)
+#define S_IFMT _S_IFMT
+#endif
+#if defined (_S_IFIFO) && !defined (S_IFIFO)
+#define S_IFIFO _S_IFIFO
+#endif
+#if defined (_S_IFCHR) && !defined (S_IFCHR)
+#define S_IFCHR _S_IFCHR
+#endif
+#if defined (_S_IFDIR) && !defined (S_IFDIR)
+#define S_IFDIR _S_IFDIR
+#endif
+#if defined (_S_IFBLK) && !defined (S_IFBLK)
+#define S_IFBLK _S_IFBLK
+#endif
+#if defined (_S_IFREG) && !defined (S_IFREG)
+#define S_IFREG _S_IFREG
+#endif
+#if defined (_S_IFLNK) && !defined (S_IFLNK)
+#define S_IFLNK _S_IFLNK
+#endif
+#if defined (_S_IFSOCK) && !defined (S_IFSOCK)
+#define S_IFSOCK _S_IFSOCK
+#endif
+
+/* Test for each symbol individually and define the ones necessary (some
+ systems claiming Posix compatibility define some but not all). */
+
+#if defined (S_IFBLK) && !defined (S_ISBLK)
+#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* block device */
+#endif
+
+#if defined (S_IFCHR) && !defined (S_ISCHR)
+#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* character device */
+#endif
+
+#if defined (S_IFDIR) && !defined (S_ISDIR)
+#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* directory */
+#endif
+
+#if defined (S_IFREG) && !defined (S_ISREG)
+#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) /* file */
+#endif
+
+#if defined (S_IFIFO) && !defined (S_ISFIFO)
+#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) /* fifo - named pipe */
+#endif
+
+#if defined (S_IFLNK) && !defined (S_ISLNK)
+#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* symbolic link */
+#endif
+
+#if defined (S_IFSOCK) && !defined (S_ISSOCK)
+#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) /* socket */
+#endif
+
+/*
+ * POSIX 1003.1 5.6.1.2 <sys/stat.h> File Modes
+ */
+
+#if !defined (S_IRWXU)
+# if !defined (S_IREAD)
+# define S_IREAD 00400
+# define S_IWRITE 00200
+# define S_IEXEC 00100
+# endif /* S_IREAD */
+
+# if !defined (S_IRUSR)
+# define S_IRUSR S_IREAD /* read, owner */
+# define S_IWUSR S_IWRITE /* write, owner */
+# define S_IXUSR S_IEXEC /* execute, owner */
+
+# define S_IRGRP (S_IREAD >> 3) /* read, group */
+# define S_IWGRP (S_IWRITE >> 3) /* write, group */
+# define S_IXGRP (S_IEXEC >> 3) /* execute, group */
+
+# define S_IROTH (S_IREAD >> 6) /* read, other */
+# define S_IWOTH (S_IWRITE >> 6) /* write, other */
+# define S_IXOTH (S_IEXEC >> 6) /* execute, other */
+# endif /* !S_IRUSR */
+
+# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
+# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
+# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
+#endif /* !S_IRWXU */
+
+/* These are non-standard, but are used in builtins.c$symbolic_umask() */
+#define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH)
+#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH)
+#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
+
+#endif /* _POSIXSTAT_H_ */
diff --git a/MSVC/readline/readline.c b/MSVC/readline/readline.c
index 21694c7..54fea59 100644
--- a/MSVC/readline/readline.c
+++ b/MSVC/readline/readline.c
@@ -1,979 +1,979 @@
-/* readline.c -- a general facility for reading lines of input
- with emacs style editing and completion. */
-
-/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-#include "posixstat.h"
-#include <fcntl.h>
-#if defined (HAVE_SYS_FILE_H)
-# include <sys/file.h>
-#endif /* HAVE_SYS_FILE_H */
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_LOCALE_H)
-# include <locale.h>
-#endif
-
-#include <stdio.h>
-#include "posixjmp.h"
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-#if defined (__EMX__)
-# define INCL_DOSPROCESS
-# include <os2.h>
-#endif /* __EMX__ */
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "rlshell.h"
-#include "xmalloc.h"
-
-#ifndef RL_LIBRARY_VERSION
-# define RL_LIBRARY_VERSION "4.3"
-#endif
-
-#ifndef RL_READLINE_VERSION
-# define RL_READLINE_VERSION 0x0403
-#endif
-
-extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
-
-/* Forward declarations used in this file. */
-static char *readline_internal PARAMS((void));
-static void readline_initialize_everything PARAMS((void));
-
-static void bind_arrow_keys_internal PARAMS((Keymap));
-static void bind_arrow_keys PARAMS((void));
-
-static void readline_default_bindings PARAMS((void));
-
-/* **************************************************************** */
-/* */
-/* Line editing input utility */
-/* */
-/* **************************************************************** */
-
-const char *rl_library_version = RL_LIBRARY_VERSION;
-
-int rl_readline_version = RL_READLINE_VERSION;
-
-/* True if this is `real' readline as opposed to some stub substitute. */
-int rl_gnu_readline_p = 1;
-
-/* A pointer to the keymap that is currently in use.
- By default, it is the standard emacs keymap. */
-Keymap _rl_keymap = emacs_standard_keymap;
-
-/* The current style of editing. */
-int rl_editing_mode = emacs_mode;
-
-/* The current insert mode: input (the default) or overwrite */
-int rl_insert_mode = RL_IM_DEFAULT;
-
-/* Non-zero if we called this function from _rl_dispatch(). It's present
- so functions can find out whether they were called from a key binding
- or directly from an application. */
-int rl_dispatching;
-
-/* Non-zero if the previous command was a kill command. */
-int _rl_last_command_was_kill = 0;
-
-/* The current value of the numeric argument specified by the user. */
-int rl_numeric_arg = 1;
-
-/* Non-zero if an argument was typed. */
-int rl_explicit_arg = 0;
-
-/* Temporary value used while generating the argument. */
-int rl_arg_sign = 1;
-
-/* Non-zero means we have been called at least once before. */
-static int rl_initialized;
-
-#if 0
-/* If non-zero, this program is running in an EMACS buffer. */
-static int running_in_emacs;
-#endif
-
-/* Flags word encapsulating the current readline state. */
-int rl_readline_state = RL_STATE_NONE;
-
-/* The current offset in the current input line. */
-int rl_point;
-
-/* Mark in the current input line. */
-int rl_mark;
-
-/* Length of the current input line. */
-int rl_end;
-
-/* Make this non-zero to return the current input_line. */
-int rl_done;
-
-/* The last function executed by readline. */
-rl_command_func_t *rl_last_func = (rl_command_func_t *)NULL;
-
-/* Top level environment for readline_internal (). */
-procenv_t readline_top_level;
-
-/* The streams we interact with. */
-FILE *_rl_in_stream, *_rl_out_stream;
-
-/* The names of the streams that we do input and output to. */
-FILE *rl_instream = (FILE *)NULL;
-FILE *rl_outstream = (FILE *)NULL;
-
-/* Non-zero means echo characters as they are read. Defaults to no echo;
- set to 1 if there is a controlling terminal, we can get its attributes,
- and the attributes include `echo'. Look at rltty.c:prepare_terminal_settings
- for the code that sets it. */
-int readline_echoing_p = 0;
-
-/* Current prompt. */
-char *rl_prompt = (char *)NULL;
-int rl_visible_prompt_length = 0;
-
-/* Set to non-zero by calling application if it has already printed rl_prompt
- and does not want readline to do it the first time. */
-int rl_already_prompted = 0;
-
-/* The number of characters read in order to type this complete command. */
-int rl_key_sequence_length = 0;
-
-/* If non-zero, then this is the address of a function to call just
- before readline_internal_setup () prints the first prompt. */
-rl_hook_func_t *rl_startup_hook = (rl_hook_func_t *)NULL;
-
-/* If non-zero, this is the address of a function to call just before
- readline_internal_setup () returns and readline_internal starts
- reading input characters. */
-rl_hook_func_t *rl_pre_input_hook = (rl_hook_func_t *)NULL;
-
-/* What we use internally. You should always refer to RL_LINE_BUFFER. */
-static char *the_line;
-
-/* The character that can generate an EOF. Really read from
- the terminal driver... just defaulted here. */
-int _rl_eof_char = CTRL ('D');
-
-/* Non-zero makes this the next keystroke to read. */
-int rl_pending_input = 0;
-
-/* Pointer to a useful terminal name. */
-const char *rl_terminal_name = (const char *)NULL;
-
-/* Non-zero means to always use horizontal scrolling in line display. */
-int _rl_horizontal_scroll_mode = 0;
-
-/* Non-zero means to display an asterisk at the starts of history lines
- which have been modified. */
-int _rl_mark_modified_lines = 0;
-
-/* The style of `bell' notification preferred. This can be set to NO_BELL,
- AUDIBLE_BELL, or VISIBLE_BELL. */
-int _rl_bell_preference = AUDIBLE_BELL;
-
-/* String inserted into the line by rl_insert_comment (). */
-char *_rl_comment_begin;
-
-/* Keymap holding the function currently being executed. */
-Keymap rl_executing_keymap;
-
-/* Non-zero means to erase entire line, including prompt, on empty input lines. */
-int rl_erase_empty_line = 0;
-
-/* Non-zero means to read only this many characters rather than up to a
- character bound to accept-line. */
-int rl_num_chars_to_read;
-
-/* Line buffer and maintenence. */
-char *rl_line_buffer = (char *)NULL;
-int rl_line_buffer_len = 0;
-
-/* Forward declarations used by the display, termcap, and history code. */
-
-/* **************************************************************** */
-/* */
-/* `Forward' declarations */
-/* */
-/* **************************************************************** */
-
-/* Non-zero means do not parse any lines other than comments and
- parser directives. */
-unsigned char _rl_parsing_conditionalized_out = 0;
-
-/* Non-zero means to convert characters with the meta bit set to
- escape-prefixed characters so we can indirect through
- emacs_meta_keymap or vi_escape_keymap. */
-int _rl_convert_meta_chars_to_ascii = 1;
-
-/* Non-zero means to output characters with the meta bit set directly
- rather than as a meta-prefixed escape sequence. */
-int _rl_output_meta_chars = 0;
-
-/* **************************************************************** */
-/* */
-/* Top Level Functions */
-/* */
-/* **************************************************************** */
-
-/* Non-zero means treat 0200 bit in terminal input as Meta bit. */
-int _rl_meta_flag = 0; /* Forward declaration */
-
-/* Set up the prompt and expand it. Called from readline() and
- rl_callback_handler_install (). */
-int
-rl_set_prompt (prompt)
- const char *prompt;
-{
- FREE (rl_prompt);
- rl_prompt = prompt ? savestring (prompt) : (char *)NULL;
-
- rl_visible_prompt_length = rl_expand_prompt (rl_prompt);
- return 0;
-}
-
-/* Read a line of input. Prompt with PROMPT. An empty PROMPT means
- none. A return value of NULL means that EOF was encountered. */
-char *
-readline (prompt)
- const char *prompt;
-{
- char *value;
-
- /* If we are at EOF return a NULL string. */
- if (rl_pending_input == EOF)
- {
- rl_clear_pending_input ();
- return ((char *)NULL);
- }
-
- rl_set_prompt (prompt);
-
- rl_initialize ();
- (*rl_prep_term_function) (_rl_meta_flag);
-
-#if defined (HANDLE_SIGNALS)
- rl_set_signals ();
-#endif
-
- value = readline_internal ();
- (*rl_deprep_term_function) ();
-
-#if defined (HANDLE_SIGNALS)
- rl_clear_signals ();
-#endif
-
- return (value);
-}
-
-#if defined (READLINE_CALLBACKS)
-# define STATIC_CALLBACK
-#else
-# define STATIC_CALLBACK static
-#endif
-
-STATIC_CALLBACK void
-readline_internal_setup ()
-{
- char *nprompt;
-
- _rl_in_stream = rl_instream;
- _rl_out_stream = rl_outstream;
-
- if (rl_startup_hook)
- (*rl_startup_hook) ();
-
- /* If we're not echoing, we still want to at least print a prompt, because
- rl_redisplay will not do it for us. If the calling application has a
- custom redisplay function, though, let that function handle it. */
- if (readline_echoing_p == 0 && rl_redisplay_function == rl_redisplay)
- {
- if (rl_prompt && rl_already_prompted == 0)
- {
- nprompt = _rl_strip_prompt (rl_prompt);
- fprintf (_rl_out_stream, "%s", nprompt);
- fflush (_rl_out_stream);
- free (nprompt);
- }
- }
- else
- {
- if (rl_prompt && rl_already_prompted)
- rl_on_new_line_with_prompt ();
- else
- rl_on_new_line ();
- (*rl_redisplay_function) ();
- }
-
-#if defined (VI_MODE)
- if (rl_editing_mode == vi_mode)
- rl_vi_insertion_mode (1, 0);
-#endif /* VI_MODE */
-
- if (rl_pre_input_hook)
- (*rl_pre_input_hook) ();
-}
-
-STATIC_CALLBACK char *
-readline_internal_teardown (eof)
- int eof;
-{
- char *temp;
- HIST_ENTRY *entry;
-
- /* Restore the original of this history line, iff the line that we
- are editing was originally in the history, AND the line has changed. */
- entry = current_history ();
-
- if (entry && rl_undo_list)
- {
- temp = savestring (the_line);
- rl_revert_line (1, 0);
- entry = replace_history_entry (where_history (), the_line, (histdata_t)NULL);
- _rl_free_history_entry (entry);
-
- strcpy (the_line, temp);
- free (temp);
- }
-
- /* At any rate, it is highly likely that this line has an undo list. Get
- rid of it now. */
- if (rl_undo_list)
- rl_free_undo_list ();
-
- /* Restore normal cursor, if available. */
- _rl_set_insert_mode (RL_IM_INSERT, 0);
-
- return (eof ? (char *)NULL : savestring (the_line));
-}
-
-STATIC_CALLBACK int
-#if defined (READLINE_CALLBACKS)
-readline_internal_char ()
-#else
-readline_internal_charloop ()
-#endif
-{
- static int lastc, eof_found;
- int c, code, lk;
-
- lastc = -1;
- eof_found = 0;
-
-#if !defined (READLINE_CALLBACKS)
- while (rl_done == 0)
- {
-#endif
- lk = _rl_last_command_was_kill;
- code = setjmp (readline_top_level);
-
- if (code)
- (*rl_redisplay_function) ();
-
- if (rl_pending_input == 0)
- {
- /* Then initialize the argument and number of keys read. */
- _rl_init_argument ();
- rl_key_sequence_length = 0;
- }
-
- RL_SETSTATE(RL_STATE_READCMD);
- c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_READCMD);
-
- /* EOF typed to a non-blank line is a <NL>. */
- if (c == EOF && rl_end)
- c = NEWLINE;
-
- /* The character _rl_eof_char typed to blank line, and not as the
- previous character is interpreted as EOF. */
- if (((c == _rl_eof_char && lastc != c) || c == EOF) && !rl_end)
- {
-#if defined (READLINE_CALLBACKS)
- RL_SETSTATE(RL_STATE_DONE);
- return (rl_done = 1);
-#else
- eof_found = 1;
- break;
-#endif
- }
-
- lastc = c;
-// _rl_dispatch ((unsigned char)c, _rl_keymap);
- _rl_dispatch (c, _rl_keymap);
-
- /* If there was no change in _rl_last_command_was_kill, then no kill
- has taken place. Note that if input is pending we are reading
- a prefix command, so nothing has changed yet. */
- if (rl_pending_input == 0 && lk == _rl_last_command_was_kill)
- _rl_last_command_was_kill = 0;
-
-#if defined (VI_MODE)
- /* In vi mode, when you exit insert mode, the cursor moves back
- over the previous character. We explicitly check for that here. */
- if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
- rl_vi_check ();
-#endif /* VI_MODE */
-
- if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read)
- {
- (*rl_redisplay_function) ();
- rl_newline (1, '\n');
- }
-
- if (rl_done == 0)
- (*rl_redisplay_function) ();
-
- /* If the application writer has told us to erase the entire line if
- the only character typed was something bound to rl_newline, do so. */
- if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline &&
- rl_point == 0 && rl_end == 0)
- _rl_erase_entire_line ();
-
-#if defined (READLINE_CALLBACKS)
- return 0;
-#else
- }
-
- return (eof_found);
-#endif
-}
-
-#if defined (READLINE_CALLBACKS)
-static int
-readline_internal_charloop ()
-{
- int eof = 1;
-
- while (rl_done == 0)
- eof = readline_internal_char ();
- return (eof);
-}
-#endif /* READLINE_CALLBACKS */
-
-/* Read a line of input from the global rl_instream, doing output on
- the global rl_outstream.
- If rl_prompt is non-null, then that is our prompt. */
-static char *
-readline_internal ()
-{
- int eof;
-
- readline_internal_setup ();
- eof = readline_internal_charloop ();
- return (readline_internal_teardown (eof));
-}
-
-void
-_rl_init_line_state ()
-{
- rl_point = rl_end = rl_mark = 0;
- the_line = rl_line_buffer;
- the_line[0] = 0;
-}
-
-void
-_rl_set_the_line ()
-{
- the_line = rl_line_buffer;
-}
-
-/* Do the command associated with KEY in MAP.
- If the associated command is really a keymap, then read
- another key, and dispatch into that map. */
-int
-_rl_dispatch (key, map)
- register int key;
- Keymap map;
-{
- return _rl_dispatch_subseq (key, map, 0);
-}
-
-int
-_rl_dispatch_subseq (key, map, got_subseq)
- register int key;
- Keymap map;
- int got_subseq;
-{
- int r, newkey;
- char *macro;
- rl_command_func_t *func;
-
- if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
- {
- if (map[ESC].type == ISKMAP)
- {
- if (RL_ISSTATE (RL_STATE_MACRODEF))
- _rl_add_macro_char (ESC);
- map = FUNCTION_TO_KEYMAP (map, ESC);
- key = UNMETA (key);
- rl_key_sequence_length += 2;
- return (_rl_dispatch (key, map));
- }
- else
- rl_ding ();
- return 0;
- }
-
- if (RL_ISSTATE (RL_STATE_MACRODEF))
- _rl_add_macro_char (key);
-
- r = 0;
- switch (map[key].type)
- {
- case ISFUNC:
- func = map[key].function;
- if (func)
- {
- /* Special case rl_do_lowercase_version (). */
- if (func == rl_do_lowercase_version)
- return (_rl_dispatch (_rl_to_lower (key), map));
-
- rl_executing_keymap = map;
-
-#if 0
- _rl_suppress_redisplay = (map[key].function == rl_insert) && _rl_input_available ();
-#endif
-
- rl_dispatching = 1;
- RL_SETSTATE(RL_STATE_DISPATCHING);
- r = (*map[key].function)(rl_numeric_arg * rl_arg_sign, key);
- RL_UNSETSTATE(RL_STATE_DISPATCHING);
- rl_dispatching = 0;
-
- /* If we have input pending, then the last command was a prefix
- command. Don't change the state of rl_last_func. Otherwise,
- remember the last command executed in this variable. */
- if (rl_pending_input == 0 && map[key].function != rl_digit_argument)
- rl_last_func = map[key].function;
- }
- else if (map[ANYOTHERKEY].function)
- {
- /* OK, there's no function bound in this map, but there is a
- shadow function that was overridden when the current keymap
- was created. Return -2 to note that. */
- _rl_unget_char (key);
- return -2;
- }
- else if (got_subseq)
- {
- /* Return -1 to note that we're in a subsequence, but we don't
- have a matching key, nor was one overridden. This means
- we need to back up the recursion chain and find the last
- subsequence that is bound to a function. */
- _rl_unget_char (key);
- return -1;
- }
- else
- {
- _rl_abort_internal ();
- return -1;
- }
- break;
-
- case ISKMAP:
- if (map[key].function != 0)
- {
-#if defined (VI_MODE)
- /* The only way this test will be true is if a subsequence has been
- bound starting with ESC, generally the arrow keys. What we do is
- check whether there's input in the queue, which there generally
- will be if an arrow key has been pressed, and, if there's not,
- just dispatch to (what we assume is) rl_vi_movement_mode right
- away. This is essentially an input test with a zero timeout. */
- if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap
- && _rl_input_queued (0) == 0)
- return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key)));
-#endif
-
- rl_key_sequence_length++;
-
- if (key == ESC)
- RL_SETSTATE(RL_STATE_METANEXT);
- RL_SETSTATE(RL_STATE_MOREINPUT);
- newkey = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
- if (key == ESC)
- RL_UNSETSTATE(RL_STATE_METANEXT);
-
- if (newkey < 0)
- {
- _rl_abort_internal ();
- return -1;
- }
-
- r = _rl_dispatch_subseq (newkey, FUNCTION_TO_KEYMAP (map, key), got_subseq || map[ANYOTHERKEY].function);
-
- if (r == -2)
- /* We didn't match anything, and the keymap we're indexed into
- shadowed a function previously bound to that prefix. Call
- the function. The recursive call to _rl_dispatch_subseq has
- already taken care of pushing any necessary input back onto
- the input queue with _rl_unget_char. */
- r = _rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key));
- else if (r && map[ANYOTHERKEY].function)
- {
- /* We didn't match (r is probably -1), so return something to
- tell the caller that it should try ANYOTHERKEY for an
- overridden function. */
- _rl_unget_char (key);
- return -2;
- }
- else if (r && got_subseq)
- {
- /* OK, back up the chain. */
- _rl_unget_char (key);
- return -1;
- }
- }
- else
- {
- _rl_abort_internal ();
- return -1;
- }
- break;
-
- case ISMACR:
- if (map[key].function != 0)
- {
- macro = savestring ((char *)map[key].function);
- _rl_with_macro_input (macro);
- return 0;
- }
- break;
- }
-#if defined (VI_MODE)
- if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap &&
- _rl_vi_textmod_command (key))
- _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
-#endif
- return (r);
-}
-
-/* **************************************************************** */
-/* */
-/* Initializations */
-/* */
-/* **************************************************************** */
-
-/* Initialize readline (and terminal if not already). */
-int
-rl_initialize ()
-{
- /* If we have never been called before, initialize the
- terminal and data structures. */
- if (!rl_initialized)
- {
- RL_SETSTATE(RL_STATE_INITIALIZING);
- readline_initialize_everything ();
- RL_UNSETSTATE(RL_STATE_INITIALIZING);
- rl_initialized++;
- RL_SETSTATE(RL_STATE_INITIALIZED);
- }
-
- /* Initalize the current line information. */
- _rl_init_line_state ();
-
- /* We aren't done yet. We haven't even gotten started yet! */
- rl_done = 0;
- RL_UNSETSTATE(RL_STATE_DONE);
-
- /* Tell the history routines what is going on. */
- _rl_start_using_history ();
-
- /* Make the display buffer match the state of the line. */
- rl_reset_line_state ();
-
- /* No such function typed yet. */
- rl_last_func = (rl_command_func_t *)NULL;
-
- /* Parsing of key-bindings begins in an enabled state. */
- _rl_parsing_conditionalized_out = 0;
-
-#if defined (VI_MODE)
- if (rl_editing_mode == vi_mode)
- _rl_vi_initialize_line ();
-#endif
-
- /* Each line starts in insert mode (the default). */
- _rl_set_insert_mode (RL_IM_DEFAULT, 1);
-
- return 0;
-}
-
-#if 0
-#if defined (__EMX__)
-static void
-_emx_build_environ ()
-{
- TIB *tibp;
- PIB *pibp;
- char *t, **tp;
- int c;
-
- DosGetInfoBlocks (&tibp, &pibp);
- t = pibp->pib_pchenv;
- for (c = 1; *t; c++)
- t += strlen (t) + 1;
- tp = environ = (char **)xmalloc ((c + 1) * sizeof (char *));
- t = pibp->pib_pchenv;
- while (*t)
- {
- *tp++ = t;
- t += strlen (t) + 1;
- }
- *tp = 0;
-}
-#endif /* __EMX__ */
-#endif
-
-/* Initialize the entire state of the world. */
-static void
-readline_initialize_everything ()
-{
-#if 0
-#if defined (__EMX__)
- if (environ == 0)
- _emx_build_environ ();
-#endif
-#endif
-
-#if 0
- /* Find out if we are running in Emacs -- UNUSED. */
- running_in_emacs = sh_get_env_value ("EMACS") != (char *)0;
-#endif
-
- /* Set up input and output if they are not already set up. */
- if (!rl_instream)
- rl_instream = stdin;
-
- if (!rl_outstream)
- rl_outstream = stdout;
-
- /* Bind _rl_in_stream and _rl_out_stream immediately. These values
- may change, but they may also be used before readline_internal ()
- is called. */
- _rl_in_stream = rl_instream;
- _rl_out_stream = rl_outstream;
-
- /* Allocate data structures. */
- if (rl_line_buffer == 0)
- rl_line_buffer = (char *)xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE);
-
- /* Initialize the terminal interface. */
- if (rl_terminal_name == 0)
- rl_terminal_name = sh_get_env_value ("TERM");
- _rl_init_terminal_io (rl_terminal_name);
-
- /* Bind tty characters to readline functions. */
- readline_default_bindings ();
-
- /* Initialize the function names. */
- rl_initialize_funmap ();
-
- /* Decide whether we should automatically go into eight-bit mode. */
- _rl_init_eightbit ();
-
- /* Read in the init file. */
- rl_read_init_file ((char *)NULL);
-
- /* XXX */
- if (_rl_horizontal_scroll_mode && _rl_term_autowrap)
- {
- _rl_screenwidth--;
- _rl_screenchars -= _rl_screenheight;
- }
-
- /* Override the effect of any `set keymap' assignments in the
- inputrc file. */
- rl_set_keymap_from_edit_mode ();
-
-#if !defined _WIN32
- /* Try to bind a common arrow key prefix, if not already bound. */
- bind_arrow_keys ();
-#endif /* !_WIN32 */
-
- /* Enable the meta key, if this terminal has one. */
- if (_rl_enable_meta)
- _rl_enable_meta_key ();
-
- /* If the completion parser's default word break characters haven't
- been set yet, then do so now. */
- if (rl_completer_word_break_characters == (char *)NULL)
- rl_completer_word_break_characters = rl_basic_word_break_characters;
-}
-
-/* If this system allows us to look at the values of the regular
- input editing characters, then bind them to their readline
- equivalents, iff the characters are not bound to keymaps. */
-static void
-readline_default_bindings ()
-{
- rl_tty_set_default_bindings (_rl_keymap);
-}
-
-#if !defined _WIN32 /* in Windows the rltty, i.e. console binding is sufficient */
-/* Bind some common arrow key sequences in MAP. */
-static void
-bind_arrow_keys_internal (map)
- Keymap map;
-{
- Keymap xkeymap;
-
- xkeymap = _rl_keymap;
- _rl_keymap = map;
-
-#if defined (__MSDOS__)
- _rl_bind_if_unbound ("\033[0A", rl_get_previous_history);
- _rl_bind_if_unbound ("\033[0B", rl_backward_char);
- _rl_bind_if_unbound ("\033[0C", rl_forward_char);
- _rl_bind_if_unbound ("\033[0D", rl_get_next_history);
-#endif
-
- _rl_bind_if_unbound ("\033[A", rl_get_previous_history);
- _rl_bind_if_unbound ("\033[B", rl_get_next_history);
- _rl_bind_if_unbound ("\033[C", rl_forward_char);
- _rl_bind_if_unbound ("\033[D", rl_backward_char);
- _rl_bind_if_unbound ("\033[H", rl_beg_of_line);
- _rl_bind_if_unbound ("\033[F", rl_end_of_line);
-
- _rl_bind_if_unbound ("\033OA", rl_get_previous_history);
- _rl_bind_if_unbound ("\033OB", rl_get_next_history);
- _rl_bind_if_unbound ("\033OC", rl_forward_char);
- _rl_bind_if_unbound ("\033OD", rl_backward_char);
- _rl_bind_if_unbound ("\033OH", rl_beg_of_line);
- _rl_bind_if_unbound ("\033OF", rl_end_of_line);
-
- _rl_keymap = xkeymap;
-}
-
-/* Try and bind the common arrow key prefixes after giving termcap and
- the inputrc file a chance to bind them and create `real' keymaps
- for the arrow key prefix. */
-static void
-bind_arrow_keys ()
-{
- bind_arrow_keys_internal (emacs_standard_keymap);
-
-#if defined (VI_MODE)
- bind_arrow_keys_internal (vi_movement_keymap);
- bind_arrow_keys_internal (vi_insertion_keymap);
-#endif
-}
-
-#endif /* !_WIN32 */
-
-/* **************************************************************** */
-/* */
-/* Saving and Restoring Readline's state */
-/* */
-/* **************************************************************** */
-
-int
-rl_save_state (sp)
- struct readline_state *sp;
-{
- if (sp == 0)
- return -1;
-
- sp->point = rl_point;
- sp->end = rl_end;
- sp->mark = rl_mark;
- sp->buffer = rl_line_buffer;
- sp->buflen = rl_line_buffer_len;
- sp->ul = rl_undo_list;
- sp->prompt = rl_prompt;
-
- sp->rlstate = rl_readline_state;
- sp->done = rl_done;
- sp->kmap = _rl_keymap;
-
- sp->lastfunc = rl_last_func;
- sp->insmode = rl_insert_mode;
- sp->edmode = rl_editing_mode;
- sp->kseqlen = rl_key_sequence_length;
- sp->inf = rl_instream;
- sp->outf = rl_outstream;
- sp->pendingin = rl_pending_input;
- sp->macro = rl_executing_macro;
-
- sp->catchsigs = rl_catch_signals;
-#ifdef SIGWINCH
- sp->catchsigwinch = rl_catch_sigwinch;
-#endif
-
- return (0);
-}
-
-int
-rl_restore_state (sp)
- struct readline_state *sp;
-{
- if (sp == 0)
- return -1;
-
- rl_point = sp->point;
- rl_end = sp->end;
- rl_mark = sp->mark;
- the_line = rl_line_buffer = sp->buffer;
- rl_line_buffer_len = sp->buflen;
- rl_undo_list = sp->ul;
- rl_prompt = sp->prompt;
-
- rl_readline_state = sp->rlstate;
- rl_done = sp->done;
- _rl_keymap = sp->kmap;
-
- rl_last_func = sp->lastfunc;
- rl_insert_mode = sp->insmode;
- rl_editing_mode = sp->edmode;
- rl_key_sequence_length = sp->kseqlen;
- rl_instream = sp->inf;
- rl_outstream = sp->outf;
- rl_pending_input = sp->pendingin;
- rl_executing_macro = sp->macro;
-
- rl_catch_signals = sp->catchsigs;
-#ifdef SIGWINCH
- rl_catch_sigwinch = sp->catchsigwinch;
-#endif
- return (0);
-}
+/* readline.c -- a general facility for reading lines of input
+ with emacs style editing and completion. */
+
+/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+#include "posixstat.h"
+#include <fcntl.h>
+#if defined (HAVE_SYS_FILE_H)
+# include <sys/file.h>
+#endif /* HAVE_SYS_FILE_H */
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_LOCALE_H)
+# include <locale.h>
+#endif
+
+#include <stdio.h>
+#include "posixjmp.h"
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+#include "rlmbutil.h"
+
+#if defined (__EMX__)
+# define INCL_DOSPROCESS
+# include <os2.h>
+#endif /* __EMX__ */
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "rlshell.h"
+#include "xmalloc.h"
+
+#ifndef RL_LIBRARY_VERSION
+# define RL_LIBRARY_VERSION "4.3"
+#endif
+
+#ifndef RL_READLINE_VERSION
+# define RL_READLINE_VERSION 0x0403
+#endif
+
+extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
+
+/* Forward declarations used in this file. */
+static char *readline_internal PARAMS((void));
+static void readline_initialize_everything PARAMS((void));
+
+static void bind_arrow_keys_internal PARAMS((Keymap));
+static void bind_arrow_keys PARAMS((void));
+
+static void readline_default_bindings PARAMS((void));
+
+/* **************************************************************** */
+/* */
+/* Line editing input utility */
+/* */
+/* **************************************************************** */
+
+const char *rl_library_version = RL_LIBRARY_VERSION;
+
+int rl_readline_version = RL_READLINE_VERSION;
+
+/* True if this is `real' readline as opposed to some stub substitute. */
+int rl_gnu_readline_p = 1;
+
+/* A pointer to the keymap that is currently in use.
+ By default, it is the standard emacs keymap. */
+Keymap _rl_keymap = emacs_standard_keymap;
+
+/* The current style of editing. */
+int rl_editing_mode = emacs_mode;
+
+/* The current insert mode: input (the default) or overwrite */
+int rl_insert_mode = RL_IM_DEFAULT;
+
+/* Non-zero if we called this function from _rl_dispatch(). It's present
+ so functions can find out whether they were called from a key binding
+ or directly from an application. */
+int rl_dispatching;
+
+/* Non-zero if the previous command was a kill command. */
+int _rl_last_command_was_kill = 0;
+
+/* The current value of the numeric argument specified by the user. */
+int rl_numeric_arg = 1;
+
+/* Non-zero if an argument was typed. */
+int rl_explicit_arg = 0;
+
+/* Temporary value used while generating the argument. */
+int rl_arg_sign = 1;
+
+/* Non-zero means we have been called at least once before. */
+static int rl_initialized;
+
+#if 0
+/* If non-zero, this program is running in an EMACS buffer. */
+static int running_in_emacs;
+#endif
+
+/* Flags word encapsulating the current readline state. */
+int rl_readline_state = RL_STATE_NONE;
+
+/* The current offset in the current input line. */
+int rl_point;
+
+/* Mark in the current input line. */
+int rl_mark;
+
+/* Length of the current input line. */
+int rl_end;
+
+/* Make this non-zero to return the current input_line. */
+int rl_done;
+
+/* The last function executed by readline. */
+rl_command_func_t *rl_last_func = (rl_command_func_t *)NULL;
+
+/* Top level environment for readline_internal (). */
+procenv_t readline_top_level;
+
+/* The streams we interact with. */
+FILE *_rl_in_stream, *_rl_out_stream;
+
+/* The names of the streams that we do input and output to. */
+FILE *rl_instream = (FILE *)NULL;
+FILE *rl_outstream = (FILE *)NULL;
+
+/* Non-zero means echo characters as they are read. Defaults to no echo;
+ set to 1 if there is a controlling terminal, we can get its attributes,
+ and the attributes include `echo'. Look at rltty.c:prepare_terminal_settings
+ for the code that sets it. */
+int readline_echoing_p = 0;
+
+/* Current prompt. */
+char *rl_prompt = (char *)NULL;
+int rl_visible_prompt_length = 0;
+
+/* Set to non-zero by calling application if it has already printed rl_prompt
+ and does not want readline to do it the first time. */
+int rl_already_prompted = 0;
+
+/* The number of characters read in order to type this complete command. */
+int rl_key_sequence_length = 0;
+
+/* If non-zero, then this is the address of a function to call just
+ before readline_internal_setup () prints the first prompt. */
+rl_hook_func_t *rl_startup_hook = (rl_hook_func_t *)NULL;
+
+/* If non-zero, this is the address of a function to call just before
+ readline_internal_setup () returns and readline_internal starts
+ reading input characters. */
+rl_hook_func_t *rl_pre_input_hook = (rl_hook_func_t *)NULL;
+
+/* What we use internally. You should always refer to RL_LINE_BUFFER. */
+static char *the_line;
+
+/* The character that can generate an EOF. Really read from
+ the terminal driver... just defaulted here. */
+int _rl_eof_char = CTRL ('D');
+
+/* Non-zero makes this the next keystroke to read. */
+int rl_pending_input = 0;
+
+/* Pointer to a useful terminal name. */
+const char *rl_terminal_name = (const char *)NULL;
+
+/* Non-zero means to always use horizontal scrolling in line display. */
+int _rl_horizontal_scroll_mode = 0;
+
+/* Non-zero means to display an asterisk at the starts of history lines
+ which have been modified. */
+int _rl_mark_modified_lines = 0;
+
+/* The style of `bell' notification preferred. This can be set to NO_BELL,
+ AUDIBLE_BELL, or VISIBLE_BELL. */
+int _rl_bell_preference = AUDIBLE_BELL;
+
+/* String inserted into the line by rl_insert_comment (). */
+char *_rl_comment_begin;
+
+/* Keymap holding the function currently being executed. */
+Keymap rl_executing_keymap;
+
+/* Non-zero means to erase entire line, including prompt, on empty input lines. */
+int rl_erase_empty_line = 0;
+
+/* Non-zero means to read only this many characters rather than up to a
+ character bound to accept-line. */
+int rl_num_chars_to_read;
+
+/* Line buffer and maintenence. */
+char *rl_line_buffer = (char *)NULL;
+int rl_line_buffer_len = 0;
+
+/* Forward declarations used by the display, termcap, and history code. */
+
+/* **************************************************************** */
+/* */
+/* `Forward' declarations */
+/* */
+/* **************************************************************** */
+
+/* Non-zero means do not parse any lines other than comments and
+ parser directives. */
+unsigned char _rl_parsing_conditionalized_out = 0;
+
+/* Non-zero means to convert characters with the meta bit set to
+ escape-prefixed characters so we can indirect through
+ emacs_meta_keymap or vi_escape_keymap. */
+int _rl_convert_meta_chars_to_ascii = 1;
+
+/* Non-zero means to output characters with the meta bit set directly
+ rather than as a meta-prefixed escape sequence. */
+int _rl_output_meta_chars = 0;
+
+/* **************************************************************** */
+/* */
+/* Top Level Functions */
+/* */
+/* **************************************************************** */
+
+/* Non-zero means treat 0200 bit in terminal input as Meta bit. */
+int _rl_meta_flag = 0; /* Forward declaration */
+
+/* Set up the prompt and expand it. Called from readline() and
+ rl_callback_handler_install (). */
+int
+rl_set_prompt (prompt)
+ const char *prompt;
+{
+ FREE (rl_prompt);
+ rl_prompt = prompt ? savestring (prompt) : (char *)NULL;
+
+ rl_visible_prompt_length = rl_expand_prompt (rl_prompt);
+ return 0;
+}
+
+/* Read a line of input. Prompt with PROMPT. An empty PROMPT means
+ none. A return value of NULL means that EOF was encountered. */
+char *
+readline (prompt)
+ const char *prompt;
+{
+ char *value;
+
+ /* If we are at EOF return a NULL string. */
+ if (rl_pending_input == EOF)
+ {
+ rl_clear_pending_input ();
+ return ((char *)NULL);
+ }
+
+ rl_set_prompt (prompt);
+
+ rl_initialize ();
+ (*rl_prep_term_function) (_rl_meta_flag);
+
+#if defined (HANDLE_SIGNALS)
+ rl_set_signals ();
+#endif
+
+ value = readline_internal ();
+ (*rl_deprep_term_function) ();
+
+#if defined (HANDLE_SIGNALS)
+ rl_clear_signals ();
+#endif
+
+ return (value);
+}
+
+#if defined (READLINE_CALLBACKS)
+# define STATIC_CALLBACK
+#else
+# define STATIC_CALLBACK static
+#endif
+
+STATIC_CALLBACK void
+readline_internal_setup ()
+{
+ char *nprompt;
+
+ _rl_in_stream = rl_instream;
+ _rl_out_stream = rl_outstream;
+
+ if (rl_startup_hook)
+ (*rl_startup_hook) ();
+
+ /* If we're not echoing, we still want to at least print a prompt, because
+ rl_redisplay will not do it for us. If the calling application has a
+ custom redisplay function, though, let that function handle it. */
+ if (readline_echoing_p == 0 && rl_redisplay_function == rl_redisplay)
+ {
+ if (rl_prompt && rl_already_prompted == 0)
+ {
+ nprompt = _rl_strip_prompt (rl_prompt);
+ fprintf (_rl_out_stream, "%s", nprompt);
+ fflush (_rl_out_stream);
+ free (nprompt);
+ }
+ }
+ else
+ {
+ if (rl_prompt && rl_already_prompted)
+ rl_on_new_line_with_prompt ();
+ else
+ rl_on_new_line ();
+ (*rl_redisplay_function) ();
+ }
+
+#if defined (VI_MODE)
+ if (rl_editing_mode == vi_mode)
+ rl_vi_insertion_mode (1, 0);
+#endif /* VI_MODE */
+
+ if (rl_pre_input_hook)
+ (*rl_pre_input_hook) ();
+}
+
+STATIC_CALLBACK char *
+readline_internal_teardown (eof)
+ int eof;
+{
+ char *temp;
+ HIST_ENTRY *entry;
+
+ /* Restore the original of this history line, iff the line that we
+ are editing was originally in the history, AND the line has changed. */
+ entry = current_history ();
+
+ if (entry && rl_undo_list)
+ {
+ temp = savestring (the_line);
+ rl_revert_line (1, 0);
+ entry = replace_history_entry (where_history (), the_line, (histdata_t)NULL);
+ _rl_free_history_entry (entry);
+
+ strcpy (the_line, temp);
+ free (temp);
+ }
+
+ /* At any rate, it is highly likely that this line has an undo list. Get
+ rid of it now. */
+ if (rl_undo_list)
+ rl_free_undo_list ();
+
+ /* Restore normal cursor, if available. */
+ _rl_set_insert_mode (RL_IM_INSERT, 0);
+
+ return (eof ? (char *)NULL : savestring (the_line));
+}
+
+STATIC_CALLBACK int
+#if defined (READLINE_CALLBACKS)
+readline_internal_char ()
+#else
+readline_internal_charloop ()
+#endif
+{
+ static int lastc, eof_found;
+ int c, code, lk;
+
+ lastc = -1;
+ eof_found = 0;
+
+#if !defined (READLINE_CALLBACKS)
+ while (rl_done == 0)
+ {
+#endif
+ lk = _rl_last_command_was_kill;
+ code = setjmp (readline_top_level);
+
+ if (code)
+ (*rl_redisplay_function) ();
+
+ if (rl_pending_input == 0)
+ {
+ /* Then initialize the argument and number of keys read. */
+ _rl_init_argument ();
+ rl_key_sequence_length = 0;
+ }
+
+ RL_SETSTATE(RL_STATE_READCMD);
+ c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_READCMD);
+
+ /* EOF typed to a non-blank line is a <NL>. */
+ if (c == EOF && rl_end)
+ c = NEWLINE;
+
+ /* The character _rl_eof_char typed to blank line, and not as the
+ previous character is interpreted as EOF. */
+ if (((c == _rl_eof_char && lastc != c) || c == EOF) && !rl_end)
+ {
+#if defined (READLINE_CALLBACKS)
+ RL_SETSTATE(RL_STATE_DONE);
+ return (rl_done = 1);
+#else
+ eof_found = 1;
+ break;
+#endif
+ }
+
+ lastc = c;
+// _rl_dispatch ((unsigned char)c, _rl_keymap);
+ _rl_dispatch (c, _rl_keymap);
+
+ /* If there was no change in _rl_last_command_was_kill, then no kill
+ has taken place. Note that if input is pending we are reading
+ a prefix command, so nothing has changed yet. */
+ if (rl_pending_input == 0 && lk == _rl_last_command_was_kill)
+ _rl_last_command_was_kill = 0;
+
+#if defined (VI_MODE)
+ /* In vi mode, when you exit insert mode, the cursor moves back
+ over the previous character. We explicitly check for that here. */
+ if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
+ rl_vi_check ();
+#endif /* VI_MODE */
+
+ if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read)
+ {
+ (*rl_redisplay_function) ();
+ rl_newline (1, '\n');
+ }
+
+ if (rl_done == 0)
+ (*rl_redisplay_function) ();
+
+ /* If the application writer has told us to erase the entire line if
+ the only character typed was something bound to rl_newline, do so. */
+ if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline &&
+ rl_point == 0 && rl_end == 0)
+ _rl_erase_entire_line ();
+
+#if defined (READLINE_CALLBACKS)
+ return 0;
+#else
+ }
+
+ return (eof_found);
+#endif
+}
+
+#if defined (READLINE_CALLBACKS)
+static int
+readline_internal_charloop ()
+{
+ int eof = 1;
+
+ while (rl_done == 0)
+ eof = readline_internal_char ();
+ return (eof);
+}
+#endif /* READLINE_CALLBACKS */
+
+/* Read a line of input from the global rl_instream, doing output on
+ the global rl_outstream.
+ If rl_prompt is non-null, then that is our prompt. */
+static char *
+readline_internal ()
+{
+ int eof;
+
+ readline_internal_setup ();
+ eof = readline_internal_charloop ();
+ return (readline_internal_teardown (eof));
+}
+
+void
+_rl_init_line_state ()
+{
+ rl_point = rl_end = rl_mark = 0;
+ the_line = rl_line_buffer;
+ the_line[0] = 0;
+}
+
+void
+_rl_set_the_line ()
+{
+ the_line = rl_line_buffer;
+}
+
+/* Do the command associated with KEY in MAP.
+ If the associated command is really a keymap, then read
+ another key, and dispatch into that map. */
+int
+_rl_dispatch (key, map)
+ register int key;
+ Keymap map;
+{
+ return _rl_dispatch_subseq (key, map, 0);
+}
+
+int
+_rl_dispatch_subseq (key, map, got_subseq)
+ register int key;
+ Keymap map;
+ int got_subseq;
+{
+ int r, newkey;
+ char *macro;
+ rl_command_func_t *func;
+
+ if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
+ {
+ if (map[ESC].type == ISKMAP)
+ {
+ if (RL_ISSTATE (RL_STATE_MACRODEF))
+ _rl_add_macro_char (ESC);
+ map = FUNCTION_TO_KEYMAP (map, ESC);
+ key = UNMETA (key);
+ rl_key_sequence_length += 2;
+ return (_rl_dispatch (key, map));
+ }
+ else
+ rl_ding ();
+ return 0;
+ }
+
+ if (RL_ISSTATE (RL_STATE_MACRODEF))
+ _rl_add_macro_char (key);
+
+ r = 0;
+ switch (map[key].type)
+ {
+ case ISFUNC:
+ func = map[key].function;
+ if (func)
+ {
+ /* Special case rl_do_lowercase_version (). */
+ if (func == rl_do_lowercase_version)
+ return (_rl_dispatch (_rl_to_lower (key), map));
+
+ rl_executing_keymap = map;
+
+#if 0
+ _rl_suppress_redisplay = (map[key].function == rl_insert) && _rl_input_available ();
+#endif
+
+ rl_dispatching = 1;
+ RL_SETSTATE(RL_STATE_DISPATCHING);
+ r = (*map[key].function)(rl_numeric_arg * rl_arg_sign, key);
+ RL_UNSETSTATE(RL_STATE_DISPATCHING);
+ rl_dispatching = 0;
+
+ /* If we have input pending, then the last command was a prefix
+ command. Don't change the state of rl_last_func. Otherwise,
+ remember the last command executed in this variable. */
+ if (rl_pending_input == 0 && map[key].function != rl_digit_argument)
+ rl_last_func = map[key].function;
+ }
+ else if (map[ANYOTHERKEY].function)
+ {
+ /* OK, there's no function bound in this map, but there is a
+ shadow function that was overridden when the current keymap
+ was created. Return -2 to note that. */
+ _rl_unget_char (key);
+ return -2;
+ }
+ else if (got_subseq)
+ {
+ /* Return -1 to note that we're in a subsequence, but we don't
+ have a matching key, nor was one overridden. This means
+ we need to back up the recursion chain and find the last
+ subsequence that is bound to a function. */
+ _rl_unget_char (key);
+ return -1;
+ }
+ else
+ {
+ _rl_abort_internal ();
+ return -1;
+ }
+ break;
+
+ case ISKMAP:
+ if (map[key].function != 0)
+ {
+#if defined (VI_MODE)
+ /* The only way this test will be true is if a subsequence has been
+ bound starting with ESC, generally the arrow keys. What we do is
+ check whether there's input in the queue, which there generally
+ will be if an arrow key has been pressed, and, if there's not,
+ just dispatch to (what we assume is) rl_vi_movement_mode right
+ away. This is essentially an input test with a zero timeout. */
+ if (rl_editing_mode == vi_mode && key == ESC && map == vi_insertion_keymap
+ && _rl_input_queued (0) == 0)
+ return (_rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key)));
+#endif
+
+ rl_key_sequence_length++;
+
+ if (key == ESC)
+ RL_SETSTATE(RL_STATE_METANEXT);
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ newkey = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+ if (key == ESC)
+ RL_UNSETSTATE(RL_STATE_METANEXT);
+
+ if (newkey < 0)
+ {
+ _rl_abort_internal ();
+ return -1;
+ }
+
+ r = _rl_dispatch_subseq (newkey, FUNCTION_TO_KEYMAP (map, key), got_subseq || map[ANYOTHERKEY].function);
+
+ if (r == -2)
+ /* We didn't match anything, and the keymap we're indexed into
+ shadowed a function previously bound to that prefix. Call
+ the function. The recursive call to _rl_dispatch_subseq has
+ already taken care of pushing any necessary input back onto
+ the input queue with _rl_unget_char. */
+ r = _rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key));
+ else if (r && map[ANYOTHERKEY].function)
+ {
+ /* We didn't match (r is probably -1), so return something to
+ tell the caller that it should try ANYOTHERKEY for an
+ overridden function. */
+ _rl_unget_char (key);
+ return -2;
+ }
+ else if (r && got_subseq)
+ {
+ /* OK, back up the chain. */
+ _rl_unget_char (key);
+ return -1;
+ }
+ }
+ else
+ {
+ _rl_abort_internal ();
+ return -1;
+ }
+ break;
+
+ case ISMACR:
+ if (map[key].function != 0)
+ {
+ macro = savestring ((char *)map[key].function);
+ _rl_with_macro_input (macro);
+ return 0;
+ }
+ break;
+ }
+#if defined (VI_MODE)
+ if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap &&
+ _rl_vi_textmod_command (key))
+ _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
+#endif
+ return (r);
+}
+
+/* **************************************************************** */
+/* */
+/* Initializations */
+/* */
+/* **************************************************************** */
+
+/* Initialize readline (and terminal if not already). */
+int
+rl_initialize ()
+{
+ /* If we have never been called before, initialize the
+ terminal and data structures. */
+ if (!rl_initialized)
+ {
+ RL_SETSTATE(RL_STATE_INITIALIZING);
+ readline_initialize_everything ();
+ RL_UNSETSTATE(RL_STATE_INITIALIZING);
+ rl_initialized++;
+ RL_SETSTATE(RL_STATE_INITIALIZED);
+ }
+
+ /* Initalize the current line information. */
+ _rl_init_line_state ();
+
+ /* We aren't done yet. We haven't even gotten started yet! */
+ rl_done = 0;
+ RL_UNSETSTATE(RL_STATE_DONE);
+
+ /* Tell the history routines what is going on. */
+ _rl_start_using_history ();
+
+ /* Make the display buffer match the state of the line. */
+ rl_reset_line_state ();
+
+ /* No such function typed yet. */
+ rl_last_func = (rl_command_func_t *)NULL;
+
+ /* Parsing of key-bindings begins in an enabled state. */
+ _rl_parsing_conditionalized_out = 0;
+
+#if defined (VI_MODE)
+ if (rl_editing_mode == vi_mode)
+ _rl_vi_initialize_line ();
+#endif
+
+ /* Each line starts in insert mode (the default). */
+ _rl_set_insert_mode (RL_IM_DEFAULT, 1);
+
+ return 0;
+}
+
+#if 0
+#if defined (__EMX__)
+static void
+_emx_build_environ ()
+{
+ TIB *tibp;
+ PIB *pibp;
+ char *t, **tp;
+ int c;
+
+ DosGetInfoBlocks (&tibp, &pibp);
+ t = pibp->pib_pchenv;
+ for (c = 1; *t; c++)
+ t += strlen (t) + 1;
+ tp = environ = (char **)xmalloc ((c + 1) * sizeof (char *));
+ t = pibp->pib_pchenv;
+ while (*t)
+ {
+ *tp++ = t;
+ t += strlen (t) + 1;
+ }
+ *tp = 0;
+}
+#endif /* __EMX__ */
+#endif
+
+/* Initialize the entire state of the world. */
+static void
+readline_initialize_everything ()
+{
+#if 0
+#if defined (__EMX__)
+ if (environ == 0)
+ _emx_build_environ ();
+#endif
+#endif
+
+#if 0
+ /* Find out if we are running in Emacs -- UNUSED. */
+ running_in_emacs = sh_get_env_value ("EMACS") != (char *)0;
+#endif
+
+ /* Set up input and output if they are not already set up. */
+ if (!rl_instream)
+ rl_instream = stdin;
+
+ if (!rl_outstream)
+ rl_outstream = stdout;
+
+ /* Bind _rl_in_stream and _rl_out_stream immediately. These values
+ may change, but they may also be used before readline_internal ()
+ is called. */
+ _rl_in_stream = rl_instream;
+ _rl_out_stream = rl_outstream;
+
+ /* Allocate data structures. */
+ if (rl_line_buffer == 0)
+ rl_line_buffer = (char *)xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE);
+
+ /* Initialize the terminal interface. */
+ if (rl_terminal_name == 0)
+ rl_terminal_name = sh_get_env_value ("TERM");
+ _rl_init_terminal_io (rl_terminal_name);
+
+ /* Bind tty characters to readline functions. */
+ readline_default_bindings ();
+
+ /* Initialize the function names. */
+ rl_initialize_funmap ();
+
+ /* Decide whether we should automatically go into eight-bit mode. */
+ _rl_init_eightbit ();
+
+ /* Read in the init file. */
+ rl_read_init_file ((char *)NULL);
+
+ /* XXX */
+ if (_rl_horizontal_scroll_mode && _rl_term_autowrap)
+ {
+ _rl_screenwidth--;
+ _rl_screenchars -= _rl_screenheight;
+ }
+
+ /* Override the effect of any `set keymap' assignments in the
+ inputrc file. */
+ rl_set_keymap_from_edit_mode ();
+
+#if !defined _WIN32
+ /* Try to bind a common arrow key prefix, if not already bound. */
+ bind_arrow_keys ();
+#endif /* !_WIN32 */
+
+ /* Enable the meta key, if this terminal has one. */
+ if (_rl_enable_meta)
+ _rl_enable_meta_key ();
+
+ /* If the completion parser's default word break characters haven't
+ been set yet, then do so now. */
+ if (rl_completer_word_break_characters == (char *)NULL)
+ rl_completer_word_break_characters = rl_basic_word_break_characters;
+}
+
+/* If this system allows us to look at the values of the regular
+ input editing characters, then bind them to their readline
+ equivalents, iff the characters are not bound to keymaps. */
+static void
+readline_default_bindings ()
+{
+ rl_tty_set_default_bindings (_rl_keymap);
+}
+
+#if !defined _WIN32 /* in Windows the rltty, i.e. console binding is sufficient */
+/* Bind some common arrow key sequences in MAP. */
+static void
+bind_arrow_keys_internal (map)
+ Keymap map;
+{
+ Keymap xkeymap;
+
+ xkeymap = _rl_keymap;
+ _rl_keymap = map;
+
+#if defined (__MSDOS__)
+ _rl_bind_if_unbound ("\033[0A", rl_get_previous_history);
+ _rl_bind_if_unbound ("\033[0B", rl_backward_char);
+ _rl_bind_if_unbound ("\033[0C", rl_forward_char);
+ _rl_bind_if_unbound ("\033[0D", rl_get_next_history);
+#endif
+
+ _rl_bind_if_unbound ("\033[A", rl_get_previous_history);
+ _rl_bind_if_unbound ("\033[B", rl_get_next_history);
+ _rl_bind_if_unbound ("\033[C", rl_forward_char);
+ _rl_bind_if_unbound ("\033[D", rl_backward_char);
+ _rl_bind_if_unbound ("\033[H", rl_beg_of_line);
+ _rl_bind_if_unbound ("\033[F", rl_end_of_line);
+
+ _rl_bind_if_unbound ("\033OA", rl_get_previous_history);
+ _rl_bind_if_unbound ("\033OB", rl_get_next_history);
+ _rl_bind_if_unbound ("\033OC", rl_forward_char);
+ _rl_bind_if_unbound ("\033OD", rl_backward_char);
+ _rl_bind_if_unbound ("\033OH", rl_beg_of_line);
+ _rl_bind_if_unbound ("\033OF", rl_end_of_line);
+
+ _rl_keymap = xkeymap;
+}
+
+/* Try and bind the common arrow key prefixes after giving termcap and
+ the inputrc file a chance to bind them and create `real' keymaps
+ for the arrow key prefix. */
+static void
+bind_arrow_keys ()
+{
+ bind_arrow_keys_internal (emacs_standard_keymap);
+
+#if defined (VI_MODE)
+ bind_arrow_keys_internal (vi_movement_keymap);
+ bind_arrow_keys_internal (vi_insertion_keymap);
+#endif
+}
+
+#endif /* !_WIN32 */
+
+/* **************************************************************** */
+/* */
+/* Saving and Restoring Readline's state */
+/* */
+/* **************************************************************** */
+
+int
+rl_save_state (sp)
+ struct readline_state *sp;
+{
+ if (sp == 0)
+ return -1;
+
+ sp->point = rl_point;
+ sp->end = rl_end;
+ sp->mark = rl_mark;
+ sp->buffer = rl_line_buffer;
+ sp->buflen = rl_line_buffer_len;
+ sp->ul = rl_undo_list;
+ sp->prompt = rl_prompt;
+
+ sp->rlstate = rl_readline_state;
+ sp->done = rl_done;
+ sp->kmap = _rl_keymap;
+
+ sp->lastfunc = rl_last_func;
+ sp->insmode = rl_insert_mode;
+ sp->edmode = rl_editing_mode;
+ sp->kseqlen = rl_key_sequence_length;
+ sp->inf = rl_instream;
+ sp->outf = rl_outstream;
+ sp->pendingin = rl_pending_input;
+ sp->macro = rl_executing_macro;
+
+ sp->catchsigs = rl_catch_signals;
+#ifdef SIGWINCH
+ sp->catchsigwinch = rl_catch_sigwinch;
+#endif
+
+ return (0);
+}
+
+int
+rl_restore_state (sp)
+ struct readline_state *sp;
+{
+ if (sp == 0)
+ return -1;
+
+ rl_point = sp->point;
+ rl_end = sp->end;
+ rl_mark = sp->mark;
+ the_line = rl_line_buffer = sp->buffer;
+ rl_line_buffer_len = sp->buflen;
+ rl_undo_list = sp->ul;
+ rl_prompt = sp->prompt;
+
+ rl_readline_state = sp->rlstate;
+ rl_done = sp->done;
+ _rl_keymap = sp->kmap;
+
+ rl_last_func = sp->lastfunc;
+ rl_insert_mode = sp->insmode;
+ rl_editing_mode = sp->edmode;
+ rl_key_sequence_length = sp->kseqlen;
+ rl_instream = sp->inf;
+ rl_outstream = sp->outf;
+ rl_pending_input = sp->pendingin;
+ rl_executing_macro = sp->macro;
+
+ rl_catch_signals = sp->catchsigs;
+#ifdef SIGWINCH
+ rl_catch_sigwinch = sp->catchsigwinch;
+#endif
+ return (0);
+}
diff --git a/MSVC/readline/readline.h b/MSVC/readline/readline.h
index b3068bc..9efa5a0 100644
--- a/MSVC/readline/readline.h
+++ b/MSVC/readline/readline.h
@@ -1,806 +1,806 @@
-/* Readline.h -- the names of functions callable from within readline. */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_READLINE_H_)
-#define _READLINE_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined (READLINE_LIBRARY)
-# include "rlstdc.h"
-# include "rltypedefs.h"
-# include "keymaps.h"
-# include "tilde.h"
-#else
-# include <readline/rlstdc.h>
-# include <readline/rltypedefs.h>
-# include <readline/keymaps.h>
-# include <readline/tilde.h>
-#endif
-
-/* Hex-encoded Readline version number. */
-#define RL_READLINE_VERSION 0x0403 /* Readline 4.3 */
-#define RL_VERSION_MAJOR 4
-#define RL_VERSION_MINOR 3
-
-#include "rldynlink.h" /* for export / import macros */
-
-/* Readline data structures. */
-
-/* Maintaining the state of undo. We remember individual deletes and inserts
- on a chain of things to do. */
-
-/* The actions that undo knows how to undo. Notice that UNDO_DELETE means
- to insert some text, and UNDO_INSERT means to delete some text. I.e.,
- the code tells undo what to undo, not how to undo it. */
-enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END };
-
-/* What an element of THE_UNDO_LIST looks like. */
-typedef struct undo_list {
- struct undo_list *next;
- int start, end; /* Where the change took place. */
- char *text; /* The text to insert, if undoing a delete. */
- enum undo_code what; /* Delete, Insert, Begin, End. */
-} UNDO_LIST;
-
-/* The current undo list for RL_LINE_BUFFER. */
-RL_EXTERN UNDO_LIST *rl_undo_list;
-
-/* The data structure for mapping textual names to code addresses. */
-typedef struct _funmap {
- const char *name;
- rl_command_func_t *function;
-} FUNMAP;
-
-RL_EXTERN FUNMAP **funmap;
-
-/* **************************************************************** */
-/* */
-/* Functions available to bind to key sequences */
-/* */
-/* **************************************************************** */
-
-/* Bindable commands for numeric arguments. */
-RL_EXTERN int rl_digit_argument PARAMS((int, int));
-RL_EXTERN int rl_universal_argument PARAMS((int, int));
-
-/* Bindable commands for moving the cursor. */
-RL_EXTERN int rl_forward_byte PARAMS((int, int));
-RL_EXTERN int rl_forward_char PARAMS((int, int));
-RL_EXTERN int rl_forward PARAMS((int, int));
-RL_EXTERN int rl_backward_byte PARAMS((int, int));
-RL_EXTERN int rl_backward_char PARAMS((int, int));
-RL_EXTERN int rl_backward PARAMS((int, int));
-RL_EXTERN int rl_beg_of_line PARAMS((int, int));
-RL_EXTERN int rl_end_of_line PARAMS((int, int));
-RL_EXTERN int rl_forward_word PARAMS((int, int));
-RL_EXTERN int rl_backward_word PARAMS((int, int));
-RL_EXTERN int rl_refresh_line PARAMS((int, int));
-RL_EXTERN int rl_clear_screen PARAMS((int, int));
-RL_EXTERN int rl_arrow_keys PARAMS((int, int));
-
-/* Bindable commands for inserting and deleting text. */
-RL_EXTERN int rl_insert PARAMS((int, int));
-RL_EXTERN int rl_quoted_insert PARAMS((int, int));
-RL_EXTERN int rl_tab_insert PARAMS((int, int));
-RL_EXTERN int rl_newline PARAMS((int, int));
-RL_EXTERN int rl_do_lowercase_version PARAMS((int, int));
-RL_EXTERN int rl_rubout PARAMS((int, int));
-RL_EXTERN int rl_delete PARAMS((int, int));
-RL_EXTERN int rl_rubout_or_delete PARAMS((int, int));
-RL_EXTERN int rl_delete_horizontal_space PARAMS((int, int));
-RL_EXTERN int rl_delete_or_show_completions PARAMS((int, int));
-RL_EXTERN int rl_insert_comment PARAMS((int, int));
-
-/* Bindable commands for changing case. */
-RL_EXTERN int rl_upcase_word PARAMS((int, int));
-RL_EXTERN int rl_downcase_word PARAMS((int, int));
-RL_EXTERN int rl_capitalize_word PARAMS((int, int));
-
-/* Bindable commands for transposing characters and words. */
-RL_EXTERN int rl_transpose_words PARAMS((int, int));
-RL_EXTERN int rl_transpose_chars PARAMS((int, int));
-
-/* Bindable commands for searching within a line. */
-RL_EXTERN int rl_char_search PARAMS((int, int));
-RL_EXTERN int rl_backward_char_search PARAMS((int, int));
-
-/* Bindable commands for readline's interface to the command history. */
-RL_EXTERN int rl_beginning_of_history PARAMS((int, int));
-RL_EXTERN int rl_end_of_history PARAMS((int, int));
-RL_EXTERN int rl_get_next_history PARAMS((int, int));
-RL_EXTERN int rl_get_previous_history PARAMS((int, int));
-
-/* Bindable commands for managing the mark and region. */
-RL_EXTERN int rl_set_mark PARAMS((int, int));
-RL_EXTERN int rl_exchange_point_and_mark PARAMS((int, int));
-
-/* Bindable commands to set the editing mode (emacs or vi). */
-RL_EXTERN int rl_vi_editing_mode PARAMS((int, int));
-RL_EXTERN int rl_emacs_editing_mode PARAMS((int, int));
-
-/* Bindable commands to change the insert mode (insert or overwrite) */
-RL_EXTERN int rl_overwrite_mode PARAMS((int, int));
-
-/* Bindable commands for managing key bindings. */
-RL_EXTERN int rl_re_read_init_file PARAMS((int, int));
-RL_EXTERN int rl_dump_functions PARAMS((int, int));
-RL_EXTERN int rl_dump_macros PARAMS((int, int));
-RL_EXTERN int rl_dump_variables PARAMS((int, int));
-
-/* Bindable commands for word completion. */
-RL_EXTERN int rl_complete PARAMS((int, int));
-RL_EXTERN int rl_possible_completions PARAMS((int, int));
-RL_EXTERN int rl_insert_completions PARAMS((int, int));
-RL_EXTERN int rl_menu_complete PARAMS((int, int));
-
-/* Bindable commands for killing and yanking text, and managing the kill ring. */
-RL_EXTERN int rl_kill_word PARAMS((int, int));
-RL_EXTERN int rl_backward_kill_word PARAMS((int, int));
-RL_EXTERN int rl_kill_line PARAMS((int, int));
-RL_EXTERN int rl_backward_kill_line PARAMS((int, int));
-RL_EXTERN int rl_kill_full_line PARAMS((int, int));
-RL_EXTERN int rl_unix_word_rubout PARAMS((int, int));
-RL_EXTERN int rl_unix_line_discard PARAMS((int, int));
-RL_EXTERN int rl_copy_region_to_kill PARAMS((int, int));
-RL_EXTERN int rl_kill_region PARAMS((int, int));
-RL_EXTERN int rl_copy_forward_word PARAMS((int, int));
-RL_EXTERN int rl_copy_backward_word PARAMS((int, int));
-RL_EXTERN int rl_yank PARAMS((int, int));
-RL_EXTERN int rl_yank_pop PARAMS((int, int));
-RL_EXTERN int rl_yank_nth_arg PARAMS((int, int));
-RL_EXTERN int rl_yank_last_arg PARAMS((int, int));
-/* Not available unless __CYGWIN__ is defined. */
-#if defined __CYGWIN__ || defined _WIN32
-RL_EXTERN int rl_paste_from_clipboard PARAMS((int, int));
-#endif
-
-/* Bindable commands for incremental searching. */
-RL_EXTERN int rl_reverse_search_history PARAMS((int, int));
-RL_EXTERN int rl_forward_search_history PARAMS((int, int));
-
-/* Bindable keyboard macro commands. */
-RL_EXTERN int rl_start_kbd_macro PARAMS((int, int));
-RL_EXTERN int rl_end_kbd_macro PARAMS((int, int));
-RL_EXTERN int rl_call_last_kbd_macro PARAMS((int, int));
-
-/* Bindable undo commands. */
-RL_EXTERN int rl_revert_line PARAMS((int, int));
-RL_EXTERN int rl_undo_command PARAMS((int, int));
-
-/* Bindable tilde expansion commands. */
-RL_EXTERN int rl_tilde_expand PARAMS((int, int));
-
-/* Bindable terminal control commands. */
-RL_EXTERN int rl_restart_output PARAMS((int, int));
-RL_EXTERN int rl_stop_output PARAMS((int, int));
-
-/* Miscellaneous bindable commands. */
-RL_EXTERN int rl_abort PARAMS((int, int));
-RL_EXTERN int rl_tty_status PARAMS((int, int));
-
-/* Bindable commands for incremental and non-incremental history searching. */
-RL_EXTERN int rl_history_search_forward PARAMS((int, int));
-RL_EXTERN int rl_history_search_backward PARAMS((int, int));
-RL_EXTERN int rl_noninc_forward_search PARAMS((int, int));
-RL_EXTERN int rl_noninc_reverse_search PARAMS((int, int));
-RL_EXTERN int rl_noninc_forward_search_again PARAMS((int, int));
-RL_EXTERN int rl_noninc_reverse_search_again PARAMS((int, int));
-
-/* Bindable command used when inserting a matching close character. */
-RL_EXTERN int rl_insert_close PARAMS((int, int));
-
-/* Not available unless READLINE_CALLBACKS is defined. */
-RL_EXTERN void rl_callback_handler_install PARAMS((const char *, rl_vcpfunc_t *));
-RL_EXTERN void rl_callback_read_char PARAMS((void));
-RL_EXTERN void rl_callback_handler_remove PARAMS((void));
-
-/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
-/* VI-mode bindable commands. */
-RL_EXTERN int rl_vi_redo PARAMS((int, int));
-RL_EXTERN int rl_vi_undo PARAMS((int, int));
-RL_EXTERN int rl_vi_yank_arg PARAMS((int, int));
-RL_EXTERN int rl_vi_fetch_history PARAMS((int, int));
-RL_EXTERN int rl_vi_search_again PARAMS((int, int));
-RL_EXTERN int rl_vi_search PARAMS((int, int));
-RL_EXTERN int rl_vi_complete PARAMS((int, int));
-RL_EXTERN int rl_vi_tilde_expand PARAMS((int, int));
-RL_EXTERN int rl_vi_prev_word PARAMS((int, int));
-RL_EXTERN int rl_vi_next_word PARAMS((int, int));
-RL_EXTERN int rl_vi_end_word PARAMS((int, int));
-RL_EXTERN int rl_vi_insert_beg PARAMS((int, int));
-RL_EXTERN int rl_vi_append_mode PARAMS((int, int));
-RL_EXTERN int rl_vi_append_eol PARAMS((int, int));
-RL_EXTERN int rl_vi_eof_maybe PARAMS((int, int));
-RL_EXTERN int rl_vi_insertion_mode PARAMS((int, int));
-RL_EXTERN int rl_vi_movement_mode PARAMS((int, int));
-RL_EXTERN int rl_vi_arg_digit PARAMS((int, int));
-RL_EXTERN int rl_vi_change_case PARAMS((int, int));
-RL_EXTERN int rl_vi_put PARAMS((int, int));
-RL_EXTERN int rl_vi_column PARAMS((int, int));
-RL_EXTERN int rl_vi_delete_to PARAMS((int, int));
-RL_EXTERN int rl_vi_change_to PARAMS((int, int));
-RL_EXTERN int rl_vi_yank_to PARAMS((int, int));
-RL_EXTERN int rl_vi_delete PARAMS((int, int));
-RL_EXTERN int rl_vi_back_to_indent PARAMS((int, int));
-RL_EXTERN int rl_vi_first_print PARAMS((int, int));
-RL_EXTERN int rl_vi_char_search PARAMS((int, int));
-RL_EXTERN int rl_vi_match PARAMS((int, int));
-RL_EXTERN int rl_vi_change_char PARAMS((int, int));
-RL_EXTERN int rl_vi_subst PARAMS((int, int));
-RL_EXTERN int rl_vi_overstrike PARAMS((int, int));
-RL_EXTERN int rl_vi_overstrike_delete PARAMS((int, int));
-RL_EXTERN int rl_vi_replace PARAMS((int, int));
-RL_EXTERN int rl_vi_set_mark PARAMS((int, int));
-RL_EXTERN int rl_vi_goto_mark PARAMS((int, int));
-
-/* VI-mode utility functions. */
-RL_EXTERN int rl_vi_check PARAMS((void));
-RL_EXTERN int rl_vi_domove PARAMS((int, int *));
-RL_EXTERN int rl_vi_bracktype PARAMS((int));
-
-/* VI-mode pseudo-bindable commands, used as utility functions. */
-RL_EXTERN int rl_vi_fWord PARAMS((int, int));
-RL_EXTERN int rl_vi_bWord PARAMS((int, int));
-RL_EXTERN int rl_vi_eWord PARAMS((int, int));
-RL_EXTERN int rl_vi_fword PARAMS((int, int));
-RL_EXTERN int rl_vi_bword PARAMS((int, int));
-RL_EXTERN int rl_vi_eword PARAMS((int, int));
-
-/* **************************************************************** */
-/* */
-/* Well Published Functions */
-/* */
-/* **************************************************************** */
-
-/* Readline functions. */
-/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */
-RL_EXTERN char *readline PARAMS((const char *));
-
-RL_EXTERN int rl_set_prompt PARAMS((const char *));
-RL_EXTERN int rl_expand_prompt PARAMS((char *));
-
-RL_EXTERN int rl_initialize PARAMS((void));
-
-/* Undocumented; unused by readline */
-RL_EXTERN int rl_discard_argument PARAMS((void));
-
-/* Utility functions to bind keys to readline commands. */
-RL_EXTERN int rl_add_defun PARAMS((const char *, rl_command_func_t *, int));
-RL_EXTERN int rl_bind_key PARAMS((int, rl_command_func_t *));
-RL_EXTERN int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap));
-RL_EXTERN int rl_unbind_key PARAMS((int));
-RL_EXTERN int rl_unbind_key_in_map PARAMS((int, Keymap));
-RL_EXTERN int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap));
-RL_EXTERN int rl_unbind_command_in_map PARAMS((const char *, Keymap));
-RL_EXTERN int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap));
-RL_EXTERN int rl_generic_bind PARAMS((int, const char *, char *, Keymap));
-RL_EXTERN int rl_variable_bind PARAMS((const char *, const char *));
-
-/* Backwards compatibility, use rl_generic_bind instead. */
-RL_EXTERN int rl_macro_bind PARAMS((const char *, const char *, Keymap));
-
-/* Undocumented in the texinfo manual; not really useful to programs. */
-RL_EXTERN int rl_translate_keyseq PARAMS((const char *, char *, int *));
-RL_EXTERN char *rl_untranslate_keyseq PARAMS((int));
-
-RL_EXTERN rl_command_func_t *rl_named_function PARAMS((const char *));
-RL_EXTERN rl_command_func_t *rl_function_of_keyseq PARAMS((const char *, Keymap, int *));
-
-RL_EXTERN void rl_list_funmap_names PARAMS((void));
-RL_EXTERN char **rl_invoking_keyseqs_in_map PARAMS((rl_command_func_t *, Keymap));
-RL_EXTERN char **rl_invoking_keyseqs PARAMS((rl_command_func_t *));
-
-RL_EXTERN void rl_function_dumper PARAMS((int));
-RL_EXTERN void rl_macro_dumper PARAMS((int));
-RL_EXTERN void rl_variable_dumper PARAMS((int));
-
-RL_EXTERN int rl_read_init_file PARAMS((const char *));
-RL_EXTERN int rl_parse_and_bind PARAMS((char *));
-
-/* Functions for manipulating keymaps. */
-RL_EXTERN Keymap rl_make_bare_keymap PARAMS((void));
-RL_EXTERN Keymap rl_copy_keymap PARAMS((Keymap));
-RL_EXTERN Keymap rl_make_keymap PARAMS((void));
-RL_EXTERN void rl_discard_keymap PARAMS((Keymap));
-
-RL_EXTERN Keymap rl_get_keymap_by_name PARAMS((const char *));
-RL_EXTERN char *rl_get_keymap_name PARAMS((Keymap));
-RL_EXTERN void rl_set_keymap PARAMS((Keymap));
-RL_EXTERN Keymap rl_get_keymap PARAMS((void));
-/* Undocumented; used internally only. */
-RL_EXTERN void rl_set_keymap_from_edit_mode PARAMS((void));
-RL_EXTERN char *rl_get_keymap_name_from_edit_mode PARAMS((void));
-
-/* Functions for manipulating the funmap, which maps command names to functions. */
-RL_EXTERN int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *));
-RL_EXTERN const char **rl_funmap_names PARAMS((void));
-/* Undocumented, only used internally -- there is only one funmap, and this
- function may be called only once. */
-RL_EXTERN void rl_initialize_funmap PARAMS((void));
-
-/* Utility functions for managing keyboard macros. */
-RL_EXTERN void rl_push_macro_input PARAMS((char *));
-
-/* Functions for undoing, from undo.c */
-RL_EXTERN void rl_add_undo PARAMS((enum undo_code, int, int, char *));
-RL_EXTERN void rl_free_undo_list PARAMS((void));
-RL_EXTERN int rl_do_undo PARAMS((void));
-RL_EXTERN int rl_begin_undo_group PARAMS((void));
-RL_EXTERN int rl_end_undo_group PARAMS((void));
-RL_EXTERN int rl_modifying PARAMS((int, int));
-
-/* Functions for redisplay. */
-RL_EXTERN void rl_redisplay PARAMS((void));
-RL_EXTERN int rl_on_new_line PARAMS((void));
-RL_EXTERN int rl_on_new_line_with_prompt PARAMS((void));
-RL_EXTERN int rl_forced_update_display PARAMS((void));
-RL_EXTERN int rl_clear_message PARAMS((void));
-RL_EXTERN int rl_reset_line_state PARAMS((void));
-RL_EXTERN int rl_crlf PARAMS((void));
-
-#if (defined (__STDC__) || defined (__cplusplus)) && defined (USE_VARARGS) && defined (PREFER_STDARG)
-RL_EXTERN int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
-#else
-RL_EXTERN int rl_message ();
-#endif
-
-RL_EXTERN int rl_show_char PARAMS((int));
-
-/* Undocumented in texinfo manual. */
-RL_EXTERN int rl_character_len PARAMS((int, int));
-
-/* Save and restore internal prompt redisplay information. */
-RL_EXTERN void rl_save_prompt PARAMS((void));
-RL_EXTERN void rl_restore_prompt PARAMS((void));
-
-/* Modifying text. */
-RL_EXTERN void rl_replace_line PARAMS((const char *, int));
-RL_EXTERN int rl_insert_text PARAMS((const char *));
-RL_EXTERN int rl_delete_text PARAMS((int, int));
-RL_EXTERN int rl_kill_text PARAMS((int, int));
-RL_EXTERN char *rl_copy_text PARAMS((int, int));
-
-/* Terminal and tty mode management. */
-RL_EXTERN void rl_prep_terminal PARAMS((int));
-RL_EXTERN void rl_deprep_terminal PARAMS((void));
-RL_EXTERN void rl_tty_set_default_bindings PARAMS((Keymap));
-
-RL_EXTERN int rl_reset_terminal PARAMS((const char *));
-RL_EXTERN void rl_resize_terminal PARAMS((void));
-RL_EXTERN void rl_set_screen_size PARAMS((int, int));
-RL_EXTERN void rl_get_screen_size PARAMS((int *, int *));
-
-RL_EXTERN char *rl_get_termcap PARAMS((const char *));
-
-/* Functions for character input. */
-RL_EXTERN int rl_stuff_char PARAMS((int));
-RL_EXTERN int rl_execute_next PARAMS((int));
-RL_EXTERN int rl_clear_pending_input PARAMS((void));
-RL_EXTERN int rl_read_key PARAMS((void));
-RL_EXTERN int rl_getc PARAMS((FILE *));
-RL_EXTERN int rl_set_keyboard_input_timeout PARAMS((int));
-
-/* `Public' utility functions . */
-RL_EXTERN void rl_extend_line_buffer PARAMS((int));
-RL_EXTERN int rl_ding PARAMS((void));
-RL_EXTERN int rl_alphabetic PARAMS((int));
-
-/* Readline signal handling, from signals.c */
-RL_EXTERN int rl_set_signals PARAMS((void));
-RL_EXTERN int rl_clear_signals PARAMS((void));
-RL_EXTERN void rl_cleanup_after_signal PARAMS((void));
-RL_EXTERN void rl_reset_after_signal PARAMS((void));
-RL_EXTERN void rl_free_line_state PARAMS((void));
-
-RL_EXTERN int rl_set_paren_blink_timeout PARAMS((int));
-
-/* Undocumented. */
-RL_EXTERN int rl_maybe_save_line PARAMS((void));
-RL_EXTERN int rl_maybe_unsave_line PARAMS((void));
-RL_EXTERN int rl_maybe_replace_line PARAMS((void));
-
-/* Completion functions. */
-RL_EXTERN int rl_complete_internal PARAMS((int));
-RL_EXTERN void rl_display_match_list PARAMS((char **, int, int));
-
-RL_EXTERN char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *));
-RL_EXTERN char *rl_username_completion_function PARAMS((const char *, int));
-RL_EXTERN char *rl_filename_completion_function PARAMS((const char *, int));
-
-RL_EXTERN int rl_completion_mode PARAMS((rl_command_func_t *));
-
-#if 0
-/* Backwards compatibility (compat.c). These will go away sometime. */
-RL_EXTERN void free_undo_list PARAMS((void));
-RL_EXTERN int maybe_save_line PARAMS((void));
-RL_EXTERN int maybe_unsave_line PARAMS((void));
-RL_EXTERN int maybe_replace_line PARAMS((void));
-
-RL_EXTERN int ding PARAMS((void));
-RL_EXTERN int alphabetic PARAMS((int));
-RL_EXTERN int crlf PARAMS((void));
-
-RL_EXTERN char **completion_matches PARAMS((char *, rl_compentry_func_t *));
-RL_EXTERN char *username_completion_function PARAMS((const char *, int));
-RL_EXTERN char *filename_completion_function PARAMS((const char *, int));
-#endif
-
-/* **************************************************************** */
-/* */
-/* Well Published Variables */
-/* */
-/* **************************************************************** */
-
-/* The version of this incarnation of the readline library. */
-RL_EXTERN const char *rl_library_version; /* e.g., "4.2" */
-RL_EXTERN int rl_readline_version; /* e.g., 0x0402 */
-
-/* True if this is real GNU readline. */
-RL_EXTERN int rl_gnu_readline_p;
-
-/* Flags word encapsulating the current readline state. */
-RL_EXTERN int rl_readline_state;
-
-/* Says which editing mode readline is currently using. 1 means emacs mode;
- 0 means vi mode. */
-RL_EXTERN int rl_editing_mode;
-
-/* Insert or overwrite mode for emacs mode. 1 means insert mode; 0 means
- overwrite mode. Reset to insert mode on each input line. */
-RL_EXTERN int rl_insert_mode;
-
-/* The name of the calling program. You should initialize this to
- whatever was in argv[0]. It is used when parsing conditionals. */
-RL_EXTERN const char *rl_readline_name;
-
-/* The prompt readline uses. This is set from the argument to
- readline (), and should not be assigned to directly. */
-RL_EXTERN char *rl_prompt;
-
-/* The line buffer that is in use. */
-RL_EXTERN char *rl_line_buffer;
-
-/* The location of point, and end. */
-RL_EXTERN int rl_point;
-RL_EXTERN int rl_end;
-
-/* The mark, or saved cursor position. */
-RL_EXTERN int rl_mark;
-
-/* Flag to indicate that readline has finished with the current input
- line and should return it. */
-RL_EXTERN int rl_done;
-
-/* If set to a character value, that will be the next keystroke read. */
-RL_EXTERN int rl_pending_input;
-
-/* Non-zero if we called this function from _rl_dispatch(). It's present
- so functions can find out whether they were called from a key binding
- or directly from an application. */
-RL_EXTERN int rl_dispatching;
-
-/* Non-zero if the user typed a numeric argument before executing the
- current function. */
-RL_EXTERN int rl_explicit_arg;
-
-/* The current value of the numeric argument specified by the user. */
-RL_EXTERN int rl_numeric_arg;
-
-/* The address of the last command function Readline executed. */
-RL_EXTERN rl_command_func_t *rl_last_func;
-
-/* The name of the terminal to use. */
-RL_EXTERN const char *rl_terminal_name;
-
-/* The input and output streams. */
-RL_EXTERN FILE *rl_instream;
-RL_EXTERN FILE *rl_outstream;
-
-/* If non-zero, then this is the address of a function to call just
- before readline_internal () prints the first prompt. */
-RL_EXTERN rl_hook_func_t *rl_startup_hook;
-
-/* If non-zero, this is the address of a function to call just before
- readline_internal_setup () returns and readline_internal starts
- reading input characters. */
-RL_EXTERN rl_hook_func_t *rl_pre_input_hook;
-
-/* The address of a function to call periodically while Readline is
- awaiting character input, or NULL, for no event handling. */
-RL_EXTERN rl_hook_func_t *rl_event_hook;
-
-/* The address of the function to call to fetch a character from the current
- Readline input stream */
-RL_EXTERN rl_getc_func_t *rl_getc_function;
-
-RL_EXTERN rl_voidfunc_t *rl_redisplay_function;
-
-RL_EXTERN rl_vintfunc_t *rl_prep_term_function;
-RL_EXTERN rl_voidfunc_t *rl_deprep_term_function;
-
-/* Dispatch variables. */
-RL_EXTERN Keymap rl_executing_keymap;
-RL_EXTERN Keymap rl_binding_keymap;
-
-/* Display variables. */
-/* If non-zero, readline will erase the entire line, including any prompt,
- if the only thing typed on an otherwise-blank line is something bound to
- rl_newline. */
-RL_EXTERN int rl_erase_empty_line;
-
-/* If non-zero, the application has already printed the prompt (rl_prompt)
- before calling readline, so readline should not output it the first time
- redisplay is done. */
-RL_EXTERN int rl_already_prompted;
-
-/* A non-zero value means to read only this many characters rather than
- up to a character bound to accept-line. */
-RL_EXTERN int rl_num_chars_to_read;
-
-/* The text of a currently-executing keyboard macro. */
-RL_EXTERN char *rl_executing_macro;
-
-/* Variables to control readline signal handling. */
-/* If non-zero, readline will install its own signal handlers for
- SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
-RL_EXTERN int rl_catch_signals;
-
-/* If non-zero, readline will install a signal handler for SIGWINCH
- that also attempts to call any calling application's SIGWINCH signal
- handler. Note that the terminal is not cleaned up before the
- application's signal handler is called; use rl_cleanup_after_signal()
- to do that. */
-RL_EXTERN int rl_catch_sigwinch;
-
-/* Completion variables. */
-/* Pointer to the generator function for completion_matches ().
- NULL means to use rl_filename_completion_function (), the default
- filename completer. */
-RL_EXTERN rl_compentry_func_t *rl_completion_entry_function;
-
-/* If rl_ignore_some_completions_function is non-NULL it is the address
- of a function to call after all of the possible matches have been
- generated, but before the actual completion is done to the input line.
- The function is called with one argument; a NULL terminated array
- of (char *). If your function removes any of the elements, they
- must be free()'ed. */
-RL_EXTERN rl_compignore_func_t *rl_ignore_some_completions_function;
-
-/* Pointer to alternative function to create matches.
- Function is called with TEXT, START, and END.
- START and END are indices in RL_LINE_BUFFER saying what the boundaries
- of TEXT are.
- If this function exists and returns NULL then call the value of
- rl_completion_entry_function to try to match, otherwise use the
- array of strings returned. */
-RL_EXTERN rl_completion_func_t *rl_attempted_completion_function;
-
-/* The basic list of characters that signal a break between words for the
- completer routine. The initial contents of this variable is what
- breaks words in the shell, i.e. "n\"\\'`@$>". */
-RL_EXTERN const char *rl_basic_word_break_characters;
-
-/* The list of characters that signal a break between words for
- rl_complete_internal. The default list is the contents of
- rl_basic_word_break_characters. */
-RL_EXTERN const char *rl_completer_word_break_characters;
-
-/* List of characters which can be used to quote a substring of the line.
- Completion occurs on the entire substring, and within the substring
- rl_completer_word_break_characters are treated as any other character,
- unless they also appear within this list. */
-RL_EXTERN const char *rl_completer_quote_characters;
-
-/* List of quote characters which cause a word break. */
-RL_EXTERN const char *rl_basic_quote_characters;
-
-/* List of characters that need to be quoted in filenames by the completer. */
-RL_EXTERN const char *rl_filename_quote_characters;
-
-/* List of characters that are word break characters, but should be left
- in TEXT when it is passed to the completion function. The shell uses
- this to help determine what kind of completing to do. */
-RL_EXTERN const char *rl_special_prefixes;
-
-/* If non-zero, then this is the address of a function to call when
- completing on a directory name. The function is called with
- the address of a string (the current directory name) as an arg. It
- changes what is displayed when the possible completions are printed
- or inserted. */
-RL_EXTERN rl_icppfunc_t *rl_directory_completion_hook;
-
-/* If non-zero, this is the address of a function to call when completing
- a directory name. This function takes the address of the directory name
- to be modified as an argument. Unlike rl_directory_completion_hook, it
- only modifies the directory name used in opendir(2), not what is displayed
- when the possible completions are printed or inserted. It is called
- before rl_directory_completion_hook. I'm not happy with how this works
- yet, so it's undocumented. */
-RL_EXTERN rl_icppfunc_t *rl_directory_rewrite_hook;
-
-/* Backwards compatibility with previous versions of readline. */
-#define rl_symbolic_link_hook rl_directory_completion_hook
-
-/* If non-zero, then this is the address of a function to call when
- completing a word would normally display the list of possible matches.
- This function is called instead of actually doing the display.
- It takes three arguments: (char **matches, int num_matches, int max_length)
- where MATCHES is the array of strings that matched, NUM_MATCHES is the
- number of strings in that array, and MAX_LENGTH is the length of the
- longest string in that array. */
-RL_EXTERN rl_compdisp_func_t *rl_completion_display_matches_hook;
-
-/* Non-zero means that the results of the matches are to be treated
- as filenames. This is ALWAYS zero on entry, and can only be changed
- within a completion entry finder function. */
-RL_EXTERN int rl_filename_completion_desired;
-
-/* Non-zero means that the results of the matches are to be quoted using
- double quotes (or an application-specific quoting mechanism) if the
- filename contains any characters in rl_word_break_chars. This is
- ALWAYS non-zero on entry, and can only be changed within a completion
- entry finder function. */
-RL_EXTERN int rl_filename_quoting_desired;
-
-/* Set to a function to quote a filename in an application-specific fashion.
- Called with the text to quote, the type of match found (single or multiple)
- and a pointer to the quoting character to be used, which the function can
- reset if desired. */
-RL_EXTERN rl_quote_func_t *rl_filename_quoting_function;
-
-/* Function to call to remove quoting characters from a filename. Called
- before completion is attempted, so the embedded quotes do not interfere
- with matching names in the file system. */
-RL_EXTERN rl_dequote_func_t *rl_filename_dequoting_function;
-
-/* Function to call to decide whether or not a word break character is
- quoted. If a character is quoted, it does not break words for the
- completer. */
-RL_EXTERN rl_linebuf_func_t *rl_char_is_quoted_p;
-
-/* Non-zero means to suppress normal filename completion after the
- user-specified completion function has been called. */
-RL_EXTERN int rl_attempted_completion_over;
-
-/* Set to a character describing the type of completion being attempted by
- rl_complete_internal; available for use by application completion
- functions. */
-RL_EXTERN int rl_completion_type;
-
-/* Character appended to completed words when at the end of the line. The
- default is a space. Nothing is added if this is '\0'. */
-RL_EXTERN int rl_completion_append_character;
-
-/* If set to non-zero by an application completion function,
- rl_completion_append_character will not be appended. */
-RL_EXTERN int rl_completion_suppress_append;
-
-/* Up to this many items will be displayed in response to a
- possible-completions call. After that, we ask the user if she
- is sure she wants to see them all. The default value is 100. */
-RL_EXTERN int rl_completion_query_items;
-
-/* If non-zero, a slash will be appended to completed filenames that are
- symbolic links to directory names, subject to the value of the
- mark-directories variable (which is user-settable). This exists so
- that application completion functions can override the user's preference
- (set via the mark-symlinked-directories variable) if appropriate.
- It's set to the value of _rl_complete_mark_symlink_dirs in
- rl_complete_internal before any application-specific completion
- function is called, so without that function doing anything, the user's
- preferences are honored. */
-RL_EXTERN int rl_completion_mark_symlink_dirs;
-
-/* If non-zero, then disallow duplicates in the matches. */
-RL_EXTERN int rl_ignore_completion_duplicates;
-
-/* If this is non-zero, completion is (temporarily) inhibited, and the
- completion character will be inserted as any other. */
-RL_EXTERN int rl_inhibit_completion;
-
-/* Definitions available for use by readline clients. */
-#define RL_PROMPT_START_IGNORE '\001'
-#define RL_PROMPT_END_IGNORE '\002'
-
-/* Possible values for do_replace argument to rl_filename_quoting_function,
- called by rl_complete_internal. */
-#define NO_MATCH 0
-#define SINGLE_MATCH 1
-#define MULT_MATCH 2
-
-/* Possible state values for rl_readline_state */
-#define RL_STATE_NONE 0x00000 /* no state; before first call */
-
-#define RL_STATE_INITIALIZING 0x00001 /* initializing */
-#define RL_STATE_INITIALIZED 0x00002 /* initialization done */
-#define RL_STATE_TERMPREPPED 0x00004 /* terminal is prepped */
-#define RL_STATE_READCMD 0x00008 /* reading a command key */
-#define RL_STATE_METANEXT 0x00010 /* reading input after ESC */
-#define RL_STATE_DISPATCHING 0x00020 /* dispatching to a command */
-#define RL_STATE_MOREINPUT 0x00040 /* reading more input in a command function */
-#define RL_STATE_ISEARCH 0x00080 /* doing incremental search */
-#define RL_STATE_NSEARCH 0x00100 /* doing non-inc search */
-#define RL_STATE_SEARCH 0x00200 /* doing a history search */
-#define RL_STATE_NUMERICARG 0x00400 /* reading numeric argument */
-#define RL_STATE_MACROINPUT 0x00800 /* getting input from a macro */
-#define RL_STATE_MACRODEF 0x01000 /* defining keyboard macro */
-#define RL_STATE_OVERWRITE 0x02000 /* overwrite mode */
-#define RL_STATE_COMPLETING 0x04000 /* doing completion */
-#define RL_STATE_SIGHANDLER 0x08000 /* in readline sighandler */
-#define RL_STATE_UNDOING 0x10000 /* doing an undo */
-#define RL_STATE_INPUTPENDING 0x20000 /* rl_execute_next called */
-
-#define RL_STATE_DONE 0x80000 /* done; accepted line */
-
-#define RL_SETSTATE(x) (rl_readline_state |= (x))
-#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x))
-#define RL_ISSTATE(x) (rl_readline_state & (x))
-
-struct readline_state {
- /* line state */
- int point;
- int end;
- int mark;
- char *buffer;
- int buflen;
- UNDO_LIST *ul;
- char *prompt;
-
- /* global state */
- int rlstate;
- int done;
- Keymap kmap;
-
- /* input state */
- rl_command_func_t *lastfunc;
- int insmode;
- int edmode;
- int kseqlen;
- FILE *inf;
- FILE *outf;
- int pendingin;
- char *macro;
-
- /* signal state */
- int catchsigs;
- int catchsigwinch;
-
- /* reserved for future expansion, so the struct size doesn't change */
- char reserved[64];
-};
-
-RL_EXTERN int rl_save_state PARAMS((struct readline_state *));
-RL_EXTERN int rl_restore_state PARAMS((struct readline_state *));
-
-#ifdef _MSC_VER
-#define __attribute__(x)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _READLINE_H_ */
-
+/* Readline.h -- the names of functions callable from within readline. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_READLINE_H_)
+#define _READLINE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined (READLINE_LIBRARY)
+# include "rlstdc.h"
+# include "rltypedefs.h"
+# include "keymaps.h"
+# include "tilde.h"
+#else
+# include <readline/rlstdc.h>
+# include <readline/rltypedefs.h>
+# include <readline/keymaps.h>
+# include <readline/tilde.h>
+#endif
+
+/* Hex-encoded Readline version number. */
+#define RL_READLINE_VERSION 0x0403 /* Readline 4.3 */
+#define RL_VERSION_MAJOR 4
+#define RL_VERSION_MINOR 3
+
+#include "rldynlink.h" /* for export / import macros */
+
+/* Readline data structures. */
+
+/* Maintaining the state of undo. We remember individual deletes and inserts
+ on a chain of things to do. */
+
+/* The actions that undo knows how to undo. Notice that UNDO_DELETE means
+ to insert some text, and UNDO_INSERT means to delete some text. I.e.,
+ the code tells undo what to undo, not how to undo it. */
+enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END };
+
+/* What an element of THE_UNDO_LIST looks like. */
+typedef struct undo_list {
+ struct undo_list *next;
+ int start, end; /* Where the change took place. */
+ char *text; /* The text to insert, if undoing a delete. */
+ enum undo_code what; /* Delete, Insert, Begin, End. */
+} UNDO_LIST;
+
+/* The current undo list for RL_LINE_BUFFER. */
+RL_EXTERN UNDO_LIST *rl_undo_list;
+
+/* The data structure for mapping textual names to code addresses. */
+typedef struct _funmap {
+ const char *name;
+ rl_command_func_t *function;
+} FUNMAP;
+
+RL_EXTERN FUNMAP **funmap;
+
+/* **************************************************************** */
+/* */
+/* Functions available to bind to key sequences */
+/* */
+/* **************************************************************** */
+
+/* Bindable commands for numeric arguments. */
+RL_EXTERN int rl_digit_argument PARAMS((int, int));
+RL_EXTERN int rl_universal_argument PARAMS((int, int));
+
+/* Bindable commands for moving the cursor. */
+RL_EXTERN int rl_forward_byte PARAMS((int, int));
+RL_EXTERN int rl_forward_char PARAMS((int, int));
+RL_EXTERN int rl_forward PARAMS((int, int));
+RL_EXTERN int rl_backward_byte PARAMS((int, int));
+RL_EXTERN int rl_backward_char PARAMS((int, int));
+RL_EXTERN int rl_backward PARAMS((int, int));
+RL_EXTERN int rl_beg_of_line PARAMS((int, int));
+RL_EXTERN int rl_end_of_line PARAMS((int, int));
+RL_EXTERN int rl_forward_word PARAMS((int, int));
+RL_EXTERN int rl_backward_word PARAMS((int, int));
+RL_EXTERN int rl_refresh_line PARAMS((int, int));
+RL_EXTERN int rl_clear_screen PARAMS((int, int));
+RL_EXTERN int rl_arrow_keys PARAMS((int, int));
+
+/* Bindable commands for inserting and deleting text. */
+RL_EXTERN int rl_insert PARAMS((int, int));
+RL_EXTERN int rl_quoted_insert PARAMS((int, int));
+RL_EXTERN int rl_tab_insert PARAMS((int, int));
+RL_EXTERN int rl_newline PARAMS((int, int));
+RL_EXTERN int rl_do_lowercase_version PARAMS((int, int));
+RL_EXTERN int rl_rubout PARAMS((int, int));
+RL_EXTERN int rl_delete PARAMS((int, int));
+RL_EXTERN int rl_rubout_or_delete PARAMS((int, int));
+RL_EXTERN int rl_delete_horizontal_space PARAMS((int, int));
+RL_EXTERN int rl_delete_or_show_completions PARAMS((int, int));
+RL_EXTERN int rl_insert_comment PARAMS((int, int));
+
+/* Bindable commands for changing case. */
+RL_EXTERN int rl_upcase_word PARAMS((int, int));
+RL_EXTERN int rl_downcase_word PARAMS((int, int));
+RL_EXTERN int rl_capitalize_word PARAMS((int, int));
+
+/* Bindable commands for transposing characters and words. */
+RL_EXTERN int rl_transpose_words PARAMS((int, int));
+RL_EXTERN int rl_transpose_chars PARAMS((int, int));
+
+/* Bindable commands for searching within a line. */
+RL_EXTERN int rl_char_search PARAMS((int, int));
+RL_EXTERN int rl_backward_char_search PARAMS((int, int));
+
+/* Bindable commands for readline's interface to the command history. */
+RL_EXTERN int rl_beginning_of_history PARAMS((int, int));
+RL_EXTERN int rl_end_of_history PARAMS((int, int));
+RL_EXTERN int rl_get_next_history PARAMS((int, int));
+RL_EXTERN int rl_get_previous_history PARAMS((int, int));
+
+/* Bindable commands for managing the mark and region. */
+RL_EXTERN int rl_set_mark PARAMS((int, int));
+RL_EXTERN int rl_exchange_point_and_mark PARAMS((int, int));
+
+/* Bindable commands to set the editing mode (emacs or vi). */
+RL_EXTERN int rl_vi_editing_mode PARAMS((int, int));
+RL_EXTERN int rl_emacs_editing_mode PARAMS((int, int));
+
+/* Bindable commands to change the insert mode (insert or overwrite) */
+RL_EXTERN int rl_overwrite_mode PARAMS((int, int));
+
+/* Bindable commands for managing key bindings. */
+RL_EXTERN int rl_re_read_init_file PARAMS((int, int));
+RL_EXTERN int rl_dump_functions PARAMS((int, int));
+RL_EXTERN int rl_dump_macros PARAMS((int, int));
+RL_EXTERN int rl_dump_variables PARAMS((int, int));
+
+/* Bindable commands for word completion. */
+RL_EXTERN int rl_complete PARAMS((int, int));
+RL_EXTERN int rl_possible_completions PARAMS((int, int));
+RL_EXTERN int rl_insert_completions PARAMS((int, int));
+RL_EXTERN int rl_menu_complete PARAMS((int, int));
+
+/* Bindable commands for killing and yanking text, and managing the kill ring. */
+RL_EXTERN int rl_kill_word PARAMS((int, int));
+RL_EXTERN int rl_backward_kill_word PARAMS((int, int));
+RL_EXTERN int rl_kill_line PARAMS((int, int));
+RL_EXTERN int rl_backward_kill_line PARAMS((int, int));
+RL_EXTERN int rl_kill_full_line PARAMS((int, int));
+RL_EXTERN int rl_unix_word_rubout PARAMS((int, int));
+RL_EXTERN int rl_unix_line_discard PARAMS((int, int));
+RL_EXTERN int rl_copy_region_to_kill PARAMS((int, int));
+RL_EXTERN int rl_kill_region PARAMS((int, int));
+RL_EXTERN int rl_copy_forward_word PARAMS((int, int));
+RL_EXTERN int rl_copy_backward_word PARAMS((int, int));
+RL_EXTERN int rl_yank PARAMS((int, int));
+RL_EXTERN int rl_yank_pop PARAMS((int, int));
+RL_EXTERN int rl_yank_nth_arg PARAMS((int, int));
+RL_EXTERN int rl_yank_last_arg PARAMS((int, int));
+/* Not available unless __CYGWIN__ is defined. */
+#if defined __CYGWIN__ || defined _WIN32
+RL_EXTERN int rl_paste_from_clipboard PARAMS((int, int));
+#endif
+
+/* Bindable commands for incremental searching. */
+RL_EXTERN int rl_reverse_search_history PARAMS((int, int));
+RL_EXTERN int rl_forward_search_history PARAMS((int, int));
+
+/* Bindable keyboard macro commands. */
+RL_EXTERN int rl_start_kbd_macro PARAMS((int, int));
+RL_EXTERN int rl_end_kbd_macro PARAMS((int, int));
+RL_EXTERN int rl_call_last_kbd_macro PARAMS((int, int));
+
+/* Bindable undo commands. */
+RL_EXTERN int rl_revert_line PARAMS((int, int));
+RL_EXTERN int rl_undo_command PARAMS((int, int));
+
+/* Bindable tilde expansion commands. */
+RL_EXTERN int rl_tilde_expand PARAMS((int, int));
+
+/* Bindable terminal control commands. */
+RL_EXTERN int rl_restart_output PARAMS((int, int));
+RL_EXTERN int rl_stop_output PARAMS((int, int));
+
+/* Miscellaneous bindable commands. */
+RL_EXTERN int rl_abort PARAMS((int, int));
+RL_EXTERN int rl_tty_status PARAMS((int, int));
+
+/* Bindable commands for incremental and non-incremental history searching. */
+RL_EXTERN int rl_history_search_forward PARAMS((int, int));
+RL_EXTERN int rl_history_search_backward PARAMS((int, int));
+RL_EXTERN int rl_noninc_forward_search PARAMS((int, int));
+RL_EXTERN int rl_noninc_reverse_search PARAMS((int, int));
+RL_EXTERN int rl_noninc_forward_search_again PARAMS((int, int));
+RL_EXTERN int rl_noninc_reverse_search_again PARAMS((int, int));
+
+/* Bindable command used when inserting a matching close character. */
+RL_EXTERN int rl_insert_close PARAMS((int, int));
+
+/* Not available unless READLINE_CALLBACKS is defined. */
+RL_EXTERN void rl_callback_handler_install PARAMS((const char *, rl_vcpfunc_t *));
+RL_EXTERN void rl_callback_read_char PARAMS((void));
+RL_EXTERN void rl_callback_handler_remove PARAMS((void));
+
+/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
+/* VI-mode bindable commands. */
+RL_EXTERN int rl_vi_redo PARAMS((int, int));
+RL_EXTERN int rl_vi_undo PARAMS((int, int));
+RL_EXTERN int rl_vi_yank_arg PARAMS((int, int));
+RL_EXTERN int rl_vi_fetch_history PARAMS((int, int));
+RL_EXTERN int rl_vi_search_again PARAMS((int, int));
+RL_EXTERN int rl_vi_search PARAMS((int, int));
+RL_EXTERN int rl_vi_complete PARAMS((int, int));
+RL_EXTERN int rl_vi_tilde_expand PARAMS((int, int));
+RL_EXTERN int rl_vi_prev_word PARAMS((int, int));
+RL_EXTERN int rl_vi_next_word PARAMS((int, int));
+RL_EXTERN int rl_vi_end_word PARAMS((int, int));
+RL_EXTERN int rl_vi_insert_beg PARAMS((int, int));
+RL_EXTERN int rl_vi_append_mode PARAMS((int, int));
+RL_EXTERN int rl_vi_append_eol PARAMS((int, int));
+RL_EXTERN int rl_vi_eof_maybe PARAMS((int, int));
+RL_EXTERN int rl_vi_insertion_mode PARAMS((int, int));
+RL_EXTERN int rl_vi_movement_mode PARAMS((int, int));
+RL_EXTERN int rl_vi_arg_digit PARAMS((int, int));
+RL_EXTERN int rl_vi_change_case PARAMS((int, int));
+RL_EXTERN int rl_vi_put PARAMS((int, int));
+RL_EXTERN int rl_vi_column PARAMS((int, int));
+RL_EXTERN int rl_vi_delete_to PARAMS((int, int));
+RL_EXTERN int rl_vi_change_to PARAMS((int, int));
+RL_EXTERN int rl_vi_yank_to PARAMS((int, int));
+RL_EXTERN int rl_vi_delete PARAMS((int, int));
+RL_EXTERN int rl_vi_back_to_indent PARAMS((int, int));
+RL_EXTERN int rl_vi_first_print PARAMS((int, int));
+RL_EXTERN int rl_vi_char_search PARAMS((int, int));
+RL_EXTERN int rl_vi_match PARAMS((int, int));
+RL_EXTERN int rl_vi_change_char PARAMS((int, int));
+RL_EXTERN int rl_vi_subst PARAMS((int, int));
+RL_EXTERN int rl_vi_overstrike PARAMS((int, int));
+RL_EXTERN int rl_vi_overstrike_delete PARAMS((int, int));
+RL_EXTERN int rl_vi_replace PARAMS((int, int));
+RL_EXTERN int rl_vi_set_mark PARAMS((int, int));
+RL_EXTERN int rl_vi_goto_mark PARAMS((int, int));
+
+/* VI-mode utility functions. */
+RL_EXTERN int rl_vi_check PARAMS((void));
+RL_EXTERN int rl_vi_domove PARAMS((int, int *));
+RL_EXTERN int rl_vi_bracktype PARAMS((int));
+
+/* VI-mode pseudo-bindable commands, used as utility functions. */
+RL_EXTERN int rl_vi_fWord PARAMS((int, int));
+RL_EXTERN int rl_vi_bWord PARAMS((int, int));
+RL_EXTERN int rl_vi_eWord PARAMS((int, int));
+RL_EXTERN int rl_vi_fword PARAMS((int, int));
+RL_EXTERN int rl_vi_bword PARAMS((int, int));
+RL_EXTERN int rl_vi_eword PARAMS((int, int));
+
+/* **************************************************************** */
+/* */
+/* Well Published Functions */
+/* */
+/* **************************************************************** */
+
+/* Readline functions. */
+/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */
+RL_EXTERN char *readline PARAMS((const char *));
+
+RL_EXTERN int rl_set_prompt PARAMS((const char *));
+RL_EXTERN int rl_expand_prompt PARAMS((char *));
+
+RL_EXTERN int rl_initialize PARAMS((void));
+
+/* Undocumented; unused by readline */
+RL_EXTERN int rl_discard_argument PARAMS((void));
+
+/* Utility functions to bind keys to readline commands. */
+RL_EXTERN int rl_add_defun PARAMS((const char *, rl_command_func_t *, int));
+RL_EXTERN int rl_bind_key PARAMS((int, rl_command_func_t *));
+RL_EXTERN int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap));
+RL_EXTERN int rl_unbind_key PARAMS((int));
+RL_EXTERN int rl_unbind_key_in_map PARAMS((int, Keymap));
+RL_EXTERN int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap));
+RL_EXTERN int rl_unbind_command_in_map PARAMS((const char *, Keymap));
+RL_EXTERN int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap));
+RL_EXTERN int rl_generic_bind PARAMS((int, const char *, char *, Keymap));
+RL_EXTERN int rl_variable_bind PARAMS((const char *, const char *));
+
+/* Backwards compatibility, use rl_generic_bind instead. */
+RL_EXTERN int rl_macro_bind PARAMS((const char *, const char *, Keymap));
+
+/* Undocumented in the texinfo manual; not really useful to programs. */
+RL_EXTERN int rl_translate_keyseq PARAMS((const char *, char *, int *));
+RL_EXTERN char *rl_untranslate_keyseq PARAMS((int));
+
+RL_EXTERN rl_command_func_t *rl_named_function PARAMS((const char *));
+RL_EXTERN rl_command_func_t *rl_function_of_keyseq PARAMS((const char *, Keymap, int *));
+
+RL_EXTERN void rl_list_funmap_names PARAMS((void));
+RL_EXTERN char **rl_invoking_keyseqs_in_map PARAMS((rl_command_func_t *, Keymap));
+RL_EXTERN char **rl_invoking_keyseqs PARAMS((rl_command_func_t *));
+
+RL_EXTERN void rl_function_dumper PARAMS((int));
+RL_EXTERN void rl_macro_dumper PARAMS((int));
+RL_EXTERN void rl_variable_dumper PARAMS((int));
+
+RL_EXTERN int rl_read_init_file PARAMS((const char *));
+RL_EXTERN int rl_parse_and_bind PARAMS((char *));
+
+/* Functions for manipulating keymaps. */
+RL_EXTERN Keymap rl_make_bare_keymap PARAMS((void));
+RL_EXTERN Keymap rl_copy_keymap PARAMS((Keymap));
+RL_EXTERN Keymap rl_make_keymap PARAMS((void));
+RL_EXTERN void rl_discard_keymap PARAMS((Keymap));
+
+RL_EXTERN Keymap rl_get_keymap_by_name PARAMS((const char *));
+RL_EXTERN char *rl_get_keymap_name PARAMS((Keymap));
+RL_EXTERN void rl_set_keymap PARAMS((Keymap));
+RL_EXTERN Keymap rl_get_keymap PARAMS((void));
+/* Undocumented; used internally only. */
+RL_EXTERN void rl_set_keymap_from_edit_mode PARAMS((void));
+RL_EXTERN char *rl_get_keymap_name_from_edit_mode PARAMS((void));
+
+/* Functions for manipulating the funmap, which maps command names to functions. */
+RL_EXTERN int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *));
+RL_EXTERN const char **rl_funmap_names PARAMS((void));
+/* Undocumented, only used internally -- there is only one funmap, and this
+ function may be called only once. */
+RL_EXTERN void rl_initialize_funmap PARAMS((void));
+
+/* Utility functions for managing keyboard macros. */
+RL_EXTERN void rl_push_macro_input PARAMS((char *));
+
+/* Functions for undoing, from undo.c */
+RL_EXTERN void rl_add_undo PARAMS((enum undo_code, int, int, char *));
+RL_EXTERN void rl_free_undo_list PARAMS((void));
+RL_EXTERN int rl_do_undo PARAMS((void));
+RL_EXTERN int rl_begin_undo_group PARAMS((void));
+RL_EXTERN int rl_end_undo_group PARAMS((void));
+RL_EXTERN int rl_modifying PARAMS((int, int));
+
+/* Functions for redisplay. */
+RL_EXTERN void rl_redisplay PARAMS((void));
+RL_EXTERN int rl_on_new_line PARAMS((void));
+RL_EXTERN int rl_on_new_line_with_prompt PARAMS((void));
+RL_EXTERN int rl_forced_update_display PARAMS((void));
+RL_EXTERN int rl_clear_message PARAMS((void));
+RL_EXTERN int rl_reset_line_state PARAMS((void));
+RL_EXTERN int rl_crlf PARAMS((void));
+
+#if (defined (__STDC__) || defined (__cplusplus)) && defined (USE_VARARGS) && defined (PREFER_STDARG)
+RL_EXTERN int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
+#else
+RL_EXTERN int rl_message ();
+#endif
+
+RL_EXTERN int rl_show_char PARAMS((int));
+
+/* Undocumented in texinfo manual. */
+RL_EXTERN int rl_character_len PARAMS((int, int));
+
+/* Save and restore internal prompt redisplay information. */
+RL_EXTERN void rl_save_prompt PARAMS((void));
+RL_EXTERN void rl_restore_prompt PARAMS((void));
+
+/* Modifying text. */
+RL_EXTERN void rl_replace_line PARAMS((const char *, int));
+RL_EXTERN int rl_insert_text PARAMS((const char *));
+RL_EXTERN int rl_delete_text PARAMS((int, int));
+RL_EXTERN int rl_kill_text PARAMS((int, int));
+RL_EXTERN char *rl_copy_text PARAMS((int, int));
+
+/* Terminal and tty mode management. */
+RL_EXTERN void rl_prep_terminal PARAMS((int));
+RL_EXTERN void rl_deprep_terminal PARAMS((void));
+RL_EXTERN void rl_tty_set_default_bindings PARAMS((Keymap));
+
+RL_EXTERN int rl_reset_terminal PARAMS((const char *));
+RL_EXTERN void rl_resize_terminal PARAMS((void));
+RL_EXTERN void rl_set_screen_size PARAMS((int, int));
+RL_EXTERN void rl_get_screen_size PARAMS((int *, int *));
+
+RL_EXTERN char *rl_get_termcap PARAMS((const char *));
+
+/* Functions for character input. */
+RL_EXTERN int rl_stuff_char PARAMS((int));
+RL_EXTERN int rl_execute_next PARAMS((int));
+RL_EXTERN int rl_clear_pending_input PARAMS((void));
+RL_EXTERN int rl_read_key PARAMS((void));
+RL_EXTERN int rl_getc PARAMS((FILE *));
+RL_EXTERN int rl_set_keyboard_input_timeout PARAMS((int));
+
+/* `Public' utility functions . */
+RL_EXTERN void rl_extend_line_buffer PARAMS((int));
+RL_EXTERN int rl_ding PARAMS((void));
+RL_EXTERN int rl_alphabetic PARAMS((int));
+
+/* Readline signal handling, from signals.c */
+RL_EXTERN int rl_set_signals PARAMS((void));
+RL_EXTERN int rl_clear_signals PARAMS((void));
+RL_EXTERN void rl_cleanup_after_signal PARAMS((void));
+RL_EXTERN void rl_reset_after_signal PARAMS((void));
+RL_EXTERN void rl_free_line_state PARAMS((void));
+
+RL_EXTERN int rl_set_paren_blink_timeout PARAMS((int));
+
+/* Undocumented. */
+RL_EXTERN int rl_maybe_save_line PARAMS((void));
+RL_EXTERN int rl_maybe_unsave_line PARAMS((void));
+RL_EXTERN int rl_maybe_replace_line PARAMS((void));
+
+/* Completion functions. */
+RL_EXTERN int rl_complete_internal PARAMS((int));
+RL_EXTERN void rl_display_match_list PARAMS((char **, int, int));
+
+RL_EXTERN char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *));
+RL_EXTERN char *rl_username_completion_function PARAMS((const char *, int));
+RL_EXTERN char *rl_filename_completion_function PARAMS((const char *, int));
+
+RL_EXTERN int rl_completion_mode PARAMS((rl_command_func_t *));
+
+#if 0
+/* Backwards compatibility (compat.c). These will go away sometime. */
+RL_EXTERN void free_undo_list PARAMS((void));
+RL_EXTERN int maybe_save_line PARAMS((void));
+RL_EXTERN int maybe_unsave_line PARAMS((void));
+RL_EXTERN int maybe_replace_line PARAMS((void));
+
+RL_EXTERN int ding PARAMS((void));
+RL_EXTERN int alphabetic PARAMS((int));
+RL_EXTERN int crlf PARAMS((void));
+
+RL_EXTERN char **completion_matches PARAMS((char *, rl_compentry_func_t *));
+RL_EXTERN char *username_completion_function PARAMS((const char *, int));
+RL_EXTERN char *filename_completion_function PARAMS((const char *, int));
+#endif
+
+/* **************************************************************** */
+/* */
+/* Well Published Variables */
+/* */
+/* **************************************************************** */
+
+/* The version of this incarnation of the readline library. */
+RL_EXTERN const char *rl_library_version; /* e.g., "4.2" */
+RL_EXTERN int rl_readline_version; /* e.g., 0x0402 */
+
+/* True if this is real GNU readline. */
+RL_EXTERN int rl_gnu_readline_p;
+
+/* Flags word encapsulating the current readline state. */
+RL_EXTERN int rl_readline_state;
+
+/* Says which editing mode readline is currently using. 1 means emacs mode;
+ 0 means vi mode. */
+RL_EXTERN int rl_editing_mode;
+
+/* Insert or overwrite mode for emacs mode. 1 means insert mode; 0 means
+ overwrite mode. Reset to insert mode on each input line. */
+RL_EXTERN int rl_insert_mode;
+
+/* The name of the calling program. You should initialize this to
+ whatever was in argv[0]. It is used when parsing conditionals. */
+RL_EXTERN const char *rl_readline_name;
+
+/* The prompt readline uses. This is set from the argument to
+ readline (), and should not be assigned to directly. */
+RL_EXTERN char *rl_prompt;
+
+/* The line buffer that is in use. */
+RL_EXTERN char *rl_line_buffer;
+
+/* The location of point, and end. */
+RL_EXTERN int rl_point;
+RL_EXTERN int rl_end;
+
+/* The mark, or saved cursor position. */
+RL_EXTERN int rl_mark;
+
+/* Flag to indicate that readline has finished with the current input
+ line and should return it. */
+RL_EXTERN int rl_done;
+
+/* If set to a character value, that will be the next keystroke read. */
+RL_EXTERN int rl_pending_input;
+
+/* Non-zero if we called this function from _rl_dispatch(). It's present
+ so functions can find out whether they were called from a key binding
+ or directly from an application. */
+RL_EXTERN int rl_dispatching;
+
+/* Non-zero if the user typed a numeric argument before executing the
+ current function. */
+RL_EXTERN int rl_explicit_arg;
+
+/* The current value of the numeric argument specified by the user. */
+RL_EXTERN int rl_numeric_arg;
+
+/* The address of the last command function Readline executed. */
+RL_EXTERN rl_command_func_t *rl_last_func;
+
+/* The name of the terminal to use. */
+RL_EXTERN const char *rl_terminal_name;
+
+/* The input and output streams. */
+RL_EXTERN FILE *rl_instream;
+RL_EXTERN FILE *rl_outstream;
+
+/* If non-zero, then this is the address of a function to call just
+ before readline_internal () prints the first prompt. */
+RL_EXTERN rl_hook_func_t *rl_startup_hook;
+
+/* If non-zero, this is the address of a function to call just before
+ readline_internal_setup () returns and readline_internal starts
+ reading input characters. */
+RL_EXTERN rl_hook_func_t *rl_pre_input_hook;
+
+/* The address of a function to call periodically while Readline is
+ awaiting character input, or NULL, for no event handling. */
+RL_EXTERN rl_hook_func_t *rl_event_hook;
+
+/* The address of the function to call to fetch a character from the current
+ Readline input stream */
+RL_EXTERN rl_getc_func_t *rl_getc_function;
+
+RL_EXTERN rl_voidfunc_t *rl_redisplay_function;
+
+RL_EXTERN rl_vintfunc_t *rl_prep_term_function;
+RL_EXTERN rl_voidfunc_t *rl_deprep_term_function;
+
+/* Dispatch variables. */
+RL_EXTERN Keymap rl_executing_keymap;
+RL_EXTERN Keymap rl_binding_keymap;
+
+/* Display variables. */
+/* If non-zero, readline will erase the entire line, including any prompt,
+ if the only thing typed on an otherwise-blank line is something bound to
+ rl_newline. */
+RL_EXTERN int rl_erase_empty_line;
+
+/* If non-zero, the application has already printed the prompt (rl_prompt)
+ before calling readline, so readline should not output it the first time
+ redisplay is done. */
+RL_EXTERN int rl_already_prompted;
+
+/* A non-zero value means to read only this many characters rather than
+ up to a character bound to accept-line. */
+RL_EXTERN int rl_num_chars_to_read;
+
+/* The text of a currently-executing keyboard macro. */
+RL_EXTERN char *rl_executing_macro;
+
+/* Variables to control readline signal handling. */
+/* If non-zero, readline will install its own signal handlers for
+ SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
+RL_EXTERN int rl_catch_signals;
+
+/* If non-zero, readline will install a signal handler for SIGWINCH
+ that also attempts to call any calling application's SIGWINCH signal
+ handler. Note that the terminal is not cleaned up before the
+ application's signal handler is called; use rl_cleanup_after_signal()
+ to do that. */
+RL_EXTERN int rl_catch_sigwinch;
+
+/* Completion variables. */
+/* Pointer to the generator function for completion_matches ().
+ NULL means to use rl_filename_completion_function (), the default
+ filename completer. */
+RL_EXTERN rl_compentry_func_t *rl_completion_entry_function;
+
+/* If rl_ignore_some_completions_function is non-NULL it is the address
+ of a function to call after all of the possible matches have been
+ generated, but before the actual completion is done to the input line.
+ The function is called with one argument; a NULL terminated array
+ of (char *). If your function removes any of the elements, they
+ must be free()'ed. */
+RL_EXTERN rl_compignore_func_t *rl_ignore_some_completions_function;
+
+/* Pointer to alternative function to create matches.
+ Function is called with TEXT, START, and END.
+ START and END are indices in RL_LINE_BUFFER saying what the boundaries
+ of TEXT are.
+ If this function exists and returns NULL then call the value of
+ rl_completion_entry_function to try to match, otherwise use the
+ array of strings returned. */
+RL_EXTERN rl_completion_func_t *rl_attempted_completion_function;
+
+/* The basic list of characters that signal a break between words for the
+ completer routine. The initial contents of this variable is what
+ breaks words in the shell, i.e. "n\"\\'`@$>". */
+RL_EXTERN const char *rl_basic_word_break_characters;
+
+/* The list of characters that signal a break between words for
+ rl_complete_internal. The default list is the contents of
+ rl_basic_word_break_characters. */
+RL_EXTERN const char *rl_completer_word_break_characters;
+
+/* List of characters which can be used to quote a substring of the line.
+ Completion occurs on the entire substring, and within the substring
+ rl_completer_word_break_characters are treated as any other character,
+ unless they also appear within this list. */
+RL_EXTERN const char *rl_completer_quote_characters;
+
+/* List of quote characters which cause a word break. */
+RL_EXTERN const char *rl_basic_quote_characters;
+
+/* List of characters that need to be quoted in filenames by the completer. */
+RL_EXTERN const char *rl_filename_quote_characters;
+
+/* List of characters that are word break characters, but should be left
+ in TEXT when it is passed to the completion function. The shell uses
+ this to help determine what kind of completing to do. */
+RL_EXTERN const char *rl_special_prefixes;
+
+/* If non-zero, then this is the address of a function to call when
+ completing on a directory name. The function is called with
+ the address of a string (the current directory name) as an arg. It
+ changes what is displayed when the possible completions are printed
+ or inserted. */
+RL_EXTERN rl_icppfunc_t *rl_directory_completion_hook;
+
+/* If non-zero, this is the address of a function to call when completing
+ a directory name. This function takes the address of the directory name
+ to be modified as an argument. Unlike rl_directory_completion_hook, it
+ only modifies the directory name used in opendir(2), not what is displayed
+ when the possible completions are printed or inserted. It is called
+ before rl_directory_completion_hook. I'm not happy with how this works
+ yet, so it's undocumented. */
+RL_EXTERN rl_icppfunc_t *rl_directory_rewrite_hook;
+
+/* Backwards compatibility with previous versions of readline. */
+#define rl_symbolic_link_hook rl_directory_completion_hook
+
+/* If non-zero, then this is the address of a function to call when
+ completing a word would normally display the list of possible matches.
+ This function is called instead of actually doing the display.
+ It takes three arguments: (char **matches, int num_matches, int max_length)
+ where MATCHES is the array of strings that matched, NUM_MATCHES is the
+ number of strings in that array, and MAX_LENGTH is the length of the
+ longest string in that array. */
+RL_EXTERN rl_compdisp_func_t *rl_completion_display_matches_hook;
+
+/* Non-zero means that the results of the matches are to be treated
+ as filenames. This is ALWAYS zero on entry, and can only be changed
+ within a completion entry finder function. */
+RL_EXTERN int rl_filename_completion_desired;
+
+/* Non-zero means that the results of the matches are to be quoted using
+ double quotes (or an application-specific quoting mechanism) if the
+ filename contains any characters in rl_word_break_chars. This is
+ ALWAYS non-zero on entry, and can only be changed within a completion
+ entry finder function. */
+RL_EXTERN int rl_filename_quoting_desired;
+
+/* Set to a function to quote a filename in an application-specific fashion.
+ Called with the text to quote, the type of match found (single or multiple)
+ and a pointer to the quoting character to be used, which the function can
+ reset if desired. */
+RL_EXTERN rl_quote_func_t *rl_filename_quoting_function;
+
+/* Function to call to remove quoting characters from a filename. Called
+ before completion is attempted, so the embedded quotes do not interfere
+ with matching names in the file system. */
+RL_EXTERN rl_dequote_func_t *rl_filename_dequoting_function;
+
+/* Function to call to decide whether or not a word break character is
+ quoted. If a character is quoted, it does not break words for the
+ completer. */
+RL_EXTERN rl_linebuf_func_t *rl_char_is_quoted_p;
+
+/* Non-zero means to suppress normal filename completion after the
+ user-specified completion function has been called. */
+RL_EXTERN int rl_attempted_completion_over;
+
+/* Set to a character describing the type of completion being attempted by
+ rl_complete_internal; available for use by application completion
+ functions. */
+RL_EXTERN int rl_completion_type;
+
+/* Character appended to completed words when at the end of the line. The
+ default is a space. Nothing is added if this is '\0'. */
+RL_EXTERN int rl_completion_append_character;
+
+/* If set to non-zero by an application completion function,
+ rl_completion_append_character will not be appended. */
+RL_EXTERN int rl_completion_suppress_append;
+
+/* Up to this many items will be displayed in response to a
+ possible-completions call. After that, we ask the user if she
+ is sure she wants to see them all. The default value is 100. */
+RL_EXTERN int rl_completion_query_items;
+
+/* If non-zero, a slash will be appended to completed filenames that are
+ symbolic links to directory names, subject to the value of the
+ mark-directories variable (which is user-settable). This exists so
+ that application completion functions can override the user's preference
+ (set via the mark-symlinked-directories variable) if appropriate.
+ It's set to the value of _rl_complete_mark_symlink_dirs in
+ rl_complete_internal before any application-specific completion
+ function is called, so without that function doing anything, the user's
+ preferences are honored. */
+RL_EXTERN int rl_completion_mark_symlink_dirs;
+
+/* If non-zero, then disallow duplicates in the matches. */
+RL_EXTERN int rl_ignore_completion_duplicates;
+
+/* If this is non-zero, completion is (temporarily) inhibited, and the
+ completion character will be inserted as any other. */
+RL_EXTERN int rl_inhibit_completion;
+
+/* Definitions available for use by readline clients. */
+#define RL_PROMPT_START_IGNORE '\001'
+#define RL_PROMPT_END_IGNORE '\002'
+
+/* Possible values for do_replace argument to rl_filename_quoting_function,
+ called by rl_complete_internal. */
+#define NO_MATCH 0
+#define SINGLE_MATCH 1
+#define MULT_MATCH 2
+
+/* Possible state values for rl_readline_state */
+#define RL_STATE_NONE 0x00000 /* no state; before first call */
+
+#define RL_STATE_INITIALIZING 0x00001 /* initializing */
+#define RL_STATE_INITIALIZED 0x00002 /* initialization done */
+#define RL_STATE_TERMPREPPED 0x00004 /* terminal is prepped */
+#define RL_STATE_READCMD 0x00008 /* reading a command key */
+#define RL_STATE_METANEXT 0x00010 /* reading input after ESC */
+#define RL_STATE_DISPATCHING 0x00020 /* dispatching to a command */
+#define RL_STATE_MOREINPUT 0x00040 /* reading more input in a command function */
+#define RL_STATE_ISEARCH 0x00080 /* doing incremental search */
+#define RL_STATE_NSEARCH 0x00100 /* doing non-inc search */
+#define RL_STATE_SEARCH 0x00200 /* doing a history search */
+#define RL_STATE_NUMERICARG 0x00400 /* reading numeric argument */
+#define RL_STATE_MACROINPUT 0x00800 /* getting input from a macro */
+#define RL_STATE_MACRODEF 0x01000 /* defining keyboard macro */
+#define RL_STATE_OVERWRITE 0x02000 /* overwrite mode */
+#define RL_STATE_COMPLETING 0x04000 /* doing completion */
+#define RL_STATE_SIGHANDLER 0x08000 /* in readline sighandler */
+#define RL_STATE_UNDOING 0x10000 /* doing an undo */
+#define RL_STATE_INPUTPENDING 0x20000 /* rl_execute_next called */
+
+#define RL_STATE_DONE 0x80000 /* done; accepted line */
+
+#define RL_SETSTATE(x) (rl_readline_state |= (x))
+#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x))
+#define RL_ISSTATE(x) (rl_readline_state & (x))
+
+struct readline_state {
+ /* line state */
+ int point;
+ int end;
+ int mark;
+ char *buffer;
+ int buflen;
+ UNDO_LIST *ul;
+ char *prompt;
+
+ /* global state */
+ int rlstate;
+ int done;
+ Keymap kmap;
+
+ /* input state */
+ rl_command_func_t *lastfunc;
+ int insmode;
+ int edmode;
+ int kseqlen;
+ FILE *inf;
+ FILE *outf;
+ int pendingin;
+ char *macro;
+
+ /* signal state */
+ int catchsigs;
+ int catchsigwinch;
+
+ /* reserved for future expansion, so the struct size doesn't change */
+ char reserved[64];
+};
+
+RL_EXTERN int rl_save_state PARAMS((struct readline_state *));
+RL_EXTERN int rl_restore_state PARAMS((struct readline_state *));
+
+#ifdef _MSC_VER
+#define __attribute__(x)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _READLINE_H_ */
+
diff --git a/MSVC/readline/rlconf.h b/MSVC/readline/rlconf.h
index 09aaeba..264315b 100644
--- a/MSVC/readline/rlconf.h
+++ b/MSVC/readline/rlconf.h
@@ -1,80 +1,80 @@
-/* rlconf.h -- readline configuration definitions */
-
-/* Copyright (C) 1994 Free Software Foundation, Inc.
-
- This file contains the Readline Library (the Library), a set of
- routines for providing Emacs style line input to programs that ask
- for it.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_RLCONF_H_)
-#define _RLCONF_H_
-
-/* Define this if you want the vi-mode editing available. */
-#define VI_MODE
-
-/* Define this to get an indication of file type when listing completions. */
-#define VISIBLE_STATS
-
-/* This definition is needed by readline.c, rltty.c, and signals.c. */
-/* If on, then readline handles signals in a way that doesn't screw. */
-#define HANDLE_SIGNALS
-
-/* Ugly but working hack for binding prefix meta. */
-#define PREFIX_META_HACK
-
-/* The final, last-ditch effort file name for an init file. */
-#define DEFAULT_INPUTRC "~/.inputrc"
-
-/* If defined, expand tabs to spaces. */
-//#define DISPLAY_TABS
-
-/* If defined, use the terminal escape sequence to move the cursor forward
- over a character when updating the line rather than rewriting it. */
-/* #define HACK_TERMCAP_MOTION */
-
-/* The string inserted by the `insert comment' command. */
-#define RL_COMMENT_BEGIN_DEFAULT "#"
-
-/* Define this if you want code that allows readline to be used in an
- X `callback' style. */
-#define READLINE_CALLBACKS
-
-/* Define this if you want the cursor to indicate insert or overwrite mode. */
-/* #define CURSOR_MODE */
-
-#if defined (_WIN32)
-
-/* undefine this if you do not wish to use the mouse for positioning the
- cursor of a win32 console */
-#define WITH_MINI_MOUSE 1
-
-/* undefine this when readline / history should not look into the registry
- for the path to their init files */
-#define INITFILES_IN_REGISTRY 1
-
-#if defined (INITFILES_IN_REGISTRY)
-/* We also try to get the .inputrc and .history file paths from the registry,
- define what to look for */
-#define READLINE_REGKEY "Software\\Free Software Foundation\\libreadline"
-#define INPUTRC_REGVAL "inputrc-file"
-#define HISTFILE_REGVAL "history-file"
-#endif
-
-#endif /* _WIN32 */
-
-#endif /* _RLCONF_H_ */
+/* rlconf.h -- readline configuration definitions */
+
+/* Copyright (C) 1994 Free Software Foundation, Inc.
+
+ This file contains the Readline Library (the Library), a set of
+ routines for providing Emacs style line input to programs that ask
+ for it.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_RLCONF_H_)
+#define _RLCONF_H_
+
+/* Define this if you want the vi-mode editing available. */
+#define VI_MODE
+
+/* Define this to get an indication of file type when listing completions. */
+#define VISIBLE_STATS
+
+/* This definition is needed by readline.c, rltty.c, and signals.c. */
+/* If on, then readline handles signals in a way that doesn't screw. */
+#define HANDLE_SIGNALS
+
+/* Ugly but working hack for binding prefix meta. */
+#define PREFIX_META_HACK
+
+/* The final, last-ditch effort file name for an init file. */
+#define DEFAULT_INPUTRC "~/.inputrc"
+
+/* If defined, expand tabs to spaces. */
+//#define DISPLAY_TABS
+
+/* If defined, use the terminal escape sequence to move the cursor forward
+ over a character when updating the line rather than rewriting it. */
+/* #define HACK_TERMCAP_MOTION */
+
+/* The string inserted by the `insert comment' command. */
+#define RL_COMMENT_BEGIN_DEFAULT "#"
+
+/* Define this if you want code that allows readline to be used in an
+ X `callback' style. */
+#define READLINE_CALLBACKS
+
+/* Define this if you want the cursor to indicate insert or overwrite mode. */
+/* #define CURSOR_MODE */
+
+#if defined (_WIN32)
+
+/* undefine this if you do not wish to use the mouse for positioning the
+ cursor of a win32 console */
+#define WITH_MINI_MOUSE 1
+
+/* undefine this when readline / history should not look into the registry
+ for the path to their init files */
+#define INITFILES_IN_REGISTRY 1
+
+#if defined (INITFILES_IN_REGISTRY)
+/* We also try to get the .inputrc and .history file paths from the registry,
+ define what to look for */
+#define READLINE_REGKEY "Software\\Free Software Foundation\\libreadline"
+#define INPUTRC_REGVAL "inputrc-file"
+#define HISTFILE_REGVAL "history-file"
+#endif
+
+#endif /* _WIN32 */
+
+#endif /* _RLCONF_H_ */
diff --git a/MSVC/readline/rldefs.h b/MSVC/readline/rldefs.h
index 5aceb7f..fccb7da 100644
--- a/MSVC/readline/rldefs.h
+++ b/MSVC/readline/rldefs.h
@@ -1,163 +1,163 @@
-/* rldefs.h -- an attempt to isolate some of the system-specific defines
- for readline. This should be included after any files that define
- system-specific constants like _POSIX_VERSION or USG. */
-
-/* Copyright (C) 1987,1989 Free Software Foundation, Inc.
-
- This file contains the Readline Library (the Library), a set of
- routines for providing Emacs style line input to programs that ask
- for it.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_RLDEFS_H_)
-#define _RLDEFS_H_
-
-#include "config.h"
-
-#include "rlstdc.h"
-
-#if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING)
-# define TERMIOS_TTY_DRIVER
-#else
-# if defined (HAVE_TERMIO_H)
-# define TERMIO_TTY_DRIVER
-# else
-# define NEW_TTY_DRIVER
-# endif
-#endif
-
-/* Posix macro to check file in statbuf for directory-ness.
- This requires that <sys/stat.h> be included before this test. */
-#if defined (S_IFDIR) && !defined (S_ISDIR)
-# define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
-#endif
-
-/* Decide which flavor of the header file describing the C library
- string functions to include and include it. */
-
-#if defined (HAVE_STRING_H)
-# include <string.h>
-#else /* !HAVE_STRING_H */
-# include <strings.h>
-#endif /* !HAVE_STRING_H */
-
-#if !defined (strchr) && !defined (__STDC__) && !defined _MSC_VER
-extern char *strchr (), *strrchr ();
-#endif /* !strchr && !__STDC__ */
-
-#if defined (PREFER_STDARG)
-# include <stdarg.h>
-#else
-# if defined (PREFER_VARARGS)
-# include <varargs.h>
-# endif
-#endif
-
-#if defined (HAVE_STRCASECMP)
-#define _rl_stricmp strcasecmp
-#define _rl_strnicmp strncasecmp
-#else
-extern int _rl_stricmp PARAMS((const char *, const char *));
-extern int _rl_strnicmp PARAMS((const char *, const char *, int));
-#endif
-
-#if defined (HAVE_STRPBRK)
-# define _rl_strpbrk(a,b) strpbrk((a),(b))
-#else
-extern char *_rl_strpbrk PARAMS((const char *, const char *));
-#endif
-
-#if !defined (emacs_mode)
-# define no_mode -1
-# define vi_mode 0
-# define emacs_mode 1
-#endif
-
-#if !defined (RL_IM_INSERT)
-# define RL_IM_INSERT 1
-# define RL_IM_OVERWRITE 0
-#
-# define RL_IM_DEFAULT RL_IM_INSERT
-#endif
-
-/* If you cast map[key].function to type (Keymap) on a Cray,
- the compiler takes the value of map[key].function and
- divides it by 4 to convert between pointer types (pointers
- to functions and pointers to structs are different sizes).
- This is not what is wanted. */
-#if defined (CRAY)
-# define FUNCTION_TO_KEYMAP(map, key) (Keymap)((int)map[key].function)
-# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)((int)(data))
-#else
-# define FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function)
-# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)(data)
-#endif
-
-#ifndef savestring
-#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
-#endif
-
-/* Possible values for _rl_bell_preference. */
-#define NO_BELL 0
-#define AUDIBLE_BELL 1
-#define VISIBLE_BELL 2
-
-/* Definitions used when searching the line for characters. */
-/* NOTE: it is necessary that opposite directions are inverses */
-#define FTO 1 /* forward to */
-#define BTO -1 /* backward to */
-#define FFIND 2 /* forward find */
-#define BFIND -2 /* backward find */
-
-/* Possible values for the found_quote flags word used by the completion
- functions. It says what kind of (shell-like) quoting we found anywhere
- in the line. */
-#define RL_QF_SINGLE_QUOTE 0x01
-#define RL_QF_DOUBLE_QUOTE 0x02
-#define RL_QF_BACKSLASH 0x04
-#define RL_QF_OTHER_QUOTE 0x08
-
-/* Default readline line buffer length. */
-#define DEFAULT_BUFFER_SIZE 256
-
-#if !defined (STREQ)
-#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
-#define STREQN(a, b, n) (((n) == 0) ? (1) \
- : ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
-#endif
-
-#if !defined (FREE)
-# define FREE(x) if (x) free (x)
-#endif
-
-#if !defined (SWAP)
-# define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
-#endif
-
-#if defined (_WIN32)
-
- #define WAIT_FOR_INPUT 200 /* milliseconds to suspend maximally
- when waiting for input */
- #define FOR_INPUT 1 /* flags for open state of the console */
- #define FOR_OUTPUT 2
- #define INITIALIZED 4
-#endif /* _WIN32 */
-
-/* CONFIGURATION SECTION */
-#include "rlconf.h"
-
-#endif /* !_RLDEFS_H_ */
+/* rldefs.h -- an attempt to isolate some of the system-specific defines
+ for readline. This should be included after any files that define
+ system-specific constants like _POSIX_VERSION or USG. */
+
+/* Copyright (C) 1987,1989 Free Software Foundation, Inc.
+
+ This file contains the Readline Library (the Library), a set of
+ routines for providing Emacs style line input to programs that ask
+ for it.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_RLDEFS_H_)
+#define _RLDEFS_H_
+
+#include "config.h"
+
+#include "rlstdc.h"
+
+#if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING)
+# define TERMIOS_TTY_DRIVER
+#else
+# if defined (HAVE_TERMIO_H)
+# define TERMIO_TTY_DRIVER
+# else
+# define NEW_TTY_DRIVER
+# endif
+#endif
+
+/* Posix macro to check file in statbuf for directory-ness.
+ This requires that <sys/stat.h> be included before this test. */
+#if defined (S_IFDIR) && !defined (S_ISDIR)
+# define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
+#endif
+
+/* Decide which flavor of the header file describing the C library
+ string functions to include and include it. */
+
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else /* !HAVE_STRING_H */
+# include <strings.h>
+#endif /* !HAVE_STRING_H */
+
+#if !defined (strchr) && !defined (__STDC__) && !defined _MSC_VER
+extern char *strchr (), *strrchr ();
+#endif /* !strchr && !__STDC__ */
+
+#if defined (PREFER_STDARG)
+# include <stdarg.h>
+#else
+# if defined (PREFER_VARARGS)
+# include <varargs.h>
+# endif
+#endif
+
+#if defined (HAVE_STRCASECMP)
+#define _rl_stricmp strcasecmp
+#define _rl_strnicmp strncasecmp
+#else
+extern int _rl_stricmp PARAMS((const char *, const char *));
+extern int _rl_strnicmp PARAMS((const char *, const char *, int));
+#endif
+
+#if defined (HAVE_STRPBRK)
+# define _rl_strpbrk(a,b) strpbrk((a),(b))
+#else
+extern char *_rl_strpbrk PARAMS((const char *, const char *));
+#endif
+
+#if !defined (emacs_mode)
+# define no_mode -1
+# define vi_mode 0
+# define emacs_mode 1
+#endif
+
+#if !defined (RL_IM_INSERT)
+# define RL_IM_INSERT 1
+# define RL_IM_OVERWRITE 0
+#
+# define RL_IM_DEFAULT RL_IM_INSERT
+#endif
+
+/* If you cast map[key].function to type (Keymap) on a Cray,
+ the compiler takes the value of map[key].function and
+ divides it by 4 to convert between pointer types (pointers
+ to functions and pointers to structs are different sizes).
+ This is not what is wanted. */
+#if defined (CRAY)
+# define FUNCTION_TO_KEYMAP(map, key) (Keymap)((int)map[key].function)
+# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)((int)(data))
+#else
+# define FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function)
+# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)(data)
+#endif
+
+#ifndef savestring
+#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
+#endif
+
+/* Possible values for _rl_bell_preference. */
+#define NO_BELL 0
+#define AUDIBLE_BELL 1
+#define VISIBLE_BELL 2
+
+/* Definitions used when searching the line for characters. */
+/* NOTE: it is necessary that opposite directions are inverses */
+#define FTO 1 /* forward to */
+#define BTO -1 /* backward to */
+#define FFIND 2 /* forward find */
+#define BFIND -2 /* backward find */
+
+/* Possible values for the found_quote flags word used by the completion
+ functions. It says what kind of (shell-like) quoting we found anywhere
+ in the line. */
+#define RL_QF_SINGLE_QUOTE 0x01
+#define RL_QF_DOUBLE_QUOTE 0x02
+#define RL_QF_BACKSLASH 0x04
+#define RL_QF_OTHER_QUOTE 0x08
+
+/* Default readline line buffer length. */
+#define DEFAULT_BUFFER_SIZE 256
+
+#if !defined (STREQ)
+#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
+#define STREQN(a, b, n) (((n) == 0) ? (1) \
+ : ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
+#endif
+
+#if !defined (FREE)
+# define FREE(x) if (x) free (x)
+#endif
+
+#if !defined (SWAP)
+# define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
+#endif
+
+#if defined (_WIN32)
+
+ #define WAIT_FOR_INPUT 200 /* milliseconds to suspend maximally
+ when waiting for input */
+ #define FOR_INPUT 1 /* flags for open state of the console */
+ #define FOR_OUTPUT 2
+ #define INITIALIZED 4
+#endif /* _WIN32 */
+
+/* CONFIGURATION SECTION */
+#include "rlconf.h"
+
+#endif /* !_RLDEFS_H_ */
diff --git a/MSVC/readline/rldynlink.h b/MSVC/readline/rldynlink.h
index 034e66c..94d42c2 100644
--- a/MSVC/readline/rldynlink.h
+++ b/MSVC/readline/rldynlink.h
@@ -1,17 +1,17 @@
-
-#ifndef _DYN_LINK_H
-#define _DYN_LINK_H
-
-#if defined (READLINE_STATIC)
- #define _RL_DLL
-#elif defined (_WIN32)
- #if defined (BUILDING_DLL)
- #define _RL_DLL __declspec(dllexport)
- #else
- #define _RL_DLL __declspec(dllimport)
- #endif /* BUILDING_DLL */
-#endif /* _WIN32 ... _DYNAMIC_LINK */
-
-#define RL_EXTERN extern _RL_DLL
-
-#endif /* _DYN_LINK_H */
+
+#ifndef _DYN_LINK_H
+#define _DYN_LINK_H
+
+#if defined (READLINE_STATIC)
+ #define _RL_DLL
+#elif defined (_WIN32)
+ #if defined (BUILDING_DLL)
+ #define _RL_DLL __declspec(dllexport)
+ #else
+ #define _RL_DLL __declspec(dllimport)
+ #endif /* BUILDING_DLL */
+#endif /* _WIN32 ... _DYNAMIC_LINK */
+
+#define RL_EXTERN extern _RL_DLL
+
+#endif /* _DYN_LINK_H */
diff --git a/MSVC/readline/rlmbutil.h b/MSVC/readline/rlmbutil.h
index 80029a5..27ca32b 100644
--- a/MSVC/readline/rlmbutil.h
+++ b/MSVC/readline/rlmbutil.h
@@ -1,108 +1,108 @@
-/* rlmbutil.h -- utility functions for multibyte characters. */
-
-/* Copyright (C) 2001 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_RL_MBUTIL_H_)
-#define _RL_MBUTIL_H_
-
-#include "rlstdc.h"
-
-/************************************************/
-/* check multibyte capability for I18N code */
-/************************************************/
-
-/* For platforms which support the ISO C amendement 1 functionality we
- support user defined character classes. */
- /* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
-#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H)
-# include <wchar.h>
-# include <wctype.h>
-# if defined (HAVE_MBSRTOWCS) /* system is supposed to support XPG5 */
-# define HANDLE_MULTIBYTE 1
-# endif
-#endif
-
-/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
-#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T)
-# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0)
-# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0)
-# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0)
-# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
-# define mbrlen(s, n, ps) (mbrlen) (s, n, 0)
-# define mbstate_t int
-#endif
-
-/* Make sure MB_LEN_MAX is at least 16 on systems that claim to be able to
- handle multibyte chars (some systems define MB_LEN_MAX as 1) */
-#ifdef HANDLE_MULTIBYTE
-# include <limits.h>
-# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16)
-# undef MB_LEN_MAX
-# endif
-# if !defined (MB_LEN_MAX)
-# define MB_LEN_MAX 16
-# endif
-#endif
-
-/************************************************/
-/* end of multibyte capability checks for I18N */
-/************************************************/
-
-/*
- * Flags for _rl_find_prev_mbchar and _rl_find_next_mbchar:
- *
- * MB_FIND_ANY find any multibyte character
- * MB_FIND_NONZERO find a non-zero-width multibyte character
- */
-
-#define MB_FIND_ANY 0x00
-#define MB_FIND_NONZERO 0x01
-
-extern int _rl_find_prev_mbchar PARAMS((char *, int, int));
-extern int _rl_find_next_mbchar PARAMS((char *, int, int, int));
-
-#ifdef HANDLE_MULTIBYTE
-
-extern int _rl_compare_chars PARAMS((char *, int, mbstate_t *, char *, int, mbstate_t *));
-extern int _rl_get_char_len PARAMS((char *, mbstate_t *));
-extern int _rl_adjust_point PARAMS((char *, int, mbstate_t *));
-
-extern int _rl_read_mbchar PARAMS((char *, int));
-extern int _rl_read_mbstring PARAMS((int, char *, int));
-
-extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
-
-#else /* !HANDLE_MULTIBYTE */
-
-#undef MB_LEN_MAX
-#undef MB_CUR_MAX
-
-#define MB_LEN_MAX 1
-#define MB_CUR_MAX 1
-
-#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1))
-#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2))
-
-#endif /* !HANDLE_MULTIBYTE */
-
-extern int rl_byte_oriented;
-
-#endif /* _RL_MBUTIL_H_ */
+/* rlmbutil.h -- utility functions for multibyte characters. */
+
+/* Copyright (C) 2001 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_RL_MBUTIL_H_)
+#define _RL_MBUTIL_H_
+
+#include "rlstdc.h"
+
+/************************************************/
+/* check multibyte capability for I18N code */
+/************************************************/
+
+/* For platforms which support the ISO C amendement 1 functionality we
+ support user defined character classes. */
+ /* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
+#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H)
+# include <wchar.h>
+# include <wctype.h>
+# if defined (HAVE_MBSRTOWCS) /* system is supposed to support XPG5 */
+# define HANDLE_MULTIBYTE 1
+# endif
+#endif
+
+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
+#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T)
+# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0)
+# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0)
+# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0)
+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
+# define mbrlen(s, n, ps) (mbrlen) (s, n, 0)
+# define mbstate_t int
+#endif
+
+/* Make sure MB_LEN_MAX is at least 16 on systems that claim to be able to
+ handle multibyte chars (some systems define MB_LEN_MAX as 1) */
+#ifdef HANDLE_MULTIBYTE
+# include <limits.h>
+# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16)
+# undef MB_LEN_MAX
+# endif
+# if !defined (MB_LEN_MAX)
+# define MB_LEN_MAX 16
+# endif
+#endif
+
+/************************************************/
+/* end of multibyte capability checks for I18N */
+/************************************************/
+
+/*
+ * Flags for _rl_find_prev_mbchar and _rl_find_next_mbchar:
+ *
+ * MB_FIND_ANY find any multibyte character
+ * MB_FIND_NONZERO find a non-zero-width multibyte character
+ */
+
+#define MB_FIND_ANY 0x00
+#define MB_FIND_NONZERO 0x01
+
+extern int _rl_find_prev_mbchar PARAMS((char *, int, int));
+extern int _rl_find_next_mbchar PARAMS((char *, int, int, int));
+
+#ifdef HANDLE_MULTIBYTE
+
+extern int _rl_compare_chars PARAMS((char *, int, mbstate_t *, char *, int, mbstate_t *));
+extern int _rl_get_char_len PARAMS((char *, mbstate_t *));
+extern int _rl_adjust_point PARAMS((char *, int, mbstate_t *));
+
+extern int _rl_read_mbchar PARAMS((char *, int));
+extern int _rl_read_mbstring PARAMS((int, char *, int));
+
+extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
+
+#else /* !HANDLE_MULTIBYTE */
+
+#undef MB_LEN_MAX
+#undef MB_CUR_MAX
+
+#define MB_LEN_MAX 1
+#define MB_CUR_MAX 1
+
+#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1))
+#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2))
+
+#endif /* !HANDLE_MULTIBYTE */
+
+extern int rl_byte_oriented;
+
+#endif /* _RL_MBUTIL_H_ */
diff --git a/MSVC/readline/rlprivate.h b/MSVC/readline/rlprivate.h
index 5ef1737..ccb9144 100644
--- a/MSVC/readline/rlprivate.h
+++ b/MSVC/readline/rlprivate.h
@@ -1,284 +1,284 @@
-/* rlprivate.h -- functions and variables global to the readline library,
- but not intended for use by applications. */
-
-/* Copyright (C) 1999 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_RL_PRIVATE_H_)
-#define _RL_PRIVATE_H_
-
-#include "rlconf.h" /* for VISIBLE_STATS */
-#include "rlstdc.h"
-#include "posixjmp.h" /* defines procenv_t */
-
-/*************************************************************************
- * *
- * Global functions undocumented in texinfo manual and not in readline.h *
- * *
- *************************************************************************/
-
-/*************************************************************************
- * *
- * Global variables undocumented in texinfo manual and not in readline.h *
- * *
- *************************************************************************/
-
-/* complete.c */
-extern int rl_complete_with_tilde_expansion;
-#if defined (VISIBLE_STATS)
-extern int rl_visible_stats;
-#endif /* VISIBLE_STATS */
-
-/* readline.c */
-extern int rl_line_buffer_len;
-extern int rl_arg_sign;
-extern int rl_visible_prompt_length;
-extern int readline_echoing_p;
-extern int rl_key_sequence_length;
-extern int rl_byte_oriented;
-
-/* display.c */
-extern int rl_display_fixed;
-
-/* parens.c */
-extern int rl_blink_matching_paren;
-
-/*************************************************************************
- * *
- * Global functions and variables unsed and undocumented *
- * *
- *************************************************************************/
-
-/* kill.c */
-extern int rl_set_retained_kills PARAMS((int));
-
-/* terminal.c */
-extern void _rl_set_screen_size PARAMS((int, int));
-
-/* undo.c */
-extern int _rl_fix_last_undo_of_type PARAMS((int, int, int));
-
-/* util.c */
-extern char *_rl_savestring PARAMS((const char *));
-
-/*************************************************************************
- * *
- * Functions and variables private to the readline library *
- * *
- *************************************************************************/
-
-/* NOTE: Functions and variables prefixed with `_rl_' are
- pseudo-global: they are global so they can be shared
- between files in the readline library, but are not intended
- to be visible to readline callers. */
-
-/*************************************************************************
- * Undocumented private functions *
- *************************************************************************/
-
-#if defined(READLINE_CALLBACKS)
-
-/* readline.c */
-extern void readline_internal_setup PARAMS((void));
-extern char *readline_internal_teardown PARAMS((int));
-extern int readline_internal_char PARAMS((void));
-
-#endif /* READLINE_CALLBACKS */
-
-/* bind.c */
-extern void _rl_bind_if_unbound PARAMS((const char *, rl_command_func_t *));
-
-/* complete.c */
-extern char _rl_find_completion_word PARAMS((int *, int *));
-extern void _rl_free_match_list PARAMS((char **));
-
-/* display.c */
-extern char *_rl_strip_prompt PARAMS((char *));
-extern void _rl_move_cursor_relative PARAMS((int, const char *));
-extern void _rl_move_vert PARAMS((int));
-extern void _rl_save_prompt PARAMS((void));
-extern void _rl_restore_prompt PARAMS((void));
-extern char *_rl_make_prompt_for_search PARAMS((int));
-extern void _rl_erase_at_end_of_line PARAMS((int));
-extern void _rl_clear_to_eol PARAMS((int));
-extern void _rl_clear_screen PARAMS((void));
-extern void _rl_update_final PARAMS((void));
-extern void _rl_redisplay_after_sigwinch PARAMS((void));
-extern void _rl_clean_up_for_exit PARAMS((void));
-extern void _rl_erase_entire_line PARAMS((void));
-extern int _rl_current_display_line PARAMS((void));
-
-/* input.c */
-extern int _rl_any_typein PARAMS((void));
-extern int _rl_input_available PARAMS((void));
-extern int _rl_input_queued PARAMS((int));
-extern void _rl_insert_typein PARAMS((int));
-extern int _rl_unget_char PARAMS((int));
-
-/* macro.c */
-extern void _rl_with_macro_input PARAMS((char *));
-extern int _rl_next_macro_key PARAMS((void));
-extern void _rl_push_executing_macro PARAMS((void));
-extern void _rl_pop_executing_macro PARAMS((void));
-extern void _rl_add_macro_char PARAMS((int));
-extern void _rl_kill_kbd_macro PARAMS((void));
-
-/* misc.c */
-extern int _rl_init_argument PARAMS((void));
-extern void _rl_start_using_history PARAMS((void));
-extern int _rl_free_saved_history_line PARAMS((void));
-extern void _rl_set_insert_mode PARAMS((int, int));
-
-/* nls.c */
-extern int _rl_init_eightbit PARAMS((void));
-
-/* parens.c */
-extern void _rl_enable_paren_matching PARAMS((int));
-
-/* readline.c */
-extern void _rl_init_line_state PARAMS((void));
-extern void _rl_set_the_line PARAMS((void));
-extern int _rl_dispatch PARAMS((int, Keymap));
-extern int _rl_dispatch_subseq PARAMS((int, Keymap, int));
-
-/* rltty.c */
-extern int _rl_disable_tty_signals PARAMS((void));
-extern int _rl_restore_tty_signals PARAMS((void));
-
-/* terminal.c */
-extern void _rl_get_screen_size PARAMS((int, int));
-extern int _rl_init_terminal_io PARAMS((const char *));
-#ifdef _MINIX
-extern void _rl_output_character_function PARAMS((int));
-#else
-extern int _rl_output_character_function PARAMS((int));
-#endif
-extern void _rl_output_some_chars PARAMS((const char *, int));
-extern int _rl_backspace PARAMS((int));
-extern void _rl_enable_meta_key PARAMS((void));
-extern void _rl_control_keypad PARAMS((int));
-extern void _rl_set_cursor PARAMS((int, int));
-
-/* text.c */
-extern void _rl_fix_point PARAMS((int));
-extern int _rl_replace_text PARAMS((const char *, int, int));
-extern int _rl_insert_char PARAMS((int, int));
-extern int _rl_overwrite_char PARAMS((int, int));
-extern int _rl_overwrite_rubout PARAMS((int, int));
-extern int _rl_rubout_char PARAMS((int, int));
-#if defined (HANDLE_MULTIBYTE)
-extern int _rl_char_search_internal PARAMS((int, int, char *, int));
-#else
-extern int _rl_char_search_internal PARAMS((int, int, int));
-#endif
-extern int _rl_set_mark_at_pos PARAMS((int));
-
-/* util.c */
-extern int _rl_abort_internal PARAMS((void));
-extern char *_rl_strindex PARAMS((const char *, const char *));
-extern int _rl_qsort_string_compare PARAMS((char **, char **));
-extern int (_rl_uppercase_p) PARAMS((int));
-extern int (_rl_lowercase_p) PARAMS((int));
-extern int (_rl_pure_alphabetic) PARAMS((int));
-extern int (_rl_digit_p) PARAMS((int));
-extern int (_rl_to_lower) PARAMS((int));
-extern int (_rl_to_upper) PARAMS((int));
-extern int (_rl_digit_value) PARAMS((int));
-
-/* vi_mode.c */
-extern void _rl_vi_initialize_line PARAMS((void));
-extern void _rl_vi_reset_last PARAMS((void));
-extern void _rl_vi_set_last PARAMS((int, int, int));
-extern int _rl_vi_textmod_command PARAMS((int));
-extern void _rl_vi_done_inserting PARAMS((void));
-
-/*************************************************************************
- * Undocumented private variables *
- *************************************************************************/
-
-/* bind.c */
-extern const char *_rl_possible_control_prefixes[];
-extern const char *_rl_possible_meta_prefixes[];
-
-/* complete.c */
-extern int _rl_complete_show_all;
-extern int _rl_complete_mark_directories;
-extern int _rl_complete_mark_symlink_dirs;
-extern int _rl_print_completions_horizontally;
-extern int _rl_completion_case_fold;
-extern int _rl_match_hidden_files;
-extern int _rl_page_completions;
-
-/* display.c */
-extern int _rl_vis_botlin;
-extern int _rl_last_c_pos;
-extern int _rl_suppress_redisplay;
-extern char *rl_display_prompt;
-
-/* isearch.c */
-extern char *_rl_isearch_terminators;
-
-/* macro.c */
-extern char *_rl_executing_macro;
-
-/* misc.c */
-extern int _rl_history_preserve_point;
-extern int _rl_history_saved_point;
-
-/* readline.c */
-extern int _rl_horizontal_scroll_mode;
-extern int _rl_mark_modified_lines;
-extern int _rl_bell_preference;
-extern int _rl_meta_flag;
-extern int _rl_convert_meta_chars_to_ascii;
-extern int _rl_output_meta_chars;
-extern char *_rl_comment_begin;
-extern unsigned char _rl_parsing_conditionalized_out;
-extern Keymap _rl_keymap;
-extern FILE *_rl_in_stream;
-extern FILE *_rl_out_stream;
-extern int _rl_last_command_was_kill;
-extern int _rl_eof_char;
-extern procenv_t readline_top_level;
-
-/* terminal.c */
-extern int _rl_enable_keypad;
-extern int _rl_enable_meta;
-extern char *_rl_term_clreol;
-extern char *_rl_term_clrpag;
-extern char *_rl_term_im;
-extern char *_rl_term_ic;
-extern char *_rl_term_ei;
-extern char *_rl_term_DC;
-extern char *_rl_term_up;
-extern char *_rl_term_dc;
-extern char *_rl_term_cr;
-extern char *_rl_term_IC;
-extern int _rl_screenheight;
-extern int _rl_screenwidth;
-extern int _rl_screenchars;
-extern int _rl_terminal_can_insert;
-extern int _rl_term_autowrap;
-
-/* undo.c */
-extern int _rl_doing_an_undo;
-extern int _rl_undo_group_level;
-
-#endif /* _RL_PRIVATE_H_ */
+/* rlprivate.h -- functions and variables global to the readline library,
+ but not intended for use by applications. */
+
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_RL_PRIVATE_H_)
+#define _RL_PRIVATE_H_
+
+#include "rlconf.h" /* for VISIBLE_STATS */
+#include "rlstdc.h"
+#include "posixjmp.h" /* defines procenv_t */
+
+/*************************************************************************
+ * *
+ * Global functions undocumented in texinfo manual and not in readline.h *
+ * *
+ *************************************************************************/
+
+/*************************************************************************
+ * *
+ * Global variables undocumented in texinfo manual and not in readline.h *
+ * *
+ *************************************************************************/
+
+/* complete.c */
+extern int rl_complete_with_tilde_expansion;
+#if defined (VISIBLE_STATS)
+extern int rl_visible_stats;
+#endif /* VISIBLE_STATS */
+
+/* readline.c */
+extern int rl_line_buffer_len;
+extern int rl_arg_sign;
+extern int rl_visible_prompt_length;
+extern int readline_echoing_p;
+extern int rl_key_sequence_length;
+extern int rl_byte_oriented;
+
+/* display.c */
+extern int rl_display_fixed;
+
+/* parens.c */
+extern int rl_blink_matching_paren;
+
+/*************************************************************************
+ * *
+ * Global functions and variables unsed and undocumented *
+ * *
+ *************************************************************************/
+
+/* kill.c */
+extern int rl_set_retained_kills PARAMS((int));
+
+/* terminal.c */
+extern void _rl_set_screen_size PARAMS((int, int));
+
+/* undo.c */
+extern int _rl_fix_last_undo_of_type PARAMS((int, int, int));
+
+/* util.c */
+extern char *_rl_savestring PARAMS((const char *));
+
+/*************************************************************************
+ * *
+ * Functions and variables private to the readline library *
+ * *
+ *************************************************************************/
+
+/* NOTE: Functions and variables prefixed with `_rl_' are
+ pseudo-global: they are global so they can be shared
+ between files in the readline library, but are not intended
+ to be visible to readline callers. */
+
+/*************************************************************************
+ * Undocumented private functions *
+ *************************************************************************/
+
+#if defined(READLINE_CALLBACKS)
+
+/* readline.c */
+extern void readline_internal_setup PARAMS((void));
+extern char *readline_internal_teardown PARAMS((int));
+extern int readline_internal_char PARAMS((void));
+
+#endif /* READLINE_CALLBACKS */
+
+/* bind.c */
+extern void _rl_bind_if_unbound PARAMS((const char *, rl_command_func_t *));
+
+/* complete.c */
+extern char _rl_find_completion_word PARAMS((int *, int *));
+extern void _rl_free_match_list PARAMS((char **));
+
+/* display.c */
+extern char *_rl_strip_prompt PARAMS((char *));
+extern void _rl_move_cursor_relative PARAMS((int, const char *));
+extern void _rl_move_vert PARAMS((int));
+extern void _rl_save_prompt PARAMS((void));
+extern void _rl_restore_prompt PARAMS((void));
+extern char *_rl_make_prompt_for_search PARAMS((int));
+extern void _rl_erase_at_end_of_line PARAMS((int));
+extern void _rl_clear_to_eol PARAMS((int));
+extern void _rl_clear_screen PARAMS((void));
+extern void _rl_update_final PARAMS((void));
+extern void _rl_redisplay_after_sigwinch PARAMS((void));
+extern void _rl_clean_up_for_exit PARAMS((void));
+extern void _rl_erase_entire_line PARAMS((void));
+extern int _rl_current_display_line PARAMS((void));
+
+/* input.c */
+extern int _rl_any_typein PARAMS((void));
+extern int _rl_input_available PARAMS((void));
+extern int _rl_input_queued PARAMS((int));
+extern void _rl_insert_typein PARAMS((int));
+extern int _rl_unget_char PARAMS((int));
+
+/* macro.c */
+extern void _rl_with_macro_input PARAMS((char *));
+extern int _rl_next_macro_key PARAMS((void));
+extern void _rl_push_executing_macro PARAMS((void));
+extern void _rl_pop_executing_macro PARAMS((void));
+extern void _rl_add_macro_char PARAMS((int));
+extern void _rl_kill_kbd_macro PARAMS((void));
+
+/* misc.c */
+extern int _rl_init_argument PARAMS((void));
+extern void _rl_start_using_history PARAMS((void));
+extern int _rl_free_saved_history_line PARAMS((void));
+extern void _rl_set_insert_mode PARAMS((int, int));
+
+/* nls.c */
+extern int _rl_init_eightbit PARAMS((void));
+
+/* parens.c */
+extern void _rl_enable_paren_matching PARAMS((int));
+
+/* readline.c */
+extern void _rl_init_line_state PARAMS((void));
+extern void _rl_set_the_line PARAMS((void));
+extern int _rl_dispatch PARAMS((int, Keymap));
+extern int _rl_dispatch_subseq PARAMS((int, Keymap, int));
+
+/* rltty.c */
+extern int _rl_disable_tty_signals PARAMS((void));
+extern int _rl_restore_tty_signals PARAMS((void));
+
+/* terminal.c */
+extern void _rl_get_screen_size PARAMS((int, int));
+extern int _rl_init_terminal_io PARAMS((const char *));
+#ifdef _MINIX
+extern void _rl_output_character_function PARAMS((int));
+#else
+extern int _rl_output_character_function PARAMS((int));
+#endif
+extern void _rl_output_some_chars PARAMS((const char *, int));
+extern int _rl_backspace PARAMS((int));
+extern void _rl_enable_meta_key PARAMS((void));
+extern void _rl_control_keypad PARAMS((int));
+extern void _rl_set_cursor PARAMS((int, int));
+
+/* text.c */
+extern void _rl_fix_point PARAMS((int));
+extern int _rl_replace_text PARAMS((const char *, int, int));
+extern int _rl_insert_char PARAMS((int, int));
+extern int _rl_overwrite_char PARAMS((int, int));
+extern int _rl_overwrite_rubout PARAMS((int, int));
+extern int _rl_rubout_char PARAMS((int, int));
+#if defined (HANDLE_MULTIBYTE)
+extern int _rl_char_search_internal PARAMS((int, int, char *, int));
+#else
+extern int _rl_char_search_internal PARAMS((int, int, int));
+#endif
+extern int _rl_set_mark_at_pos PARAMS((int));
+
+/* util.c */
+extern int _rl_abort_internal PARAMS((void));
+extern char *_rl_strindex PARAMS((const char *, const char *));
+extern int _rl_qsort_string_compare PARAMS((char **, char **));
+extern int (_rl_uppercase_p) PARAMS((int));
+extern int (_rl_lowercase_p) PARAMS((int));
+extern int (_rl_pure_alphabetic) PARAMS((int));
+extern int (_rl_digit_p) PARAMS((int));
+extern int (_rl_to_lower) PARAMS((int));
+extern int (_rl_to_upper) PARAMS((int));
+extern int (_rl_digit_value) PARAMS((int));
+
+/* vi_mode.c */
+extern void _rl_vi_initialize_line PARAMS((void));
+extern void _rl_vi_reset_last PARAMS((void));
+extern void _rl_vi_set_last PARAMS((int, int, int));
+extern int _rl_vi_textmod_command PARAMS((int));
+extern void _rl_vi_done_inserting PARAMS((void));
+
+/*************************************************************************
+ * Undocumented private variables *
+ *************************************************************************/
+
+/* bind.c */
+extern const char *_rl_possible_control_prefixes[];
+extern const char *_rl_possible_meta_prefixes[];
+
+/* complete.c */
+extern int _rl_complete_show_all;
+extern int _rl_complete_mark_directories;
+extern int _rl_complete_mark_symlink_dirs;
+extern int _rl_print_completions_horizontally;
+extern int _rl_completion_case_fold;
+extern int _rl_match_hidden_files;
+extern int _rl_page_completions;
+
+/* display.c */
+extern int _rl_vis_botlin;
+extern int _rl_last_c_pos;
+extern int _rl_suppress_redisplay;
+extern char *rl_display_prompt;
+
+/* isearch.c */
+extern char *_rl_isearch_terminators;
+
+/* macro.c */
+extern char *_rl_executing_macro;
+
+/* misc.c */
+extern int _rl_history_preserve_point;
+extern int _rl_history_saved_point;
+
+/* readline.c */
+extern int _rl_horizontal_scroll_mode;
+extern int _rl_mark_modified_lines;
+extern int _rl_bell_preference;
+extern int _rl_meta_flag;
+extern int _rl_convert_meta_chars_to_ascii;
+extern int _rl_output_meta_chars;
+extern char *_rl_comment_begin;
+extern unsigned char _rl_parsing_conditionalized_out;
+extern Keymap _rl_keymap;
+extern FILE *_rl_in_stream;
+extern FILE *_rl_out_stream;
+extern int _rl_last_command_was_kill;
+extern int _rl_eof_char;
+extern procenv_t readline_top_level;
+
+/* terminal.c */
+extern int _rl_enable_keypad;
+extern int _rl_enable_meta;
+extern char *_rl_term_clreol;
+extern char *_rl_term_clrpag;
+extern char *_rl_term_im;
+extern char *_rl_term_ic;
+extern char *_rl_term_ei;
+extern char *_rl_term_DC;
+extern char *_rl_term_up;
+extern char *_rl_term_dc;
+extern char *_rl_term_cr;
+extern char *_rl_term_IC;
+extern int _rl_screenheight;
+extern int _rl_screenwidth;
+extern int _rl_screenchars;
+extern int _rl_terminal_can_insert;
+extern int _rl_term_autowrap;
+
+/* undo.c */
+extern int _rl_doing_an_undo;
+extern int _rl_undo_group_level;
+
+#endif /* _RL_PRIVATE_H_ */
diff --git a/MSVC/readline/rlshell.h b/MSVC/readline/rlshell.h
index 15953e2..10aac2e 100644
--- a/MSVC/readline/rlshell.h
+++ b/MSVC/readline/rlshell.h
@@ -1,37 +1,37 @@
-/* rlshell.h -- utility functions normally provided by bash. */
-
-/* Copyright (C) 1999 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_RL_SHELL_H_)
-#define _RL_SHELL_H_
-
-#include "rlstdc.h"
-
-extern char *sh_single_quote PARAMS((char *));
-extern void sh_set_lines_and_columns PARAMS((int, int));
-extern char *sh_get_env_value PARAMS((const char *));
-extern char *sh_get_home_dir PARAMS((void));
-extern int sh_unset_nodelay_mode PARAMS((int));
-#if defined (_WIN32)
-char *get_user_registry_string PARAMS((char *keyName, char* valName));
-#endif /* _WIN32 */
-
-#endif /* _RL_SHELL_H_ */
+/* rlshell.h -- utility functions normally provided by bash. */
+
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_RL_SHELL_H_)
+#define _RL_SHELL_H_
+
+#include "rlstdc.h"
+
+extern char *sh_single_quote PARAMS((char *));
+extern void sh_set_lines_and_columns PARAMS((int, int));
+extern char *sh_get_env_value PARAMS((const char *));
+extern char *sh_get_home_dir PARAMS((void));
+extern int sh_unset_nodelay_mode PARAMS((int));
+#if defined (_WIN32)
+char *get_user_registry_string PARAMS((char *keyName, char* valName));
+#endif /* _WIN32 */
+
+#endif /* _RL_SHELL_H_ */
diff --git a/MSVC/readline/rlstdc.h b/MSVC/readline/rlstdc.h
index 9104e8c..47589ac 100644
--- a/MSVC/readline/rlstdc.h
+++ b/MSVC/readline/rlstdc.h
@@ -1,45 +1,45 @@
-/* stdc.h -- macros to make source compile on both ANSI C and K&R C
- compilers. */
-
-/* Copyright (C) 1993 Free Software Foundation, Inc.
-
- This file is part of GNU Bash, the Bourne Again SHell.
-
- Bash 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, or (at your option)
- any later version.
-
- Bash 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 Bash; see the file COPYING. If not, write to the Free
- Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_RL_STDC_H_)
-#define _RL_STDC_H_
-
-/* Adapted from BSD /usr/include/sys/cdefs.h. */
-
-/* A function can be defined using prototypes and compile on both ANSI C
- and traditional C compilers with something like this:
- extern char *func PARAMS((char *, char *, int)); */
-
-#if !defined (PARAMS)
-# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) || defined _MSC_VER
-# define PARAMS(protos) protos
-# else
-# define PARAMS(protos) ()
-# endif
-#endif
-
-#ifndef __attribute__
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
-# define __attribute__(x)
-# endif
-#endif
-
-#endif /* !_RL_STDC_H_ */
+/* stdc.h -- macros to make source compile on both ANSI C and K&R C
+ compilers. */
+
+/* Copyright (C) 1993 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ Bash 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, or (at your option)
+ any later version.
+
+ Bash 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 Bash; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_RL_STDC_H_)
+#define _RL_STDC_H_
+
+/* Adapted from BSD /usr/include/sys/cdefs.h. */
+
+/* A function can be defined using prototypes and compile on both ANSI C
+ and traditional C compilers with something like this:
+ extern char *func PARAMS((char *, char *, int)); */
+
+#if !defined (PARAMS)
+# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) || defined _MSC_VER
+# define PARAMS(protos) protos
+# else
+# define PARAMS(protos) ()
+# endif
+#endif
+
+#ifndef __attribute__
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
+# define __attribute__(x)
+# endif
+#endif
+
+#endif /* !_RL_STDC_H_ */
diff --git a/MSVC/readline/rltty.c b/MSVC/readline/rltty.c
index bad8e6e..6996ca9 100644
--- a/MSVC/readline/rltty.c
+++ b/MSVC/readline/rltty.c
@@ -1,1046 +1,1046 @@
-/* rltty.c -- functions to prepare and restore the terminal for readline's
- use. */
-
-/* Copyright (C) 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#if !defined _WIN32 /* for native Win32 environments this is hard stuff */
-
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdio.h>
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#include "rldefs.h"
-
-#if defined (GWINSZ_IN_SYS_IOCTL)
-# include <sys/ioctl.h>
-#endif /* GWINSZ_IN_SYS_IOCTL */
-
-#include "rltty.h"
-#else /* _WIN32 */
- #include "rldefs.h"
- #include <stdio.h>
-#endif /* _WIN32 */
-#include "readline.h"
-#include "rlprivate.h"
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
-rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
-
-static void block_sigint PARAMS((void));
-static void release_sigint PARAMS((void));
-
-static void set_winsize PARAMS((int));
-
-#if !defined _WIN32
-
-/* **************************************************************** */
-/* */
-/* Signal Management */
-/* */
-/* **************************************************************** */
-
-#if defined (HAVE_POSIX_SIGNALS)
-static sigset_t sigint_set, sigint_oset;
-#else /* !HAVE_POSIX_SIGNALS */
-# if defined (HAVE_BSD_SIGNALS)
-static int sigint_oldmask;
-# endif /* HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-static int sigint_blocked;
-
-/* Cause SIGINT to not be delivered until the corresponding call to
- release_sigint(). */
-static void
-block_sigint ()
-{
- if (sigint_blocked)
- return;
-
-#if defined (HAVE_POSIX_SIGNALS)
- sigemptyset (&sigint_set);
- sigemptyset (&sigint_oset);
- sigaddset (&sigint_set, SIGINT);
- sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
-#else /* !HAVE_POSIX_SIGNALS */
-# if defined (HAVE_BSD_SIGNALS)
- sigint_oldmask = sigblock (sigmask (SIGINT));
-# else /* !HAVE_BSD_SIGNALS */
-# if defined (HAVE_USG_SIGHOLD)
- sighold (SIGINT);
-# endif /* HAVE_USG_SIGHOLD */
-# endif /* !HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
- sigint_blocked = 1;
-}
-
-/* Allow SIGINT to be delivered. */
-static void
-release_sigint ()
-{
- if (sigint_blocked == 0)
- return;
-
-#if defined (HAVE_POSIX_SIGNALS)
- sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
-#else
-# if defined (HAVE_BSD_SIGNALS)
- sigsetmask (sigint_oldmask);
-# else /* !HAVE_BSD_SIGNALS */
-# if defined (HAVE_USG_SIGHOLD)
- sigrelse (SIGINT);
-# endif /* HAVE_USG_SIGHOLD */
-# endif /* !HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
- sigint_blocked = 0;
-}
-
-/* **************************************************************** */
-/* */
-/* Saving and Restoring the TTY */
-/* */
-/* **************************************************************** */
-
-/* Non-zero means that the terminal is in a prepped state. */
-static int terminal_prepped;
-
-static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
-
-/* If non-zero, means that this process has called tcflow(fd, TCOOFF)
- and output is suspended. */
-#if defined (__ksr1__)
-static int ksrflow;
-#endif
-
-/* Dummy call to force a backgrounded readline to stop before it tries
- to get the tty settings. */
-static void
-set_winsize (tty)
- int tty;
-{
-#if defined (TIOCGWINSZ)
- struct winsize w;
-
- if (ioctl (tty, TIOCGWINSZ, &w) == 0)
- (void) ioctl (tty, TIOCSWINSZ, &w);
-#endif /* TIOCGWINSZ */
-}
-
-#if defined (NEW_TTY_DRIVER)
-
-/* Values for the `flags' field of a struct bsdtty. This tells which
- elements of the struct bsdtty have been fetched from the system and
- are valid. */
-#define SGTTY_SET 0x01
-#define LFLAG_SET 0x02
-#define TCHARS_SET 0x04
-#define LTCHARS_SET 0x08
-
-struct bsdtty {
- struct sgttyb sgttyb; /* Basic BSD tty driver information. */
- int lflag; /* Local mode flags, like LPASS8. */
-#if defined (TIOCGETC)
- struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
-#endif
-#if defined (TIOCGLTC)
- struct ltchars ltchars; /* 4.2 BSD editing characters */
-#endif
- int flags; /* Bitmap saying which parts of the struct are valid. */
-};
-
-#define TIOTYPE struct bsdtty
-
-static TIOTYPE otio;
-
-static void save_tty_chars PARAMS((TIOTYPE *));
-static int _get_tty_settings PARAMS((int, TIOTYPE *));
-static int get_tty_settings PARAMS((int, TIOTYPE *));
-static int _set_tty_settings PARAMS((int, TIOTYPE *));
-static int set_tty_settings PARAMS((int, TIOTYPE *));
-
-static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
-
-static void
-save_tty_chars (tiop)
- TIOTYPE *tiop;
-{
- _rl_last_tty_chars = _rl_tty_chars;
-
- if (tiop->flags & SGTTY_SET)
- {
- _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase;
- _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill;
- }
-
- if (tiop->flags & TCHARS_SET)
- {
- _rl_tty_chars.t_intr = tiop->tchars.t_intrc;
- _rl_tty_chars.t_quit = tiop->tchars.t_quitc;
- _rl_tty_chars.t_start = tiop->tchars.t_startc;
- _rl_tty_chars.t_stop = tiop->tchars.t_stopc;
- _rl_tty_chars.t_eof = tiop->tchars.t_eofc;
- _rl_tty_chars.t_eol = '\n';
- _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
- }
-
- if (tiop->flags & LTCHARS_SET)
- {
- _rl_tty_chars.t_susp = tiop->ltchars.t_suspc;
- _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc;
- _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc;
- _rl_tty_chars.t_flush = tiop->ltchars.t_flushc;
- _rl_tty_chars.t_werase = tiop->ltchars.t_werasc;
- _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc;
- }
-
- _rl_tty_chars.t_status = -1;
-}
-
-static int
-get_tty_settings (tty, tiop)
- int tty;
- TIOTYPE *tiop;
-{
-#if defined (TIOCGWINSZ)
- set_winsize (tty);
-#endif
-
- tiop->flags = tiop->lflag = 0;
-
- if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
- return -1;
- tiop->flags |= SGTTY_SET;
-
-#if defined (TIOCLGET)
- if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0)
- tiop->flags |= LFLAG_SET;
-#endif
-
-#if defined (TIOCGETC)
- if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0)
- tiop->flags |= TCHARS_SET;
-#endif
-
-#if defined (TIOCGLTC)
- if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0)
- tiop->flags |= LTCHARS_SET;
-#endif
-
- return 0;
-}
-
-static int
-set_tty_settings (tty, tiop)
- int tty;
- TIOTYPE *tiop;
-{
- if (tiop->flags & SGTTY_SET)
- {
- ioctl (tty, TIOCSETN, &(tiop->sgttyb));
- tiop->flags &= ~SGTTY_SET;
- }
- readline_echoing_p = 1;
-
-#if defined (TIOCLSET)
- if (tiop->flags & LFLAG_SET)
- {
- ioctl (tty, TIOCLSET, &(tiop->lflag));
- tiop->flags &= ~LFLAG_SET;
- }
-#endif
-
-#if defined (TIOCSETC)
- if (tiop->flags & TCHARS_SET)
- {
- ioctl (tty, TIOCSETC, &(tiop->tchars));
- tiop->flags &= ~TCHARS_SET;
- }
-#endif
-
-#if defined (TIOCSLTC)
- if (tiop->flags & LTCHARS_SET)
- {
- ioctl (tty, TIOCSLTC, &(tiop->ltchars));
- tiop->flags &= ~LTCHARS_SET;
- }
-#endif
-
- return 0;
-}
-
-static void
-prepare_terminal_settings (meta_flag, oldtio, tiop)
- int meta_flag;
- TIOTYPE oldtio, *tiop;
-{
- readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
-
- /* Copy the original settings to the structure we're going to use for
- our settings. */
- tiop->sgttyb = oldtio.sgttyb;
- tiop->lflag = oldtio.lflag;
-#if defined (TIOCGETC)
- tiop->tchars = oldtio.tchars;
-#endif
-#if defined (TIOCGLTC)
- tiop->ltchars = oldtio.ltchars;
-#endif
- tiop->flags = oldtio.flags;
-
- /* First, the basic settings to put us into character-at-a-time, no-echo
- input mode. */
- tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
- tiop->sgttyb.sg_flags |= CBREAK;
-
- /* If this terminal doesn't care how the 8th bit is used, then we can
- use it for the meta-key. If only one of even or odd parity is
- specified, then the terminal is using parity, and we cannot. */
-#if !defined (ANYP)
-# define ANYP (EVENP | ODDP)
-#endif
- if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) ||
- ((oldtio.sgttyb.sg_flags & ANYP) == 0))
- {
- tiop->sgttyb.sg_flags |= ANYP;
-
- /* Hack on local mode flags if we can. */
-#if defined (TIOCLGET)
-# if defined (LPASS8)
- tiop->lflag |= LPASS8;
-# endif /* LPASS8 */
-#endif /* TIOCLGET */
- }
-
-#if defined (TIOCGETC)
-# if defined (USE_XON_XOFF)
- /* Get rid of terminal output start and stop characters. */
- tiop->tchars.t_stopc = -1; /* C-s */
- tiop->tchars.t_startc = -1; /* C-q */
-
- /* If there is an XON character, bind it to restart the output. */
- if (oldtio.tchars.t_startc != -1)
- rl_bind_key (oldtio.tchars.t_startc, rl_restart_output);
-# endif /* USE_XON_XOFF */
-
- /* If there is an EOF char, bind _rl_eof_char to it. */
- if (oldtio.tchars.t_eofc != -1)
- _rl_eof_char = oldtio.tchars.t_eofc;
-
-# if defined (NO_KILL_INTR)
- /* Get rid of terminal-generated SIGQUIT and SIGINT. */
- tiop->tchars.t_quitc = -1; /* C-\ */
- tiop->tchars.t_intrc = -1; /* C-c */
-# endif /* NO_KILL_INTR */
-#endif /* TIOCGETC */
-
-#if defined (TIOCGLTC)
- /* Make the interrupt keys go away. Just enough to make people happy. */
- tiop->ltchars.t_dsuspc = -1; /* C-y */
- tiop->ltchars.t_lnextc = -1; /* C-v */
-#endif /* TIOCGLTC */
-}
-
-#else /* !defined (NEW_TTY_DRIVER) */
-
-#if !defined (VMIN)
-# define VMIN VEOF
-#endif
-
-#if !defined (VTIME)
-# define VTIME VEOL
-#endif
-
-#if defined (TERMIOS_TTY_DRIVER)
-# define TIOTYPE struct termios
-# define DRAIN_OUTPUT(fd) tcdrain (fd)
-# define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
-# ifdef M_UNIX
-# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
-# else
-# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
-# endif /* !M_UNIX */
-#else
-# define TIOTYPE struct termio
-# define DRAIN_OUTPUT(fd)
-# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
-# define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop))
-#endif /* !TERMIOS_TTY_DRIVER */
-
-static TIOTYPE otio;
-
-static void save_tty_chars PARAMS((TIOTYPE *));
-static int _get_tty_settings PARAMS((int, TIOTYPE *));
-static int get_tty_settings PARAMS((int, TIOTYPE *));
-static int _set_tty_settings PARAMS((int, TIOTYPE *));
-static int set_tty_settings PARAMS((int, TIOTYPE *));
-
-static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
-
-#if defined (FLUSHO)
-# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
-#else
-# define OUTPUT_BEING_FLUSHED(tp) 0
-#endif
-
-static void
-save_tty_chars (tiop)
- TIOTYPE *tiop;
-{
- _rl_last_tty_chars = _rl_tty_chars;
-
- _rl_tty_chars.t_eof = tiop->c_cc[VEOF];
- _rl_tty_chars.t_eol = tiop->c_cc[VEOL];
-#ifdef VEOL2
- _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
-#endif
- _rl_tty_chars.t_erase = tiop->c_cc[VERASE];
-#ifdef VWERASE
- _rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
-#endif
- _rl_tty_chars.t_kill = tiop->c_cc[VKILL];
-#ifdef VREPRINT
- _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
-#endif
- _rl_tty_chars.t_intr = tiop->c_cc[VINTR];
- _rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
-#ifdef VSUSP
- _rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
-#endif
-#ifdef VDSUSP
- _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
-#endif
-#ifdef VSTART
- _rl_tty_chars.t_start = tiop->c_cc[VSTART];
-#endif
-#ifdef VSTOP
- _rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
-#endif
-#ifdef VLNEXT
- _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
-#endif
-#ifdef VDISCARD
- _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
-#endif
-#ifdef VSTATUS
- _rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
-#endif
-}
-
-#if defined (_AIX) || defined (_AIX41)
-/* Currently this is only used on AIX */
-static void
-rltty_warning (msg)
- char *msg;
-{
- fprintf (stderr, "readline: warning: %s\n", msg);
-}
-#endif
-
-#if defined (_AIX)
-void
-setopost(tp)
-TIOTYPE *tp;
-{
- if ((tp->c_oflag & OPOST) == 0)
- {
- rltty_warning ("turning on OPOST for terminal\r");
- tp->c_oflag |= OPOST|ONLCR;
- }
-}
-#endif
-
-static int
-_get_tty_settings (tty, tiop)
- int tty;
- TIOTYPE *tiop;
-{
- int ioctl_ret;
-
- while (1)
- {
- ioctl_ret = GETATTR (tty, tiop);
- if (ioctl_ret < 0)
- {
- if (errno != EINTR)
- return -1;
- else
- continue;
- }
- if (OUTPUT_BEING_FLUSHED (tiop))
- {
-#if defined (FLUSHO) && defined (_AIX41)
- rltty_warning ("turning off output flushing");
- tiop->c_lflag &= ~FLUSHO;
- break;
-#else
- continue;
-#endif
- }
- break;
- }
-
- return 0;
-}
-
-static int
-get_tty_settings (tty, tiop)
- int tty;
- TIOTYPE *tiop;
-{
-#if defined TIOCGWINSZ
- set_winsize (tty);
-#endif
-
- if (_get_tty_settings (tty, tiop) < 0)
- return -1;
-
-#if defined (_AIX)
- setopost(tiop);
-#endif
-
- return 0;
-}
-
-static int
-_set_tty_settings (tty, tiop)
- int tty;
- TIOTYPE *tiop;
-{
- while (SETATTR (tty, tiop) < 0)
- {
- if (errno != EINTR)
- return -1;
- errno = 0;
- }
- return 0;
-}
-
-static int
-set_tty_settings (tty, tiop)
- int tty;
- TIOTYPE *tiop;
-{
- if (_set_tty_settings (tty, tiop) < 0)
- return -1;
-
-#if 0
-
-#if defined (TERMIOS_TTY_DRIVER)
-# if defined (__ksr1__)
- if (ksrflow)
- {
- ksrflow = 0;
- tcflow (tty, TCOON);
- }
-# else /* !ksr1 */
- tcflow (tty, TCOON); /* Simulate a ^Q. */
-# endif /* !ksr1 */
-#else
- ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
-#endif /* !TERMIOS_TTY_DRIVER */
-
-#endif /* 0 */
-
- return 0;
-}
-
-static void
-prepare_terminal_settings (meta_flag, oldtio, tiop)
- int meta_flag;
- TIOTYPE oldtio, *tiop;
-{
- readline_echoing_p = (oldtio.c_lflag & ECHO);
-
- tiop->c_lflag &= ~(ICANON | ECHO);
-
- if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
- _rl_eof_char = oldtio.c_cc[VEOF];
-
-#if defined (USE_XON_XOFF)
-#if defined (IXANY)
- tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
-#else
- /* `strict' Posix systems do not define IXANY. */
- tiop->c_iflag &= ~(IXON | IXOFF);
-#endif /* IXANY */
-#endif /* USE_XON_XOFF */
-
- /* Only turn this off if we are using all 8 bits. */
- if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
- tiop->c_iflag &= ~(ISTRIP | INPCK);
-
- /* Make sure we differentiate between CR and NL on input. */
- tiop->c_iflag &= ~(ICRNL | INLCR);
-
-#if !defined (HANDLE_SIGNALS)
- tiop->c_lflag &= ~ISIG;
-#else
- tiop->c_lflag |= ISIG;
-#endif
-
- tiop->c_cc[VMIN] = 1;
- tiop->c_cc[VTIME] = 0;
-
-#if defined (FLUSHO)
- if (OUTPUT_BEING_FLUSHED (tiop))
- {
- tiop->c_lflag &= ~FLUSHO;
- oldtio.c_lflag &= ~FLUSHO;
- }
-#endif
-
- /* Turn off characters that we need on Posix systems with job control,
- just to be sure. This includes ^Y and ^V. This should not really
- be necessary. */
-#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
-
-#if defined (VLNEXT)
- tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
-#endif
-
-#if defined (VDSUSP)
- tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
-#endif
-
-#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
-}
-#endif /* NEW_TTY_DRIVER */
-
-/* Put the terminal in CBREAK mode so that we can detect key presses. */
-void
-rl_prep_terminal (meta_flag)
- int meta_flag;
-{
- int tty;
- TIOTYPE tio;
-
- if (terminal_prepped)
- return;
-
- /* Try to keep this function from being INTerrupted. */
- block_sigint ();
-
- tty = fileno (rl_instream);
-
- if (get_tty_settings (tty, &tio) < 0)
- {
- release_sigint ();
- return;
- }
-
- otio = tio;
-
- save_tty_chars (&otio);
-
- prepare_terminal_settings (meta_flag, otio, &tio);
-
- if (set_tty_settings (tty, &tio) < 0)
- {
- release_sigint ();
- return;
- }
-
- if (_rl_enable_keypad)
- _rl_control_keypad (1);
-
- fflush (rl_outstream);
- terminal_prepped = 1;
- RL_SETSTATE(RL_STATE_TERMPREPPED);
-
- release_sigint ();
-}
-
-/* Restore the terminal's normal settings and modes. */
-void
-rl_deprep_terminal ()
-{
- int tty;
-
- if (!terminal_prepped)
- return;
-
- /* Try to keep this function from being interrupted. */
- block_sigint ();
-
- tty = fileno (rl_instream);
-
- if (_rl_enable_keypad)
- _rl_control_keypad (0);
-
- fflush (rl_outstream);
-
- if (set_tty_settings (tty, &otio) < 0)
- {
- release_sigint ();
- return;
- }
-
- terminal_prepped = 0;
- RL_UNSETSTATE(RL_STATE_TERMPREPPED);
-
- release_sigint ();
-}
-
-/* **************************************************************** */
-/* */
-/* Bogus Flow Control */
-/* */
-/* **************************************************************** */
-
-int
-rl_restart_output (count, key)
- int count, key;
-{
- int fildes = fileno (rl_outstream);
-#if defined (TIOCSTART)
-#if defined (apollo)
- ioctl (&fildes, TIOCSTART, 0);
-#else
- ioctl (fildes, TIOCSTART, 0);
-#endif /* apollo */
-
-#else /* !TIOCSTART */
-# if defined (TERMIOS_TTY_DRIVER)
-# if defined (__ksr1__)
- if (ksrflow)
- {
- ksrflow = 0;
- tcflow (fildes, TCOON);
- }
-# else /* !ksr1 */
- tcflow (fildes, TCOON); /* Simulate a ^Q. */
-# endif /* !ksr1 */
-# else /* !TERMIOS_TTY_DRIVER */
-# if defined (TCXONC)
- ioctl (fildes, TCXONC, TCOON);
-# endif /* TCXONC */
-# endif /* !TERMIOS_TTY_DRIVER */
-#endif /* !TIOCSTART */
-
- return 0;
-}
-
-int
-rl_stop_output (count, key)
- int count, key;
-{
- int fildes = fileno (rl_instream);
-
-#if defined (TIOCSTOP)
-# if defined (apollo)
- ioctl (&fildes, TIOCSTOP, 0);
-# else
- ioctl (fildes, TIOCSTOP, 0);
-# endif /* apollo */
-#else /* !TIOCSTOP */
-# if defined (TERMIOS_TTY_DRIVER)
-# if defined (__ksr1__)
- ksrflow = 1;
-# endif /* ksr1 */
- tcflow (fildes, TCOOFF);
-# else
-# if defined (TCXONC)
- ioctl (fildes, TCXONC, TCOON);
-# endif /* TCXONC */
-# endif /* !TERMIOS_TTY_DRIVER */
-#endif /* !TIOCSTOP */
-
- return 0;
-}
-
-/* **************************************************************** */
-/* */
-/* Default Key Bindings */
-/* */
-/* **************************************************************** */
-
-/* Set the system's default editing characters to their readline equivalents
- in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
-void
-rltty_set_default_bindings (kmap)
- Keymap kmap;
-{
- TIOTYPE ttybuff;
- int tty = fileno (rl_instream);
-
-#if defined (NEW_TTY_DRIVER)
-
-#define SET_SPECIAL(sc, func) \
- do \
- { \
- int ic; \
- ic = sc; \
- if (ic != -1 && kmap[(unsigned char)ic].type == ISFUNC) \
- kmap[(unsigned char)ic].function = func; \
- } \
- while (0)
-
- if (get_tty_settings (tty, &ttybuff) == 0)
- {
- if (ttybuff.flags & SGTTY_SET)
- {
- SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
- SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
- }
-
-# if defined (TIOCGLTC)
- if (ttybuff.flags & LTCHARS_SET)
- {
- SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
- SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
- }
-# endif /* TIOCGLTC */
- }
-
-#else /* !NEW_TTY_DRIVER */
-
-#define SET_SPECIAL(sc, func) \
- do \
- { \
- unsigned char uc; \
- uc = ttybuff.c_cc[sc]; \
- if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
- kmap[uc].function = func; \
- } \
- while (0)
-
- if (get_tty_settings (tty, &ttybuff) == 0)
- {
- SET_SPECIAL (VERASE, rl_rubout);
- SET_SPECIAL (VKILL, rl_unix_line_discard);
-
-# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
- SET_SPECIAL (VLNEXT, rl_quoted_insert);
-# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
-
-# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
- SET_SPECIAL (VWERASE, rl_unix_word_rubout);
-# endif /* VWERASE && TERMIOS_TTY_DRIVER */
- }
-#endif /* !NEW_TTY_DRIVER */
-}
-
-/* New public way to set the system default editing chars to their readline
- equivalents. */
-void
-rl_tty_set_default_bindings (kmap)
- Keymap kmap;
-{
- rltty_set_default_bindings (kmap);
-}
-
-#if defined (HANDLE_SIGNALS)
-
-#if defined (NEW_TTY_DRIVER)
-int
-_rl_disable_tty_signals ()
-{
- return 0;
-}
-
-int
-_rl_restore_tty_signals ()
-{
- return 0;
-}
-#else
-
-static TIOTYPE sigstty, nosigstty;
-static int tty_sigs_disabled = 0;
-
-int
-_rl_disable_tty_signals ()
-{
- if (tty_sigs_disabled)
- return 0;
-
- if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
- return -1;
-
- nosigstty = sigstty;
-
- nosigstty.c_lflag &= ~ISIG;
- nosigstty.c_iflag &= ~IXON;
-
- if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
- return (_set_tty_settings (fileno (rl_instream), &sigstty));
-
- tty_sigs_disabled = 1;
- return 0;
-}
-
-int
-_rl_restore_tty_signals ()
-{
- int r;
-
- if (tty_sigs_disabled == 0)
- return 0;
-
- r = _set_tty_settings (fileno (rl_instream), &sigstty);
-
- if (r == 0)
- tty_sigs_disabled = 0;
-
- return r;
-}
-#endif /* !NEW_TTY_DRIVER */
-
-#endif /* HANDLE_SIGNALS */
-
-#else /* _WIN32 */
-
-/* **************************************************************** */
-/* */
-/* Default Key Bindings for Win32 Console */
-/* */
-/* **************************************************************** */
-
-#include <windows.h>
-
-#if defined (WITH_MINI_MOUSE)
- #define CONSOLE_MODE ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT
-#else
- #define CONSOLE_MODE ENABLE_PROCESSED_INPUT
-#endif
-
-/* global vars used by other modules */
-
-int haveConsole = 0; /* remember init result of the console */
-HANDLE hStdout, hStdin; /* these are different from stdin, stdout */
-
-#if defined (WITH_MINI_MOUSE)
- COORD rlScreenOrigin; /* readline origin in frame buffer coordinates */
- int rlScreenStart = 0; /* readline origin as frame screen buffer offset */
- COORD rlScreenEnd; /* end of line in frame buffer coordinates */
- int rlScreenMax = 0; /* end of line as linear frame buffer offset */
-#endif /* WITH_MINI_MOUSE */
-
-static DWORD savedConsoleMode = 0; /* to restore console on exit */
-
-void
-rltty_set_default_bindings (kmap)
- Keymap kmap;
-{
-/* I bet this is required on Win32 ;-) */
- {
- char buf[40]; strcpy(buf,"set bell-style none");
- rl_parse_and_bind(buf);
- }
-
- rl_set_key ("\\M-\xf8&", rl_get_previous_history, kmap);
- rl_set_key ("\\M-\xf8(", rl_get_next_history, kmap);
- rl_set_key ("\\M-\xf8'", rl_forward, kmap);
- rl_set_key ("\\M-\xf8%", rl_backward, kmap);
-
- rl_set_key ("\\M-\xf8$", rl_beg_of_line, kmap);
- rl_set_key ("\\M-\xf8#", rl_end_of_line, kmap);
- rl_set_key ("\\M-\xfa%", rl_backward_word, kmap);
- rl_set_key ("\\M-\xfa'", rl_forward_word, kmap);
-
- rl_set_key ("\\M-\xf9-", rl_paste_from_clipboard, kmap);
- rl_set_key ("\\M-\xf8.", rl_delete, kmap);
- rl_set_key ("\x7f", rl_unix_word_rubout, kmap);
-}
-
-/* New public way to set the system default editing chars to their readline
- equivalents. */
-void
-rl_tty_set_default_bindings (kmap)
- Keymap kmap;
-{
- rltty_set_default_bindings (kmap);
-}
-
-/* Query and set up a Window Console */
-
-void
-rl_prep_terminal (meta_flag)
- int meta_flag __attribute__((unused));
-{
- readline_echoing_p = 1;
-
- if ( !(haveConsole & INITIALIZED) )
- {
- if ( !(haveConsole & FOR_INPUT)
- && ((hStdin = GetStdHandle(STD_INPUT_HANDLE)) != INVALID_HANDLE_VALUE) )
- {
- DWORD dummy;
- INPUT_RECORD irec;
- if ( PeekConsoleInput(hStdin, &irec, 1, &dummy) )
- {
- haveConsole |= FOR_INPUT;
- if ( GetConsoleMode(hStdin, &savedConsoleMode) )
- SetConsoleMode(hStdin, CONSOLE_MODE);
- }
- }
- if ( (hStdout = GetStdHandle(STD_OUTPUT_HANDLE)) != INVALID_HANDLE_VALUE)
- {
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- if ( GetConsoleScreenBufferInfo(hStdout, &csbi)
- && (csbi.dwSize.X > 0) && (csbi.dwSize.Y > 0) )
- {
- haveConsole |= FOR_OUTPUT;
-#if defined (WITH_MINI_MOUSE)
- rlScreenOrigin = csbi.dwCursorPosition;
- rlScreenStart = (int)csbi.dwCursorPosition.Y * (int)csbi.dwSize.X
- + (int)csbi.dwCursorPosition.X;
-#endif /* WITH_MINI_MOUSE */
- }
- }
- haveConsole |= INITIALIZED;
- }
-}
-
-/* Restore the consoles's normal settings and modes. */
-void
-rl_deprep_terminal ()
-{
- SetConsoleMode(hStdin, savedConsoleMode);
- haveConsole = 0;
-}
-
-int
-_rl_disable_tty_signals ()
-{
- return 0;
-}
-
-int
-_rl_restore_tty_signals ()
-{
- return 0;
-}
-#endif /* _WIN32 */
+/* rltty.c -- functions to prepare and restore the terminal for readline's
+ use. */
+
+/* Copyright (C) 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#if !defined _WIN32 /* for native Win32 environments this is hard stuff */
+
+#include <sys/types.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include "rldefs.h"
+
+#if defined (GWINSZ_IN_SYS_IOCTL)
+# include <sys/ioctl.h>
+#endif /* GWINSZ_IN_SYS_IOCTL */
+
+#include "rltty.h"
+#else /* _WIN32 */
+ #include "rldefs.h"
+ #include <stdio.h>
+#endif /* _WIN32 */
+#include "readline.h"
+#include "rlprivate.h"
+
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
+rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
+
+static void block_sigint PARAMS((void));
+static void release_sigint PARAMS((void));
+
+static void set_winsize PARAMS((int));
+
+#if !defined _WIN32
+
+/* **************************************************************** */
+/* */
+/* Signal Management */
+/* */
+/* **************************************************************** */
+
+#if defined (HAVE_POSIX_SIGNALS)
+static sigset_t sigint_set, sigint_oset;
+#else /* !HAVE_POSIX_SIGNALS */
+# if defined (HAVE_BSD_SIGNALS)
+static int sigint_oldmask;
+# endif /* HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+static int sigint_blocked;
+
+/* Cause SIGINT to not be delivered until the corresponding call to
+ release_sigint(). */
+static void
+block_sigint ()
+{
+ if (sigint_blocked)
+ return;
+
+#if defined (HAVE_POSIX_SIGNALS)
+ sigemptyset (&sigint_set);
+ sigemptyset (&sigint_oset);
+ sigaddset (&sigint_set, SIGINT);
+ sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
+#else /* !HAVE_POSIX_SIGNALS */
+# if defined (HAVE_BSD_SIGNALS)
+ sigint_oldmask = sigblock (sigmask (SIGINT));
+# else /* !HAVE_BSD_SIGNALS */
+# if defined (HAVE_USG_SIGHOLD)
+ sighold (SIGINT);
+# endif /* HAVE_USG_SIGHOLD */
+# endif /* !HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+ sigint_blocked = 1;
+}
+
+/* Allow SIGINT to be delivered. */
+static void
+release_sigint ()
+{
+ if (sigint_blocked == 0)
+ return;
+
+#if defined (HAVE_POSIX_SIGNALS)
+ sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
+#else
+# if defined (HAVE_BSD_SIGNALS)
+ sigsetmask (sigint_oldmask);
+# else /* !HAVE_BSD_SIGNALS */
+# if defined (HAVE_USG_SIGHOLD)
+ sigrelse (SIGINT);
+# endif /* HAVE_USG_SIGHOLD */
+# endif /* !HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+ sigint_blocked = 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Saving and Restoring the TTY */
+/* */
+/* **************************************************************** */
+
+/* Non-zero means that the terminal is in a prepped state. */
+static int terminal_prepped;
+
+static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
+
+/* If non-zero, means that this process has called tcflow(fd, TCOOFF)
+ and output is suspended. */
+#if defined (__ksr1__)
+static int ksrflow;
+#endif
+
+/* Dummy call to force a backgrounded readline to stop before it tries
+ to get the tty settings. */
+static void
+set_winsize (tty)
+ int tty;
+{
+#if defined (TIOCGWINSZ)
+ struct winsize w;
+
+ if (ioctl (tty, TIOCGWINSZ, &w) == 0)
+ (void) ioctl (tty, TIOCSWINSZ, &w);
+#endif /* TIOCGWINSZ */
+}
+
+#if defined (NEW_TTY_DRIVER)
+
+/* Values for the `flags' field of a struct bsdtty. This tells which
+ elements of the struct bsdtty have been fetched from the system and
+ are valid. */
+#define SGTTY_SET 0x01
+#define LFLAG_SET 0x02
+#define TCHARS_SET 0x04
+#define LTCHARS_SET 0x08
+
+struct bsdtty {
+ struct sgttyb sgttyb; /* Basic BSD tty driver information. */
+ int lflag; /* Local mode flags, like LPASS8. */
+#if defined (TIOCGETC)
+ struct tchars tchars; /* Terminal special characters, including ^S and ^Q. */
+#endif
+#if defined (TIOCGLTC)
+ struct ltchars ltchars; /* 4.2 BSD editing characters */
+#endif
+ int flags; /* Bitmap saying which parts of the struct are valid. */
+};
+
+#define TIOTYPE struct bsdtty
+
+static TIOTYPE otio;
+
+static void save_tty_chars PARAMS((TIOTYPE *));
+static int _get_tty_settings PARAMS((int, TIOTYPE *));
+static int get_tty_settings PARAMS((int, TIOTYPE *));
+static int _set_tty_settings PARAMS((int, TIOTYPE *));
+static int set_tty_settings PARAMS((int, TIOTYPE *));
+
+static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
+
+static void
+save_tty_chars (tiop)
+ TIOTYPE *tiop;
+{
+ _rl_last_tty_chars = _rl_tty_chars;
+
+ if (tiop->flags & SGTTY_SET)
+ {
+ _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase;
+ _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill;
+ }
+
+ if (tiop->flags & TCHARS_SET)
+ {
+ _rl_tty_chars.t_intr = tiop->tchars.t_intrc;
+ _rl_tty_chars.t_quit = tiop->tchars.t_quitc;
+ _rl_tty_chars.t_start = tiop->tchars.t_startc;
+ _rl_tty_chars.t_stop = tiop->tchars.t_stopc;
+ _rl_tty_chars.t_eof = tiop->tchars.t_eofc;
+ _rl_tty_chars.t_eol = '\n';
+ _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
+ }
+
+ if (tiop->flags & LTCHARS_SET)
+ {
+ _rl_tty_chars.t_susp = tiop->ltchars.t_suspc;
+ _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc;
+ _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc;
+ _rl_tty_chars.t_flush = tiop->ltchars.t_flushc;
+ _rl_tty_chars.t_werase = tiop->ltchars.t_werasc;
+ _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc;
+ }
+
+ _rl_tty_chars.t_status = -1;
+}
+
+static int
+get_tty_settings (tty, tiop)
+ int tty;
+ TIOTYPE *tiop;
+{
+#if defined (TIOCGWINSZ)
+ set_winsize (tty);
+#endif
+
+ tiop->flags = tiop->lflag = 0;
+
+ if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
+ return -1;
+ tiop->flags |= SGTTY_SET;
+
+#if defined (TIOCLGET)
+ if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0)
+ tiop->flags |= LFLAG_SET;
+#endif
+
+#if defined (TIOCGETC)
+ if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0)
+ tiop->flags |= TCHARS_SET;
+#endif
+
+#if defined (TIOCGLTC)
+ if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0)
+ tiop->flags |= LTCHARS_SET;
+#endif
+
+ return 0;
+}
+
+static int
+set_tty_settings (tty, tiop)
+ int tty;
+ TIOTYPE *tiop;
+{
+ if (tiop->flags & SGTTY_SET)
+ {
+ ioctl (tty, TIOCSETN, &(tiop->sgttyb));
+ tiop->flags &= ~SGTTY_SET;
+ }
+ readline_echoing_p = 1;
+
+#if defined (TIOCLSET)
+ if (tiop->flags & LFLAG_SET)
+ {
+ ioctl (tty, TIOCLSET, &(tiop->lflag));
+ tiop->flags &= ~LFLAG_SET;
+ }
+#endif
+
+#if defined (TIOCSETC)
+ if (tiop->flags & TCHARS_SET)
+ {
+ ioctl (tty, TIOCSETC, &(tiop->tchars));
+ tiop->flags &= ~TCHARS_SET;
+ }
+#endif
+
+#if defined (TIOCSLTC)
+ if (tiop->flags & LTCHARS_SET)
+ {
+ ioctl (tty, TIOCSLTC, &(tiop->ltchars));
+ tiop->flags &= ~LTCHARS_SET;
+ }
+#endif
+
+ return 0;
+}
+
+static void
+prepare_terminal_settings (meta_flag, oldtio, tiop)
+ int meta_flag;
+ TIOTYPE oldtio, *tiop;
+{
+ readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
+
+ /* Copy the original settings to the structure we're going to use for
+ our settings. */
+ tiop->sgttyb = oldtio.sgttyb;
+ tiop->lflag = oldtio.lflag;
+#if defined (TIOCGETC)
+ tiop->tchars = oldtio.tchars;
+#endif
+#if defined (TIOCGLTC)
+ tiop->ltchars = oldtio.ltchars;
+#endif
+ tiop->flags = oldtio.flags;
+
+ /* First, the basic settings to put us into character-at-a-time, no-echo
+ input mode. */
+ tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
+ tiop->sgttyb.sg_flags |= CBREAK;
+
+ /* If this terminal doesn't care how the 8th bit is used, then we can
+ use it for the meta-key. If only one of even or odd parity is
+ specified, then the terminal is using parity, and we cannot. */
+#if !defined (ANYP)
+# define ANYP (EVENP | ODDP)
+#endif
+ if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) ||
+ ((oldtio.sgttyb.sg_flags & ANYP) == 0))
+ {
+ tiop->sgttyb.sg_flags |= ANYP;
+
+ /* Hack on local mode flags if we can. */
+#if defined (TIOCLGET)
+# if defined (LPASS8)
+ tiop->lflag |= LPASS8;
+# endif /* LPASS8 */
+#endif /* TIOCLGET */
+ }
+
+#if defined (TIOCGETC)
+# if defined (USE_XON_XOFF)
+ /* Get rid of terminal output start and stop characters. */
+ tiop->tchars.t_stopc = -1; /* C-s */
+ tiop->tchars.t_startc = -1; /* C-q */
+
+ /* If there is an XON character, bind it to restart the output. */
+ if (oldtio.tchars.t_startc != -1)
+ rl_bind_key (oldtio.tchars.t_startc, rl_restart_output);
+# endif /* USE_XON_XOFF */
+
+ /* If there is an EOF char, bind _rl_eof_char to it. */
+ if (oldtio.tchars.t_eofc != -1)
+ _rl_eof_char = oldtio.tchars.t_eofc;
+
+# if defined (NO_KILL_INTR)
+ /* Get rid of terminal-generated SIGQUIT and SIGINT. */
+ tiop->tchars.t_quitc = -1; /* C-\ */
+ tiop->tchars.t_intrc = -1; /* C-c */
+# endif /* NO_KILL_INTR */
+#endif /* TIOCGETC */
+
+#if defined (TIOCGLTC)
+ /* Make the interrupt keys go away. Just enough to make people happy. */
+ tiop->ltchars.t_dsuspc = -1; /* C-y */
+ tiop->ltchars.t_lnextc = -1; /* C-v */
+#endif /* TIOCGLTC */
+}
+
+#else /* !defined (NEW_TTY_DRIVER) */
+
+#if !defined (VMIN)
+# define VMIN VEOF
+#endif
+
+#if !defined (VTIME)
+# define VTIME VEOL
+#endif
+
+#if defined (TERMIOS_TTY_DRIVER)
+# define TIOTYPE struct termios
+# define DRAIN_OUTPUT(fd) tcdrain (fd)
+# define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
+# ifdef M_UNIX
+# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
+# else
+# define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
+# endif /* !M_UNIX */
+#else
+# define TIOTYPE struct termio
+# define DRAIN_OUTPUT(fd)
+# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
+# define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop))
+#endif /* !TERMIOS_TTY_DRIVER */
+
+static TIOTYPE otio;
+
+static void save_tty_chars PARAMS((TIOTYPE *));
+static int _get_tty_settings PARAMS((int, TIOTYPE *));
+static int get_tty_settings PARAMS((int, TIOTYPE *));
+static int _set_tty_settings PARAMS((int, TIOTYPE *));
+static int set_tty_settings PARAMS((int, TIOTYPE *));
+
+static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
+
+#if defined (FLUSHO)
+# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
+#else
+# define OUTPUT_BEING_FLUSHED(tp) 0
+#endif
+
+static void
+save_tty_chars (tiop)
+ TIOTYPE *tiop;
+{
+ _rl_last_tty_chars = _rl_tty_chars;
+
+ _rl_tty_chars.t_eof = tiop->c_cc[VEOF];
+ _rl_tty_chars.t_eol = tiop->c_cc[VEOL];
+#ifdef VEOL2
+ _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
+#endif
+ _rl_tty_chars.t_erase = tiop->c_cc[VERASE];
+#ifdef VWERASE
+ _rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
+#endif
+ _rl_tty_chars.t_kill = tiop->c_cc[VKILL];
+#ifdef VREPRINT
+ _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
+#endif
+ _rl_tty_chars.t_intr = tiop->c_cc[VINTR];
+ _rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
+#ifdef VSUSP
+ _rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
+#endif
+#ifdef VDSUSP
+ _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
+#endif
+#ifdef VSTART
+ _rl_tty_chars.t_start = tiop->c_cc[VSTART];
+#endif
+#ifdef VSTOP
+ _rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
+#endif
+#ifdef VLNEXT
+ _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
+#endif
+#ifdef VDISCARD
+ _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
+#endif
+#ifdef VSTATUS
+ _rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
+#endif
+}
+
+#if defined (_AIX) || defined (_AIX41)
+/* Currently this is only used on AIX */
+static void
+rltty_warning (msg)
+ char *msg;
+{
+ fprintf (stderr, "readline: warning: %s\n", msg);
+}
+#endif
+
+#if defined (_AIX)
+void
+setopost(tp)
+TIOTYPE *tp;
+{
+ if ((tp->c_oflag & OPOST) == 0)
+ {
+ rltty_warning ("turning on OPOST for terminal\r");
+ tp->c_oflag |= OPOST|ONLCR;
+ }
+}
+#endif
+
+static int
+_get_tty_settings (tty, tiop)
+ int tty;
+ TIOTYPE *tiop;
+{
+ int ioctl_ret;
+
+ while (1)
+ {
+ ioctl_ret = GETATTR (tty, tiop);
+ if (ioctl_ret < 0)
+ {
+ if (errno != EINTR)
+ return -1;
+ else
+ continue;
+ }
+ if (OUTPUT_BEING_FLUSHED (tiop))
+ {
+#if defined (FLUSHO) && defined (_AIX41)
+ rltty_warning ("turning off output flushing");
+ tiop->c_lflag &= ~FLUSHO;
+ break;
+#else
+ continue;
+#endif
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static int
+get_tty_settings (tty, tiop)
+ int tty;
+ TIOTYPE *tiop;
+{
+#if defined TIOCGWINSZ
+ set_winsize (tty);
+#endif
+
+ if (_get_tty_settings (tty, tiop) < 0)
+ return -1;
+
+#if defined (_AIX)
+ setopost(tiop);
+#endif
+
+ return 0;
+}
+
+static int
+_set_tty_settings (tty, tiop)
+ int tty;
+ TIOTYPE *tiop;
+{
+ while (SETATTR (tty, tiop) < 0)
+ {
+ if (errno != EINTR)
+ return -1;
+ errno = 0;
+ }
+ return 0;
+}
+
+static int
+set_tty_settings (tty, tiop)
+ int tty;
+ TIOTYPE *tiop;
+{
+ if (_set_tty_settings (tty, tiop) < 0)
+ return -1;
+
+#if 0
+
+#if defined (TERMIOS_TTY_DRIVER)
+# if defined (__ksr1__)
+ if (ksrflow)
+ {
+ ksrflow = 0;
+ tcflow (tty, TCOON);
+ }
+# else /* !ksr1 */
+ tcflow (tty, TCOON); /* Simulate a ^Q. */
+# endif /* !ksr1 */
+#else
+ ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
+#endif /* !TERMIOS_TTY_DRIVER */
+
+#endif /* 0 */
+
+ return 0;
+}
+
+static void
+prepare_terminal_settings (meta_flag, oldtio, tiop)
+ int meta_flag;
+ TIOTYPE oldtio, *tiop;
+{
+ readline_echoing_p = (oldtio.c_lflag & ECHO);
+
+ tiop->c_lflag &= ~(ICANON | ECHO);
+
+ if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
+ _rl_eof_char = oldtio.c_cc[VEOF];
+
+#if defined (USE_XON_XOFF)
+#if defined (IXANY)
+ tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
+#else
+ /* `strict' Posix systems do not define IXANY. */
+ tiop->c_iflag &= ~(IXON | IXOFF);
+#endif /* IXANY */
+#endif /* USE_XON_XOFF */
+
+ /* Only turn this off if we are using all 8 bits. */
+ if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
+ tiop->c_iflag &= ~(ISTRIP | INPCK);
+
+ /* Make sure we differentiate between CR and NL on input. */
+ tiop->c_iflag &= ~(ICRNL | INLCR);
+
+#if !defined (HANDLE_SIGNALS)
+ tiop->c_lflag &= ~ISIG;
+#else
+ tiop->c_lflag |= ISIG;
+#endif
+
+ tiop->c_cc[VMIN] = 1;
+ tiop->c_cc[VTIME] = 0;
+
+#if defined (FLUSHO)
+ if (OUTPUT_BEING_FLUSHED (tiop))
+ {
+ tiop->c_lflag &= ~FLUSHO;
+ oldtio.c_lflag &= ~FLUSHO;
+ }
+#endif
+
+ /* Turn off characters that we need on Posix systems with job control,
+ just to be sure. This includes ^Y and ^V. This should not really
+ be necessary. */
+#if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
+
+#if defined (VLNEXT)
+ tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
+#endif
+
+#if defined (VDSUSP)
+ tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
+#endif
+
+#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
+}
+#endif /* NEW_TTY_DRIVER */
+
+/* Put the terminal in CBREAK mode so that we can detect key presses. */
+void
+rl_prep_terminal (meta_flag)
+ int meta_flag;
+{
+ int tty;
+ TIOTYPE tio;
+
+ if (terminal_prepped)
+ return;
+
+ /* Try to keep this function from being INTerrupted. */
+ block_sigint ();
+
+ tty = fileno (rl_instream);
+
+ if (get_tty_settings (tty, &tio) < 0)
+ {
+ release_sigint ();
+ return;
+ }
+
+ otio = tio;
+
+ save_tty_chars (&otio);
+
+ prepare_terminal_settings (meta_flag, otio, &tio);
+
+ if (set_tty_settings (tty, &tio) < 0)
+ {
+ release_sigint ();
+ return;
+ }
+
+ if (_rl_enable_keypad)
+ _rl_control_keypad (1);
+
+ fflush (rl_outstream);
+ terminal_prepped = 1;
+ RL_SETSTATE(RL_STATE_TERMPREPPED);
+
+ release_sigint ();
+}
+
+/* Restore the terminal's normal settings and modes. */
+void
+rl_deprep_terminal ()
+{
+ int tty;
+
+ if (!terminal_prepped)
+ return;
+
+ /* Try to keep this function from being interrupted. */
+ block_sigint ();
+
+ tty = fileno (rl_instream);
+
+ if (_rl_enable_keypad)
+ _rl_control_keypad (0);
+
+ fflush (rl_outstream);
+
+ if (set_tty_settings (tty, &otio) < 0)
+ {
+ release_sigint ();
+ return;
+ }
+
+ terminal_prepped = 0;
+ RL_UNSETSTATE(RL_STATE_TERMPREPPED);
+
+ release_sigint ();
+}
+
+/* **************************************************************** */
+/* */
+/* Bogus Flow Control */
+/* */
+/* **************************************************************** */
+
+int
+rl_restart_output (count, key)
+ int count, key;
+{
+ int fildes = fileno (rl_outstream);
+#if defined (TIOCSTART)
+#if defined (apollo)
+ ioctl (&fildes, TIOCSTART, 0);
+#else
+ ioctl (fildes, TIOCSTART, 0);
+#endif /* apollo */
+
+#else /* !TIOCSTART */
+# if defined (TERMIOS_TTY_DRIVER)
+# if defined (__ksr1__)
+ if (ksrflow)
+ {
+ ksrflow = 0;
+ tcflow (fildes, TCOON);
+ }
+# else /* !ksr1 */
+ tcflow (fildes, TCOON); /* Simulate a ^Q. */
+# endif /* !ksr1 */
+# else /* !TERMIOS_TTY_DRIVER */
+# if defined (TCXONC)
+ ioctl (fildes, TCXONC, TCOON);
+# endif /* TCXONC */
+# endif /* !TERMIOS_TTY_DRIVER */
+#endif /* !TIOCSTART */
+
+ return 0;
+}
+
+int
+rl_stop_output (count, key)
+ int count, key;
+{
+ int fildes = fileno (rl_instream);
+
+#if defined (TIOCSTOP)
+# if defined (apollo)
+ ioctl (&fildes, TIOCSTOP, 0);
+# else
+ ioctl (fildes, TIOCSTOP, 0);
+# endif /* apollo */
+#else /* !TIOCSTOP */
+# if defined (TERMIOS_TTY_DRIVER)
+# if defined (__ksr1__)
+ ksrflow = 1;
+# endif /* ksr1 */
+ tcflow (fildes, TCOOFF);
+# else
+# if defined (TCXONC)
+ ioctl (fildes, TCXONC, TCOON);
+# endif /* TCXONC */
+# endif /* !TERMIOS_TTY_DRIVER */
+#endif /* !TIOCSTOP */
+
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Default Key Bindings */
+/* */
+/* **************************************************************** */
+
+/* Set the system's default editing characters to their readline equivalents
+ in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
+void
+rltty_set_default_bindings (kmap)
+ Keymap kmap;
+{
+ TIOTYPE ttybuff;
+ int tty = fileno (rl_instream);
+
+#if defined (NEW_TTY_DRIVER)
+
+#define SET_SPECIAL(sc, func) \
+ do \
+ { \
+ int ic; \
+ ic = sc; \
+ if (ic != -1 && kmap[(unsigned char)ic].type == ISFUNC) \
+ kmap[(unsigned char)ic].function = func; \
+ } \
+ while (0)
+
+ if (get_tty_settings (tty, &ttybuff) == 0)
+ {
+ if (ttybuff.flags & SGTTY_SET)
+ {
+ SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
+ SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
+ }
+
+# if defined (TIOCGLTC)
+ if (ttybuff.flags & LTCHARS_SET)
+ {
+ SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
+ SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
+ }
+# endif /* TIOCGLTC */
+ }
+
+#else /* !NEW_TTY_DRIVER */
+
+#define SET_SPECIAL(sc, func) \
+ do \
+ { \
+ unsigned char uc; \
+ uc = ttybuff.c_cc[sc]; \
+ if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
+ kmap[uc].function = func; \
+ } \
+ while (0)
+
+ if (get_tty_settings (tty, &ttybuff) == 0)
+ {
+ SET_SPECIAL (VERASE, rl_rubout);
+ SET_SPECIAL (VKILL, rl_unix_line_discard);
+
+# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
+ SET_SPECIAL (VLNEXT, rl_quoted_insert);
+# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
+
+# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
+ SET_SPECIAL (VWERASE, rl_unix_word_rubout);
+# endif /* VWERASE && TERMIOS_TTY_DRIVER */
+ }
+#endif /* !NEW_TTY_DRIVER */
+}
+
+/* New public way to set the system default editing chars to their readline
+ equivalents. */
+void
+rl_tty_set_default_bindings (kmap)
+ Keymap kmap;
+{
+ rltty_set_default_bindings (kmap);
+}
+
+#if defined (HANDLE_SIGNALS)
+
+#if defined (NEW_TTY_DRIVER)
+int
+_rl_disable_tty_signals ()
+{
+ return 0;
+}
+
+int
+_rl_restore_tty_signals ()
+{
+ return 0;
+}
+#else
+
+static TIOTYPE sigstty, nosigstty;
+static int tty_sigs_disabled = 0;
+
+int
+_rl_disable_tty_signals ()
+{
+ if (tty_sigs_disabled)
+ return 0;
+
+ if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
+ return -1;
+
+ nosigstty = sigstty;
+
+ nosigstty.c_lflag &= ~ISIG;
+ nosigstty.c_iflag &= ~IXON;
+
+ if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
+ return (_set_tty_settings (fileno (rl_instream), &sigstty));
+
+ tty_sigs_disabled = 1;
+ return 0;
+}
+
+int
+_rl_restore_tty_signals ()
+{
+ int r;
+
+ if (tty_sigs_disabled == 0)
+ return 0;
+
+ r = _set_tty_settings (fileno (rl_instream), &sigstty);
+
+ if (r == 0)
+ tty_sigs_disabled = 0;
+
+ return r;
+}
+#endif /* !NEW_TTY_DRIVER */
+
+#endif /* HANDLE_SIGNALS */
+
+#else /* _WIN32 */
+
+/* **************************************************************** */
+/* */
+/* Default Key Bindings for Win32 Console */
+/* */
+/* **************************************************************** */
+
+#include <windows.h>
+
+#if defined (WITH_MINI_MOUSE)
+ #define CONSOLE_MODE ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT
+#else
+ #define CONSOLE_MODE ENABLE_PROCESSED_INPUT
+#endif
+
+/* global vars used by other modules */
+
+int haveConsole = 0; /* remember init result of the console */
+HANDLE hStdout, hStdin; /* these are different from stdin, stdout */
+
+#if defined (WITH_MINI_MOUSE)
+ COORD rlScreenOrigin; /* readline origin in frame buffer coordinates */
+ int rlScreenStart = 0; /* readline origin as frame screen buffer offset */
+ COORD rlScreenEnd; /* end of line in frame buffer coordinates */
+ int rlScreenMax = 0; /* end of line as linear frame buffer offset */
+#endif /* WITH_MINI_MOUSE */
+
+static DWORD savedConsoleMode = 0; /* to restore console on exit */
+
+void
+rltty_set_default_bindings (kmap)
+ Keymap kmap;
+{
+/* I bet this is required on Win32 ;-) */
+ {
+ char buf[40]; strcpy(buf,"set bell-style none");
+ rl_parse_and_bind(buf);
+ }
+
+ rl_set_key ("\\M-\xf8&", rl_get_previous_history, kmap);
+ rl_set_key ("\\M-\xf8(", rl_get_next_history, kmap);
+ rl_set_key ("\\M-\xf8'", rl_forward, kmap);
+ rl_set_key ("\\M-\xf8%", rl_backward, kmap);
+
+ rl_set_key ("\\M-\xf8$", rl_beg_of_line, kmap);
+ rl_set_key ("\\M-\xf8#", rl_end_of_line, kmap);
+ rl_set_key ("\\M-\xfa%", rl_backward_word, kmap);
+ rl_set_key ("\\M-\xfa'", rl_forward_word, kmap);
+
+ rl_set_key ("\\M-\xf9-", rl_paste_from_clipboard, kmap);
+ rl_set_key ("\\M-\xf8.", rl_delete, kmap);
+ rl_set_key ("\x7f", rl_unix_word_rubout, kmap);
+}
+
+/* New public way to set the system default editing chars to their readline
+ equivalents. */
+void
+rl_tty_set_default_bindings (kmap)
+ Keymap kmap;
+{
+ rltty_set_default_bindings (kmap);
+}
+
+/* Query and set up a Window Console */
+
+void
+rl_prep_terminal (meta_flag)
+ int meta_flag __attribute__((unused));
+{
+ readline_echoing_p = 1;
+
+ if ( !(haveConsole & INITIALIZED) )
+ {
+ if ( !(haveConsole & FOR_INPUT)
+ && ((hStdin = GetStdHandle(STD_INPUT_HANDLE)) != INVALID_HANDLE_VALUE) )
+ {
+ DWORD dummy;
+ INPUT_RECORD irec;
+ if ( PeekConsoleInput(hStdin, &irec, 1, &dummy) )
+ {
+ haveConsole |= FOR_INPUT;
+ if ( GetConsoleMode(hStdin, &savedConsoleMode) )
+ SetConsoleMode(hStdin, CONSOLE_MODE);
+ }
+ }
+ if ( (hStdout = GetStdHandle(STD_OUTPUT_HANDLE)) != INVALID_HANDLE_VALUE)
+ {
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if ( GetConsoleScreenBufferInfo(hStdout, &csbi)
+ && (csbi.dwSize.X > 0) && (csbi.dwSize.Y > 0) )
+ {
+ haveConsole |= FOR_OUTPUT;
+#if defined (WITH_MINI_MOUSE)
+ rlScreenOrigin = csbi.dwCursorPosition;
+ rlScreenStart = (int)csbi.dwCursorPosition.Y * (int)csbi.dwSize.X
+ + (int)csbi.dwCursorPosition.X;
+#endif /* WITH_MINI_MOUSE */
+ }
+ }
+ haveConsole |= INITIALIZED;
+ }
+}
+
+/* Restore the consoles's normal settings and modes. */
+void
+rl_deprep_terminal ()
+{
+ SetConsoleMode(hStdin, savedConsoleMode);
+ haveConsole = 0;
+}
+
+int
+_rl_disable_tty_signals ()
+{
+ return 0;
+}
+
+int
+_rl_restore_tty_signals ()
+{
+ return 0;
+}
+#endif /* _WIN32 */
diff --git a/MSVC/readline/rltty.h b/MSVC/readline/rltty.h
index 8a06ec3..da375e5 100644
--- a/MSVC/readline/rltty.h
+++ b/MSVC/readline/rltty.h
@@ -1,82 +1,82 @@
-/* rltty.h - tty driver-related definitions used by some library files. */
-
-/* Copyright (C) 1995 Free Software Foundation, Inc.
-
- This file contains the Readline Library (the Library), a set of
- routines for providing Emacs style line input to programs that ask
- for it.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_RLTTY_H_)
-#define _RLTTY_H_
-
-/* Posix systems use termios and the Posix signal functions. */
-#if defined (TERMIOS_TTY_DRIVER)
-# include <termios.h>
-#endif /* TERMIOS_TTY_DRIVER */
-
-/* System V machines use termio. */
-#if defined (TERMIO_TTY_DRIVER)
-# include <termio.h>
-# if !defined (TCOON)
-# define TCOON 1
-# endif
-#endif /* TERMIO_TTY_DRIVER */
-
-/* Other (BSD) machines use sgtty. */
-#if defined (NEW_TTY_DRIVER) && !defined _WIN32
-# include <sgtty.h>
-#endif
-
-#include "rlwinsize.h"
-
-/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and
- it is not already defined. It is used both to determine if a
- special character is disabled and to disable certain special
- characters. Posix systems should set to 0, USG systems to -1. */
-#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE)
-# if defined (_SVR4_VDISABLE)
-# define _POSIX_VDISABLE _SVR4_VDISABLE
-# else
-# if defined (_POSIX_VERSION)
-# define _POSIX_VDISABLE 0
-# else /* !_POSIX_VERSION */
-# define _POSIX_VDISABLE -1
-# endif /* !_POSIX_VERSION */
-# endif /* !_SVR4_DISABLE */
-#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
-
-typedef struct _rl_tty_chars {
- char t_eof;
- char t_eol;
- char t_eol2;
- char t_erase;
- char t_werase;
- char t_kill;
- char t_reprint;
- char t_intr;
- char t_quit;
- char t_susp;
- char t_dsusp;
- char t_start;
- char t_stop;
- char t_lnext;
- char t_flush;
- char t_status;
-} _RL_TTY_CHARS;
-
-#endif /* _RLTTY_H_ */
+/* rltty.h - tty driver-related definitions used by some library files. */
+
+/* Copyright (C) 1995 Free Software Foundation, Inc.
+
+ This file contains the Readline Library (the Library), a set of
+ routines for providing Emacs style line input to programs that ask
+ for it.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_RLTTY_H_)
+#define _RLTTY_H_
+
+/* Posix systems use termios and the Posix signal functions. */
+#if defined (TERMIOS_TTY_DRIVER)
+# include <termios.h>
+#endif /* TERMIOS_TTY_DRIVER */
+
+/* System V machines use termio. */
+#if defined (TERMIO_TTY_DRIVER)
+# include <termio.h>
+# if !defined (TCOON)
+# define TCOON 1
+# endif
+#endif /* TERMIO_TTY_DRIVER */
+
+/* Other (BSD) machines use sgtty. */
+#if defined (NEW_TTY_DRIVER) && !defined _WIN32
+# include <sgtty.h>
+#endif
+
+#include "rlwinsize.h"
+
+/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and
+ it is not already defined. It is used both to determine if a
+ special character is disabled and to disable certain special
+ characters. Posix systems should set to 0, USG systems to -1. */
+#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE)
+# if defined (_SVR4_VDISABLE)
+# define _POSIX_VDISABLE _SVR4_VDISABLE
+# else
+# if defined (_POSIX_VERSION)
+# define _POSIX_VDISABLE 0
+# else /* !_POSIX_VERSION */
+# define _POSIX_VDISABLE -1
+# endif /* !_POSIX_VERSION */
+# endif /* !_SVR4_DISABLE */
+#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
+
+typedef struct _rl_tty_chars {
+ char t_eof;
+ char t_eol;
+ char t_eol2;
+ char t_erase;
+ char t_werase;
+ char t_kill;
+ char t_reprint;
+ char t_intr;
+ char t_quit;
+ char t_susp;
+ char t_dsusp;
+ char t_start;
+ char t_stop;
+ char t_lnext;
+ char t_flush;
+ char t_status;
+} _RL_TTY_CHARS;
+
+#endif /* _RLTTY_H_ */
diff --git a/MSVC/readline/rltypedefs.h b/MSVC/readline/rltypedefs.h
index 66c34e7..f3280e9 100644
--- a/MSVC/readline/rltypedefs.h
+++ b/MSVC/readline/rltypedefs.h
@@ -1,88 +1,88 @@
-/* rltypedefs.h -- Type declarations for readline functions. */
-
-/* Copyright (C) 2000 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#ifndef _RL_TYPEDEFS_H_
-#define _RL_TYPEDEFS_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Old-style */
-
-#if !defined (_FUNCTION_DEF)
-# define _FUNCTION_DEF
-
-typedef int Function ();
-typedef void VFunction ();
-typedef char *CPFunction ();
-typedef char **CPPFunction ();
-
-#endif /* _FUNCTION_DEF */
-
-/* New style. */
-
-#if !defined (_RL_FUNCTION_TYPEDEF)
-# define _RL_FUNCTION_TYPEDEF
-
-/* Bindable functions */
-typedef int rl_command_func_t PARAMS((int, int));
-
-/* Typedefs for the completion system */
-typedef char *rl_compentry_func_t PARAMS((const char *, int));
-typedef char **rl_completion_func_t PARAMS((const char *, int, int));
-
-typedef char *rl_quote_func_t PARAMS((char *, int, char *));
-typedef char *rl_dequote_func_t PARAMS((char *, int));
-
-typedef int rl_compignore_func_t PARAMS((char **));
-
-typedef void rl_compdisp_func_t PARAMS((char **, int, int));
-
-/* Type for input and pre-read hook functions like rl_event_hook */
-typedef int rl_hook_func_t PARAMS((void));
-
-/* Input function type */
-typedef int rl_getc_func_t PARAMS((FILE *));
-
-/* Generic function that takes a character buffer (which could be the readline
- line buffer) and an index into it (which could be rl_point) and returns
- an int. */
-typedef int rl_linebuf_func_t PARAMS((char *, int));
-
-/* `Generic' function pointer typedefs */
-typedef int rl_intfunc_t PARAMS((int));
-#define rl_ivoidfunc_t rl_hook_func_t
-typedef int rl_icpfunc_t PARAMS((char *));
-typedef int rl_icppfunc_t PARAMS((char **));
-
-typedef void rl_voidfunc_t PARAMS((void));
-typedef void rl_vintfunc_t PARAMS((int));
-typedef void rl_vcpfunc_t PARAMS((char *));
-typedef void rl_vcppfunc_t PARAMS((char **));
-#endif /* _RL_FUNCTION_TYPEDEF */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RL_TYPEDEFS_H_ */
+/* rltypedefs.h -- Type declarations for readline functions. */
+
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#ifndef _RL_TYPEDEFS_H_
+#define _RL_TYPEDEFS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Old-style */
+
+#if !defined (_FUNCTION_DEF)
+# define _FUNCTION_DEF
+
+typedef int Function ();
+typedef void VFunction ();
+typedef char *CPFunction ();
+typedef char **CPPFunction ();
+
+#endif /* _FUNCTION_DEF */
+
+/* New style. */
+
+#if !defined (_RL_FUNCTION_TYPEDEF)
+# define _RL_FUNCTION_TYPEDEF
+
+/* Bindable functions */
+typedef int rl_command_func_t PARAMS((int, int));
+
+/* Typedefs for the completion system */
+typedef char *rl_compentry_func_t PARAMS((const char *, int));
+typedef char **rl_completion_func_t PARAMS((const char *, int, int));
+
+typedef char *rl_quote_func_t PARAMS((char *, int, char *));
+typedef char *rl_dequote_func_t PARAMS((char *, int));
+
+typedef int rl_compignore_func_t PARAMS((char **));
+
+typedef void rl_compdisp_func_t PARAMS((char **, int, int));
+
+/* Type for input and pre-read hook functions like rl_event_hook */
+typedef int rl_hook_func_t PARAMS((void));
+
+/* Input function type */
+typedef int rl_getc_func_t PARAMS((FILE *));
+
+/* Generic function that takes a character buffer (which could be the readline
+ line buffer) and an index into it (which could be rl_point) and returns
+ an int. */
+typedef int rl_linebuf_func_t PARAMS((char *, int));
+
+/* `Generic' function pointer typedefs */
+typedef int rl_intfunc_t PARAMS((int));
+#define rl_ivoidfunc_t rl_hook_func_t
+typedef int rl_icpfunc_t PARAMS((char *));
+typedef int rl_icppfunc_t PARAMS((char **));
+
+typedef void rl_voidfunc_t PARAMS((void));
+typedef void rl_vintfunc_t PARAMS((int));
+typedef void rl_vcpfunc_t PARAMS((char *));
+typedef void rl_vcppfunc_t PARAMS((char **));
+#endif /* _RL_FUNCTION_TYPEDEF */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RL_TYPEDEFS_H_ */
diff --git a/MSVC/readline/rlwinsize.h b/MSVC/readline/rlwinsize.h
index 0179345..2951bf3 100644
--- a/MSVC/readline/rlwinsize.h
+++ b/MSVC/readline/rlwinsize.h
@@ -1,55 +1,55 @@
-/* rlwinsize.h -- an attempt to isolate some of the system-specific defines
- for `struct winsize' and TIOCGWINSZ. */
-
-/* Copyright (C) 1997 Free Software Foundation, Inc.
-
- This file contains the Readline Library (the Library), a set of
- routines for providing Emacs style line input to programs that ask
- for it.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_RLWINSIZE_H_)
-#define _RLWINSIZE_H_
-
-#include "config.h"
-
-/* Try to find the definitions of `struct winsize' and TIOGCWINSZ */
-
-#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
-# include <sys/ioctl.h>
-#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
-
-#if defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
-# include <termios.h>
-#endif /* STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */
-
-/* Not in either of the standard places, look around. */
-#if !defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
-# if defined (HAVE_SYS_STREAM_H)
-# include <sys/stream.h>
-# endif /* HAVE_SYS_STREAM_H */
-# if defined (HAVE_SYS_PTEM_H) /* SVR4.2, at least, has it here */
-# include <sys/ptem.h>
-# define _IO_PTEM_H /* work around SVR4.2 1.1.4 bug */
-# endif /* HAVE_SYS_PTEM_H */
-# if defined (HAVE_SYS_PTE_H) /* ??? */
-# include <sys/pte.h>
-# endif /* HAVE_SYS_PTE_H */
-#endif /* !STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */
-
-#endif /* _RL_WINSIZE_H */
-
+/* rlwinsize.h -- an attempt to isolate some of the system-specific defines
+ for `struct winsize' and TIOCGWINSZ. */
+
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+
+ This file contains the Readline Library (the Library), a set of
+ routines for providing Emacs style line input to programs that ask
+ for it.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_RLWINSIZE_H_)
+#define _RLWINSIZE_H_
+
+#include "config.h"
+
+/* Try to find the definitions of `struct winsize' and TIOGCWINSZ */
+
+#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
+# include <sys/ioctl.h>
+#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
+
+#if defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
+# include <termios.h>
+#endif /* STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */
+
+/* Not in either of the standard places, look around. */
+#if !defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
+# if defined (HAVE_SYS_STREAM_H)
+# include <sys/stream.h>
+# endif /* HAVE_SYS_STREAM_H */
+# if defined (HAVE_SYS_PTEM_H) /* SVR4.2, at least, has it here */
+# include <sys/ptem.h>
+# define _IO_PTEM_H /* work around SVR4.2 1.1.4 bug */
+# endif /* HAVE_SYS_PTEM_H */
+# if defined (HAVE_SYS_PTE_H) /* ??? */
+# include <sys/pte.h>
+# endif /* HAVE_SYS_PTE_H */
+#endif /* !STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */
+
+#endif /* _RL_WINSIZE_H */
+
diff --git a/MSVC/readline/savestring.c b/MSVC/readline/savestring.c
index 6371edd..2b69089 100644
--- a/MSVC/readline/savestring.c
+++ b/MSVC/readline/savestring.c
@@ -1,36 +1,36 @@
-/* savestring.c */
-
-/* Copyright (C) 1998 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#include "config.h"
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-#include "xmalloc.h"
-
-/* Backwards compatibility, now that savestring has been removed from
- all `public' readline header files. */
-char *
-savestring (s)
- const char *s;
-{
- return ((char *)strcpy ((char *)xmalloc (1 + strlen (s)), (s)));
-}
+/* savestring.c */
+
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#include "config.h"
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+#include "xmalloc.h"
+
+/* Backwards compatibility, now that savestring has been removed from
+ all `public' readline header files. */
+char *
+savestring (s)
+ const char *s;
+{
+ return ((char *)strcpy ((char *)xmalloc (1 + strlen (s)), (s)));
+}
diff --git a/MSVC/readline/search.c b/MSVC/readline/search.c
index 9385cb1..2f7d4b9 100644
--- a/MSVC/readline/search.c
+++ b/MSVC/readline/search.c
@@ -1,463 +1,463 @@
-/* search.c - code for non-incremental searching in emacs and vi modes. */
-
-/* Copyright (C) 1992 Free Software Foundation, Inc.
-
- This file is part of the Readline Library (the Library), a set of
- routines for providing Emacs style line input to programs that ask
- for it.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <stdio.h>
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif
-
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-#ifdef abs
-# undef abs
-#endif
-#define abs(x) (((x) >= 0) ? (x) : -(x))
-
-extern HIST_ENTRY *_rl_saved_line_for_history;
-
-/* Functions imported from the rest of the library. */
-extern int _rl_free_history_entry PARAMS((HIST_ENTRY *));
-
-static char *noninc_search_string = (char *) NULL;
-static int noninc_history_pos;
-
-static char *prev_line_found = (char *) NULL;
-
-static int rl_history_search_len;
-static int rl_history_search_pos;
-static char *history_search_string;
-static int history_string_size;
-
-static void make_history_line_current PARAMS((HIST_ENTRY *));
-static int noninc_search_from_pos PARAMS((char *, int, int));
-static void noninc_dosearch PARAMS((char *, int));
-static void noninc_search PARAMS((int, int));
-static int rl_history_search_internal PARAMS((int, int));
-static void rl_history_search_reinit PARAMS((void));
-
-/* Make the data from the history entry ENTRY be the contents of the
- current line. This doesn't do anything with rl_point; the caller
- must set it. */
-static void
-make_history_line_current (entry)
- HIST_ENTRY *entry;
-{
- rl_replace_line (entry->line, 0);
- rl_undo_list = (UNDO_LIST *)entry->data;
-
- if (_rl_saved_line_for_history)
- _rl_free_history_entry (_rl_saved_line_for_history);
- _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
-}
-
-/* Search the history list for STRING starting at absolute history position
- POS. If STRING begins with `^', the search must match STRING at the
- beginning of a history line, otherwise a full substring match is performed
- for STRING. DIR < 0 means to search backwards through the history list,
- DIR >= 0 means to search forward. */
-static int
-noninc_search_from_pos (string, pos, dir)
- char *string;
- int pos, dir;
-{
- int ret, old;
-
- if (pos < 0)
- return -1;
-
- old = where_history ();
- if (history_set_pos (pos) == 0)
- return -1;
-
- RL_SETSTATE(RL_STATE_SEARCH);
- if (*string == '^')
- ret = history_search_prefix (string + 1, dir);
- else
- ret = history_search (string, dir);
- RL_UNSETSTATE(RL_STATE_SEARCH);
-
- if (ret != -1)
- ret = where_history ();
-
- history_set_pos (old);
- return (ret);
-}
-
-/* Search for a line in the history containing STRING. If DIR is < 0, the
- search is backwards through previous entries, else through subsequent
- entries. */
-static void
-noninc_dosearch (string, dir)
- char *string;
- int dir;
-{
- int oldpos, pos;
- HIST_ENTRY *entry;
-
- if (string == 0 || *string == '\0' || noninc_history_pos < 0)
- {
- rl_ding ();
- return;
- }
-
- pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
- if (pos == -1)
- {
- /* Search failed, current history position unchanged. */
- rl_maybe_unsave_line ();
- rl_clear_message ();
- rl_point = 0;
- rl_ding ();
- return;
- }
-
- noninc_history_pos = pos;
-
- oldpos = where_history ();
- history_set_pos (noninc_history_pos);
- entry = current_history ();
-#if defined (VI_MODE)
- if (rl_editing_mode != vi_mode)
-#endif
- history_set_pos (oldpos);
-
- make_history_line_current (entry);
-
- rl_point = 0;
- rl_mark = rl_end;
-
- rl_clear_message ();
-}
-
-/* Search non-interactively through the history list. DIR < 0 means to
- search backwards through the history of previous commands; otherwise
- the search is for commands subsequent to the current position in the
- history list. PCHAR is the character to use for prompting when reading
- the search string; if not specified (0), it defaults to `:'. */
-static void
-noninc_search (dir, pchar)
- int dir;
- int pchar;
-{
- int saved_point, saved_mark, c;
- char *p;
-#if defined (HANDLE_MULTIBYTE)
- char mb[MB_LEN_MAX];
-#endif
-
- rl_maybe_save_line ();
- saved_point = rl_point;
- saved_mark = rl_mark;
-
- /* Use the line buffer to read the search string. */
- rl_line_buffer[0] = 0;
- rl_end = rl_point = 0;
-
- p = _rl_make_prompt_for_search (pchar ? pchar : ':');
- rl_message (p, 0, 0);
- free (p);
-
-#define SEARCH_RETURN rl_restore_prompt (); RL_UNSETSTATE(RL_STATE_NSEARCH); return
-
- RL_SETSTATE(RL_STATE_NSEARCH);
- /* Read the search string. */
- while (1)
- {
- RL_SETSTATE(RL_STATE_MOREINPUT);
- c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
-#endif
-
- if (c == 0)
- break;
-
- switch (c)
- {
- case CTRL('H'):
- case RUBOUT:
- if (rl_point == 0)
- {
- rl_maybe_unsave_line ();
- rl_clear_message ();
- rl_point = saved_point;
- rl_mark = saved_mark;
- SEARCH_RETURN;
- }
- _rl_rubout_char (1, c);
- break;
-
- case CTRL('W'):
- rl_unix_word_rubout (1, c);
- break;
-
- case CTRL('U'):
- rl_unix_line_discard (1, c);
- break;
-
- case RETURN:
- case NEWLINE:
- goto dosearch;
- /* NOTREACHED */
- break;
-
- case CTRL('C'):
- case CTRL('G'):
- rl_maybe_unsave_line ();
- rl_clear_message ();
- rl_point = saved_point;
- rl_mark = saved_mark;
- rl_ding ();
- SEARCH_RETURN;
-
- default:
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- rl_insert_text (mb);
- else
-#endif
- _rl_insert_char (1, c);
- break;
- }
- (*rl_redisplay_function) ();
- }
-
- dosearch:
- rl_mark = saved_mark;
-
- /* If rl_point == 0, we want to re-use the previous search string and
- start from the saved history position. If there's no previous search
- string, punt. */
- if (rl_point == 0)
- {
- if (!noninc_search_string)
- {
- rl_ding ();
- SEARCH_RETURN;
- }
- }
- else
- {
- /* We want to start the search from the current history position. */
- noninc_history_pos = where_history ();
- FREE (noninc_search_string);
- noninc_search_string = savestring (rl_line_buffer);
- }
-
- rl_restore_prompt ();
- noninc_dosearch (noninc_search_string, dir);
- RL_UNSETSTATE(RL_STATE_NSEARCH);
-}
-
-/* Search forward through the history list for a string. If the vi-mode
- code calls this, KEY will be `?'. */
-int
-rl_noninc_forward_search (count, key)
- int count, key;
-{
- noninc_search (1, (key == '?') ? '?' : 0);
- return 0;
-}
-
-/* Reverse search the history list for a string. If the vi-mode code
- calls this, KEY will be `/'. */
-int
-rl_noninc_reverse_search (count, key)
- int count, key;
-{
- noninc_search (-1, (key == '/') ? '/' : 0);
- return 0;
-}
-
-/* Search forward through the history list for the last string searched
- for. If there is no saved search string, abort. */
-int
-rl_noninc_forward_search_again (count, key)
- int count, key;
-{
- if (!noninc_search_string)
- {
- rl_ding ();
- return (-1);
- }
- noninc_dosearch (noninc_search_string, 1);
- return 0;
-}
-
-/* Reverse search in the history list for the last string searched
- for. If there is no saved search string, abort. */
-int
-rl_noninc_reverse_search_again (count, key)
- int count, key;
-{
- if (!noninc_search_string)
- {
- rl_ding ();
- return (-1);
- }
- noninc_dosearch (noninc_search_string, -1);
- return 0;
-}
-
-static int
-rl_history_search_internal (count, dir)
- int count, dir;
-{
- HIST_ENTRY *temp;
- int ret, oldpos;
-
- rl_maybe_save_line ();
- temp = (HIST_ENTRY *)NULL;
-
- /* Search COUNT times through the history for a line whose prefix
- matches history_search_string. When this loop finishes, TEMP,
- if non-null, is the history line to copy into the line buffer. */
- while (count)
- {
- ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir);
- if (ret == -1)
- break;
-
- /* Get the history entry we found. */
- rl_history_search_pos = ret;
- oldpos = where_history ();
- history_set_pos (rl_history_search_pos);
- temp = current_history ();
- history_set_pos (oldpos);
-
- /* Don't find multiple instances of the same line. */
- if (prev_line_found && STREQ (prev_line_found, temp->line))
- continue;
- prev_line_found = temp->line;
- count--;
- }
-
- /* If we didn't find anything at all, return. */
- if (temp == 0)
- {
- rl_maybe_unsave_line ();
- rl_ding ();
- /* If you don't want the saved history line (last match) to show up
- in the line buffer after the search fails, change the #if 0 to
- #if 1 */
-#if 0
- if (rl_point > rl_history_search_len)
- {
- rl_point = rl_end = rl_history_search_len;
- rl_line_buffer[rl_end] = '\0';
- rl_mark = 0;
- }
-#else
- rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
- rl_mark = rl_end;
-#endif
- return 1;
- }
-
- /* Copy the line we found into the current line buffer. */
- make_history_line_current (temp);
-
- rl_point = rl_history_search_len;
- rl_mark = rl_end;
-
- return 0;
-}
-
-static void
-rl_history_search_reinit ()
-{
- rl_history_search_pos = where_history ();
- rl_history_search_len = rl_point;
- prev_line_found = (char *)NULL;
- if (rl_point)
- {
- if (rl_history_search_len >= history_string_size - 2)
- {
- history_string_size = rl_history_search_len + 2;
- history_search_string = (char *)xrealloc (history_search_string, history_string_size);
- }
- history_search_string[0] = '^';
- strncpy (history_search_string + 1, rl_line_buffer, rl_point);
- history_search_string[rl_point + 1] = '\0';
- }
- _rl_free_saved_history_line ();
-}
-
-/* Search forward in the history for the string of characters
- from the start of the line to rl_point. This is a non-incremental
- search. */
-int
-rl_history_search_forward (count, ignore)
- int count, ignore;
-{
- if (count == 0)
- return (0);
-
- if (rl_last_func != rl_history_search_forward &&
- rl_last_func != rl_history_search_backward)
- rl_history_search_reinit ();
-
- if (rl_history_search_len == 0)
- return (rl_get_next_history (count, ignore));
- return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
-}
-
-/* Search backward through the history for the string of characters
- from the start of the line to rl_point. This is a non-incremental
- search. */
-int
-rl_history_search_backward (count, ignore)
- int count, ignore;
-{
- if (count == 0)
- return (0);
-
- if (rl_last_func != rl_history_search_forward &&
- rl_last_func != rl_history_search_backward)
- rl_history_search_reinit ();
-
- if (rl_history_search_len == 0)
- return (rl_get_previous_history (count, ignore));
- return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
-}
+/* search.c - code for non-incremental searching in emacs and vi modes. */
+
+/* Copyright (C) 1992 Free Software Foundation, Inc.
+
+ This file is part of the Readline Library (the Library), a set of
+ routines for providing Emacs style line input to programs that ask
+ for it.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif
+
+#include "rldefs.h"
+#include "rlmbutil.h"
+
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "xmalloc.h"
+
+#ifdef abs
+# undef abs
+#endif
+#define abs(x) (((x) >= 0) ? (x) : -(x))
+
+extern HIST_ENTRY *_rl_saved_line_for_history;
+
+/* Functions imported from the rest of the library. */
+extern int _rl_free_history_entry PARAMS((HIST_ENTRY *));
+
+static char *noninc_search_string = (char *) NULL;
+static int noninc_history_pos;
+
+static char *prev_line_found = (char *) NULL;
+
+static int rl_history_search_len;
+static int rl_history_search_pos;
+static char *history_search_string;
+static int history_string_size;
+
+static void make_history_line_current PARAMS((HIST_ENTRY *));
+static int noninc_search_from_pos PARAMS((char *, int, int));
+static void noninc_dosearch PARAMS((char *, int));
+static void noninc_search PARAMS((int, int));
+static int rl_history_search_internal PARAMS((int, int));
+static void rl_history_search_reinit PARAMS((void));
+
+/* Make the data from the history entry ENTRY be the contents of the
+ current line. This doesn't do anything with rl_point; the caller
+ must set it. */
+static void
+make_history_line_current (entry)
+ HIST_ENTRY *entry;
+{
+ rl_replace_line (entry->line, 0);
+ rl_undo_list = (UNDO_LIST *)entry->data;
+
+ if (_rl_saved_line_for_history)
+ _rl_free_history_entry (_rl_saved_line_for_history);
+ _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
+}
+
+/* Search the history list for STRING starting at absolute history position
+ POS. If STRING begins with `^', the search must match STRING at the
+ beginning of a history line, otherwise a full substring match is performed
+ for STRING. DIR < 0 means to search backwards through the history list,
+ DIR >= 0 means to search forward. */
+static int
+noninc_search_from_pos (string, pos, dir)
+ char *string;
+ int pos, dir;
+{
+ int ret, old;
+
+ if (pos < 0)
+ return -1;
+
+ old = where_history ();
+ if (history_set_pos (pos) == 0)
+ return -1;
+
+ RL_SETSTATE(RL_STATE_SEARCH);
+ if (*string == '^')
+ ret = history_search_prefix (string + 1, dir);
+ else
+ ret = history_search (string, dir);
+ RL_UNSETSTATE(RL_STATE_SEARCH);
+
+ if (ret != -1)
+ ret = where_history ();
+
+ history_set_pos (old);
+ return (ret);
+}
+
+/* Search for a line in the history containing STRING. If DIR is < 0, the
+ search is backwards through previous entries, else through subsequent
+ entries. */
+static void
+noninc_dosearch (string, dir)
+ char *string;
+ int dir;
+{
+ int oldpos, pos;
+ HIST_ENTRY *entry;
+
+ if (string == 0 || *string == '\0' || noninc_history_pos < 0)
+ {
+ rl_ding ();
+ return;
+ }
+
+ pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
+ if (pos == -1)
+ {
+ /* Search failed, current history position unchanged. */
+ rl_maybe_unsave_line ();
+ rl_clear_message ();
+ rl_point = 0;
+ rl_ding ();
+ return;
+ }
+
+ noninc_history_pos = pos;
+
+ oldpos = where_history ();
+ history_set_pos (noninc_history_pos);
+ entry = current_history ();
+#if defined (VI_MODE)
+ if (rl_editing_mode != vi_mode)
+#endif
+ history_set_pos (oldpos);
+
+ make_history_line_current (entry);
+
+ rl_point = 0;
+ rl_mark = rl_end;
+
+ rl_clear_message ();
+}
+
+/* Search non-interactively through the history list. DIR < 0 means to
+ search backwards through the history of previous commands; otherwise
+ the search is for commands subsequent to the current position in the
+ history list. PCHAR is the character to use for prompting when reading
+ the search string; if not specified (0), it defaults to `:'. */
+static void
+noninc_search (dir, pchar)
+ int dir;
+ int pchar;
+{
+ int saved_point, saved_mark, c;
+ char *p;
+#if defined (HANDLE_MULTIBYTE)
+ char mb[MB_LEN_MAX];
+#endif
+
+ rl_maybe_save_line ();
+ saved_point = rl_point;
+ saved_mark = rl_mark;
+
+ /* Use the line buffer to read the search string. */
+ rl_line_buffer[0] = 0;
+ rl_end = rl_point = 0;
+
+ p = _rl_make_prompt_for_search (pchar ? pchar : ':');
+ rl_message (p, 0, 0);
+ free (p);
+
+#define SEARCH_RETURN rl_restore_prompt (); RL_UNSETSTATE(RL_STATE_NSEARCH); return
+
+ RL_SETSTATE(RL_STATE_NSEARCH);
+ /* Read the search string. */
+ while (1)
+ {
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
+#endif
+
+ if (c == 0)
+ break;
+
+ switch (c)
+ {
+ case CTRL('H'):
+ case RUBOUT:
+ if (rl_point == 0)
+ {
+ rl_maybe_unsave_line ();
+ rl_clear_message ();
+ rl_point = saved_point;
+ rl_mark = saved_mark;
+ SEARCH_RETURN;
+ }
+ _rl_rubout_char (1, c);
+ break;
+
+ case CTRL('W'):
+ rl_unix_word_rubout (1, c);
+ break;
+
+ case CTRL('U'):
+ rl_unix_line_discard (1, c);
+ break;
+
+ case RETURN:
+ case NEWLINE:
+ goto dosearch;
+ /* NOTREACHED */
+ break;
+
+ case CTRL('C'):
+ case CTRL('G'):
+ rl_maybe_unsave_line ();
+ rl_clear_message ();
+ rl_point = saved_point;
+ rl_mark = saved_mark;
+ rl_ding ();
+ SEARCH_RETURN;
+
+ default:
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_insert_text (mb);
+ else
+#endif
+ _rl_insert_char (1, c);
+ break;
+ }
+ (*rl_redisplay_function) ();
+ }
+
+ dosearch:
+ rl_mark = saved_mark;
+
+ /* If rl_point == 0, we want to re-use the previous search string and
+ start from the saved history position. If there's no previous search
+ string, punt. */
+ if (rl_point == 0)
+ {
+ if (!noninc_search_string)
+ {
+ rl_ding ();
+ SEARCH_RETURN;
+ }
+ }
+ else
+ {
+ /* We want to start the search from the current history position. */
+ noninc_history_pos = where_history ();
+ FREE (noninc_search_string);
+ noninc_search_string = savestring (rl_line_buffer);
+ }
+
+ rl_restore_prompt ();
+ noninc_dosearch (noninc_search_string, dir);
+ RL_UNSETSTATE(RL_STATE_NSEARCH);
+}
+
+/* Search forward through the history list for a string. If the vi-mode
+ code calls this, KEY will be `?'. */
+int
+rl_noninc_forward_search (count, key)
+ int count, key;
+{
+ noninc_search (1, (key == '?') ? '?' : 0);
+ return 0;
+}
+
+/* Reverse search the history list for a string. If the vi-mode code
+ calls this, KEY will be `/'. */
+int
+rl_noninc_reverse_search (count, key)
+ int count, key;
+{
+ noninc_search (-1, (key == '/') ? '/' : 0);
+ return 0;
+}
+
+/* Search forward through the history list for the last string searched
+ for. If there is no saved search string, abort. */
+int
+rl_noninc_forward_search_again (count, key)
+ int count, key;
+{
+ if (!noninc_search_string)
+ {
+ rl_ding ();
+ return (-1);
+ }
+ noninc_dosearch (noninc_search_string, 1);
+ return 0;
+}
+
+/* Reverse search in the history list for the last string searched
+ for. If there is no saved search string, abort. */
+int
+rl_noninc_reverse_search_again (count, key)
+ int count, key;
+{
+ if (!noninc_search_string)
+ {
+ rl_ding ();
+ return (-1);
+ }
+ noninc_dosearch (noninc_search_string, -1);
+ return 0;
+}
+
+static int
+rl_history_search_internal (count, dir)
+ int count, dir;
+{
+ HIST_ENTRY *temp;
+ int ret, oldpos;
+
+ rl_maybe_save_line ();
+ temp = (HIST_ENTRY *)NULL;
+
+ /* Search COUNT times through the history for a line whose prefix
+ matches history_search_string. When this loop finishes, TEMP,
+ if non-null, is the history line to copy into the line buffer. */
+ while (count)
+ {
+ ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir);
+ if (ret == -1)
+ break;
+
+ /* Get the history entry we found. */
+ rl_history_search_pos = ret;
+ oldpos = where_history ();
+ history_set_pos (rl_history_search_pos);
+ temp = current_history ();
+ history_set_pos (oldpos);
+
+ /* Don't find multiple instances of the same line. */
+ if (prev_line_found && STREQ (prev_line_found, temp->line))
+ continue;
+ prev_line_found = temp->line;
+ count--;
+ }
+
+ /* If we didn't find anything at all, return. */
+ if (temp == 0)
+ {
+ rl_maybe_unsave_line ();
+ rl_ding ();
+ /* If you don't want the saved history line (last match) to show up
+ in the line buffer after the search fails, change the #if 0 to
+ #if 1 */
+#if 0
+ if (rl_point > rl_history_search_len)
+ {
+ rl_point = rl_end = rl_history_search_len;
+ rl_line_buffer[rl_end] = '\0';
+ rl_mark = 0;
+ }
+#else
+ rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
+ rl_mark = rl_end;
+#endif
+ return 1;
+ }
+
+ /* Copy the line we found into the current line buffer. */
+ make_history_line_current (temp);
+
+ rl_point = rl_history_search_len;
+ rl_mark = rl_end;
+
+ return 0;
+}
+
+static void
+rl_history_search_reinit ()
+{
+ rl_history_search_pos = where_history ();
+ rl_history_search_len = rl_point;
+ prev_line_found = (char *)NULL;
+ if (rl_point)
+ {
+ if (rl_history_search_len >= history_string_size - 2)
+ {
+ history_string_size = rl_history_search_len + 2;
+ history_search_string = (char *)xrealloc (history_search_string, history_string_size);
+ }
+ history_search_string[0] = '^';
+ strncpy (history_search_string + 1, rl_line_buffer, rl_point);
+ history_search_string[rl_point + 1] = '\0';
+ }
+ _rl_free_saved_history_line ();
+}
+
+/* Search forward in the history for the string of characters
+ from the start of the line to rl_point. This is a non-incremental
+ search. */
+int
+rl_history_search_forward (count, ignore)
+ int count, ignore;
+{
+ if (count == 0)
+ return (0);
+
+ if (rl_last_func != rl_history_search_forward &&
+ rl_last_func != rl_history_search_backward)
+ rl_history_search_reinit ();
+
+ if (rl_history_search_len == 0)
+ return (rl_get_next_history (count, ignore));
+ return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
+}
+
+/* Search backward through the history for the string of characters
+ from the start of the line to rl_point. This is a non-incremental
+ search. */
+int
+rl_history_search_backward (count, ignore)
+ int count, ignore;
+{
+ if (count == 0)
+ return (0);
+
+ if (rl_last_func != rl_history_search_forward &&
+ rl_last_func != rl_history_search_backward)
+ rl_history_search_reinit ();
+
+ if (rl_history_search_len == 0)
+ return (rl_get_previous_history (count, ignore));
+ return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
+}
diff --git a/MSVC/readline/shell.c b/MSVC/readline/shell.c
index c16fe59..22ee2ad 100644
--- a/MSVC/readline/shell.c
+++ b/MSVC/readline/shell.c
@@ -1,231 +1,231 @@
-/* shell.c -- readline utility functions that are normally provided by
- bash when readline is linked as part of the shell. */
-
-/* Copyright (C) 1997 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <stdio.h>
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_STRING_H)
-# include <string.h>
-#else
-# include <strings.h>
-#endif /* !HAVE_STRING_H */
-
-#if defined (HAVE_LIMITS_H)
-# include <limits.h>
-#endif
-
-#include <fcntl.h>
-
-#if !defined _WIN32
-# include <pwd.h>
-# if !defined (HAVE_GETPW_DECLS)
- extern struct passwd *getpwuid ();
-# endif /* !HAVE_GETPW_DECLS */
-#else /* _WIN32 */
-# include <windows.h>
-#endif /* _WIN32 */
-
-#include <stdio.h>
-
-#include "rlstdc.h"
-#include "rlshell.h"
-#include "xmalloc.h"
-
-#if !defined (HAVE_GETPW_DECLS) && !defined _WIN32
-extern struct passwd *getpwuid PARAMS((uid_t));
-#endif /* !HAVE_GETPW_DECLS */
-
-#ifndef NULL
-# define NULL 0
-#endif
-
-#ifndef CHAR_BIT
-# define CHAR_BIT 8
-#endif
-
-/* Nonzero if the integer type T is signed. */
-#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-
-/* Bound on length of the string representing an integer value of type T.
- Subtract one for the sign bit if T is signed;
- 302 / 1000 is log10 (2) rounded up;
- add one for integer division truncation;
- add one more for a minus sign if t is signed. */
-#define INT_STRLEN_BOUND(t) \
- ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
- + 1 + TYPE_SIGNED (t))
-
-/* All of these functions are resolved from bash if we are linking readline
- as part of bash. */
-
-/* Does shell-like quoting using single quotes. */
-char *
-sh_single_quote (string)
- char *string;
-{
- register int c;
- char *result, *r, *s;
-
- result = (char *)xmalloc (3 + (4 * strlen (string)));
- r = result;
- *r++ = '\'';
-
- for (s = string; s && (c = *s); s++)
- {
- *r++ = c;
-
- if (c == '\'')
- {
- *r++ = '\\'; /* insert escaped single quote */
- *r++ = '\'';
- *r++ = '\''; /* start new quoted string */
- }
- }
-
- *r++ = '\'';
- *r = '\0';
-
- return (result);
-}
-
-#if !defined _WIN32
-/* Set the environment variables LINES and COLUMNS to lines and cols,
- respectively. */
-void
-sh_set_lines_and_columns (lines, cols)
- int lines, cols;
-{
- char *b;
-
-#if defined (HAVE_PUTENV)
- b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
- sprintf (b, "LINES=%d", lines);
- putenv (b);
- b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1);
- sprintf (b, "COLUMNS=%d", cols);
- putenv (b);
-#else /* !HAVE_PUTENV */
-# if defined (HAVE_SETENV)
- b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
- sprintf (b, "%d", lines);
- setenv ("LINES", b, 1);
- b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
- sprintf (b, "%d", cols);
- setenv ("COLUMNS", b, 1);
-# endif /* HAVE_SETENV */
-#endif /* !HAVE_PUTENV */
-}
-#endif /* !_WIN32 */
-
-char *
-sh_get_env_value (varname)
- const char *varname;
-{
- return ((char *)getenv (varname));
-}
-
-#if !defined _WIN32
-char *
-sh_get_home_dir ()
-{
- char *home_dir;
- struct passwd *entry;
-
- home_dir = (char *)NULL;
- entry = getpwuid (getuid ());
- if (entry)
- home_dir = entry->pw_dir;
- return (home_dir);
-}
-
-#if !defined (O_NDELAY)
-# if defined (FNDELAY)
-# define O_NDELAY FNDELAY
-# endif
-#endif
-
-int
-sh_unset_nodelay_mode (fd)
- int fd;
-{
- int flags, bflags;
-
- if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
- return -1;
-
- bflags = 0;
-
-#ifdef O_NONBLOCK
- bflags |= O_NONBLOCK;
-#endif
-
-#ifdef O_NDELAY
- bflags |= O_NDELAY;
-#endif
-
- if (flags & bflags)
- {
- flags &= ~bflags;
- return (fcntl (fd, F_SETFL, flags));
- }
-
- return 0;
-}
-#else /* _WIN32 */
-char *
-get_user_registry_string(char *keyName, char* valName)
-{
- char *result = NULL;
- HKEY subKey;
- if ( keyName && (RegOpenKeyEx(HKEY_CURRENT_USER, keyName, 0, KEY_READ, &subKey)
- == ERROR_SUCCESS) )
- {
- DWORD type;
- char *chtry = NULL;
- DWORD bufSize = 0;
-
- if ( (RegQueryValueExA(subKey, valName, NULL, &type, chtry, &bufSize)
- == ERROR_SUCCESS) && (type == REG_SZ) )
- {
- if ( (chtry = (char *)xmalloc(bufSize))
- && (RegQueryValueExA(subKey, valName, NULL, &type, chtry, &bufSize) == ERROR_SUCCESS) )
- result = chtry;
- }
- }
- return result;
-}
-#endif /* _WIN32 */
-
+/* shell.c -- readline utility functions that are normally provided by
+ bash when readline is linked as part of the shell. */
+
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else
+# include <strings.h>
+#endif /* !HAVE_STRING_H */
+
+#if defined (HAVE_LIMITS_H)
+# include <limits.h>
+#endif
+
+#include <fcntl.h>
+
+#if !defined _WIN32
+# include <pwd.h>
+# if !defined (HAVE_GETPW_DECLS)
+ extern struct passwd *getpwuid ();
+# endif /* !HAVE_GETPW_DECLS */
+#else /* _WIN32 */
+# include <windows.h>
+#endif /* _WIN32 */
+
+#include <stdio.h>
+
+#include "rlstdc.h"
+#include "rlshell.h"
+#include "xmalloc.h"
+
+#if !defined (HAVE_GETPW_DECLS) && !defined _WIN32
+extern struct passwd *getpwuid PARAMS((uid_t));
+#endif /* !HAVE_GETPW_DECLS */
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+#ifndef CHAR_BIT
+# define CHAR_BIT 8
+#endif
+
+/* Nonzero if the integer type T is signed. */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+
+/* Bound on length of the string representing an integer value of type T.
+ Subtract one for the sign bit if T is signed;
+ 302 / 1000 is log10 (2) rounded up;
+ add one for integer division truncation;
+ add one more for a minus sign if t is signed. */
+#define INT_STRLEN_BOUND(t) \
+ ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
+ + 1 + TYPE_SIGNED (t))
+
+/* All of these functions are resolved from bash if we are linking readline
+ as part of bash. */
+
+/* Does shell-like quoting using single quotes. */
+char *
+sh_single_quote (string)
+ char *string;
+{
+ register int c;
+ char *result, *r, *s;
+
+ result = (char *)xmalloc (3 + (4 * strlen (string)));
+ r = result;
+ *r++ = '\'';
+
+ for (s = string; s && (c = *s); s++)
+ {
+ *r++ = c;
+
+ if (c == '\'')
+ {
+ *r++ = '\\'; /* insert escaped single quote */
+ *r++ = '\'';
+ *r++ = '\''; /* start new quoted string */
+ }
+ }
+
+ *r++ = '\'';
+ *r = '\0';
+
+ return (result);
+}
+
+#if !defined _WIN32
+/* Set the environment variables LINES and COLUMNS to lines and cols,
+ respectively. */
+void
+sh_set_lines_and_columns (lines, cols)
+ int lines, cols;
+{
+ char *b;
+
+#if defined (HAVE_PUTENV)
+ b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
+ sprintf (b, "LINES=%d", lines);
+ putenv (b);
+ b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1);
+ sprintf (b, "COLUMNS=%d", cols);
+ putenv (b);
+#else /* !HAVE_PUTENV */
+# if defined (HAVE_SETENV)
+ b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
+ sprintf (b, "%d", lines);
+ setenv ("LINES", b, 1);
+ b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
+ sprintf (b, "%d", cols);
+ setenv ("COLUMNS", b, 1);
+# endif /* HAVE_SETENV */
+#endif /* !HAVE_PUTENV */
+}
+#endif /* !_WIN32 */
+
+char *
+sh_get_env_value (varname)
+ const char *varname;
+{
+ return ((char *)getenv (varname));
+}
+
+#if !defined _WIN32
+char *
+sh_get_home_dir ()
+{
+ char *home_dir;
+ struct passwd *entry;
+
+ home_dir = (char *)NULL;
+ entry = getpwuid (getuid ());
+ if (entry)
+ home_dir = entry->pw_dir;
+ return (home_dir);
+}
+
+#if !defined (O_NDELAY)
+# if defined (FNDELAY)
+# define O_NDELAY FNDELAY
+# endif
+#endif
+
+int
+sh_unset_nodelay_mode (fd)
+ int fd;
+{
+ int flags, bflags;
+
+ if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
+ return -1;
+
+ bflags = 0;
+
+#ifdef O_NONBLOCK
+ bflags |= O_NONBLOCK;
+#endif
+
+#ifdef O_NDELAY
+ bflags |= O_NDELAY;
+#endif
+
+ if (flags & bflags)
+ {
+ flags &= ~bflags;
+ return (fcntl (fd, F_SETFL, flags));
+ }
+
+ return 0;
+}
+#else /* _WIN32 */
+char *
+get_user_registry_string(char *keyName, char* valName)
+{
+ char *result = NULL;
+ HKEY subKey;
+ if ( keyName && (RegOpenKeyEx(HKEY_CURRENT_USER, keyName, 0, KEY_READ, &subKey)
+ == ERROR_SUCCESS) )
+ {
+ DWORD type;
+ char *chtry = NULL;
+ DWORD bufSize = 0;
+
+ if ( (RegQueryValueExA(subKey, valName, NULL, &type, chtry, &bufSize)
+ == ERROR_SUCCESS) && (type == REG_SZ) )
+ {
+ if ( (chtry = (char *)xmalloc(bufSize))
+ && (RegQueryValueExA(subKey, valName, NULL, &type, chtry, &bufSize) == ERROR_SUCCESS) )
+ result = chtry;
+ }
+ }
+ return result;
+}
+#endif /* _WIN32 */
+
diff --git a/MSVC/readline/signals.c b/MSVC/readline/signals.c
index ba92eec..75e39c6 100644
--- a/MSVC/readline/signals.c
+++ b/MSVC/readline/signals.c
@@ -1,444 +1,444 @@
-/* signals.c -- signal handling support for readline. */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <stdio.h> /* Just for NULL. Yuck. */
-#include <sys/types.h>
-#include <signal.h>
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-
-#if defined (GWINSZ_IN_SYS_IOCTL)
-# include <sys/ioctl.h>
-#endif /* GWINSZ_IN_SYS_IOCTL */
-
-#if defined (HANDLE_SIGNALS)
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-
-#if !defined (RETSIGTYPE)
-# if defined (VOID_SIGHANDLER)
-# define RETSIGTYPE void
-# else
-# define RETSIGTYPE int
-# endif /* !VOID_SIGHANDLER */
-#endif /* !RETSIGTYPE */
-
-#if defined (VOID_SIGHANDLER)
-# define SIGHANDLER_RETURN return
-#else
-# define SIGHANDLER_RETURN return (0)
-#endif
-
-/* This typedef is equivalent to the one for Function; it allows us
- to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
-typedef RETSIGTYPE SigHandler ();
-
-#if defined (HAVE_POSIX_SIGNALS)
-typedef struct sigaction sighandler_cxt;
-# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
-#else
-typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
-# define sigemptyset(m)
-#endif /* !HAVE_POSIX_SIGNALS */
-
-static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
-static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
-
-/* Exported variables for use by applications. */
-
-/* If non-zero, readline will install its own signal handlers for
- SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
-int rl_catch_signals = 1;
-
-/* If non-zero, readline will install a signal handler for SIGWINCH. */
-#ifdef SIGWINCH
-int rl_catch_sigwinch = 1;
-#endif
-
-static int signals_set_flag;
-
-#if !defined _WIN32 /* Win32 "signals" at end of file */
-static int sigwinch_set_flag;
-
-/* **************************************************************** */
-/* */
-/* Signal Handling */
-/* */
-/* **************************************************************** */
-
-static sighandler_cxt old_int, old_term, old_alrm, old_quit;
-#if defined (SIGTSTP)
-static sighandler_cxt old_tstp, old_ttou, old_ttin;
-#endif
-#if defined (SIGWINCH)
-static sighandler_cxt old_winch;
-#endif
-
-/* Readline signal handler functions. */
-
-static RETSIGTYPE
-rl_signal_handler (sig)
- int sig;
-{
-#if defined (HAVE_POSIX_SIGNALS)
- sigset_t set;
-#else /* !HAVE_POSIX_SIGNALS */
-# if defined (HAVE_BSD_SIGNALS)
- long omask;
-# else /* !HAVE_BSD_SIGNALS */
- sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */
-# endif /* !HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
- RL_SETSTATE(RL_STATE_SIGHANDLER);
-
-#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
- /* Since the signal will not be blocked while we are in the signal
- handler, ignore it until rl_clear_signals resets the catcher. */
- if (sig == SIGINT || sig == SIGALRM)
- rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
-#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
-
- switch (sig)
- {
- case SIGINT:
- rl_free_line_state ();
- /* FALLTHROUGH */
-
-#if defined (SIGTSTP)
- case SIGTSTP:
- case SIGTTOU:
- case SIGTTIN:
-#endif /* SIGTSTP */
- case SIGALRM:
- case SIGTERM:
- case SIGQUIT:
- rl_cleanup_after_signal ();
-
-#if defined (HAVE_POSIX_SIGNALS)
- sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
- sigdelset (&set, sig);
-#else /* !HAVE_POSIX_SIGNALS */
-# if defined (HAVE_BSD_SIGNALS)
- omask = sigblock (0);
-# endif /* HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-#if defined (__EMX__)
- signal (sig, SIG_ACK);
-#endif
-
- kill (getpid (), sig);
-
- /* Let the signal that we just sent through. */
-#if defined (HAVE_POSIX_SIGNALS)
- sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
-#else /* !HAVE_POSIX_SIGNALS */
-# if defined (HAVE_BSD_SIGNALS)
- sigsetmask (omask & ~(sigmask (sig)));
-# endif /* HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
- rl_reset_after_signal ();
- }
-
- RL_UNSETSTATE(RL_STATE_SIGHANDLER);
- SIGHANDLER_RETURN;
-}
-
-#if defined (SIGWINCH)
-static RETSIGTYPE
-rl_sigwinch_handler (sig)
- int sig;
-{
- SigHandler *oh;
-
-#if defined (MUST_REINSTALL_SIGHANDLERS)
- sighandler_cxt dummy_winch;
-
- /* We don't want to change old_winch -- it holds the state of SIGWINCH
- disposition set by the calling application. We need this state
- because we call the application's SIGWINCH handler after updating
- our own idea of the screen size. */
- rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
-#endif
-
- RL_SETSTATE(RL_STATE_SIGHANDLER);
- rl_resize_terminal ();
-
- /* If another sigwinch handler has been installed, call it. */
- oh = (SigHandler *)old_winch.sa_handler;
- if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
- (*oh) (sig);
-
- RL_UNSETSTATE(RL_STATE_SIGHANDLER);
- SIGHANDLER_RETURN;
-}
-#endif /* SIGWINCH */
-
-/* Functions to manage signal handling. */
-
-#if !defined (HAVE_POSIX_SIGNALS)
-static int
-rl_sigaction (sig, nh, oh)
- int sig;
- sighandler_cxt *nh, *oh;
-{
- oh->sa_handler = signal (sig, nh->sa_handler);
- return 0;
-}
-#endif /* !HAVE_POSIX_SIGNALS */
-
-/* Set up a readline-specific signal handler, saving the old signal
- information in OHANDLER. Return the old signal handler, like
- signal(). */
-static SigHandler *
-rl_set_sighandler (sig, handler, ohandler)
- int sig;
- SigHandler *handler;
- sighandler_cxt *ohandler;
-{
- sighandler_cxt old_handler;
-#if defined (HAVE_POSIX_SIGNALS)
- struct sigaction act;
-
- act.sa_handler = handler;
- act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */
- sigemptyset (&act.sa_mask);
- sigemptyset (&ohandler->sa_mask);
- sigaction (sig, &act, &old_handler);
-#else
- old_handler.sa_handler = (SigHandler *)signal (sig, handler);
-#endif /* !HAVE_POSIX_SIGNALS */
-
- /* XXX -- assume we have memcpy */
- /* If rl_set_signals is called twice in a row, don't set the old handler to
- rl_signal_handler, because that would cause infinite recursion. */
- if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
- memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
-
- return (ohandler->sa_handler);
-}
-
-static void
-rl_maybe_set_sighandler (sig, handler, ohandler)
- int sig;
- SigHandler *handler;
- sighandler_cxt *ohandler;
-{
- sighandler_cxt dummy;
- SigHandler *oh;
-
- sigemptyset (&dummy.sa_mask);
- oh = rl_set_sighandler (sig, handler, ohandler);
- if (oh == (SigHandler *)SIG_IGN)
- rl_sigaction (sig, ohandler, &dummy);
-}
-
-int
-rl_set_signals ()
-{
- sighandler_cxt dummy;
- SigHandler *oh;
-
- if (rl_catch_signals && signals_set_flag == 0)
- {
- rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
- rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
- rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
-
- oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
- if (oh == (SigHandler *)SIG_IGN)
- rl_sigaction (SIGALRM, &old_alrm, &dummy);
-#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
- /* If the application using readline has already installed a signal
- handler with SA_RESTART, SIGALRM will cause reads to be restarted
- automatically, so readline should just get out of the way. Since
- we tested for SIG_IGN above, we can just test for SIG_DFL here. */
- if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
- rl_sigaction (SIGALRM, &old_alrm, &dummy);
-#endif /* HAVE_POSIX_SIGNALS */
-
-#if defined (SIGTSTP)
- rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
-#endif /* SIGTSTP */
-
-#if defined (SIGTTOU)
- rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
-#endif /* SIGTTOU */
-
-#if defined (SIGTTIN)
- rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
-#endif /* SIGTTIN */
-
- signals_set_flag = 1;
- }
-
-#if defined (SIGWINCH)
- if (rl_catch_sigwinch && sigwinch_set_flag == 0)
- {
- rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
- sigwinch_set_flag = 1;
- }
-#endif /* SIGWINCH */
-
- return 0;
-}
-
-int
-rl_clear_signals ()
-{
- sighandler_cxt dummy;
-
- if (rl_catch_signals && signals_set_flag == 1)
- {
- sigemptyset (&dummy.sa_mask);
-
- rl_sigaction (SIGINT, &old_int, &dummy);
- rl_sigaction (SIGTERM, &old_term, &dummy);
- rl_sigaction (SIGQUIT, &old_quit, &dummy);
- rl_sigaction (SIGALRM, &old_alrm, &dummy);
-
-#if defined (SIGTSTP)
- rl_sigaction (SIGTSTP, &old_tstp, &dummy);
-#endif /* SIGTSTP */
-
-#if defined (SIGTTOU)
- rl_sigaction (SIGTTOU, &old_ttou, &dummy);
-#endif /* SIGTTOU */
-
-#if defined (SIGTTIN)
- rl_sigaction (SIGTTIN, &old_ttin, &dummy);
-#endif /* SIGTTIN */
-
- signals_set_flag = 0;
- }
-
-#if defined (SIGWINCH)
- if (rl_catch_sigwinch && sigwinch_set_flag == 1)
- {
- sigemptyset (&dummy.sa_mask);
- rl_sigaction (SIGWINCH, &old_winch, &dummy);
- sigwinch_set_flag = 0;
- }
-#endif
-
- return 0;
-}
-#endif /* !_WIN32 */
-
-/* Clean up the terminal and readline state after catching a signal, before
- resending it to the calling application. */
-void
-rl_cleanup_after_signal ()
-{
- _rl_clean_up_for_exit ();
- (*rl_deprep_term_function) ();
- rl_clear_signals ();
- rl_clear_pending_input ();
-}
-
-/* Reset the terminal and readline state after a signal handler returns. */
-void
-rl_reset_after_signal ()
-{
- (*rl_prep_term_function) (_rl_meta_flag);
- rl_set_signals ();
-}
-
-/* Free up the readline variable line state for the current line (undo list,
- any partial history entry, any keyboard macros in progress, and any
- numeric arguments in process) after catching a signal, before calling
- rl_cleanup_after_signal(). */
-void
-rl_free_line_state ()
-{
- register HIST_ENTRY *entry;
-
- rl_free_undo_list ();
-
- entry = current_history ();
- if (entry)
- entry->data = (char *)NULL;
-
- _rl_kill_kbd_macro ();
- rl_clear_message ();
- _rl_init_argument ();
-}
-
-#if defined _WIN32
-
-#include <windows.h>
-#include <signal.h>
-#include <stdio.h>
-
-/* Handling of CTRL_C_EVENT, CTRL_CLOSE_EVENT, CTRL_BREAK_EVENT, CTRL_LOGOFF_EVENT, CTRL_SHUTDOWN_EVENT,
- WINDOW_BUFFER_SIZE_EVENTs are handled separately see input.c */
-
-BOOL CtrlEventHandler(DWORD dwEventType)
- {
- if (dwEventType == CTRL_C_EVENT)
- rl_free_line_state ();
- rl_cleanup_after_signal ();
- if (dwEventType == CTRL_C_EVENT) /* special treatment */
- {
- if (rl_catch_signals == 1) /* > 1: handled only locally */
- {
- raise(SIGINT); /* pass to program signal hadler */
- rl_reset_after_signal(); /* on return goon */
- }
- return TRUE; /* don't pass to upstream handlers */
- }
- return FALSE; /* pass other events to handler chain */
-}
-
-int
-rl_set_signals ()
-{
- if (rl_catch_signals && signals_set_flag == 0)
- signals_set_flag = SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlEventHandler, TRUE);
- return signals_set_flag;
-}
-
-int
-rl_clear_signals ()
-{
- if ( signals_set_flag )
- if ( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlEventHandler, FALSE) )
- signals_set_flag = 0;
- return signals_set_flag;
-}
-
-#endif /* _WIN32 */
-#endif /* HANDLE_SIGNALS */
-
+/* signals.c -- signal handling support for readline. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <stdio.h> /* Just for NULL. Yuck. */
+#include <sys/types.h>
+#include <signal.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+#if defined (GWINSZ_IN_SYS_IOCTL)
+# include <sys/ioctl.h>
+#endif /* GWINSZ_IN_SYS_IOCTL */
+
+#if defined (HANDLE_SIGNALS)
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+
+#if !defined (RETSIGTYPE)
+# if defined (VOID_SIGHANDLER)
+# define RETSIGTYPE void
+# else
+# define RETSIGTYPE int
+# endif /* !VOID_SIGHANDLER */
+#endif /* !RETSIGTYPE */
+
+#if defined (VOID_SIGHANDLER)
+# define SIGHANDLER_RETURN return
+#else
+# define SIGHANDLER_RETURN return (0)
+#endif
+
+/* This typedef is equivalent to the one for Function; it allows us
+ to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
+typedef RETSIGTYPE SigHandler ();
+
+#if defined (HAVE_POSIX_SIGNALS)
+typedef struct sigaction sighandler_cxt;
+# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
+#else
+typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
+# define sigemptyset(m)
+#endif /* !HAVE_POSIX_SIGNALS */
+
+static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
+static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
+
+/* Exported variables for use by applications. */
+
+/* If non-zero, readline will install its own signal handlers for
+ SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
+int rl_catch_signals = 1;
+
+/* If non-zero, readline will install a signal handler for SIGWINCH. */
+#ifdef SIGWINCH
+int rl_catch_sigwinch = 1;
+#endif
+
+static int signals_set_flag;
+
+#if !defined _WIN32 /* Win32 "signals" at end of file */
+static int sigwinch_set_flag;
+
+/* **************************************************************** */
+/* */
+/* Signal Handling */
+/* */
+/* **************************************************************** */
+
+static sighandler_cxt old_int, old_term, old_alrm, old_quit;
+#if defined (SIGTSTP)
+static sighandler_cxt old_tstp, old_ttou, old_ttin;
+#endif
+#if defined (SIGWINCH)
+static sighandler_cxt old_winch;
+#endif
+
+/* Readline signal handler functions. */
+
+static RETSIGTYPE
+rl_signal_handler (sig)
+ int sig;
+{
+#if defined (HAVE_POSIX_SIGNALS)
+ sigset_t set;
+#else /* !HAVE_POSIX_SIGNALS */
+# if defined (HAVE_BSD_SIGNALS)
+ long omask;
+# else /* !HAVE_BSD_SIGNALS */
+ sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */
+# endif /* !HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+ RL_SETSTATE(RL_STATE_SIGHANDLER);
+
+#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
+ /* Since the signal will not be blocked while we are in the signal
+ handler, ignore it until rl_clear_signals resets the catcher. */
+ if (sig == SIGINT || sig == SIGALRM)
+ rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
+#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
+
+ switch (sig)
+ {
+ case SIGINT:
+ rl_free_line_state ();
+ /* FALLTHROUGH */
+
+#if defined (SIGTSTP)
+ case SIGTSTP:
+ case SIGTTOU:
+ case SIGTTIN:
+#endif /* SIGTSTP */
+ case SIGALRM:
+ case SIGTERM:
+ case SIGQUIT:
+ rl_cleanup_after_signal ();
+
+#if defined (HAVE_POSIX_SIGNALS)
+ sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
+ sigdelset (&set, sig);
+#else /* !HAVE_POSIX_SIGNALS */
+# if defined (HAVE_BSD_SIGNALS)
+ omask = sigblock (0);
+# endif /* HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+#if defined (__EMX__)
+ signal (sig, SIG_ACK);
+#endif
+
+ kill (getpid (), sig);
+
+ /* Let the signal that we just sent through. */
+#if defined (HAVE_POSIX_SIGNALS)
+ sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
+#else /* !HAVE_POSIX_SIGNALS */
+# if defined (HAVE_BSD_SIGNALS)
+ sigsetmask (omask & ~(sigmask (sig)));
+# endif /* HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+ rl_reset_after_signal ();
+ }
+
+ RL_UNSETSTATE(RL_STATE_SIGHANDLER);
+ SIGHANDLER_RETURN;
+}
+
+#if defined (SIGWINCH)
+static RETSIGTYPE
+rl_sigwinch_handler (sig)
+ int sig;
+{
+ SigHandler *oh;
+
+#if defined (MUST_REINSTALL_SIGHANDLERS)
+ sighandler_cxt dummy_winch;
+
+ /* We don't want to change old_winch -- it holds the state of SIGWINCH
+ disposition set by the calling application. We need this state
+ because we call the application's SIGWINCH handler after updating
+ our own idea of the screen size. */
+ rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
+#endif
+
+ RL_SETSTATE(RL_STATE_SIGHANDLER);
+ rl_resize_terminal ();
+
+ /* If another sigwinch handler has been installed, call it. */
+ oh = (SigHandler *)old_winch.sa_handler;
+ if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
+ (*oh) (sig);
+
+ RL_UNSETSTATE(RL_STATE_SIGHANDLER);
+ SIGHANDLER_RETURN;
+}
+#endif /* SIGWINCH */
+
+/* Functions to manage signal handling. */
+
+#if !defined (HAVE_POSIX_SIGNALS)
+static int
+rl_sigaction (sig, nh, oh)
+ int sig;
+ sighandler_cxt *nh, *oh;
+{
+ oh->sa_handler = signal (sig, nh->sa_handler);
+ return 0;
+}
+#endif /* !HAVE_POSIX_SIGNALS */
+
+/* Set up a readline-specific signal handler, saving the old signal
+ information in OHANDLER. Return the old signal handler, like
+ signal(). */
+static SigHandler *
+rl_set_sighandler (sig, handler, ohandler)
+ int sig;
+ SigHandler *handler;
+ sighandler_cxt *ohandler;
+{
+ sighandler_cxt old_handler;
+#if defined (HAVE_POSIX_SIGNALS)
+ struct sigaction act;
+
+ act.sa_handler = handler;
+ act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */
+ sigemptyset (&act.sa_mask);
+ sigemptyset (&ohandler->sa_mask);
+ sigaction (sig, &act, &old_handler);
+#else
+ old_handler.sa_handler = (SigHandler *)signal (sig, handler);
+#endif /* !HAVE_POSIX_SIGNALS */
+
+ /* XXX -- assume we have memcpy */
+ /* If rl_set_signals is called twice in a row, don't set the old handler to
+ rl_signal_handler, because that would cause infinite recursion. */
+ if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
+ memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
+
+ return (ohandler->sa_handler);
+}
+
+static void
+rl_maybe_set_sighandler (sig, handler, ohandler)
+ int sig;
+ SigHandler *handler;
+ sighandler_cxt *ohandler;
+{
+ sighandler_cxt dummy;
+ SigHandler *oh;
+
+ sigemptyset (&dummy.sa_mask);
+ oh = rl_set_sighandler (sig, handler, ohandler);
+ if (oh == (SigHandler *)SIG_IGN)
+ rl_sigaction (sig, ohandler, &dummy);
+}
+
+int
+rl_set_signals ()
+{
+ sighandler_cxt dummy;
+ SigHandler *oh;
+
+ if (rl_catch_signals && signals_set_flag == 0)
+ {
+ rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
+ rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
+ rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
+
+ oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
+ if (oh == (SigHandler *)SIG_IGN)
+ rl_sigaction (SIGALRM, &old_alrm, &dummy);
+#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
+ /* If the application using readline has already installed a signal
+ handler with SA_RESTART, SIGALRM will cause reads to be restarted
+ automatically, so readline should just get out of the way. Since
+ we tested for SIG_IGN above, we can just test for SIG_DFL here. */
+ if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
+ rl_sigaction (SIGALRM, &old_alrm, &dummy);
+#endif /* HAVE_POSIX_SIGNALS */
+
+#if defined (SIGTSTP)
+ rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
+#endif /* SIGTSTP */
+
+#if defined (SIGTTOU)
+ rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
+#endif /* SIGTTOU */
+
+#if defined (SIGTTIN)
+ rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
+#endif /* SIGTTIN */
+
+ signals_set_flag = 1;
+ }
+
+#if defined (SIGWINCH)
+ if (rl_catch_sigwinch && sigwinch_set_flag == 0)
+ {
+ rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
+ sigwinch_set_flag = 1;
+ }
+#endif /* SIGWINCH */
+
+ return 0;
+}
+
+int
+rl_clear_signals ()
+{
+ sighandler_cxt dummy;
+
+ if (rl_catch_signals && signals_set_flag == 1)
+ {
+ sigemptyset (&dummy.sa_mask);
+
+ rl_sigaction (SIGINT, &old_int, &dummy);
+ rl_sigaction (SIGTERM, &old_term, &dummy);
+ rl_sigaction (SIGQUIT, &old_quit, &dummy);
+ rl_sigaction (SIGALRM, &old_alrm, &dummy);
+
+#if defined (SIGTSTP)
+ rl_sigaction (SIGTSTP, &old_tstp, &dummy);
+#endif /* SIGTSTP */
+
+#if defined (SIGTTOU)
+ rl_sigaction (SIGTTOU, &old_ttou, &dummy);
+#endif /* SIGTTOU */
+
+#if defined (SIGTTIN)
+ rl_sigaction (SIGTTIN, &old_ttin, &dummy);
+#endif /* SIGTTIN */
+
+ signals_set_flag = 0;
+ }
+
+#if defined (SIGWINCH)
+ if (rl_catch_sigwinch && sigwinch_set_flag == 1)
+ {
+ sigemptyset (&dummy.sa_mask);
+ rl_sigaction (SIGWINCH, &old_winch, &dummy);
+ sigwinch_set_flag = 0;
+ }
+#endif
+
+ return 0;
+}
+#endif /* !_WIN32 */
+
+/* Clean up the terminal and readline state after catching a signal, before
+ resending it to the calling application. */
+void
+rl_cleanup_after_signal ()
+{
+ _rl_clean_up_for_exit ();
+ (*rl_deprep_term_function) ();
+ rl_clear_signals ();
+ rl_clear_pending_input ();
+}
+
+/* Reset the terminal and readline state after a signal handler returns. */
+void
+rl_reset_after_signal ()
+{
+ (*rl_prep_term_function) (_rl_meta_flag);
+ rl_set_signals ();
+}
+
+/* Free up the readline variable line state for the current line (undo list,
+ any partial history entry, any keyboard macros in progress, and any
+ numeric arguments in process) after catching a signal, before calling
+ rl_cleanup_after_signal(). */
+void
+rl_free_line_state ()
+{
+ register HIST_ENTRY *entry;
+
+ rl_free_undo_list ();
+
+ entry = current_history ();
+ if (entry)
+ entry->data = (char *)NULL;
+
+ _rl_kill_kbd_macro ();
+ rl_clear_message ();
+ _rl_init_argument ();
+}
+
+#if defined _WIN32
+
+#include <windows.h>
+#include <signal.h>
+#include <stdio.h>
+
+/* Handling of CTRL_C_EVENT, CTRL_CLOSE_EVENT, CTRL_BREAK_EVENT, CTRL_LOGOFF_EVENT, CTRL_SHUTDOWN_EVENT,
+ WINDOW_BUFFER_SIZE_EVENTs are handled separately see input.c */
+
+BOOL CtrlEventHandler(DWORD dwEventType)
+ {
+ if (dwEventType == CTRL_C_EVENT)
+ rl_free_line_state ();
+ rl_cleanup_after_signal ();
+ if (dwEventType == CTRL_C_EVENT) /* special treatment */
+ {
+ if (rl_catch_signals == 1) /* > 1: handled only locally */
+ {
+ raise(SIGINT); /* pass to program signal hadler */
+ rl_reset_after_signal(); /* on return goon */
+ }
+ return TRUE; /* don't pass to upstream handlers */
+ }
+ return FALSE; /* pass other events to handler chain */
+}
+
+int
+rl_set_signals ()
+{
+ if (rl_catch_signals && signals_set_flag == 0)
+ signals_set_flag = SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlEventHandler, TRUE);
+ return signals_set_flag;
+}
+
+int
+rl_clear_signals ()
+{
+ if ( signals_set_flag )
+ if ( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlEventHandler, FALSE) )
+ signals_set_flag = 0;
+ return signals_set_flag;
+}
+
+#endif /* _WIN32 */
+#endif /* HANDLE_SIGNALS */
+
diff --git a/MSVC/readline/tcap.h b/MSVC/readline/tcap.h
index a245b27..e0bd213 100644
--- a/MSVC/readline/tcap.h
+++ b/MSVC/readline/tcap.h
@@ -1,58 +1,58 @@
-/* tcap.h -- termcap library functions and variables. */
-
-/* Copyright (C) 1996 Free Software Foundation, Inc.
-
- This file contains the Readline Library (the Library), a set of
- routines for providing Emacs style line input to programs that ask
- for it.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_RLTCAP_H_)
-#define _RLTCAP_H_
-
-#include "config.h"
-
-#if defined (HAVE_TERMCAP_H)
-# if defined (__linux__) && !defined (SPEED_T_IN_SYS_TYPES)
-# include "rltty.h"
-# endif
-# include <termcap.h>
-#else
-
-/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC.
- Unfortunately, PC is a global variable used by the termcap library. */
-#ifdef PC
-# undef PC
-#endif
-
-extern char PC;
-extern char *UP, *BC;
-
-extern short ospeed;
-
-extern int tgetent ();
-extern int tgetflag ();
-extern int tgetnum ();
-extern char *tgetstr ();
-
-extern int tputs ();
-
-extern char *tgoto ();
-
-#endif /* HAVE_TERMCAP_H */
-
-#endif /* !_RLTCAP_H_ */
+/* tcap.h -- termcap library functions and variables. */
+
+/* Copyright (C) 1996 Free Software Foundation, Inc.
+
+ This file contains the Readline Library (the Library), a set of
+ routines for providing Emacs style line input to programs that ask
+ for it.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_RLTCAP_H_)
+#define _RLTCAP_H_
+
+#include "config.h"
+
+#if defined (HAVE_TERMCAP_H)
+# if defined (__linux__) && !defined (SPEED_T_IN_SYS_TYPES)
+# include "rltty.h"
+# endif
+# include <termcap.h>
+#else
+
+/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC.
+ Unfortunately, PC is a global variable used by the termcap library. */
+#ifdef PC
+# undef PC
+#endif
+
+extern char PC;
+extern char *UP, *BC;
+
+extern short ospeed;
+
+extern int tgetent ();
+extern int tgetflag ();
+extern int tgetnum ();
+extern char *tgetstr ();
+
+extern int tputs ();
+
+extern char *tgoto ();
+
+#endif /* HAVE_TERMCAP_H */
+
+#endif /* !_RLTCAP_H_ */
diff --git a/MSVC/readline/terminal.c b/MSVC/readline/terminal.c
index d4ae524..b080a88 100644
--- a/MSVC/readline/terminal.c
+++ b/MSVC/readline/terminal.c
@@ -1,807 +1,807 @@
-/* terminal.c -- controlling the terminal with termcap. */
-
-/* Copyright (C) 1996 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-#include "posixstat.h"
-#include <fcntl.h>
-#if defined (HAVE_SYS_FILE_H)
-# include <sys/file.h>
-#endif /* HAVE_SYS_FILE_H */
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_LOCALE_H)
-# include <locale.h>
-#endif
-
-#include <stdio.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-
-#if defined _WIN32
-# include <windows.h>
- void _rl_output_some_chars ();
- extern int haveConsole; /* imported from rltty.c */
- extern HANDLE hStdout, hStdin;
- #if defined (WITH_MINI_MOUSE)
- extern COORD rlScreenEnd;
- extern int rlScreenMax;
- #endif /* WITH_MINI_MOUSE */
-#else /* !_WIN32 */
-# if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
-# include <sys/ioctl.h>
-# endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
-
-# include "rltty.h"
-# include "tcap.h"
-#endif /* !_WIN32 */
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "rlshell.h"
-#include "xmalloc.h"
-
-#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
-#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
-
-/* Functions imported from display.c */
-extern void _rl_redisplay_after_sigwinch ();
-
-/* **************************************************************** */
-/* */
-/* Terminal and Termcap */
-/* */
-/* **************************************************************** */
-
-#if !defined _WIN32
-static char *term_buffer = (char *)NULL;
-static char *term_string_buffer = (char *)NULL;
-
-static int tcap_initialized;
-#endif /* !_WIN32 */
-
-#if !defined (__linux__)
-# if defined (__EMX__) || defined (NEED_EXTERN_PC)
-extern
-# endif /* __EMX__ || NEED_EXTERN_PC */
-char PC, *BC, *UP;
-#endif /* __linux__ */
-
-/* Some strings to control terminal actions. These are output by tputs (). */
-char *_rl_term_clreol;
-char *_rl_term_clrpag;
-char *_rl_term_cr;
-char *_rl_term_backspace;
-char *_rl_term_goto;
-char *_rl_term_pc;
-
-/* Non-zero if we determine that the terminal can do character insertion. */
-int _rl_terminal_can_insert = 0;
-
-/* How to insert characters. */
-char *_rl_term_im;
-char *_rl_term_ei;
-char *_rl_term_ic;
-char *_rl_term_ip;
-char *_rl_term_IC;
-
-/* How to delete characters. */
-char *_rl_term_dc;
-char *_rl_term_DC;
-
-#if defined (HACK_TERMCAP_MOTION)
-char *_rl_term_forward_char;
-#endif /* HACK_TERMCAP_MOTION */
-
-/* How to go up a line. */
-char *_rl_term_up;
-
-/* A visible bell; char if the terminal can be made to flash the screen. */
-static char *_rl_visible_bell;
-
-/* Non-zero means the terminal can auto-wrap lines. */
-int _rl_term_autowrap;
-
-/* Non-zero means that this terminal has a meta key. */
-static int term_has_meta;
-
-/* The sequences to write to turn on and off the meta key, if this
- terminal has one. */
-static char *_rl_term_mm;
-static char *_rl_term_mo;
-
-/* The key sequences output by the arrow keys, if this terminal has any. */
-static char *_rl_term_ku;
-static char *_rl_term_kd;
-static char *_rl_term_kr;
-static char *_rl_term_kl;
-
-/* How to initialize and reset the arrow keys, if this terminal has any. */
-static char *_rl_term_ks;
-static char *_rl_term_ke;
-
-/* The key sequences sent by the Home and End keys, if any. */
-static char *_rl_term_kh;
-static char *_rl_term_kH;
-static char *_rl_term_at7; /* @7 */
-
-/* Insert key */
-static char *_rl_term_kI;
-
-/* Cursor control */
-static char *_rl_term_vs; /* very visible */
-static char *_rl_term_ve; /* normal */
-
-static void bind_termcap_arrow_keys PARAMS((Keymap));
-
-/* Variables that hold the screen dimensions, used by the display code. */
-int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
-
-/* Non-zero means the user wants to enable the keypad. */
-int _rl_enable_keypad;
-
-/* Non-zero means the user wants to enable a meta key. */
-int _rl_enable_meta = 1;
-
-#if defined (__EMX__)
-static void
-_emx_get_screensize (swp, shp)
- int *swp, *shp;
-{
- int sz[2];
-
- _scrsize (sz);
-
- if (swp)
- *swp = sz[0];
- if (shp)
- *shp = sz[1];
-}
-#endif
-
-/* Get readline's idea of the screen size. TTY is a file descriptor open
- to the terminal. If IGNORE_ENV is true, we do not pay attention to the
- values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being
- non-null serve to check whether or not we have initialized termcap. */
-#if !defined _WIN32
-void
-_rl_get_screen_size (tty, ignore_env)
- int tty, ignore_env;
-{
- char *ss;
-#if defined (TIOCGWINSZ)
- struct winsize window_size;
-#endif /* TIOCGWINSZ */
-
-#if defined (TIOCGWINSZ)
- if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
- {
- _rl_screenwidth = (int) window_size.ws_col;
- _rl_screenheight = (int) window_size.ws_row;
- }
-#endif /* TIOCGWINSZ */
-
-#if defined (__EMX__)
- _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
-#endif
-
- /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
- is unset. */
- if (_rl_screenwidth <= 0)
- {
- if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
- _rl_screenwidth = atoi (ss);
-
-#if !defined (__DJGPP__)
- if (_rl_screenwidth <= 0 && term_string_buffer)
- _rl_screenwidth = tgetnum ("co");
-#endif
- }
-
- /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
- is unset. */
- if (_rl_screenheight <= 0)
- {
- if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
- _rl_screenheight = atoi (ss);
-
-#if !defined (__DJGPP__)
- if (_rl_screenheight <= 0 && term_string_buffer)
- _rl_screenheight = tgetnum ("li");
-#endif
- }
-
- /* If all else fails, default to 80x24 terminal. */
- if (_rl_screenwidth <= 1)
- _rl_screenwidth = 80;
-
- if (_rl_screenheight <= 0)
- _rl_screenheight = 24;
-
- /* If we're being compiled as part of bash, set the environment
- variables $LINES and $COLUMNS to new values. Otherwise, just
- do a pair of putenv () or setenv () calls. */
- sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
-
- if (_rl_term_autowrap == 0)
- _rl_screenwidth--;
-
- _rl_screenchars = _rl_screenwidth * _rl_screenheight;
-}
-#else /* _WIN32*/
-void
-_rl_get_screen_size (tty, ignore_env)
- int tty, ignore_env __attribute__((unused));
-{
- CONSOLE_SCREEN_BUFFER_INFO csbi;
-
- if ( (haveConsole & FOR_OUTPUT) && GetConsoleScreenBufferInfo(hStdout, &csbi) )
- {
- _rl_screenwidth = csbi.dwSize.X;
- _rl_screenheight = csbi.dwSize.Y;
- }
- else
- {
- _rl_screenwidth = 80;
- _rl_screenheight = 24;
- }
- _rl_screenchars = _rl_screenwidth * _rl_screenheight;
-}
-#endif /* _WIN32 */
-
-void
-_rl_set_screen_size (rows, cols)
- int rows, cols;
-{
- if (rows == 0 || cols == 0)
- return;
-
- _rl_screenheight = rows;
- _rl_screenwidth = cols;
-
- if (_rl_term_autowrap == 0)
- _rl_screenwidth--;
-
- _rl_screenchars = _rl_screenwidth * _rl_screenheight;
-}
-
-void
-rl_set_screen_size (rows, cols)
- int rows, cols;
-{
- _rl_set_screen_size (rows, cols);
-}
-
-void
-rl_get_screen_size (rows, cols)
- int *rows, *cols;
-{
- if (rows)
- *rows = _rl_screenheight;
- if (cols)
- *cols = _rl_screenwidth;
-}
-
-void
-rl_resize_terminal ()
-{
- if (readline_echoing_p)
- {
- _rl_get_screen_size (fileno (rl_instream), 1);
- if (CUSTOM_REDISPLAY_FUNC ())
- rl_forced_update_display ();
- else
- _rl_redisplay_after_sigwinch ();
- }
-}
-
-#if !defined _WIN32 /* for a Win32 console we set capabilities directly */
-
-struct _tc_string {
- const char *tc_var;
- char **tc_value;
-};
-
-/* This should be kept sorted, just in case we decide to change the
- search algorithm to something smarter. */
-static struct _tc_string tc_strings[] =
-{
- { "@7", &_rl_term_at7 },
- { "DC", &_rl_term_DC },
- { "IC", &_rl_term_IC },
- { "ce", &_rl_term_clreol },
- { "cl", &_rl_term_clrpag },
- { "cr", &_rl_term_cr },
- { "dc", &_rl_term_dc },
- { "ei", &_rl_term_ei },
- { "ic", &_rl_term_ic },
- { "im", &_rl_term_im },
- { "kH", &_rl_term_kH }, /* home down ?? */
- { "kI", &_rl_term_kI }, /* insert */
- { "kd", &_rl_term_kd },
- { "ke", &_rl_term_ke }, /* end keypad mode */
- { "kh", &_rl_term_kh }, /* home */
- { "kl", &_rl_term_kl },
- { "kr", &_rl_term_kr },
- { "ks", &_rl_term_ks }, /* start keypad mode */
- { "ku", &_rl_term_ku },
- { "le", &_rl_term_backspace },
- { "mm", &_rl_term_mm },
- { "mo", &_rl_term_mo },
-#if defined (HACK_TERMCAP_MOTION)
- { "nd", &_rl_term_forward_char },
-#endif
- { "pc", &_rl_term_pc },
- { "up", &_rl_term_up },
- { "vb", &_rl_visible_bell },
- { "vs", &_rl_term_vs },
- { "ve", &_rl_term_ve },
-};
-
-#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
-
-/* Read the desired terminal capability strings into BP. The capabilities
- are described in the TC_STRINGS table. */
-static void
-get_term_capabilities (bp)
- char **bp;
-{
-#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */
- register int i;
-
- for (i = 0; i < NUM_TC_STRINGS; i++)
-# ifdef __LCC__
- *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
-# else
- *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
-# endif
-#endif
- tcap_initialized = 1;
-}
-#endif /* !_WIN32 */
-
-int
-_rl_init_terminal_io (terminal_name)
- const char *terminal_name;
-{
-#if defined _WIN32
- _rl_term_cr = "\r"; /* any value != 0 */
- _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL; /* !! we emulate insertion */
- _rl_term_up = "y"; /* any value != 0 */
- _rl_term_dc = _rl_term_DC = (char *)NULL; /* !! we emulate deletion */
- _rl_visible_bell = (char *)NULL;
-
- _rl_get_screen_size (0, 1);
-
- /* Let Windows handle meta keys! */
- term_has_meta = 0;
- _rl_term_mm = _rl_term_mo = (char *)NULL;
-
- /* It probably has arrow keys, but I don't know what they are. */
- _rl_term_ku = _rl_term_kd = _rl_term_kr = _rl_term_kl = (char *)NULL;
-
-#if defined (HACK_TERMCAP_MOTION)
- term_forward_char = (char *)NULL;
-#endif /* HACK_TERMCAP_MOTION */
-
- _rl_terminal_can_insert = 0;
- _rl_term_autowrap = 1;
-#else
- const char *term;
- char *buffer;
- int tty, tgetent_ret;
-
- term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
- _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
- tty = rl_instream ? fileno (rl_instream) : 0;
- _rl_screenwidth = _rl_screenheight = 0;
-
- if (term == 0)
- term = "dumb";
-
- /* I've separated this out for later work on not calling tgetent at all
- if the calling application has supplied a custom redisplay function,
- (and possibly if the application has supplied a custom input function). */
- if (CUSTOM_REDISPLAY_FUNC())
- {
- tgetent_ret = -1;
- }
- else
- {
- if (term_string_buffer == 0)
- term_string_buffer = (char *)xmalloc(2032);
-
- if (term_buffer == 0)
- term_buffer = (char *)xmalloc(4080);
-
- buffer = term_string_buffer;
-
- tgetent_ret = tgetent (term_buffer, term);
- }
-
- if (tgetent_ret <= 0)
- {
- FREE (term_string_buffer);
- FREE (term_buffer);
- buffer = term_buffer = term_string_buffer = (char *)NULL;
-
- _rl_term_autowrap = 0; /* used by _rl_get_screen_size */
-
-#if defined (__EMX__)
- _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
- _rl_screenwidth--;
-#else /* !__EMX__ */
- _rl_get_screen_size (tty, 0);
-#endif /* !__EMX__ */
-
- /* Defaults. */
- if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
- {
- _rl_screenwidth = 79;
- _rl_screenheight = 24;
- }
-
- /* Everything below here is used by the redisplay code (tputs). */
- _rl_screenchars = _rl_screenwidth * _rl_screenheight;
- _rl_term_cr = "\r";
- _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
- _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
- _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
- _rl_term_kh = _rl_term_kH = _rl_term_kI = (char *)NULL;
- _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
- _rl_term_mm = _rl_term_mo = (char *)NULL;
- _rl_term_ve = _rl_term_vs = (char *)NULL;
-#if defined (HACK_TERMCAP_MOTION)
- term_forward_char = (char *)NULL;
-#endif
- _rl_terminal_can_insert = term_has_meta = 0;
-
- /* Reasonable defaults for tgoto(). Readline currently only uses
- tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
- change that later... */
- PC = '\0';
- BC = _rl_term_backspace = "\b";
- UP = _rl_term_up;
-
- return 0;
- }
-
- get_term_capabilities (&buffer);
-
- /* Set up the variables that the termcap library expects the application
- to provide. */
- PC = _rl_term_pc ? *_rl_term_pc : 0;
- BC = _rl_term_backspace;
- UP = _rl_term_up;
-
- if (!_rl_term_cr)
- _rl_term_cr = "\r";
-
- _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
-
- _rl_get_screen_size (tty, 0);
-
- /* "An application program can assume that the terminal can do
- character insertion if *any one of* the capabilities `IC',
- `im', `ic' or `ip' is provided." But we can't do anything if
- only `ip' is provided, so... */
- _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
-
- /* Check to see if this terminal has a meta key and clear the capability
- variables if there is none. */
- term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
- if (!term_has_meta)
- _rl_term_mm = _rl_term_mo = (char *)NULL;
-
- /* Attempt to find and bind the arrow keys. Do not override already
- bound keys in an overzealous attempt, however. */
-
- bind_termcap_arrow_keys (emacs_standard_keymap);
-
-#if defined (VI_MODE)
- bind_termcap_arrow_keys (vi_movement_keymap);
- bind_termcap_arrow_keys (vi_insertion_keymap);
-#endif /* VI_MODE */
-#endif /* !_WIN32 */
-
- return 0;
-}
-
-/* Bind the arrow key sequences from the termcap description in MAP. */
-static void
-bind_termcap_arrow_keys (map)
- Keymap map;
-{
- Keymap xkeymap;
-
- xkeymap = _rl_keymap;
- _rl_keymap = map;
-
- _rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
- _rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
- _rl_bind_if_unbound (_rl_term_kr, rl_forward);
- _rl_bind_if_unbound (_rl_term_kl, rl_backward);
-
- _rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
- _rl_bind_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
-
- _rl_keymap = xkeymap;
-}
-
-#if !defined _WIN32
-char *
-rl_get_termcap (cap)
- const char *cap;
-{
- register int i;
-
- if (tcap_initialized == 0)
- return ((char *)NULL);
- for (i = 0; i < NUM_TC_STRINGS; i++)
- {
- if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
- return *(tc_strings[i].tc_value);
- }
- return ((char *)NULL);
-}
-#endif /* !_WIN32 */
-
-/* Re-initialize the terminal considering that the TERM/TERMCAP variable
- has changed. */
-int
-rl_reset_terminal (terminal_name)
- const char *terminal_name;
-{
- _rl_init_terminal_io (terminal_name);
- return 0;
-}
-
-#if !defined _WIN32 /* Mingw's functions follow separately
- to avoid too many #if...s */
-/* A function for the use of tputs () */
-#ifdef _MINIX
-void
-_rl_output_character_function (c)
- int c;
-{
- putc (c, _rl_out_stream);
-}
-#else /* !_MINIX */
-int
-_rl_output_character_function (c)
- int c;
-{
- return putc (c, _rl_out_stream);
-}
-#endif /* !_MINIX */
-
-/* Write COUNT characters from STRING to the output stream. */
-void
-_rl_output_some_chars (string, count)
- const char *string;
- int count;
-{
- fwrite (string, 1, count, _rl_out_stream);
-}
-
-/* Move the cursor back. */
-int
-_rl_backspace (count)
- int count;
-{
- register int i;
-
- if (_rl_term_backspace)
- for (i = 0; i < count; i++)
- tputs (_rl_term_backspace, 1, _rl_output_character_function);
- else
- for (i = 0; i < count; i++)
- putc ('\b', _rl_out_stream);
- return 0;
-}
-
-/* Move to the start of the next line. */
-int
-rl_crlf ()
-{
-#if defined (NEW_TTY_DRIVER)
- if (_rl_term_cr)
- tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif /* NEW_TTY_DRIVER */
- putc ('\n', _rl_out_stream);
- return 0;
-}
-
-/* Ring the terminal bell. */
-int
-rl_ding ()
-{
- if (readline_echoing_p)
- {
- switch (_rl_bell_preference)
- {
- case NO_BELL:
- default:
- break;
- case VISIBLE_BELL:
- if (_rl_visible_bell)
- {
- tputs (_rl_visible_bell, 1, _rl_output_character_function);
- break;
- }
- /* FALLTHROUGH */
- case AUDIBLE_BELL:
- fprintf (stderr, "\007");
- fflush (stderr);
- break;
- }
- return (0);
- }
- return (-1);
-}
-
-#else /* _WIN32 */
-
-/* Write COUNT characters from STRING to the output stream. */
-void
-_rl_output_some_chars (string, count)
- const char *string;
- int count;
-{
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- fwrite (string, 1, count, _rl_out_stream);
- if ( (haveConsole & FOR_OUTPUT) && GetConsoleScreenBufferInfo(hStdout, &csbi) )
- {
- int linear_pos = (int)csbi.dwCursorPosition.Y * (int)csbi.dwSize.X
- + (int)csbi.dwCursorPosition.X;
-#if defined (WITH_MINI_MOUSE)
- if (linear_pos > rlScreenMax)
- {
- rlScreenEnd = csbi.dwCursorPosition;
- rlScreenMax = linear_pos;
- }
-#endif /* WITH_MINI_MOUSE */
- }
-}
-
-/* This is used to collect all putc output */
-int
-_rl_output_character_function (c)
- int c;
-{
- char cc = c;
- _rl_output_some_chars (&cc, 1);
- return 1;
-}
-
-/* Move the cursor back. */
-int
-_rl_backspace (count)
- int count;
-{
- CONSOLE_SCREEN_BUFFER_INFO csbi;
-
- if ( (haveConsole & FOR_OUTPUT) && GetConsoleScreenBufferInfo(hStdout, &csbi) )
- {
- while (count > csbi.dwCursorPosition.X)
- {
- --csbi.dwCursorPosition.Y;
- count -= csbi.dwCursorPosition.X + 1;
- csbi.dwCursorPosition.X = csbi.dwSize.X - 1;
- }
- csbi.dwCursorPosition.X -= count;
- SetConsoleCursorPosition(hStdout, csbi.dwCursorPosition);
- }
- return 0;
-}
-
-/* Move to the start of the next line. */
-int
-rl_crlf ()
-{
- _rl_output_some_chars ("\n", 1);
- return 0;
-}
-
-/* Ring the terminal bell. */
-int
-rl_ding ()
-{
- if (readline_echoing_p)
- {
- if (_rl_bell_preference != NO_BELL)
- MessageBeep(MB_OK);
- return (0);
- }
- return (-1);
-}
-#endif /* _WIN32 */
-
-/* **************************************************************** */
-/* */
-/* Controlling the Meta Key and Keypad */
-/* */
-/* **************************************************************** */
-
-void
-_rl_enable_meta_key ()
-{
-#if !defined (__DJGPP__) && !defined _WIN32
- if (term_has_meta && _rl_term_mm)
- tputs (_rl_term_mm, 1, _rl_output_character_function);
-#endif
-}
-
-void
-_rl_control_keypad (on)
- int on;
-{
-#if !defined (__DJGPP__) && !defined _WIN32
- if (on && _rl_term_ks)
- tputs (_rl_term_ks, 1, _rl_output_character_function);
- else if (!on && _rl_term_ke)
- tputs (_rl_term_ke, 1, _rl_output_character_function);
-#endif
-}
-
-/* **************************************************************** */
-/* */
-/* Controlling the Cursor */
-/* */
-/* **************************************************************** */
-
-/* Set the cursor appropriately depending on IM, which is one of the
- insert modes (insert or overwrite). Insert mode gets the normal
- cursor. Overwrite mode gets a very visible cursor. Only does
- anything if we have both capabilities. */
-void
-_rl_set_cursor (im, force)
- int im, force;
-{
-#if !defined (__DJGPP__) && !defined _WIN32
- if (_rl_term_ve && _rl_term_vs)
- {
- if (force || im != rl_insert_mode)
- {
- if (im == RL_IM_OVERWRITE)
- tputs (_rl_term_vs, 1, _rl_output_character_function);
- else
- tputs (_rl_term_ve, 1, _rl_output_character_function);
- }
- }
-#endif
-}
+/* terminal.c -- controlling the terminal with termcap. */
+
+/* Copyright (C) 1996 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+#include "posixstat.h"
+#include <fcntl.h>
+#if defined (HAVE_SYS_FILE_H)
+# include <sys/file.h>
+#endif /* HAVE_SYS_FILE_H */
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_LOCALE_H)
+# include <locale.h>
+#endif
+
+#include <stdio.h>
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+#if defined _WIN32
+# include <windows.h>
+ void _rl_output_some_chars ();
+ extern int haveConsole; /* imported from rltty.c */
+ extern HANDLE hStdout, hStdin;
+ #if defined (WITH_MINI_MOUSE)
+ extern COORD rlScreenEnd;
+ extern int rlScreenMax;
+ #endif /* WITH_MINI_MOUSE */
+#else /* !_WIN32 */
+# if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
+# include <sys/ioctl.h>
+# endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
+
+# include "rltty.h"
+# include "tcap.h"
+#endif /* !_WIN32 */
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "rlshell.h"
+#include "xmalloc.h"
+
+#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
+#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
+
+/* Functions imported from display.c */
+extern void _rl_redisplay_after_sigwinch ();
+
+/* **************************************************************** */
+/* */
+/* Terminal and Termcap */
+/* */
+/* **************************************************************** */
+
+#if !defined _WIN32
+static char *term_buffer = (char *)NULL;
+static char *term_string_buffer = (char *)NULL;
+
+static int tcap_initialized;
+#endif /* !_WIN32 */
+
+#if !defined (__linux__)
+# if defined (__EMX__) || defined (NEED_EXTERN_PC)
+extern
+# endif /* __EMX__ || NEED_EXTERN_PC */
+char PC, *BC, *UP;
+#endif /* __linux__ */
+
+/* Some strings to control terminal actions. These are output by tputs (). */
+char *_rl_term_clreol;
+char *_rl_term_clrpag;
+char *_rl_term_cr;
+char *_rl_term_backspace;
+char *_rl_term_goto;
+char *_rl_term_pc;
+
+/* Non-zero if we determine that the terminal can do character insertion. */
+int _rl_terminal_can_insert = 0;
+
+/* How to insert characters. */
+char *_rl_term_im;
+char *_rl_term_ei;
+char *_rl_term_ic;
+char *_rl_term_ip;
+char *_rl_term_IC;
+
+/* How to delete characters. */
+char *_rl_term_dc;
+char *_rl_term_DC;
+
+#if defined (HACK_TERMCAP_MOTION)
+char *_rl_term_forward_char;
+#endif /* HACK_TERMCAP_MOTION */
+
+/* How to go up a line. */
+char *_rl_term_up;
+
+/* A visible bell; char if the terminal can be made to flash the screen. */
+static char *_rl_visible_bell;
+
+/* Non-zero means the terminal can auto-wrap lines. */
+int _rl_term_autowrap;
+
+/* Non-zero means that this terminal has a meta key. */
+static int term_has_meta;
+
+/* The sequences to write to turn on and off the meta key, if this
+ terminal has one. */
+static char *_rl_term_mm;
+static char *_rl_term_mo;
+
+/* The key sequences output by the arrow keys, if this terminal has any. */
+static char *_rl_term_ku;
+static char *_rl_term_kd;
+static char *_rl_term_kr;
+static char *_rl_term_kl;
+
+/* How to initialize and reset the arrow keys, if this terminal has any. */
+static char *_rl_term_ks;
+static char *_rl_term_ke;
+
+/* The key sequences sent by the Home and End keys, if any. */
+static char *_rl_term_kh;
+static char *_rl_term_kH;
+static char *_rl_term_at7; /* @7 */
+
+/* Insert key */
+static char *_rl_term_kI;
+
+/* Cursor control */
+static char *_rl_term_vs; /* very visible */
+static char *_rl_term_ve; /* normal */
+
+static void bind_termcap_arrow_keys PARAMS((Keymap));
+
+/* Variables that hold the screen dimensions, used by the display code. */
+int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
+
+/* Non-zero means the user wants to enable the keypad. */
+int _rl_enable_keypad;
+
+/* Non-zero means the user wants to enable a meta key. */
+int _rl_enable_meta = 1;
+
+#if defined (__EMX__)
+static void
+_emx_get_screensize (swp, shp)
+ int *swp, *shp;
+{
+ int sz[2];
+
+ _scrsize (sz);
+
+ if (swp)
+ *swp = sz[0];
+ if (shp)
+ *shp = sz[1];
+}
+#endif
+
+/* Get readline's idea of the screen size. TTY is a file descriptor open
+ to the terminal. If IGNORE_ENV is true, we do not pay attention to the
+ values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being
+ non-null serve to check whether or not we have initialized termcap. */
+#if !defined _WIN32
+void
+_rl_get_screen_size (tty, ignore_env)
+ int tty, ignore_env;
+{
+ char *ss;
+#if defined (TIOCGWINSZ)
+ struct winsize window_size;
+#endif /* TIOCGWINSZ */
+
+#if defined (TIOCGWINSZ)
+ if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
+ {
+ _rl_screenwidth = (int) window_size.ws_col;
+ _rl_screenheight = (int) window_size.ws_row;
+ }
+#endif /* TIOCGWINSZ */
+
+#if defined (__EMX__)
+ _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
+#endif
+
+ /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
+ is unset. */
+ if (_rl_screenwidth <= 0)
+ {
+ if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
+ _rl_screenwidth = atoi (ss);
+
+#if !defined (__DJGPP__)
+ if (_rl_screenwidth <= 0 && term_string_buffer)
+ _rl_screenwidth = tgetnum ("co");
+#endif
+ }
+
+ /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
+ is unset. */
+ if (_rl_screenheight <= 0)
+ {
+ if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
+ _rl_screenheight = atoi (ss);
+
+#if !defined (__DJGPP__)
+ if (_rl_screenheight <= 0 && term_string_buffer)
+ _rl_screenheight = tgetnum ("li");
+#endif
+ }
+
+ /* If all else fails, default to 80x24 terminal. */
+ if (_rl_screenwidth <= 1)
+ _rl_screenwidth = 80;
+
+ if (_rl_screenheight <= 0)
+ _rl_screenheight = 24;
+
+ /* If we're being compiled as part of bash, set the environment
+ variables $LINES and $COLUMNS to new values. Otherwise, just
+ do a pair of putenv () or setenv () calls. */
+ sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
+
+ if (_rl_term_autowrap == 0)
+ _rl_screenwidth--;
+
+ _rl_screenchars = _rl_screenwidth * _rl_screenheight;
+}
+#else /* _WIN32*/
+void
+_rl_get_screen_size (tty, ignore_env)
+ int tty, ignore_env __attribute__((unused));
+{
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+ if ( (haveConsole & FOR_OUTPUT) && GetConsoleScreenBufferInfo(hStdout, &csbi) )
+ {
+ _rl_screenwidth = csbi.dwSize.X;
+ _rl_screenheight = csbi.dwSize.Y;
+ }
+ else
+ {
+ _rl_screenwidth = 80;
+ _rl_screenheight = 24;
+ }
+ _rl_screenchars = _rl_screenwidth * _rl_screenheight;
+}
+#endif /* _WIN32 */
+
+void
+_rl_set_screen_size (rows, cols)
+ int rows, cols;
+{
+ if (rows == 0 || cols == 0)
+ return;
+
+ _rl_screenheight = rows;
+ _rl_screenwidth = cols;
+
+ if (_rl_term_autowrap == 0)
+ _rl_screenwidth--;
+
+ _rl_screenchars = _rl_screenwidth * _rl_screenheight;
+}
+
+void
+rl_set_screen_size (rows, cols)
+ int rows, cols;
+{
+ _rl_set_screen_size (rows, cols);
+}
+
+void
+rl_get_screen_size (rows, cols)
+ int *rows, *cols;
+{
+ if (rows)
+ *rows = _rl_screenheight;
+ if (cols)
+ *cols = _rl_screenwidth;
+}
+
+void
+rl_resize_terminal ()
+{
+ if (readline_echoing_p)
+ {
+ _rl_get_screen_size (fileno (rl_instream), 1);
+ if (CUSTOM_REDISPLAY_FUNC ())
+ rl_forced_update_display ();
+ else
+ _rl_redisplay_after_sigwinch ();
+ }
+}
+
+#if !defined _WIN32 /* for a Win32 console we set capabilities directly */
+
+struct _tc_string {
+ const char *tc_var;
+ char **tc_value;
+};
+
+/* This should be kept sorted, just in case we decide to change the
+ search algorithm to something smarter. */
+static struct _tc_string tc_strings[] =
+{
+ { "@7", &_rl_term_at7 },
+ { "DC", &_rl_term_DC },
+ { "IC", &_rl_term_IC },
+ { "ce", &_rl_term_clreol },
+ { "cl", &_rl_term_clrpag },
+ { "cr", &_rl_term_cr },
+ { "dc", &_rl_term_dc },
+ { "ei", &_rl_term_ei },
+ { "ic", &_rl_term_ic },
+ { "im", &_rl_term_im },
+ { "kH", &_rl_term_kH }, /* home down ?? */
+ { "kI", &_rl_term_kI }, /* insert */
+ { "kd", &_rl_term_kd },
+ { "ke", &_rl_term_ke }, /* end keypad mode */
+ { "kh", &_rl_term_kh }, /* home */
+ { "kl", &_rl_term_kl },
+ { "kr", &_rl_term_kr },
+ { "ks", &_rl_term_ks }, /* start keypad mode */
+ { "ku", &_rl_term_ku },
+ { "le", &_rl_term_backspace },
+ { "mm", &_rl_term_mm },
+ { "mo", &_rl_term_mo },
+#if defined (HACK_TERMCAP_MOTION)
+ { "nd", &_rl_term_forward_char },
+#endif
+ { "pc", &_rl_term_pc },
+ { "up", &_rl_term_up },
+ { "vb", &_rl_visible_bell },
+ { "vs", &_rl_term_vs },
+ { "ve", &_rl_term_ve },
+};
+
+#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
+
+/* Read the desired terminal capability strings into BP. The capabilities
+ are described in the TC_STRINGS table. */
+static void
+get_term_capabilities (bp)
+ char **bp;
+{
+#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */
+ register int i;
+
+ for (i = 0; i < NUM_TC_STRINGS; i++)
+# ifdef __LCC__
+ *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
+# else
+ *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
+# endif
+#endif
+ tcap_initialized = 1;
+}
+#endif /* !_WIN32 */
+
+int
+_rl_init_terminal_io (terminal_name)
+ const char *terminal_name;
+{
+#if defined _WIN32
+ _rl_term_cr = "\r"; /* any value != 0 */
+ _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL; /* !! we emulate insertion */
+ _rl_term_up = "y"; /* any value != 0 */
+ _rl_term_dc = _rl_term_DC = (char *)NULL; /* !! we emulate deletion */
+ _rl_visible_bell = (char *)NULL;
+
+ _rl_get_screen_size (0, 1);
+
+ /* Let Windows handle meta keys! */
+ term_has_meta = 0;
+ _rl_term_mm = _rl_term_mo = (char *)NULL;
+
+ /* It probably has arrow keys, but I don't know what they are. */
+ _rl_term_ku = _rl_term_kd = _rl_term_kr = _rl_term_kl = (char *)NULL;
+
+#if defined (HACK_TERMCAP_MOTION)
+ term_forward_char = (char *)NULL;
+#endif /* HACK_TERMCAP_MOTION */
+
+ _rl_terminal_can_insert = 0;
+ _rl_term_autowrap = 1;
+#else
+ const char *term;
+ char *buffer;
+ int tty, tgetent_ret;
+
+ term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
+ _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
+ tty = rl_instream ? fileno (rl_instream) : 0;
+ _rl_screenwidth = _rl_screenheight = 0;
+
+ if (term == 0)
+ term = "dumb";
+
+ /* I've separated this out for later work on not calling tgetent at all
+ if the calling application has supplied a custom redisplay function,
+ (and possibly if the application has supplied a custom input function). */
+ if (CUSTOM_REDISPLAY_FUNC())
+ {
+ tgetent_ret = -1;
+ }
+ else
+ {
+ if (term_string_buffer == 0)
+ term_string_buffer = (char *)xmalloc(2032);
+
+ if (term_buffer == 0)
+ term_buffer = (char *)xmalloc(4080);
+
+ buffer = term_string_buffer;
+
+ tgetent_ret = tgetent (term_buffer, term);
+ }
+
+ if (tgetent_ret <= 0)
+ {
+ FREE (term_string_buffer);
+ FREE (term_buffer);
+ buffer = term_buffer = term_string_buffer = (char *)NULL;
+
+ _rl_term_autowrap = 0; /* used by _rl_get_screen_size */
+
+#if defined (__EMX__)
+ _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
+ _rl_screenwidth--;
+#else /* !__EMX__ */
+ _rl_get_screen_size (tty, 0);
+#endif /* !__EMX__ */
+
+ /* Defaults. */
+ if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
+ {
+ _rl_screenwidth = 79;
+ _rl_screenheight = 24;
+ }
+
+ /* Everything below here is used by the redisplay code (tputs). */
+ _rl_screenchars = _rl_screenwidth * _rl_screenheight;
+ _rl_term_cr = "\r";
+ _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
+ _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
+ _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
+ _rl_term_kh = _rl_term_kH = _rl_term_kI = (char *)NULL;
+ _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
+ _rl_term_mm = _rl_term_mo = (char *)NULL;
+ _rl_term_ve = _rl_term_vs = (char *)NULL;
+#if defined (HACK_TERMCAP_MOTION)
+ term_forward_char = (char *)NULL;
+#endif
+ _rl_terminal_can_insert = term_has_meta = 0;
+
+ /* Reasonable defaults for tgoto(). Readline currently only uses
+ tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
+ change that later... */
+ PC = '\0';
+ BC = _rl_term_backspace = "\b";
+ UP = _rl_term_up;
+
+ return 0;
+ }
+
+ get_term_capabilities (&buffer);
+
+ /* Set up the variables that the termcap library expects the application
+ to provide. */
+ PC = _rl_term_pc ? *_rl_term_pc : 0;
+ BC = _rl_term_backspace;
+ UP = _rl_term_up;
+
+ if (!_rl_term_cr)
+ _rl_term_cr = "\r";
+
+ _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
+
+ _rl_get_screen_size (tty, 0);
+
+ /* "An application program can assume that the terminal can do
+ character insertion if *any one of* the capabilities `IC',
+ `im', `ic' or `ip' is provided." But we can't do anything if
+ only `ip' is provided, so... */
+ _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
+
+ /* Check to see if this terminal has a meta key and clear the capability
+ variables if there is none. */
+ term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
+ if (!term_has_meta)
+ _rl_term_mm = _rl_term_mo = (char *)NULL;
+
+ /* Attempt to find and bind the arrow keys. Do not override already
+ bound keys in an overzealous attempt, however. */
+
+ bind_termcap_arrow_keys (emacs_standard_keymap);
+
+#if defined (VI_MODE)
+ bind_termcap_arrow_keys (vi_movement_keymap);
+ bind_termcap_arrow_keys (vi_insertion_keymap);
+#endif /* VI_MODE */
+#endif /* !_WIN32 */
+
+ return 0;
+}
+
+/* Bind the arrow key sequences from the termcap description in MAP. */
+static void
+bind_termcap_arrow_keys (map)
+ Keymap map;
+{
+ Keymap xkeymap;
+
+ xkeymap = _rl_keymap;
+ _rl_keymap = map;
+
+ _rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
+ _rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
+ _rl_bind_if_unbound (_rl_term_kr, rl_forward);
+ _rl_bind_if_unbound (_rl_term_kl, rl_backward);
+
+ _rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
+ _rl_bind_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
+
+ _rl_keymap = xkeymap;
+}
+
+#if !defined _WIN32
+char *
+rl_get_termcap (cap)
+ const char *cap;
+{
+ register int i;
+
+ if (tcap_initialized == 0)
+ return ((char *)NULL);
+ for (i = 0; i < NUM_TC_STRINGS; i++)
+ {
+ if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
+ return *(tc_strings[i].tc_value);
+ }
+ return ((char *)NULL);
+}
+#endif /* !_WIN32 */
+
+/* Re-initialize the terminal considering that the TERM/TERMCAP variable
+ has changed. */
+int
+rl_reset_terminal (terminal_name)
+ const char *terminal_name;
+{
+ _rl_init_terminal_io (terminal_name);
+ return 0;
+}
+
+#if !defined _WIN32 /* Mingw's functions follow separately
+ to avoid too many #if...s */
+/* A function for the use of tputs () */
+#ifdef _MINIX
+void
+_rl_output_character_function (c)
+ int c;
+{
+ putc (c, _rl_out_stream);
+}
+#else /* !_MINIX */
+int
+_rl_output_character_function (c)
+ int c;
+{
+ return putc (c, _rl_out_stream);
+}
+#endif /* !_MINIX */
+
+/* Write COUNT characters from STRING to the output stream. */
+void
+_rl_output_some_chars (string, count)
+ const char *string;
+ int count;
+{
+ fwrite (string, 1, count, _rl_out_stream);
+}
+
+/* Move the cursor back. */
+int
+_rl_backspace (count)
+ int count;
+{
+ register int i;
+
+ if (_rl_term_backspace)
+ for (i = 0; i < count; i++)
+ tputs (_rl_term_backspace, 1, _rl_output_character_function);
+ else
+ for (i = 0; i < count; i++)
+ putc ('\b', _rl_out_stream);
+ return 0;
+}
+
+/* Move to the start of the next line. */
+int
+rl_crlf ()
+{
+#if defined (NEW_TTY_DRIVER)
+ if (_rl_term_cr)
+ tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif /* NEW_TTY_DRIVER */
+ putc ('\n', _rl_out_stream);
+ return 0;
+}
+
+/* Ring the terminal bell. */
+int
+rl_ding ()
+{
+ if (readline_echoing_p)
+ {
+ switch (_rl_bell_preference)
+ {
+ case NO_BELL:
+ default:
+ break;
+ case VISIBLE_BELL:
+ if (_rl_visible_bell)
+ {
+ tputs (_rl_visible_bell, 1, _rl_output_character_function);
+ break;
+ }
+ /* FALLTHROUGH */
+ case AUDIBLE_BELL:
+ fprintf (stderr, "\007");
+ fflush (stderr);
+ break;
+ }
+ return (0);
+ }
+ return (-1);
+}
+
+#else /* _WIN32 */
+
+/* Write COUNT characters from STRING to the output stream. */
+void
+_rl_output_some_chars (string, count)
+ const char *string;
+ int count;
+{
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ fwrite (string, 1, count, _rl_out_stream);
+ if ( (haveConsole & FOR_OUTPUT) && GetConsoleScreenBufferInfo(hStdout, &csbi) )
+ {
+ int linear_pos = (int)csbi.dwCursorPosition.Y * (int)csbi.dwSize.X
+ + (int)csbi.dwCursorPosition.X;
+#if defined (WITH_MINI_MOUSE)
+ if (linear_pos > rlScreenMax)
+ {
+ rlScreenEnd = csbi.dwCursorPosition;
+ rlScreenMax = linear_pos;
+ }
+#endif /* WITH_MINI_MOUSE */
+ }
+}
+
+/* This is used to collect all putc output */
+int
+_rl_output_character_function (c)
+ int c;
+{
+ char cc = c;
+ _rl_output_some_chars (&cc, 1);
+ return 1;
+}
+
+/* Move the cursor back. */
+int
+_rl_backspace (count)
+ int count;
+{
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+ if ( (haveConsole & FOR_OUTPUT) && GetConsoleScreenBufferInfo(hStdout, &csbi) )
+ {
+ while (count > csbi.dwCursorPosition.X)
+ {
+ --csbi.dwCursorPosition.Y;
+ count -= csbi.dwCursorPosition.X + 1;
+ csbi.dwCursorPosition.X = csbi.dwSize.X - 1;
+ }
+ csbi.dwCursorPosition.X -= count;
+ SetConsoleCursorPosition(hStdout, csbi.dwCursorPosition);
+ }
+ return 0;
+}
+
+/* Move to the start of the next line. */
+int
+rl_crlf ()
+{
+ _rl_output_some_chars ("\n", 1);
+ return 0;
+}
+
+/* Ring the terminal bell. */
+int
+rl_ding ()
+{
+ if (readline_echoing_p)
+ {
+ if (_rl_bell_preference != NO_BELL)
+ MessageBeep(MB_OK);
+ return (0);
+ }
+ return (-1);
+}
+#endif /* _WIN32 */
+
+/* **************************************************************** */
+/* */
+/* Controlling the Meta Key and Keypad */
+/* */
+/* **************************************************************** */
+
+void
+_rl_enable_meta_key ()
+{
+#if !defined (__DJGPP__) && !defined _WIN32
+ if (term_has_meta && _rl_term_mm)
+ tputs (_rl_term_mm, 1, _rl_output_character_function);
+#endif
+}
+
+void
+_rl_control_keypad (on)
+ int on;
+{
+#if !defined (__DJGPP__) && !defined _WIN32
+ if (on && _rl_term_ks)
+ tputs (_rl_term_ks, 1, _rl_output_character_function);
+ else if (!on && _rl_term_ke)
+ tputs (_rl_term_ke, 1, _rl_output_character_function);
+#endif
+}
+
+/* **************************************************************** */
+/* */
+/* Controlling the Cursor */
+/* */
+/* **************************************************************** */
+
+/* Set the cursor appropriately depending on IM, which is one of the
+ insert modes (insert or overwrite). Insert mode gets the normal
+ cursor. Overwrite mode gets a very visible cursor. Only does
+ anything if we have both capabilities. */
+void
+_rl_set_cursor (im, force)
+ int im, force;
+{
+#if !defined (__DJGPP__) && !defined _WIN32
+ if (_rl_term_ve && _rl_term_vs)
+ {
+ if (force || im != rl_insert_mode)
+ {
+ if (im == RL_IM_OVERWRITE)
+ tputs (_rl_term_vs, 1, _rl_output_character_function);
+ else
+ tputs (_rl_term_ve, 1, _rl_output_character_function);
+ }
+ }
+#endif
+}
diff --git a/MSVC/readline/text.c b/MSVC/readline/text.c
index 309cc52..6272ba7 100644
--- a/MSVC/readline/text.c
+++ b/MSVC/readline/text.c
@@ -1,1538 +1,1538 @@
-/* text.c -- text handling commands for readline. */
-
-/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_LOCALE_H)
-# include <locale.h>
-#endif
-
-#include <stdio.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-#if defined (__EMX__)
-# define INCL_DOSPROCESS
-# include <os2.h>
-#endif /* __EMX__ */
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "rlshell.h"
-#include "xmalloc.h"
-
-/* Forward declarations. */
-static int rl_change_case PARAMS((int, int));
-static int _rl_char_search PARAMS((int, int, int));
-
-/* **************************************************************** */
-/* */
-/* Insert and Delete */
-/* */
-/* **************************************************************** */
-
-/* Insert a string of text into the line at point. This is the only
- way that you should do insertion. _rl_insert_char () calls this
- function. Returns the number of characters inserted. */
-int
-rl_insert_text (string)
- const char *string;
-{
- register int i, l;
-
- l = (string && *string) ? strlen (string) : 0;
- if (l == 0)
- return 0;
-
- if (rl_end + l >= rl_line_buffer_len)
- rl_extend_line_buffer (rl_end + l);
-
- for (i = rl_end; i >= rl_point; i--)
- rl_line_buffer[i + l] = rl_line_buffer[i];
- strncpy (rl_line_buffer + rl_point, string, l);
-
- /* Remember how to undo this if we aren't undoing something. */
- if (_rl_doing_an_undo == 0)
- {
- /* If possible and desirable, concatenate the undos. */
- if ((l == 1) &&
- rl_undo_list &&
- (rl_undo_list->what == UNDO_INSERT) &&
- (rl_undo_list->end == rl_point) &&
- (rl_undo_list->end - rl_undo_list->start < 20))
- rl_undo_list->end++;
- else
- rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
- }
- rl_point += l;
- rl_end += l;
- rl_line_buffer[rl_end] = '\0';
- return l;
-}
-
-/* Delete the string between FROM and TO. FROM is inclusive, TO is not.
- Returns the number of characters deleted. */
-int
-rl_delete_text (from, to)
- int from, to;
-{
- register char *text;
- register int diff, i;
-
- /* Fix it if the caller is confused. */
- if (from > to)
- SWAP (from, to);
-
- /* fix boundaries */
- if (to > rl_end)
- {
- to = rl_end;
- if (from > to)
- from = to;
- }
- if (from < 0)
- from = 0;
-
- text = rl_copy_text (from, to);
-
- /* Some versions of strncpy() can't handle overlapping arguments. */
- diff = to - from;
- for (i = from; i < rl_end - diff; i++)
- rl_line_buffer[i] = rl_line_buffer[i + diff];
-
- /* Remember how to undo this delete. */
- if (_rl_doing_an_undo == 0)
- rl_add_undo (UNDO_DELETE, from, to, text);
- else
- free (text);
-
- rl_end -= diff;
- rl_line_buffer[rl_end] = '\0';
- return (diff);
-}
-
-/* Fix up point so that it is within the line boundaries after killing
- text. If FIX_MARK_TOO is non-zero, the mark is forced within line
- boundaries also. */
-
-#define _RL_FIX_POINT(x) \
- do { \
- if (x > rl_end) \
- x = rl_end; \
- else if (x < 0) \
- x = 0; \
- } while (0)
-
-void
-_rl_fix_point (fix_mark_too)
- int fix_mark_too;
-{
- _RL_FIX_POINT (rl_point);
- if (fix_mark_too)
- _RL_FIX_POINT (rl_mark);
-}
-#undef _RL_FIX_POINT
-
-int
-_rl_replace_text (text, start, end)
- const char *text;
- int start, end;
-{
- int n;
-
- rl_begin_undo_group ();
- rl_delete_text (start, end + 1);
- rl_point = start;
- n = rl_insert_text (text);
- rl_end_undo_group ();
-
- return n;
-}
-
-/* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is
- non-zero, we free the current undo list. */
-void
-rl_replace_line (text, clear_undo)
- const char *text;
- int clear_undo;
-{
- int len;
-
- len = strlen (text);
- if (len >= rl_line_buffer_len)
- rl_extend_line_buffer (len);
- strcpy (rl_line_buffer, text);
- rl_end = len;
-
- if (clear_undo)
- rl_free_undo_list ();
-
- _rl_fix_point (1);
-}
-
-/* **************************************************************** */
-/* */
-/* Readline character functions */
-/* */
-/* **************************************************************** */
-
-/* This is not a gap editor, just a stupid line input routine. No hair
- is involved in writing any of the functions, and none should be. */
-
-/* Note that:
-
- rl_end is the place in the string that we would place '\0';
- i.e., it is always safe to place '\0' there.
-
- rl_point is the place in the string where the cursor is. Sometimes
- this is the same as rl_end.
-
- Any command that is called interactively receives two arguments.
- The first is a count: the numeric arg pased to this command.
- The second is the key which invoked this command.
-*/
-
-/* **************************************************************** */
-/* */
-/* Movement Commands */
-/* */
-/* **************************************************************** */
-
-/* Note that if you `optimize' the display for these functions, you cannot
- use said functions in other functions which do not do optimizing display.
- I.e., you will have to update the data base for rl_redisplay, and you
- might as well let rl_redisplay do that job. */
-
-/* Move forward COUNT bytes. */
-int
-rl_forward_byte (count, key)
- int count, key;
-{
- if (count < 0)
- return (rl_backward_byte (-count, key));
-
- if (count > 0)
- {
- int end = rl_point + count;
-#if defined (VI_MODE)
- int lend = rl_end > 0 ? rl_end - (rl_editing_mode == vi_mode) : rl_end;
-#else
- int lend = rl_end;
-#endif
-
- if (end > lend)
- {
- rl_point = lend;
- rl_ding ();
- }
- else
- rl_point = end;
- }
-
- if (rl_end < 0)
- rl_end = 0;
-
- return 0;
-}
-
-#if defined (HANDLE_MULTIBYTE)
-/* Move forward COUNT characters. */
-int
-rl_forward_char (count, key)
- int count, key;
-{
- int point;
-
- if (MB_CUR_MAX == 1 || rl_byte_oriented)
- return (rl_forward_byte (count, key));
-
- if (count < 0)
- return (rl_backward_char (-count, key));
-
- if (count > 0)
- {
- point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
-
-#if defined (VI_MODE)
- if (rl_end <= point && rl_editing_mode == vi_mode)
- point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
-#endif
-
- if (rl_point == point)
- rl_ding ();
-
- rl_point = point;
-
- if (rl_end < 0)
- rl_end = 0;
- }
-
- return 0;
-}
-#else /* !HANDLE_MULTIBYTE */
-int
-rl_forward_char (count, key)
- int count, key;
-{
- return (rl_forward_byte (count, key));
-}
-#endif /* !HANDLE_MULTIBYTE */
-
-/* Backwards compatibility. */
-int
-rl_forward (count, key)
- int count, key;
-{
- return (rl_forward_char (count, key));
-}
-
-/* Move backward COUNT bytes. */
-int
-rl_backward_byte (count, key)
- int count, key;
-{
- if (count < 0)
- return (rl_forward_byte (-count, key));
-
- if (count > 0)
- {
- if (rl_point < count)
- {
- rl_point = 0;
- rl_ding ();
- }
- else
- rl_point -= count;
- }
-
- if (rl_point < 0)
- rl_point = 0;
-
- return 0;
-}
-
-#if defined (HANDLE_MULTIBYTE)
-/* Move backward COUNT characters. */
-int
-rl_backward_char (count, key)
- int count, key;
-{
- int point;
-
- if (MB_CUR_MAX == 1 || rl_byte_oriented)
- return (rl_backward_byte (count, key));
-
- if (count < 0)
- return (rl_forward_char (-count, key));
-
- if (count > 0)
- {
- point = rl_point;
-
- while (count > 0 && point > 0)
- {
- point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
- count--;
- }
- if (count > 0)
- {
- rl_point = 0;
- rl_ding ();
- }
- else
- rl_point = point;
- }
-
- return 0;
-}
-#else
-int
-rl_backward_char (count, key)
- int count, key;
-{
- return (rl_backward_byte (count, key));
-}
-#endif
-
-/* Backwards compatibility. */
-int
-rl_backward (count, key)
- int count, key;
-{
- return (rl_backward_char (count, key));
-}
-
-/* Move to the beginning of the line. */
-int
-rl_beg_of_line (count, key)
- int count, key;
-{
- rl_point = 0;
- return 0;
-}
-
-/* Move to the end of the line. */
-int
-rl_end_of_line (count, key)
- int count, key;
-{
- rl_point = rl_end;
- return 0;
-}
-
-/* XXX - these might need changes for multibyte characters */
-/* Move forward a word. We do what Emacs does. */
-int
-rl_forward_word (count, key)
- int count, key;
-{
- int c;
-
- if (count < 0)
- return (rl_backward_word (-count, key));
-
- while (count)
- {
- if (rl_point == rl_end)
- return 0;
-
- /* If we are not in a word, move forward until we are in one.
- Then, move forward until we hit a non-alphabetic character. */
- c = rl_line_buffer[rl_point];
- if (rl_alphabetic (c) == 0)
- {
- while (++rl_point < rl_end)
- {
- c = rl_line_buffer[rl_point];
- if (rl_alphabetic (c))
- break;
- }
- }
-
- if (rl_point == rl_end)
- return 0;
-
- while (++rl_point < rl_end)
- {
- c = rl_line_buffer[rl_point];
- if (rl_alphabetic (c) == 0)
- break;
- }
- --count;
- }
-
- return 0;
-}
-
-/* Move backward a word. We do what Emacs does. */
-int
-rl_backward_word (count, key)
- int count, key;
-{
- int c;
-
- if (count < 0)
- return (rl_forward_word (-count, key));
-
- while (count)
- {
- if (!rl_point)
- return 0;
-
- /* Like rl_forward_word (), except that we look at the characters
- just before point. */
-
- c = rl_line_buffer[rl_point - 1];
- if (rl_alphabetic (c) == 0)
- {
- while (--rl_point)
- {
- c = rl_line_buffer[rl_point - 1];
- if (rl_alphabetic (c))
- break;
- }
- }
-
- while (rl_point)
- {
- c = rl_line_buffer[rl_point - 1];
- if (rl_alphabetic (c) == 0)
- break;
- else
- --rl_point;
- }
-
- --count;
- }
-
- return 0;
-}
-
-/* Clear the current line. Numeric argument to C-l does this. */
-int
-rl_refresh_line (ignore1, ignore2)
- int ignore1, ignore2;
-{
- int curr_line;
-
- curr_line = _rl_current_display_line ();
-
- _rl_move_vert (curr_line);
- _rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */
-
- _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */
-
- rl_forced_update_display ();
- rl_display_fixed = 1;
-
- return 0;
-}
-
-/* C-l typed to a line without quoting clears the screen, and then reprints
- the prompt and the current input line. Given a numeric arg, redraw only
- the current line. */
-int
-rl_clear_screen (count, key)
- int count, key;
-{
- if (rl_explicit_arg)
- {
- rl_refresh_line (count, key);
- return 0;
- }
-
- _rl_clear_screen (); /* calls termcap function to clear screen */
- rl_forced_update_display ();
- rl_display_fixed = 1;
-
- return 0;
-}
-
-int
-rl_arrow_keys (count, c)
- int count, c;
-{
- int ch;
-
- RL_SETSTATE(RL_STATE_MOREINPUT);
- ch = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
- switch (_rl_to_upper (ch))
- {
- case 'A':
- rl_get_previous_history (count, ch);
- break;
-
- case 'B':
- rl_get_next_history (count, ch);
- break;
-
- case 'C':
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- rl_forward_char (count, ch);
- else
- rl_forward_byte (count, ch);
- break;
-
- case 'D':
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- rl_backward_char (count, ch);
- else
- rl_backward_byte (count, ch);
- break;
-
- default:
- rl_ding ();
- }
-
- return 0;
-}
-
-/* **************************************************************** */
-/* */
-/* Text commands */
-/* */
-/* **************************************************************** */
-
-#ifdef HANDLE_MULTIBYTE
-static char pending_bytes[MB_LEN_MAX];
-static int pending_bytes_length = 0;
-static mbstate_t ps = {0};
-#endif
-
-/* Insert the character C at the current location, moving point forward.
- If C introduces a multibyte sequence, we read the whole sequence and
- then insert the multibyte char into the line buffer. */
-int
-_rl_insert_char (count, c)
- int count, c;
-{
- register int i;
- char *string;
-#ifdef HANDLE_MULTIBYTE
- int string_size;
- char incoming[MB_LEN_MAX + 1];
- int incoming_length = 0;
- mbstate_t ps_back;
- static int stored_count = 0;
-#endif
-
- if (count <= 0)
- return 0;
-
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX == 1 || rl_byte_oriented)
- {
- incoming[0] = c;
- incoming[1] = '\0';
- incoming_length = 1;
- }
- else
- {
- wchar_t wc;
- size_t ret;
-
- if (stored_count <= 0)
- stored_count = count;
- else
- count = stored_count;
-
- ps_back = ps;
- pending_bytes[pending_bytes_length++] = c;
- ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps);
-
- if (ret == (size_t)-2)
- {
- /* Bytes too short to compose character, try to wait for next byte.
- Restore the state of the byte sequence, because in this case the
- effect of mbstate is undefined. */
- ps = ps_back;
- return 1;
- }
- else if (ret == (size_t)-1)
- {
- /* Invalid byte sequence for the current locale. Treat first byte
- as a single character. */
- incoming[0] = pending_bytes[0];
- incoming[1] = '\0';
- incoming_length = 1;
- pending_bytes_length--;
- memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
- /* Clear the state of the byte sequence, because in this case the
- effect of mbstate is undefined. */
- memset (&ps, 0, sizeof (mbstate_t));
- }
- else if (ret == (size_t)0)
- {
- incoming[0] = '\0';
- incoming_length = 0;
- pending_bytes_length--;
- /* Clear the state of the byte sequence, because in this case the
- effect of mbstate is undefined. */
- memset (&ps, 0, sizeof (mbstate_t));
- }
- else
- {
- /* We successfully read a single multibyte character. */
- memcpy (incoming, pending_bytes, pending_bytes_length);
- incoming[pending_bytes_length] = '\0';
- incoming_length = pending_bytes_length;
- pending_bytes_length = 0;
- }
- }
-#endif /* HANDLE_MULTIBYTE */
-
- /* If we can optimize, then do it. But don't let people crash
- readline because of extra large arguments. */
- if (count > 1 && count <= 1024)
- {
-#if defined (HANDLE_MULTIBYTE)
- string_size = count * incoming_length;
- string = (char *)xmalloc (1 + string_size);
-
- i = 0;
- while (i < string_size)
- {
- strncpy (string + i, incoming, incoming_length);
- i += incoming_length;
- }
- incoming_length = 0;
- stored_count = 0;
-#else /* !HANDLE_MULTIBYTE */
- string = (char *)xmalloc (1 + count);
-
- for (i = 0; i < count; i++)
- string[i] = c;
-#endif /* !HANDLE_MULTIBYTE */
-
- string[i] = '\0';
- rl_insert_text (string);
- free (string);
-
- return 0;
- }
-
- if (count > 1024)
- {
- int decreaser;
-#if defined (HANDLE_MULTIBYTE)
- string_size = incoming_length * 1024;
- string = (char *)xmalloc (1 + string_size);
-
- i = 0;
- while (i < string_size)
- {
- strncpy (string + i, incoming, incoming_length);
- i += incoming_length;
- }
-
- while (count)
- {
- decreaser = (count > 1024) ? 1024 : count;
- string[decreaser*incoming_length] = '\0';
- rl_insert_text (string);
- count -= decreaser;
- }
-
- free (string);
- incoming_length = 0;
- stored_count = 0;
-#else /* !HANDLE_MULTIBYTE */
- char str[1024+1];
-
- for (i = 0; i < 1024; i++)
- str[i] = c;
-
- while (count)
- {
- decreaser = (count > 1024 ? 1024 : count);
- str[decreaser] = '\0';
- rl_insert_text (str);
- count -= decreaser;
- }
-#endif /* !HANDLE_MULTIBYTE */
-
- return 0;
- }
-
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX == 1 || rl_byte_oriented)
- {
-#endif
- /* We are inserting a single character.
- If there is pending input, then make a string of all of the
- pending characters that are bound to rl_insert, and insert
- them all. */
- if (_rl_any_typein ())
- _rl_insert_typein (c);
- else
- {
- /* Inserting a single character. */
- char str[2];
-
- str[1] = '\0';
- str[0] = c;
- rl_insert_text (str);
- }
-#if defined (HANDLE_MULTIBYTE)
- }
- else
- {
- rl_insert_text (incoming);
- stored_count = 0;
- }
-#endif
-
- return 0;
-}
-
-/* Overwrite the character at point (or next COUNT characters) with C.
- If C introduces a multibyte character sequence, read the entire sequence
- before starting the overwrite loop. */
-int
-_rl_overwrite_char (count, c)
- int count, c;
-{
- int i;
-#if defined (HANDLE_MULTIBYTE)
- char mbkey[MB_LEN_MAX];
- int k;
-
- /* Read an entire multibyte character sequence to insert COUNT times. */
- if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
-#endif
-
- for (i = 0; i < count; i++)
- {
- rl_begin_undo_group ();
-
- if (rl_point < rl_end)
- rl_delete (1, c);
-
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- rl_insert_text (mbkey);
- else
-#endif
- _rl_insert_char (1, c);
-
- rl_end_undo_group ();
- }
-
- return 0;
-}
-
-int
-rl_insert (count, c)
- int count, c;
-{
- return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c)
- : _rl_overwrite_char (count, c));
-}
-
-/* Insert the next typed character verbatim. */
-int
-rl_quoted_insert (count, key)
- int count, key;
-{
- int c;
-
-#if defined (HANDLE_SIGNALS)
- _rl_disable_tty_signals ();
-#endif
-
- RL_SETSTATE(RL_STATE_MOREINPUT);
- c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
-#if defined (HANDLE_SIGNALS)
- _rl_restore_tty_signals ();
-#endif
-
- return (_rl_insert_char (count, c));
-}
-
-/* Insert a tab character. */
-int
-rl_tab_insert (count, key)
- int count, key;
-{
- return (_rl_insert_char (count, '\t'));
-}
-
-/* What to do when a NEWLINE is pressed. We accept the whole line.
- KEY is the key that invoked this command. I guess it could have
- meaning in the future. */
-int
-rl_newline (count, key)
- int count, key;
-{
- rl_done = 1;
-
- if (_rl_history_preserve_point)
- _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
-
- RL_SETSTATE(RL_STATE_DONE);
-
-#if defined (VI_MODE)
- if (rl_editing_mode == vi_mode)
- {
- _rl_vi_done_inserting ();
- _rl_vi_reset_last ();
- }
-#endif /* VI_MODE */
-
- /* If we've been asked to erase empty lines, suppress the final update,
- since _rl_update_final calls rl_crlf(). */
- if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
- return 0;
-
- if (readline_echoing_p)
- _rl_update_final ();
- return 0;
-}
-
-/* What to do for some uppercase characters, like meta characters,
- and some characters appearing in emacs_ctlx_keymap. This function
- is just a stub, you bind keys to it and the code in _rl_dispatch ()
- is special cased. */
-int
-rl_do_lowercase_version (ignore1, ignore2)
- int ignore1, ignore2;
-{
- return 0;
-}
-
-/* This is different from what vi does, so the code's not shared. Emacs
- rubout in overwrite mode has one oddity: it replaces a control
- character that's displayed as two characters (^X) with two spaces. */
-int
-_rl_overwrite_rubout (count, key)
- int count, key;
-{
- int opoint;
- int i, l;
-
- if (rl_point == 0)
- {
- rl_ding ();
- return 1;
- }
-
- opoint = rl_point;
-
- /* L == number of spaces to insert */
- for (i = l = 0; i < count; i++)
- {
- rl_backward_char (1, key);
- l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */
- }
-
- rl_begin_undo_group ();
-
- if (count > 1 || rl_explicit_arg)
- rl_kill_text (opoint, rl_point);
- else
- rl_delete_text (opoint, rl_point);
-
- /* Emacs puts point at the beginning of the sequence of spaces. */
- opoint = rl_point;
- _rl_insert_char (l, ' ');
- rl_point = opoint;
-
- rl_end_undo_group ();
-
- return 0;
-}
-
-/* Rubout the character behind point. */
-int
-rl_rubout (count, key)
- int count, key;
-{
- if (count < 0)
- return (rl_delete (-count, key));
-
- if (!rl_point)
- {
- rl_ding ();
- return -1;
- }
-
- if (rl_insert_mode == RL_IM_OVERWRITE)
- return (_rl_overwrite_rubout (count, key));
-
- return (_rl_rubout_char (count, key));
-}
-
-int
-_rl_rubout_char (count, key)
- int count, key;
-{
- int orig_point;
- unsigned char c;
-
- /* Duplicated code because this is called from other parts of the library. */
- if (count < 0)
- return (rl_delete (-count, key));
-
- if (rl_point == 0)
- {
- rl_ding ();
- return -1;
- }
-
- if (count > 1 || rl_explicit_arg)
- {
- orig_point = rl_point;
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- rl_backward_char (count, key);
- else
-#endif
- rl_backward_byte (count, key);
- rl_kill_text (orig_point, rl_point);
- }
- else
- {
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX == 1 || rl_byte_oriented)
- {
-#endif
- c = rl_line_buffer[--rl_point];
- rl_delete_text (rl_point, rl_point + 1);
-#if defined (HANDLE_MULTIBYTE)
- }
- else
- {
- int orig_point;
-
- orig_point = rl_point;
- rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
- c = rl_line_buffer[rl_point];
- rl_delete_text (rl_point, orig_point);
- }
-#endif /* HANDLE_MULTIBYTE */
-
- /* I don't think that the hack for end of line is needed for
- multibyte chars. */
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX == 1 || rl_byte_oriented)
-#endif
- if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
- {
- int l;
- l = rl_character_len (c, rl_point);
- _rl_erase_at_end_of_line (l);
- }
- }
-
- return 0;
-}
-
-/* Delete the character under the cursor. Given a numeric argument,
- kill that many characters instead. */
-int
-rl_delete (count, key)
- int count, key;
-{
- int r;
-
- if (count < 0)
- return (_rl_rubout_char (-count, key));
-
- if (rl_point == rl_end)
- {
- rl_ding ();
- return -1;
- }
-
- if (count > 1 || rl_explicit_arg)
- {
- int orig_point = rl_point;
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- rl_forward_char (count, key);
- else
-#endif
- rl_forward_byte (count, key);
-
- r = rl_kill_text (orig_point, rl_point);
- rl_point = orig_point;
- return r;
- }
- else
- {
- int new_point;
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- new_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
- else
- new_point = rl_point + 1;
-
- return (rl_delete_text (rl_point, new_point));
- }
-}
-
-/* Delete the character under the cursor, unless the insertion
- point is at the end of the line, in which case the character
- behind the cursor is deleted. COUNT is obeyed and may be used
- to delete forward or backward that many characters. */
-int
-rl_rubout_or_delete (count, key)
- int count, key;
-{
- if (rl_end != 0 && rl_point == rl_end)
- return (_rl_rubout_char (count, key));
- else
- return (rl_delete (count, key));
-}
-
-/* Delete all spaces and tabs around point. */
-int
-rl_delete_horizontal_space (count, ignore)
- int count, ignore;
-{
- int start = rl_point;
-
- while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
- rl_point--;
-
- start = rl_point;
-
- while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
- rl_point++;
-
- if (start != rl_point)
- {
- rl_delete_text (start, rl_point);
- rl_point = start;
- }
- return 0;
-}
-
-/* Like the tcsh editing function delete-char-or-list. The eof character
- is caught before this is invoked, so this really does the same thing as
- delete-char-or-list-or-eof, as long as it's bound to the eof character. */
-int
-rl_delete_or_show_completions (count, key)
- int count, key;
-{
- if (rl_end != 0 && rl_point == rl_end)
- return (rl_possible_completions (count, key));
- else
- return (rl_delete (count, key));
-}
-
-#ifndef RL_COMMENT_BEGIN_DEFAULT
-#define RL_COMMENT_BEGIN_DEFAULT "#"
-#endif
-
-/* Turn the current line into a comment in shell history.
- A K*rn shell style function. */
-int
-rl_insert_comment (count, key)
- int count, key;
-{
- char *rl_comment_text;
- int rl_comment_len;
-
- rl_beg_of_line (1, key);
- rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
-
- if (rl_explicit_arg == 0)
- rl_insert_text (rl_comment_text);
- else
- {
- rl_comment_len = strlen (rl_comment_text);
- if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
- rl_delete_text (rl_point, rl_point + rl_comment_len);
- else
- rl_insert_text (rl_comment_text);
- }
-
- (*rl_redisplay_function) ();
- rl_newline (1, '\n');
-
- return (0);
-}
-
-/* **************************************************************** */
-/* */
-/* Changing Case */
-/* */
-/* **************************************************************** */
-
-/* The three kinds of things that we know how to do. */
-#define UpCase 1
-#define DownCase 2
-#define CapCase 3
-
-/* Uppercase the word at point. */
-int
-rl_upcase_word (count, key)
- int count, key;
-{
- return (rl_change_case (count, UpCase));
-}
-
-/* Lowercase the word at point. */
-int
-rl_downcase_word (count, key)
- int count, key;
-{
- return (rl_change_case (count, DownCase));
-}
-
-/* Upcase the first letter, downcase the rest. */
-int
-rl_capitalize_word (count, key)
- int count, key;
-{
- return (rl_change_case (count, CapCase));
-}
-
-/* The meaty function.
- Change the case of COUNT words, performing OP on them.
- OP is one of UpCase, DownCase, or CapCase.
- If a negative argument is given, leave point where it started,
- otherwise, leave it where it moves to. */
-static int
-rl_change_case (count, op)
- int count, op;
-{
- register int start, end;
- int inword, c;
-
- start = rl_point;
- rl_forward_word (count, 0);
- end = rl_point;
-
- if (count < 0)
- SWAP (start, end);
-
- /* We are going to modify some text, so let's prepare to undo it. */
- rl_modifying (start, end);
-
- for (inword = 0; start < end; start++)
- {
- c = rl_line_buffer[start];
- switch (op)
- {
- case UpCase:
- rl_line_buffer[start] = _rl_to_upper (c);
- break;
-
- case DownCase:
- rl_line_buffer[start] = _rl_to_lower (c);
- break;
-
- case CapCase:
- rl_line_buffer[start] = (inword == 0) ? _rl_to_upper (c) : _rl_to_lower (c);
- inword = rl_alphabetic (rl_line_buffer[start]);
- break;
-
- default:
- rl_ding ();
- return -1;
- }
- }
- rl_point = end;
- return 0;
-}
-
-/* **************************************************************** */
-/* */
-/* Transposition */
-/* */
-/* **************************************************************** */
-
-/* Transpose the words at point. If point is at the end of the line,
- transpose the two words before point. */
-int
-rl_transpose_words (count, key)
- int count, key;
-{
- char *word1, *word2;
- int w1_beg, w1_end, w2_beg, w2_end;
- int orig_point = rl_point;
-
- if (!count)
- return 0;
-
- /* Find the two words. */
- rl_forward_word (count, key);
- w2_end = rl_point;
- rl_backward_word (1, key);
- w2_beg = rl_point;
- rl_backward_word (count, key);
- w1_beg = rl_point;
- rl_forward_word (1, key);
- w1_end = rl_point;
-
- /* Do some check to make sure that there really are two words. */
- if ((w1_beg == w2_beg) || (w2_beg < w1_end))
- {
- rl_ding ();
- rl_point = orig_point;
- return -1;
- }
-
- /* Get the text of the words. */
- word1 = rl_copy_text (w1_beg, w1_end);
- word2 = rl_copy_text (w2_beg, w2_end);
-
- /* We are about to do many insertions and deletions. Remember them
- as one operation. */
- rl_begin_undo_group ();
-
- /* Do the stuff at word2 first, so that we don't have to worry
- about word1 moving. */
- rl_point = w2_beg;
- rl_delete_text (w2_beg, w2_end);
- rl_insert_text (word1);
-
- rl_point = w1_beg;
- rl_delete_text (w1_beg, w1_end);
- rl_insert_text (word2);
-
- /* This is exactly correct since the text before this point has not
- changed in length. */
- rl_point = w2_end;
-
- /* I think that does it. */
- rl_end_undo_group ();
- free (word1);
- free (word2);
-
- return 0;
-}
-
-/* Transpose the characters at point. If point is at the end of the line,
- then transpose the characters before point. */
-int
-rl_transpose_chars (count, key)
- int count, key;
-{
-#if defined (HANDLE_MULTIBYTE)
- char *dummy;
- int i, prev_point;
-#else
- char dummy[2];
-#endif
- int char_length;
-
- if (count == 0)
- return 0;
-
- if (!rl_point || rl_end < 2)
- {
- rl_ding ();
- return -1;
- }
-
- rl_begin_undo_group ();
-
- if (rl_point == rl_end)
- {
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
- else
- --rl_point;
- count = 1;
- }
-
-#if defined (HANDLE_MULTIBYTE)
- prev_point = rl_point;
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
- else
-#endif
- rl_point--;
-
-#if defined (HANDLE_MULTIBYTE)
- char_length = prev_point - rl_point;
- dummy = (char *)xmalloc (char_length + 1);
- for (i = 0; i < char_length; i++)
- dummy[i] = rl_line_buffer[rl_point + i];
- dummy[i] = '\0';
-#else
- dummy[0] = rl_line_buffer[rl_point];
- dummy[char_length = 1] = '\0';
-#endif
-
- rl_delete_text (rl_point, rl_point + char_length);
-
- rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
-
- _rl_fix_point (0);
- rl_insert_text (dummy);
- rl_end_undo_group ();
-
-#if defined (HANDLE_MULTIBYTE)
- free (dummy);
-#endif
-
- return 0;
-}
-
-/* **************************************************************** */
-/* */
-/* Character Searching */
-/* */
-/* **************************************************************** */
-
-int
-#if defined (HANDLE_MULTIBYTE)
-_rl_char_search_internal (count, dir, smbchar, len)
- int count, dir;
- char *smbchar;
- int len;
-#else
-_rl_char_search_internal (count, dir, schar)
- int count, dir, schar;
-#endif
-{
- int pos, inc;
-#if defined (HANDLE_MULTIBYTE)
- int prepos;
-#endif
-
- pos = rl_point;
- inc = (dir < 0) ? -1 : 1;
- while (count)
- {
- if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
- {
- rl_ding ();
- return -1;
- }
-
-#if defined (HANDLE_MULTIBYTE)
- pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
- : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
-#else
- pos += inc;
-#endif
- do
- {
-#if defined (HANDLE_MULTIBYTE)
- if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
-#else
- if (rl_line_buffer[pos] == schar)
-#endif
- {
- count--;
- if (dir < 0)
- rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
- : pos;
- else
- rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
- : pos;
- break;
- }
-#if defined (HANDLE_MULTIBYTE)
- prepos = pos;
-#endif
- }
-#if defined (HANDLE_MULTIBYTE)
- while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
- : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
-#else
- while ((dir < 0) ? pos-- : ++pos < rl_end);
-#endif
- }
- return (0);
-}
-
-/* Search COUNT times for a character read from the current input stream.
- FDIR is the direction to search if COUNT is non-negative; otherwise
- the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE
- that there are two separate versions of this function. */
-#if defined (HANDLE_MULTIBYTE)
-static int
-_rl_char_search (count, fdir, bdir)
- int count, fdir, bdir;
-{
- char mbchar[MB_LEN_MAX];
- int mb_len;
-
- mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
-
- if (count < 0)
- return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
- else
- return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
-}
-#else /* !HANDLE_MULTIBYTE */
-static int
-_rl_char_search (count, fdir, bdir)
- int count, fdir, bdir;
-{
- int c;
-
- RL_SETSTATE(RL_STATE_MOREINPUT);
- c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
- if (count < 0)
- return (_rl_char_search_internal (-count, bdir, c));
- else
- return (_rl_char_search_internal (count, fdir, c));
-}
-#endif /* !HANDLE_MULTIBYTE */
-
-int
-rl_char_search (count, key)
- int count, key;
-{
- return (_rl_char_search (count, FFIND, BFIND));
-}
-
-int
-rl_backward_char_search (count, key)
- int count, key;
-{
- return (_rl_char_search (count, BFIND, FFIND));
-}
-
-/* **************************************************************** */
-/* */
-/* The Mark and the Region. */
-/* */
-/* **************************************************************** */
-
-/* Set the mark at POSITION. */
-int
-_rl_set_mark_at_pos (position)
- int position;
-{
- if (position > rl_end)
- return -1;
-
- rl_mark = position;
- return 0;
-}
-
-/* A bindable command to set the mark. */
-int
-rl_set_mark (count, key)
- int count, key;
-{
- return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
-}
-
-/* Exchange the position of mark and point. */
-int
-rl_exchange_point_and_mark (count, key)
- int count, key;
-{
- if (rl_mark > rl_end)
- rl_mark = -1;
-
- if (rl_mark == -1)
- {
- rl_ding ();
- return -1;
- }
- else
- SWAP (rl_point, rl_mark);
-
- return 0;
-}
+/* text.c -- text handling commands for readline. */
+
+/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_LOCALE_H)
+# include <locale.h>
+#endif
+
+#include <stdio.h>
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+#include "rlmbutil.h"
+
+#if defined (__EMX__)
+# define INCL_DOSPROCESS
+# include <os2.h>
+#endif /* __EMX__ */
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "rlshell.h"
+#include "xmalloc.h"
+
+/* Forward declarations. */
+static int rl_change_case PARAMS((int, int));
+static int _rl_char_search PARAMS((int, int, int));
+
+/* **************************************************************** */
+/* */
+/* Insert and Delete */
+/* */
+/* **************************************************************** */
+
+/* Insert a string of text into the line at point. This is the only
+ way that you should do insertion. _rl_insert_char () calls this
+ function. Returns the number of characters inserted. */
+int
+rl_insert_text (string)
+ const char *string;
+{
+ register int i, l;
+
+ l = (string && *string) ? strlen (string) : 0;
+ if (l == 0)
+ return 0;
+
+ if (rl_end + l >= rl_line_buffer_len)
+ rl_extend_line_buffer (rl_end + l);
+
+ for (i = rl_end; i >= rl_point; i--)
+ rl_line_buffer[i + l] = rl_line_buffer[i];
+ strncpy (rl_line_buffer + rl_point, string, l);
+
+ /* Remember how to undo this if we aren't undoing something. */
+ if (_rl_doing_an_undo == 0)
+ {
+ /* If possible and desirable, concatenate the undos. */
+ if ((l == 1) &&
+ rl_undo_list &&
+ (rl_undo_list->what == UNDO_INSERT) &&
+ (rl_undo_list->end == rl_point) &&
+ (rl_undo_list->end - rl_undo_list->start < 20))
+ rl_undo_list->end++;
+ else
+ rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
+ }
+ rl_point += l;
+ rl_end += l;
+ rl_line_buffer[rl_end] = '\0';
+ return l;
+}
+
+/* Delete the string between FROM and TO. FROM is inclusive, TO is not.
+ Returns the number of characters deleted. */
+int
+rl_delete_text (from, to)
+ int from, to;
+{
+ register char *text;
+ register int diff, i;
+
+ /* Fix it if the caller is confused. */
+ if (from > to)
+ SWAP (from, to);
+
+ /* fix boundaries */
+ if (to > rl_end)
+ {
+ to = rl_end;
+ if (from > to)
+ from = to;
+ }
+ if (from < 0)
+ from = 0;
+
+ text = rl_copy_text (from, to);
+
+ /* Some versions of strncpy() can't handle overlapping arguments. */
+ diff = to - from;
+ for (i = from; i < rl_end - diff; i++)
+ rl_line_buffer[i] = rl_line_buffer[i + diff];
+
+ /* Remember how to undo this delete. */
+ if (_rl_doing_an_undo == 0)
+ rl_add_undo (UNDO_DELETE, from, to, text);
+ else
+ free (text);
+
+ rl_end -= diff;
+ rl_line_buffer[rl_end] = '\0';
+ return (diff);
+}
+
+/* Fix up point so that it is within the line boundaries after killing
+ text. If FIX_MARK_TOO is non-zero, the mark is forced within line
+ boundaries also. */
+
+#define _RL_FIX_POINT(x) \
+ do { \
+ if (x > rl_end) \
+ x = rl_end; \
+ else if (x < 0) \
+ x = 0; \
+ } while (0)
+
+void
+_rl_fix_point (fix_mark_too)
+ int fix_mark_too;
+{
+ _RL_FIX_POINT (rl_point);
+ if (fix_mark_too)
+ _RL_FIX_POINT (rl_mark);
+}
+#undef _RL_FIX_POINT
+
+int
+_rl_replace_text (text, start, end)
+ const char *text;
+ int start, end;
+{
+ int n;
+
+ rl_begin_undo_group ();
+ rl_delete_text (start, end + 1);
+ rl_point = start;
+ n = rl_insert_text (text);
+ rl_end_undo_group ();
+
+ return n;
+}
+
+/* Replace the current line buffer contents with TEXT. If CLEAR_UNDO is
+ non-zero, we free the current undo list. */
+void
+rl_replace_line (text, clear_undo)
+ const char *text;
+ int clear_undo;
+{
+ int len;
+
+ len = strlen (text);
+ if (len >= rl_line_buffer_len)
+ rl_extend_line_buffer (len);
+ strcpy (rl_line_buffer, text);
+ rl_end = len;
+
+ if (clear_undo)
+ rl_free_undo_list ();
+
+ _rl_fix_point (1);
+}
+
+/* **************************************************************** */
+/* */
+/* Readline character functions */
+/* */
+/* **************************************************************** */
+
+/* This is not a gap editor, just a stupid line input routine. No hair
+ is involved in writing any of the functions, and none should be. */
+
+/* Note that:
+
+ rl_end is the place in the string that we would place '\0';
+ i.e., it is always safe to place '\0' there.
+
+ rl_point is the place in the string where the cursor is. Sometimes
+ this is the same as rl_end.
+
+ Any command that is called interactively receives two arguments.
+ The first is a count: the numeric arg pased to this command.
+ The second is the key which invoked this command.
+*/
+
+/* **************************************************************** */
+/* */
+/* Movement Commands */
+/* */
+/* **************************************************************** */
+
+/* Note that if you `optimize' the display for these functions, you cannot
+ use said functions in other functions which do not do optimizing display.
+ I.e., you will have to update the data base for rl_redisplay, and you
+ might as well let rl_redisplay do that job. */
+
+/* Move forward COUNT bytes. */
+int
+rl_forward_byte (count, key)
+ int count, key;
+{
+ if (count < 0)
+ return (rl_backward_byte (-count, key));
+
+ if (count > 0)
+ {
+ int end = rl_point + count;
+#if defined (VI_MODE)
+ int lend = rl_end > 0 ? rl_end - (rl_editing_mode == vi_mode) : rl_end;
+#else
+ int lend = rl_end;
+#endif
+
+ if (end > lend)
+ {
+ rl_point = lend;
+ rl_ding ();
+ }
+ else
+ rl_point = end;
+ }
+
+ if (rl_end < 0)
+ rl_end = 0;
+
+ return 0;
+}
+
+#if defined (HANDLE_MULTIBYTE)
+/* Move forward COUNT characters. */
+int
+rl_forward_char (count, key)
+ int count, key;
+{
+ int point;
+
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ return (rl_forward_byte (count, key));
+
+ if (count < 0)
+ return (rl_backward_char (-count, key));
+
+ if (count > 0)
+ {
+ point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
+
+#if defined (VI_MODE)
+ if (rl_end <= point && rl_editing_mode == vi_mode)
+ point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
+#endif
+
+ if (rl_point == point)
+ rl_ding ();
+
+ rl_point = point;
+
+ if (rl_end < 0)
+ rl_end = 0;
+ }
+
+ return 0;
+}
+#else /* !HANDLE_MULTIBYTE */
+int
+rl_forward_char (count, key)
+ int count, key;
+{
+ return (rl_forward_byte (count, key));
+}
+#endif /* !HANDLE_MULTIBYTE */
+
+/* Backwards compatibility. */
+int
+rl_forward (count, key)
+ int count, key;
+{
+ return (rl_forward_char (count, key));
+}
+
+/* Move backward COUNT bytes. */
+int
+rl_backward_byte (count, key)
+ int count, key;
+{
+ if (count < 0)
+ return (rl_forward_byte (-count, key));
+
+ if (count > 0)
+ {
+ if (rl_point < count)
+ {
+ rl_point = 0;
+ rl_ding ();
+ }
+ else
+ rl_point -= count;
+ }
+
+ if (rl_point < 0)
+ rl_point = 0;
+
+ return 0;
+}
+
+#if defined (HANDLE_MULTIBYTE)
+/* Move backward COUNT characters. */
+int
+rl_backward_char (count, key)
+ int count, key;
+{
+ int point;
+
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ return (rl_backward_byte (count, key));
+
+ if (count < 0)
+ return (rl_forward_char (-count, key));
+
+ if (count > 0)
+ {
+ point = rl_point;
+
+ while (count > 0 && point > 0)
+ {
+ point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
+ count--;
+ }
+ if (count > 0)
+ {
+ rl_point = 0;
+ rl_ding ();
+ }
+ else
+ rl_point = point;
+ }
+
+ return 0;
+}
+#else
+int
+rl_backward_char (count, key)
+ int count, key;
+{
+ return (rl_backward_byte (count, key));
+}
+#endif
+
+/* Backwards compatibility. */
+int
+rl_backward (count, key)
+ int count, key;
+{
+ return (rl_backward_char (count, key));
+}
+
+/* Move to the beginning of the line. */
+int
+rl_beg_of_line (count, key)
+ int count, key;
+{
+ rl_point = 0;
+ return 0;
+}
+
+/* Move to the end of the line. */
+int
+rl_end_of_line (count, key)
+ int count, key;
+{
+ rl_point = rl_end;
+ return 0;
+}
+
+/* XXX - these might need changes for multibyte characters */
+/* Move forward a word. We do what Emacs does. */
+int
+rl_forward_word (count, key)
+ int count, key;
+{
+ int c;
+
+ if (count < 0)
+ return (rl_backward_word (-count, key));
+
+ while (count)
+ {
+ if (rl_point == rl_end)
+ return 0;
+
+ /* If we are not in a word, move forward until we are in one.
+ Then, move forward until we hit a non-alphabetic character. */
+ c = rl_line_buffer[rl_point];
+ if (rl_alphabetic (c) == 0)
+ {
+ while (++rl_point < rl_end)
+ {
+ c = rl_line_buffer[rl_point];
+ if (rl_alphabetic (c))
+ break;
+ }
+ }
+
+ if (rl_point == rl_end)
+ return 0;
+
+ while (++rl_point < rl_end)
+ {
+ c = rl_line_buffer[rl_point];
+ if (rl_alphabetic (c) == 0)
+ break;
+ }
+ --count;
+ }
+
+ return 0;
+}
+
+/* Move backward a word. We do what Emacs does. */
+int
+rl_backward_word (count, key)
+ int count, key;
+{
+ int c;
+
+ if (count < 0)
+ return (rl_forward_word (-count, key));
+
+ while (count)
+ {
+ if (!rl_point)
+ return 0;
+
+ /* Like rl_forward_word (), except that we look at the characters
+ just before point. */
+
+ c = rl_line_buffer[rl_point - 1];
+ if (rl_alphabetic (c) == 0)
+ {
+ while (--rl_point)
+ {
+ c = rl_line_buffer[rl_point - 1];
+ if (rl_alphabetic (c))
+ break;
+ }
+ }
+
+ while (rl_point)
+ {
+ c = rl_line_buffer[rl_point - 1];
+ if (rl_alphabetic (c) == 0)
+ break;
+ else
+ --rl_point;
+ }
+
+ --count;
+ }
+
+ return 0;
+}
+
+/* Clear the current line. Numeric argument to C-l does this. */
+int
+rl_refresh_line (ignore1, ignore2)
+ int ignore1, ignore2;
+{
+ int curr_line;
+
+ curr_line = _rl_current_display_line ();
+
+ _rl_move_vert (curr_line);
+ _rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */
+
+ _rl_clear_to_eol (0); /* arg of 0 means to not use spaces */
+
+ rl_forced_update_display ();
+ rl_display_fixed = 1;
+
+ return 0;
+}
+
+/* C-l typed to a line without quoting clears the screen, and then reprints
+ the prompt and the current input line. Given a numeric arg, redraw only
+ the current line. */
+int
+rl_clear_screen (count, key)
+ int count, key;
+{
+ if (rl_explicit_arg)
+ {
+ rl_refresh_line (count, key);
+ return 0;
+ }
+
+ _rl_clear_screen (); /* calls termcap function to clear screen */
+ rl_forced_update_display ();
+ rl_display_fixed = 1;
+
+ return 0;
+}
+
+int
+rl_arrow_keys (count, c)
+ int count, c;
+{
+ int ch;
+
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ ch = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+ switch (_rl_to_upper (ch))
+ {
+ case 'A':
+ rl_get_previous_history (count, ch);
+ break;
+
+ case 'B':
+ rl_get_next_history (count, ch);
+ break;
+
+ case 'C':
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_forward_char (count, ch);
+ else
+ rl_forward_byte (count, ch);
+ break;
+
+ case 'D':
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_backward_char (count, ch);
+ else
+ rl_backward_byte (count, ch);
+ break;
+
+ default:
+ rl_ding ();
+ }
+
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Text commands */
+/* */
+/* **************************************************************** */
+
+#ifdef HANDLE_MULTIBYTE
+static char pending_bytes[MB_LEN_MAX];
+static int pending_bytes_length = 0;
+static mbstate_t ps = {0};
+#endif
+
+/* Insert the character C at the current location, moving point forward.
+ If C introduces a multibyte sequence, we read the whole sequence and
+ then insert the multibyte char into the line buffer. */
+int
+_rl_insert_char (count, c)
+ int count, c;
+{
+ register int i;
+ char *string;
+#ifdef HANDLE_MULTIBYTE
+ int string_size;
+ char incoming[MB_LEN_MAX + 1];
+ int incoming_length = 0;
+ mbstate_t ps_back;
+ static int stored_count = 0;
+#endif
+
+ if (count <= 0)
+ return 0;
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ {
+ incoming[0] = c;
+ incoming[1] = '\0';
+ incoming_length = 1;
+ }
+ else
+ {
+ wchar_t wc;
+ size_t ret;
+
+ if (stored_count <= 0)
+ stored_count = count;
+ else
+ count = stored_count;
+
+ ps_back = ps;
+ pending_bytes[pending_bytes_length++] = c;
+ ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps);
+
+ if (ret == (size_t)-2)
+ {
+ /* Bytes too short to compose character, try to wait for next byte.
+ Restore the state of the byte sequence, because in this case the
+ effect of mbstate is undefined. */
+ ps = ps_back;
+ return 1;
+ }
+ else if (ret == (size_t)-1)
+ {
+ /* Invalid byte sequence for the current locale. Treat first byte
+ as a single character. */
+ incoming[0] = pending_bytes[0];
+ incoming[1] = '\0';
+ incoming_length = 1;
+ pending_bytes_length--;
+ memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
+ /* Clear the state of the byte sequence, because in this case the
+ effect of mbstate is undefined. */
+ memset (&ps, 0, sizeof (mbstate_t));
+ }
+ else if (ret == (size_t)0)
+ {
+ incoming[0] = '\0';
+ incoming_length = 0;
+ pending_bytes_length--;
+ /* Clear the state of the byte sequence, because in this case the
+ effect of mbstate is undefined. */
+ memset (&ps, 0, sizeof (mbstate_t));
+ }
+ else
+ {
+ /* We successfully read a single multibyte character. */
+ memcpy (incoming, pending_bytes, pending_bytes_length);
+ incoming[pending_bytes_length] = '\0';
+ incoming_length = pending_bytes_length;
+ pending_bytes_length = 0;
+ }
+ }
+#endif /* HANDLE_MULTIBYTE */
+
+ /* If we can optimize, then do it. But don't let people crash
+ readline because of extra large arguments. */
+ if (count > 1 && count <= 1024)
+ {
+#if defined (HANDLE_MULTIBYTE)
+ string_size = count * incoming_length;
+ string = (char *)xmalloc (1 + string_size);
+
+ i = 0;
+ while (i < string_size)
+ {
+ strncpy (string + i, incoming, incoming_length);
+ i += incoming_length;
+ }
+ incoming_length = 0;
+ stored_count = 0;
+#else /* !HANDLE_MULTIBYTE */
+ string = (char *)xmalloc (1 + count);
+
+ for (i = 0; i < count; i++)
+ string[i] = c;
+#endif /* !HANDLE_MULTIBYTE */
+
+ string[i] = '\0';
+ rl_insert_text (string);
+ free (string);
+
+ return 0;
+ }
+
+ if (count > 1024)
+ {
+ int decreaser;
+#if defined (HANDLE_MULTIBYTE)
+ string_size = incoming_length * 1024;
+ string = (char *)xmalloc (1 + string_size);
+
+ i = 0;
+ while (i < string_size)
+ {
+ strncpy (string + i, incoming, incoming_length);
+ i += incoming_length;
+ }
+
+ while (count)
+ {
+ decreaser = (count > 1024) ? 1024 : count;
+ string[decreaser*incoming_length] = '\0';
+ rl_insert_text (string);
+ count -= decreaser;
+ }
+
+ free (string);
+ incoming_length = 0;
+ stored_count = 0;
+#else /* !HANDLE_MULTIBYTE */
+ char str[1024+1];
+
+ for (i = 0; i < 1024; i++)
+ str[i] = c;
+
+ while (count)
+ {
+ decreaser = (count > 1024 ? 1024 : count);
+ str[decreaser] = '\0';
+ rl_insert_text (str);
+ count -= decreaser;
+ }
+#endif /* !HANDLE_MULTIBYTE */
+
+ return 0;
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ {
+#endif
+ /* We are inserting a single character.
+ If there is pending input, then make a string of all of the
+ pending characters that are bound to rl_insert, and insert
+ them all. */
+ if (_rl_any_typein ())
+ _rl_insert_typein (c);
+ else
+ {
+ /* Inserting a single character. */
+ char str[2];
+
+ str[1] = '\0';
+ str[0] = c;
+ rl_insert_text (str);
+ }
+#if defined (HANDLE_MULTIBYTE)
+ }
+ else
+ {
+ rl_insert_text (incoming);
+ stored_count = 0;
+ }
+#endif
+
+ return 0;
+}
+
+/* Overwrite the character at point (or next COUNT characters) with C.
+ If C introduces a multibyte character sequence, read the entire sequence
+ before starting the overwrite loop. */
+int
+_rl_overwrite_char (count, c)
+ int count, c;
+{
+ int i;
+#if defined (HANDLE_MULTIBYTE)
+ char mbkey[MB_LEN_MAX];
+ int k;
+
+ /* Read an entire multibyte character sequence to insert COUNT times. */
+ if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
+#endif
+
+ for (i = 0; i < count; i++)
+ {
+ rl_begin_undo_group ();
+
+ if (rl_point < rl_end)
+ rl_delete (1, c);
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_insert_text (mbkey);
+ else
+#endif
+ _rl_insert_char (1, c);
+
+ rl_end_undo_group ();
+ }
+
+ return 0;
+}
+
+int
+rl_insert (count, c)
+ int count, c;
+{
+ return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c)
+ : _rl_overwrite_char (count, c));
+}
+
+/* Insert the next typed character verbatim. */
+int
+rl_quoted_insert (count, key)
+ int count, key;
+{
+ int c;
+
+#if defined (HANDLE_SIGNALS)
+ _rl_disable_tty_signals ();
+#endif
+
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+#if defined (HANDLE_SIGNALS)
+ _rl_restore_tty_signals ();
+#endif
+
+ return (_rl_insert_char (count, c));
+}
+
+/* Insert a tab character. */
+int
+rl_tab_insert (count, key)
+ int count, key;
+{
+ return (_rl_insert_char (count, '\t'));
+}
+
+/* What to do when a NEWLINE is pressed. We accept the whole line.
+ KEY is the key that invoked this command. I guess it could have
+ meaning in the future. */
+int
+rl_newline (count, key)
+ int count, key;
+{
+ rl_done = 1;
+
+ if (_rl_history_preserve_point)
+ _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
+
+ RL_SETSTATE(RL_STATE_DONE);
+
+#if defined (VI_MODE)
+ if (rl_editing_mode == vi_mode)
+ {
+ _rl_vi_done_inserting ();
+ _rl_vi_reset_last ();
+ }
+#endif /* VI_MODE */
+
+ /* If we've been asked to erase empty lines, suppress the final update,
+ since _rl_update_final calls rl_crlf(). */
+ if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
+ return 0;
+
+ if (readline_echoing_p)
+ _rl_update_final ();
+ return 0;
+}
+
+/* What to do for some uppercase characters, like meta characters,
+ and some characters appearing in emacs_ctlx_keymap. This function
+ is just a stub, you bind keys to it and the code in _rl_dispatch ()
+ is special cased. */
+int
+rl_do_lowercase_version (ignore1, ignore2)
+ int ignore1, ignore2;
+{
+ return 0;
+}
+
+/* This is different from what vi does, so the code's not shared. Emacs
+ rubout in overwrite mode has one oddity: it replaces a control
+ character that's displayed as two characters (^X) with two spaces. */
+int
+_rl_overwrite_rubout (count, key)
+ int count, key;
+{
+ int opoint;
+ int i, l;
+
+ if (rl_point == 0)
+ {
+ rl_ding ();
+ return 1;
+ }
+
+ opoint = rl_point;
+
+ /* L == number of spaces to insert */
+ for (i = l = 0; i < count; i++)
+ {
+ rl_backward_char (1, key);
+ l += rl_character_len (rl_line_buffer[rl_point], rl_point); /* not exactly right */
+ }
+
+ rl_begin_undo_group ();
+
+ if (count > 1 || rl_explicit_arg)
+ rl_kill_text (opoint, rl_point);
+ else
+ rl_delete_text (opoint, rl_point);
+
+ /* Emacs puts point at the beginning of the sequence of spaces. */
+ opoint = rl_point;
+ _rl_insert_char (l, ' ');
+ rl_point = opoint;
+
+ rl_end_undo_group ();
+
+ return 0;
+}
+
+/* Rubout the character behind point. */
+int
+rl_rubout (count, key)
+ int count, key;
+{
+ if (count < 0)
+ return (rl_delete (-count, key));
+
+ if (!rl_point)
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ if (rl_insert_mode == RL_IM_OVERWRITE)
+ return (_rl_overwrite_rubout (count, key));
+
+ return (_rl_rubout_char (count, key));
+}
+
+int
+_rl_rubout_char (count, key)
+ int count, key;
+{
+ int orig_point;
+ unsigned char c;
+
+ /* Duplicated code because this is called from other parts of the library. */
+ if (count < 0)
+ return (rl_delete (-count, key));
+
+ if (rl_point == 0)
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ if (count > 1 || rl_explicit_arg)
+ {
+ orig_point = rl_point;
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_backward_char (count, key);
+ else
+#endif
+ rl_backward_byte (count, key);
+ rl_kill_text (orig_point, rl_point);
+ }
+ else
+ {
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ {
+#endif
+ c = rl_line_buffer[--rl_point];
+ rl_delete_text (rl_point, rl_point + 1);
+#if defined (HANDLE_MULTIBYTE)
+ }
+ else
+ {
+ int orig_point;
+
+ orig_point = rl_point;
+ rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
+ c = rl_line_buffer[rl_point];
+ rl_delete_text (rl_point, orig_point);
+ }
+#endif /* HANDLE_MULTIBYTE */
+
+ /* I don't think that the hack for end of line is needed for
+ multibyte chars. */
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+#endif
+ if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
+ {
+ int l;
+ l = rl_character_len (c, rl_point);
+ _rl_erase_at_end_of_line (l);
+ }
+ }
+
+ return 0;
+}
+
+/* Delete the character under the cursor. Given a numeric argument,
+ kill that many characters instead. */
+int
+rl_delete (count, key)
+ int count, key;
+{
+ int r;
+
+ if (count < 0)
+ return (_rl_rubout_char (-count, key));
+
+ if (rl_point == rl_end)
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ if (count > 1 || rl_explicit_arg)
+ {
+ int orig_point = rl_point;
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_forward_char (count, key);
+ else
+#endif
+ rl_forward_byte (count, key);
+
+ r = rl_kill_text (orig_point, rl_point);
+ rl_point = orig_point;
+ return r;
+ }
+ else
+ {
+ int new_point;
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ new_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
+ else
+ new_point = rl_point + 1;
+
+ return (rl_delete_text (rl_point, new_point));
+ }
+}
+
+/* Delete the character under the cursor, unless the insertion
+ point is at the end of the line, in which case the character
+ behind the cursor is deleted. COUNT is obeyed and may be used
+ to delete forward or backward that many characters. */
+int
+rl_rubout_or_delete (count, key)
+ int count, key;
+{
+ if (rl_end != 0 && rl_point == rl_end)
+ return (_rl_rubout_char (count, key));
+ else
+ return (rl_delete (count, key));
+}
+
+/* Delete all spaces and tabs around point. */
+int
+rl_delete_horizontal_space (count, ignore)
+ int count, ignore;
+{
+ int start = rl_point;
+
+ while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
+ rl_point--;
+
+ start = rl_point;
+
+ while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
+ rl_point++;
+
+ if (start != rl_point)
+ {
+ rl_delete_text (start, rl_point);
+ rl_point = start;
+ }
+ return 0;
+}
+
+/* Like the tcsh editing function delete-char-or-list. The eof character
+ is caught before this is invoked, so this really does the same thing as
+ delete-char-or-list-or-eof, as long as it's bound to the eof character. */
+int
+rl_delete_or_show_completions (count, key)
+ int count, key;
+{
+ if (rl_end != 0 && rl_point == rl_end)
+ return (rl_possible_completions (count, key));
+ else
+ return (rl_delete (count, key));
+}
+
+#ifndef RL_COMMENT_BEGIN_DEFAULT
+#define RL_COMMENT_BEGIN_DEFAULT "#"
+#endif
+
+/* Turn the current line into a comment in shell history.
+ A K*rn shell style function. */
+int
+rl_insert_comment (count, key)
+ int count, key;
+{
+ char *rl_comment_text;
+ int rl_comment_len;
+
+ rl_beg_of_line (1, key);
+ rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
+
+ if (rl_explicit_arg == 0)
+ rl_insert_text (rl_comment_text);
+ else
+ {
+ rl_comment_len = strlen (rl_comment_text);
+ if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
+ rl_delete_text (rl_point, rl_point + rl_comment_len);
+ else
+ rl_insert_text (rl_comment_text);
+ }
+
+ (*rl_redisplay_function) ();
+ rl_newline (1, '\n');
+
+ return (0);
+}
+
+/* **************************************************************** */
+/* */
+/* Changing Case */
+/* */
+/* **************************************************************** */
+
+/* The three kinds of things that we know how to do. */
+#define UpCase 1
+#define DownCase 2
+#define CapCase 3
+
+/* Uppercase the word at point. */
+int
+rl_upcase_word (count, key)
+ int count, key;
+{
+ return (rl_change_case (count, UpCase));
+}
+
+/* Lowercase the word at point. */
+int
+rl_downcase_word (count, key)
+ int count, key;
+{
+ return (rl_change_case (count, DownCase));
+}
+
+/* Upcase the first letter, downcase the rest. */
+int
+rl_capitalize_word (count, key)
+ int count, key;
+{
+ return (rl_change_case (count, CapCase));
+}
+
+/* The meaty function.
+ Change the case of COUNT words, performing OP on them.
+ OP is one of UpCase, DownCase, or CapCase.
+ If a negative argument is given, leave point where it started,
+ otherwise, leave it where it moves to. */
+static int
+rl_change_case (count, op)
+ int count, op;
+{
+ register int start, end;
+ int inword, c;
+
+ start = rl_point;
+ rl_forward_word (count, 0);
+ end = rl_point;
+
+ if (count < 0)
+ SWAP (start, end);
+
+ /* We are going to modify some text, so let's prepare to undo it. */
+ rl_modifying (start, end);
+
+ for (inword = 0; start < end; start++)
+ {
+ c = rl_line_buffer[start];
+ switch (op)
+ {
+ case UpCase:
+ rl_line_buffer[start] = _rl_to_upper (c);
+ break;
+
+ case DownCase:
+ rl_line_buffer[start] = _rl_to_lower (c);
+ break;
+
+ case CapCase:
+ rl_line_buffer[start] = (inword == 0) ? _rl_to_upper (c) : _rl_to_lower (c);
+ inword = rl_alphabetic (rl_line_buffer[start]);
+ break;
+
+ default:
+ rl_ding ();
+ return -1;
+ }
+ }
+ rl_point = end;
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Transposition */
+/* */
+/* **************************************************************** */
+
+/* Transpose the words at point. If point is at the end of the line,
+ transpose the two words before point. */
+int
+rl_transpose_words (count, key)
+ int count, key;
+{
+ char *word1, *word2;
+ int w1_beg, w1_end, w2_beg, w2_end;
+ int orig_point = rl_point;
+
+ if (!count)
+ return 0;
+
+ /* Find the two words. */
+ rl_forward_word (count, key);
+ w2_end = rl_point;
+ rl_backward_word (1, key);
+ w2_beg = rl_point;
+ rl_backward_word (count, key);
+ w1_beg = rl_point;
+ rl_forward_word (1, key);
+ w1_end = rl_point;
+
+ /* Do some check to make sure that there really are two words. */
+ if ((w1_beg == w2_beg) || (w2_beg < w1_end))
+ {
+ rl_ding ();
+ rl_point = orig_point;
+ return -1;
+ }
+
+ /* Get the text of the words. */
+ word1 = rl_copy_text (w1_beg, w1_end);
+ word2 = rl_copy_text (w2_beg, w2_end);
+
+ /* We are about to do many insertions and deletions. Remember them
+ as one operation. */
+ rl_begin_undo_group ();
+
+ /* Do the stuff at word2 first, so that we don't have to worry
+ about word1 moving. */
+ rl_point = w2_beg;
+ rl_delete_text (w2_beg, w2_end);
+ rl_insert_text (word1);
+
+ rl_point = w1_beg;
+ rl_delete_text (w1_beg, w1_end);
+ rl_insert_text (word2);
+
+ /* This is exactly correct since the text before this point has not
+ changed in length. */
+ rl_point = w2_end;
+
+ /* I think that does it. */
+ rl_end_undo_group ();
+ free (word1);
+ free (word2);
+
+ return 0;
+}
+
+/* Transpose the characters at point. If point is at the end of the line,
+ then transpose the characters before point. */
+int
+rl_transpose_chars (count, key)
+ int count, key;
+{
+#if defined (HANDLE_MULTIBYTE)
+ char *dummy;
+ int i, prev_point;
+#else
+ char dummy[2];
+#endif
+ int char_length;
+
+ if (count == 0)
+ return 0;
+
+ if (!rl_point || rl_end < 2)
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ rl_begin_undo_group ();
+
+ if (rl_point == rl_end)
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
+ else
+ --rl_point;
+ count = 1;
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ prev_point = rl_point;
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
+ else
+#endif
+ rl_point--;
+
+#if defined (HANDLE_MULTIBYTE)
+ char_length = prev_point - rl_point;
+ dummy = (char *)xmalloc (char_length + 1);
+ for (i = 0; i < char_length; i++)
+ dummy[i] = rl_line_buffer[rl_point + i];
+ dummy[i] = '\0';
+#else
+ dummy[0] = rl_line_buffer[rl_point];
+ dummy[char_length = 1] = '\0';
+#endif
+
+ rl_delete_text (rl_point, rl_point + char_length);
+
+ rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
+
+ _rl_fix_point (0);
+ rl_insert_text (dummy);
+ rl_end_undo_group ();
+
+#if defined (HANDLE_MULTIBYTE)
+ free (dummy);
+#endif
+
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Character Searching */
+/* */
+/* **************************************************************** */
+
+int
+#if defined (HANDLE_MULTIBYTE)
+_rl_char_search_internal (count, dir, smbchar, len)
+ int count, dir;
+ char *smbchar;
+ int len;
+#else
+_rl_char_search_internal (count, dir, schar)
+ int count, dir, schar;
+#endif
+{
+ int pos, inc;
+#if defined (HANDLE_MULTIBYTE)
+ int prepos;
+#endif
+
+ pos = rl_point;
+ inc = (dir < 0) ? -1 : 1;
+ while (count)
+ {
+ if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
+ {
+ rl_ding ();
+ return -1;
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
+ : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
+#else
+ pos += inc;
+#endif
+ do
+ {
+#if defined (HANDLE_MULTIBYTE)
+ if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
+#else
+ if (rl_line_buffer[pos] == schar)
+#endif
+ {
+ count--;
+ if (dir < 0)
+ rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
+ : pos;
+ else
+ rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
+ : pos;
+ break;
+ }
+#if defined (HANDLE_MULTIBYTE)
+ prepos = pos;
+#endif
+ }
+#if defined (HANDLE_MULTIBYTE)
+ while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
+ : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
+#else
+ while ((dir < 0) ? pos-- : ++pos < rl_end);
+#endif
+ }
+ return (0);
+}
+
+/* Search COUNT times for a character read from the current input stream.
+ FDIR is the direction to search if COUNT is non-negative; otherwise
+ the search goes in BDIR. So much is dependent on HANDLE_MULTIBYTE
+ that there are two separate versions of this function. */
+#if defined (HANDLE_MULTIBYTE)
+static int
+_rl_char_search (count, fdir, bdir)
+ int count, fdir, bdir;
+{
+ char mbchar[MB_LEN_MAX];
+ int mb_len;
+
+ mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
+
+ if (count < 0)
+ return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
+ else
+ return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
+}
+#else /* !HANDLE_MULTIBYTE */
+static int
+_rl_char_search (count, fdir, bdir)
+ int count, fdir, bdir;
+{
+ int c;
+
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+ if (count < 0)
+ return (_rl_char_search_internal (-count, bdir, c));
+ else
+ return (_rl_char_search_internal (count, fdir, c));
+}
+#endif /* !HANDLE_MULTIBYTE */
+
+int
+rl_char_search (count, key)
+ int count, key;
+{
+ return (_rl_char_search (count, FFIND, BFIND));
+}
+
+int
+rl_backward_char_search (count, key)
+ int count, key;
+{
+ return (_rl_char_search (count, BFIND, FFIND));
+}
+
+/* **************************************************************** */
+/* */
+/* The Mark and the Region. */
+/* */
+/* **************************************************************** */
+
+/* Set the mark at POSITION. */
+int
+_rl_set_mark_at_pos (position)
+ int position;
+{
+ if (position > rl_end)
+ return -1;
+
+ rl_mark = position;
+ return 0;
+}
+
+/* A bindable command to set the mark. */
+int
+rl_set_mark (count, key)
+ int count, key;
+{
+ return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
+}
+
+/* Exchange the position of mark and point. */
+int
+rl_exchange_point_and_mark (count, key)
+ int count, key;
+{
+ if (rl_mark > rl_end)
+ rl_mark = -1;
+
+ if (rl_mark == -1)
+ {
+ rl_ding ();
+ return -1;
+ }
+ else
+ SWAP (rl_point, rl_mark);
+
+ return 0;
+}
diff --git a/MSVC/readline/tilde.c b/MSVC/readline/tilde.c
index 9e501ef..fdf54b9 100644
--- a/MSVC/readline/tilde.c
+++ b/MSVC/readline/tilde.c
@@ -1,470 +1,470 @@
-/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */
-
-/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
-
- This file is part of GNU Readline, a library for reading lines
- of text with interactive input and history editing.
-
- Readline 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, or (at your option) any
- later version.
-
- Readline 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 Readline; see the file COPYING. If not, write to the Free
- Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#if defined (HAVE_UNISTD_H)
-# ifdef _MINIX
-# include <sys/types.h>
-# endif
-# include <unistd.h>
-#endif
-
-#if defined (HAVE_STRING_H)
-# include <string.h>
-#else /* !HAVE_STRING_H */
-# include <strings.h>
-#endif /* !HAVE_STRING_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <sys/types.h>
-
-#if !defined _WIN32
-# include <pwd.h>
-#endif /* !_WIN32 */
-
-#include "tilde.h"
-
-#if defined (TEST) || defined (STATIC_MALLOC)
-static void *xmalloc (), *xrealloc ();
-#else
-# include "xmalloc.h"
-#endif /* TEST || STATIC_MALLOC */
-
-#if !defined _WIN32
-#if !defined (HAVE_GETPW_DECLS)
-extern struct passwd *getpwuid PARAMS((uid_t));
-extern struct passwd *getpwnam PARAMS((const char *));
-#endif /* !HAVE_GETPW_DECLS */
-#endif /* !_WIN32 */
-
-#if !defined (savestring)
-#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
-#endif /* !savestring */
-
-#if !defined (NULL)
-# if defined (__STDC__)
-# define NULL ((void *) 0)
-# else
-# define NULL 0x0
-# endif /* !__STDC__ */
-#endif /* !NULL */
-
-/* If being compiled as part of bash, these will be satisfied from
- variables.o. If being compiled as part of readline, they will
- be satisfied from shell.o. */
-extern char *sh_get_home_dir PARAMS((void));
-extern char *sh_get_env_value PARAMS((const char *));
-
-/* The default value of tilde_additional_prefixes. This is set to
- whitespace preceding a tilde so that simple programs which do not
- perform any word separation get desired behaviour. */
-static const char *default_prefixes[] =
- { " ~", "\t~", (const char *)NULL };
-
-/* The default value of tilde_additional_suffixes. This is set to
- whitespace or newline so that simple programs which do not
- perform any word separation get desired behaviour. */
-static const char *default_suffixes[] =
- { " ", "\n", (const char *)NULL };
-
-/* If non-null, this contains the address of a function that the application
- wants called before trying the standard tilde expansions. The function
- is called with the text sans tilde, and returns a malloc()'ed string
- which is the expansion, or a NULL pointer if the expansion fails. */
-tilde_hook_func_t *tilde_expansion_preexpansion_hook = (tilde_hook_func_t *)NULL;
-
-/* If non-null, this contains the address of a function to call if the
- standard meaning for expanding a tilde fails. The function is called
- with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
- which is the expansion, or a NULL pointer if there is no expansion. */
-tilde_hook_func_t *tilde_expansion_failure_hook = (tilde_hook_func_t *)NULL;
-
-/* When non-null, this is a NULL terminated array of strings which
- are duplicates for a tilde prefix. Bash uses this to expand
- `=~' and `:~'. */
-char **tilde_additional_prefixes = (char **)default_prefixes;
-
-/* When non-null, this is a NULL terminated array of strings which match
- the end of a username, instead of just "/". Bash sets this to
- `:' and `=~'. */
-char **tilde_additional_suffixes = (char **)default_suffixes;
-
-static int tilde_find_prefix PARAMS((const char *, int *));
-static int tilde_find_suffix PARAMS((const char *));
-static char *isolate_tilde_prefix PARAMS((const char *, int *));
-static char *glue_prefix_and_suffix PARAMS((char *, const char *, int));
-
-/* Find the start of a tilde expansion in STRING, and return the index of
- the tilde which starts the expansion. Place the length of the text
- which identified this tilde starter in LEN, excluding the tilde itself. */
-static int
-tilde_find_prefix (string, len)
- const char *string;
- int *len;
-{
- register int i, j, string_len;
- register char **prefixes;
-
- prefixes = tilde_additional_prefixes;
-
- string_len = strlen (string);
- *len = 0;
-
- if (*string == '\0' || *string == '~')
- return (0);
-
- if (prefixes)
- {
- for (i = 0; i < string_len; i++)
- {
- for (j = 0; prefixes[j]; j++)
- {
- if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0)
- {
- *len = strlen (prefixes[j]) - 1;
- return (i + *len);
- }
- }
- }
- }
- return (string_len);
-}
-
-/* Find the end of a tilde expansion in STRING, and return the index of
- the character which ends the tilde definition. */
-static int
-tilde_find_suffix (string)
- const char *string;
-{
- register int i, j, string_len;
- register char **suffixes;
-
- suffixes = tilde_additional_suffixes;
- string_len = strlen (string);
-
- for (i = 0; i < string_len; i++)
- {
-#if defined (__MSDOS__)
- if (string[i] == '/' || string[i] == '\\' /* || !string[i] */)
-#else
- if (string[i] == '/' /* || !string[i] */)
-#endif
- break;
-
- for (j = 0; suffixes && suffixes[j]; j++)
- {
- if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0)
- return (i);
- }
- }
- return (i);
-}
-
-/* Return a new string which is the result of tilde expanding STRING. */
-char *
-tilde_expand (string)
- const char *string;
-{
- char *result;
- int result_size, result_index;
-
- result_index = result_size = 0;
- if (result = strchr (string, '~'))
- result = (char *)xmalloc (result_size = (strlen (string) + 16));
- else
- result = (char *)xmalloc (result_size = (strlen (string) + 1));
-
- /* Scan through STRING expanding tildes as we come to them. */
- while (1)
- {
- register int start, end;
- char *tilde_word, *expansion;
- int len;
-
- /* Make START point to the tilde which starts the expansion. */
- start = tilde_find_prefix (string, &len);
-
- /* Copy the skipped text into the result. */
- if ((result_index + start + 1) > result_size)
- result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
-
- strncpy (result + result_index, string, start);
- result_index += start;
-
- /* Advance STRING to the starting tilde. */
- string += start;
-
- /* Make END be the index of one after the last character of the
- username. */
- end = tilde_find_suffix (string);
-
- /* If both START and END are zero, we are all done. */
- if (!start && !end)
- break;
-
- /* Expand the entire tilde word, and copy it into RESULT. */
- tilde_word = (char *)xmalloc (1 + end);
- strncpy (tilde_word, string, end);
- tilde_word[end] = '\0';
- string += end;
-
- expansion = tilde_expand_word (tilde_word);
- free (tilde_word);
-
- len = strlen (expansion);
-#ifdef __CYGWIN__
- /* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when
- $HOME for `user' is /. On cygwin, // denotes a network drive. */
- if (len > 1 || *expansion != '/' || *string != '/')
-#endif
- {
- if ((result_index + len + 1) > result_size)
- result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
-
- strcpy (result + result_index, expansion);
- result_index += len;
- }
- free (expansion);
- }
-
- result[result_index] = '\0';
-
- return (result);
-}
-
-/* Take FNAME and return the tilde prefix we want expanded. If LENP is
- non-null, the index of the end of the prefix into FNAME is returned in
- the location it points to. */
-static char *
-isolate_tilde_prefix (fname, lenp)
- const char *fname;
- int *lenp;
-{
- char *ret;
- int i;
-
- ret = (char *)xmalloc (strlen (fname));
-#if defined (__MSDOS__)
- for (i = 1; fname[i] && fname[i] != '/' && fname[i] != '\\'; i++)
-#else
- for (i = 1; fname[i] && fname[i] != '/'; i++)
-#endif
- ret[i - 1] = fname[i];
- ret[i - 1] = '\0';
- if (lenp)
- *lenp = i;
- return ret;
-}
-
-/* Return a string that is PREFIX concatenated with SUFFIX starting at
- SUFFIND. */
-static char *
-glue_prefix_and_suffix (prefix, suffix, suffind)
- char *prefix;
- const char *suffix;
- int suffind;
-{
- char *ret;
- int plen, slen;
-
- plen = (prefix && *prefix) ? strlen (prefix) : 0;
- slen = strlen (suffix + suffind);
- ret = (char *)xmalloc (plen + slen + 1);
- if (plen)
- strcpy (ret, prefix);
- strcpy (ret + plen, suffix + suffind);
- return ret;
-}
-
-/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
- tilde. If there is no expansion, call tilde_expansion_failure_hook.
- This always returns a newly-allocated string, never static storage. */
-char *
-tilde_expand_word (filename)
- const char *filename;
-{
- char *dirname, *expansion, *username;
- int user_len;
-#if !defined _WIN32
- struct passwd *user_entry;
-#endif /* !_WIN32 */
-
- if (filename == 0)
- return ((char *)NULL);
-
- if (*filename != '~')
- return (savestring (filename));
-
- /* A leading `~/' or a bare `~' is *always* translated to the value of
- $HOME or the home directory of the current user, regardless of any
- preexpansion hook. */
- if (filename[1] == '\0' || filename[1] == '/')
- {
- /* Prefix $HOME to the rest of the string. */
- expansion = sh_get_env_value ("HOME");
-
-#if !defined _WIN32
- /* If there is no HOME variable, look up the directory in
- the password database. */
- if (expansion == 0)
- expansion = sh_get_home_dir ();
-#endif /* !_WIN32 */
-
- return (glue_prefix_and_suffix (expansion, filename, 1));
- }
-
- username = isolate_tilde_prefix (filename, &user_len);
-
- if (tilde_expansion_preexpansion_hook)
- {
- expansion = (*tilde_expansion_preexpansion_hook) (username);
- if (expansion)
- {
- dirname = glue_prefix_and_suffix (expansion, filename, user_len);
- free (username);
- free (expansion);
- return (dirname);
- }
- }
-
- /* No preexpansion hook, or the preexpansion hook failed. Look in the
- password database. */
- dirname = (char *)NULL;
-#if !defined _WIN32
- user_entry = getpwnam (username);
- if (user_entry == 0)
- {
-#endif /* !_WIN32 */
- /* If the calling program has a special syntax for expanding tildes,
- and we couldn't find a standard expansion, then let them try. */
- if (tilde_expansion_failure_hook)
- {
- expansion = (*tilde_expansion_failure_hook) (username);
- if (expansion)
- {
- dirname = glue_prefix_and_suffix (expansion, filename, user_len);
- free (expansion);
- }
- }
- free (username);
- /* If we don't have a failure hook, or if the failure hook did not
- expand the tilde, return a copy of what we were passed. */
- if (dirname == 0)
- dirname = savestring (filename);
-#if !defined _WIN32
- }
- else
- {
- free (username);
- dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len);
- }
-
- endpwent ();
-#endif /* !_WIN32 */
- return (dirname);
-}
-
-
-#if defined (TEST)
-#undef NULL
-#include <stdio.h>
-
-main (argc, argv)
- int argc;
- char **argv;
-{
- char *result, line[512];
- int done = 0;
-
- while (!done)
- {
- printf ("~expand: ");
- fflush (stdout);
-
- if (!gets (line))
- strcpy (line, "done");
-
- if ((strcmp (line, "done") == 0) ||
- (strcmp (line, "quit") == 0) ||
- (strcmp (line, "exit") == 0))
- {
- done = 1;
- break;
- }
-
- result = tilde_expand (line);
- printf (" --> %s\n", result);
- free (result);
- }
- exit (0);
-}
-
-static void memory_error_and_abort ();
-
-static void *
-xmalloc (bytes)
- size_t bytes;
-{
- void *temp = (char *)malloc (bytes);
-
- if (!temp)
- memory_error_and_abort ();
- return (temp);
-}
-
-static void *
-xrealloc (pointer, bytes)
- void *pointer;
- int bytes;
-{
- void *temp;
-
- if (!pointer)
- temp = malloc (bytes);
- else
- temp = realloc (pointer, bytes);
-
- if (!temp)
- memory_error_and_abort ();
-
- return (temp);
-}
-
-static void
-memory_error_and_abort ()
-{
- fprintf (stderr, "readline: out of virtual memory\n");
- abort ();
-}
-
-/*
- * Local variables:
- * compile-command: "gcc -g -DTEST -o tilde tilde.c"
- * end:
- */
-#endif /* TEST */
+/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */
+
+/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
+
+ This file is part of GNU Readline, a library for reading lines
+ of text with interactive input and history editing.
+
+ Readline 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, or (at your option) any
+ later version.
+
+ Readline 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 Readline; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#if defined (HAVE_UNISTD_H)
+# ifdef _MINIX
+# include <sys/types.h>
+# endif
+# include <unistd.h>
+#endif
+
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else /* !HAVE_STRING_H */
+# include <strings.h>
+#endif /* !HAVE_STRING_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <sys/types.h>
+
+#if !defined _WIN32
+# include <pwd.h>
+#endif /* !_WIN32 */
+
+#include "tilde.h"
+
+#if defined (TEST) || defined (STATIC_MALLOC)
+static void *xmalloc (), *xrealloc ();
+#else
+# include "xmalloc.h"
+#endif /* TEST || STATIC_MALLOC */
+
+#if !defined _WIN32
+#if !defined (HAVE_GETPW_DECLS)
+extern struct passwd *getpwuid PARAMS((uid_t));
+extern struct passwd *getpwnam PARAMS((const char *));
+#endif /* !HAVE_GETPW_DECLS */
+#endif /* !_WIN32 */
+
+#if !defined (savestring)
+#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
+#endif /* !savestring */
+
+#if !defined (NULL)
+# if defined (__STDC__)
+# define NULL ((void *) 0)
+# else
+# define NULL 0x0
+# endif /* !__STDC__ */
+#endif /* !NULL */
+
+/* If being compiled as part of bash, these will be satisfied from
+ variables.o. If being compiled as part of readline, they will
+ be satisfied from shell.o. */
+extern char *sh_get_home_dir PARAMS((void));
+extern char *sh_get_env_value PARAMS((const char *));
+
+/* The default value of tilde_additional_prefixes. This is set to
+ whitespace preceding a tilde so that simple programs which do not
+ perform any word separation get desired behaviour. */
+static const char *default_prefixes[] =
+ { " ~", "\t~", (const char *)NULL };
+
+/* The default value of tilde_additional_suffixes. This is set to
+ whitespace or newline so that simple programs which do not
+ perform any word separation get desired behaviour. */
+static const char *default_suffixes[] =
+ { " ", "\n", (const char *)NULL };
+
+/* If non-null, this contains the address of a function that the application
+ wants called before trying the standard tilde expansions. The function
+ is called with the text sans tilde, and returns a malloc()'ed string
+ which is the expansion, or a NULL pointer if the expansion fails. */
+tilde_hook_func_t *tilde_expansion_preexpansion_hook = (tilde_hook_func_t *)NULL;
+
+/* If non-null, this contains the address of a function to call if the
+ standard meaning for expanding a tilde fails. The function is called
+ with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
+ which is the expansion, or a NULL pointer if there is no expansion. */
+tilde_hook_func_t *tilde_expansion_failure_hook = (tilde_hook_func_t *)NULL;
+
+/* When non-null, this is a NULL terminated array of strings which
+ are duplicates for a tilde prefix. Bash uses this to expand
+ `=~' and `:~'. */
+char **tilde_additional_prefixes = (char **)default_prefixes;
+
+/* When non-null, this is a NULL terminated array of strings which match
+ the end of a username, instead of just "/". Bash sets this to
+ `:' and `=~'. */
+char **tilde_additional_suffixes = (char **)default_suffixes;
+
+static int tilde_find_prefix PARAMS((const char *, int *));
+static int tilde_find_suffix PARAMS((const char *));
+static char *isolate_tilde_prefix PARAMS((const char *, int *));
+static char *glue_prefix_and_suffix PARAMS((char *, const char *, int));
+
+/* Find the start of a tilde expansion in STRING, and return the index of
+ the tilde which starts the expansion. Place the length of the text
+ which identified this tilde starter in LEN, excluding the tilde itself. */
+static int
+tilde_find_prefix (string, len)
+ const char *string;
+ int *len;
+{
+ register int i, j, string_len;
+ register char **prefixes;
+
+ prefixes = tilde_additional_prefixes;
+
+ string_len = strlen (string);
+ *len = 0;
+
+ if (*string == '\0' || *string == '~')
+ return (0);
+
+ if (prefixes)
+ {
+ for (i = 0; i < string_len; i++)
+ {
+ for (j = 0; prefixes[j]; j++)
+ {
+ if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0)
+ {
+ *len = strlen (prefixes[j]) - 1;
+ return (i + *len);
+ }
+ }
+ }
+ }
+ return (string_len);
+}
+
+/* Find the end of a tilde expansion in STRING, and return the index of
+ the character which ends the tilde definition. */
+static int
+tilde_find_suffix (string)
+ const char *string;
+{
+ register int i, j, string_len;
+ register char **suffixes;
+
+ suffixes = tilde_additional_suffixes;
+ string_len = strlen (string);
+
+ for (i = 0; i < string_len; i++)
+ {
+#if defined (__MSDOS__)
+ if (string[i] == '/' || string[i] == '\\' /* || !string[i] */)
+#else
+ if (string[i] == '/' /* || !string[i] */)
+#endif
+ break;
+
+ for (j = 0; suffixes && suffixes[j]; j++)
+ {
+ if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0)
+ return (i);
+ }
+ }
+ return (i);
+}
+
+/* Return a new string which is the result of tilde expanding STRING. */
+char *
+tilde_expand (string)
+ const char *string;
+{
+ char *result;
+ int result_size, result_index;
+
+ result_index = result_size = 0;
+ if (result = strchr (string, '~'))
+ result = (char *)xmalloc (result_size = (strlen (string) + 16));
+ else
+ result = (char *)xmalloc (result_size = (strlen (string) + 1));
+
+ /* Scan through STRING expanding tildes as we come to them. */
+ while (1)
+ {
+ register int start, end;
+ char *tilde_word, *expansion;
+ int len;
+
+ /* Make START point to the tilde which starts the expansion. */
+ start = tilde_find_prefix (string, &len);
+
+ /* Copy the skipped text into the result. */
+ if ((result_index + start + 1) > result_size)
+ result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
+
+ strncpy (result + result_index, string, start);
+ result_index += start;
+
+ /* Advance STRING to the starting tilde. */
+ string += start;
+
+ /* Make END be the index of one after the last character of the
+ username. */
+ end = tilde_find_suffix (string);
+
+ /* If both START and END are zero, we are all done. */
+ if (!start && !end)
+ break;
+
+ /* Expand the entire tilde word, and copy it into RESULT. */
+ tilde_word = (char *)xmalloc (1 + end);
+ strncpy (tilde_word, string, end);
+ tilde_word[end] = '\0';
+ string += end;
+
+ expansion = tilde_expand_word (tilde_word);
+ free (tilde_word);
+
+ len = strlen (expansion);
+#ifdef __CYGWIN__
+ /* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when
+ $HOME for `user' is /. On cygwin, // denotes a network drive. */
+ if (len > 1 || *expansion != '/' || *string != '/')
+#endif
+ {
+ if ((result_index + len + 1) > result_size)
+ result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
+
+ strcpy (result + result_index, expansion);
+ result_index += len;
+ }
+ free (expansion);
+ }
+
+ result[result_index] = '\0';
+
+ return (result);
+}
+
+/* Take FNAME and return the tilde prefix we want expanded. If LENP is
+ non-null, the index of the end of the prefix into FNAME is returned in
+ the location it points to. */
+static char *
+isolate_tilde_prefix (fname, lenp)
+ const char *fname;
+ int *lenp;
+{
+ char *ret;
+ int i;
+
+ ret = (char *)xmalloc (strlen (fname));
+#if defined (__MSDOS__)
+ for (i = 1; fname[i] && fname[i] != '/' && fname[i] != '\\'; i++)
+#else
+ for (i = 1; fname[i] && fname[i] != '/'; i++)
+#endif
+ ret[i - 1] = fname[i];
+ ret[i - 1] = '\0';
+ if (lenp)
+ *lenp = i;
+ return ret;
+}
+
+/* Return a string that is PREFIX concatenated with SUFFIX starting at
+ SUFFIND. */
+static char *
+glue_prefix_and_suffix (prefix, suffix, suffind)
+ char *prefix;
+ const char *suffix;
+ int suffind;
+{
+ char *ret;
+ int plen, slen;
+
+ plen = (prefix && *prefix) ? strlen (prefix) : 0;
+ slen = strlen (suffix + suffind);
+ ret = (char *)xmalloc (plen + slen + 1);
+ if (plen)
+ strcpy (ret, prefix);
+ strcpy (ret + plen, suffix + suffind);
+ return ret;
+}
+
+/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
+ tilde. If there is no expansion, call tilde_expansion_failure_hook.
+ This always returns a newly-allocated string, never static storage. */
+char *
+tilde_expand_word (filename)
+ const char *filename;
+{
+ char *dirname, *expansion, *username;
+ int user_len;
+#if !defined _WIN32
+ struct passwd *user_entry;
+#endif /* !_WIN32 */
+
+ if (filename == 0)
+ return ((char *)NULL);
+
+ if (*filename != '~')
+ return (savestring (filename));
+
+ /* A leading `~/' or a bare `~' is *always* translated to the value of
+ $HOME or the home directory of the current user, regardless of any
+ preexpansion hook. */
+ if (filename[1] == '\0' || filename[1] == '/')
+ {
+ /* Prefix $HOME to the rest of the string. */
+ expansion = sh_get_env_value ("HOME");
+
+#if !defined _WIN32
+ /* If there is no HOME variable, look up the directory in
+ the password database. */
+ if (expansion == 0)
+ expansion = sh_get_home_dir ();
+#endif /* !_WIN32 */
+
+ return (glue_prefix_and_suffix (expansion, filename, 1));
+ }
+
+ username = isolate_tilde_prefix (filename, &user_len);
+
+ if (tilde_expansion_preexpansion_hook)
+ {
+ expansion = (*tilde_expansion_preexpansion_hook) (username);
+ if (expansion)
+ {
+ dirname = glue_prefix_and_suffix (expansion, filename, user_len);
+ free (username);
+ free (expansion);
+ return (dirname);
+ }
+ }
+
+ /* No preexpansion hook, or the preexpansion hook failed. Look in the
+ password database. */
+ dirname = (char *)NULL;
+#if !defined _WIN32
+ user_entry = getpwnam (username);
+ if (user_entry == 0)
+ {
+#endif /* !_WIN32 */
+ /* If the calling program has a special syntax for expanding tildes,
+ and we couldn't find a standard expansion, then let them try. */
+ if (tilde_expansion_failure_hook)
+ {
+ expansion = (*tilde_expansion_failure_hook) (username);
+ if (expansion)
+ {
+ dirname = glue_prefix_and_suffix (expansion, filename, user_len);
+ free (expansion);
+ }
+ }
+ free (username);
+ /* If we don't have a failure hook, or if the failure hook did not
+ expand the tilde, return a copy of what we were passed. */
+ if (dirname == 0)
+ dirname = savestring (filename);
+#if !defined _WIN32
+ }
+ else
+ {
+ free (username);
+ dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len);
+ }
+
+ endpwent ();
+#endif /* !_WIN32 */
+ return (dirname);
+}
+
+
+#if defined (TEST)
+#undef NULL
+#include <stdio.h>
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ char *result, line[512];
+ int done = 0;
+
+ while (!done)
+ {
+ printf ("~expand: ");
+ fflush (stdout);
+
+ if (!gets (line))
+ strcpy (line, "done");
+
+ if ((strcmp (line, "done") == 0) ||
+ (strcmp (line, "quit") == 0) ||
+ (strcmp (line, "exit") == 0))
+ {
+ done = 1;
+ break;
+ }
+
+ result = tilde_expand (line);
+ printf (" --> %s\n", result);
+ free (result);
+ }
+ exit (0);
+}
+
+static void memory_error_and_abort ();
+
+static void *
+xmalloc (bytes)
+ size_t bytes;
+{
+ void *temp = (char *)malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+ return (temp);
+}
+
+static void *
+xrealloc (pointer, bytes)
+ void *pointer;
+ int bytes;
+{
+ void *temp;
+
+ if (!pointer)
+ temp = malloc (bytes);
+ else
+ temp = realloc (pointer, bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+
+ return (temp);
+}
+
+static void
+memory_error_and_abort ()
+{
+ fprintf (stderr, "readline: out of virtual memory\n");
+ abort ();
+}
+
+/*
+ * Local variables:
+ * compile-command: "gcc -g -DTEST -o tilde tilde.c"
+ * end:
+ */
+#endif /* TEST */
diff --git a/MSVC/readline/tilde.h b/MSVC/readline/tilde.h
index a25825f..0f1b2f8 100644
--- a/MSVC/readline/tilde.h
+++ b/MSVC/readline/tilde.h
@@ -1,80 +1,80 @@
-/* tilde.h: Externally available variables and function in libtilde.a. */
-
-/* Copyright (C) 1992 Free Software Foundation, Inc.
-
- This file contains the Readline Library (the Library), a set of
- routines for providing Emacs style line input to programs that ask
- for it.
-
- The Library 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, or (at your option)
- any later version.
-
- The Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_TILDE_H_)
-# define _TILDE_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* A function can be defined using prototypes and compile on both ANSI C
- and traditional C compilers with something like this:
- extern char *func PARAMS((char *, char *, int)); */
-
-#if !defined (PARAMS)
-# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) || defined _MSC_VER
-# define PARAMS(protos) protos
-# else
-# define PARAMS(protos) ()
-# endif
-#endif
-
-#include "rldynlink.h" /* for export / import macros */
-
-typedef char *tilde_hook_func_t PARAMS((char *));
-
-/* If non-null, this contains the address of a function that the application
- wants called before trying the standard tilde expansions. The function
- is called with the text sans tilde, and returns a malloc()'ed string
- which is the expansion, or a NULL pointer if the expansion fails. */
-RL_EXTERN tilde_hook_func_t *tilde_expansion_preexpansion_hook;
-
-/* If non-null, this contains the address of a function to call if the
- standard meaning for expanding a tilde fails. The function is called
- with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
- which is the expansion, or a NULL pointer if there is no expansion. */
-RL_EXTERN tilde_hook_func_t *tilde_expansion_failure_hook;
-
-/* When non-null, this is a NULL terminated array of strings which
- are duplicates for a tilde prefix. Bash uses this to expand
- `=~' and `:~'. */
-RL_EXTERN char **tilde_additional_prefixes;
-
-/* When non-null, this is a NULL terminated array of strings which match
- the end of a username, instead of just "/". Bash sets this to
- `:' and `=~'. */
-RL_EXTERN char **tilde_additional_suffixes;
-
-/* Return a new string which is the result of tilde expanding STRING. */
-RL_EXTERN char *tilde_expand PARAMS((const char *));
-
-/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
- tilde. If there is no expansion, call tilde_expansion_failure_hook. */
-RL_EXTERN char *tilde_expand_word PARAMS((const char *));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _TILDE_H_ */
+/* tilde.h: Externally available variables and function in libtilde.a. */
+
+/* Copyright (C) 1992 Free Software Foundation, Inc.
+
+ This file contains the Readline Library (the Library), a set of
+ routines for providing Emacs style line input to programs that ask
+ for it.
+
+ The Library 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, or (at your option)
+ any later version.
+
+ The Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_TILDE_H_)
+# define _TILDE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* A function can be defined using prototypes and compile on both ANSI C
+ and traditional C compilers with something like this:
+ extern char *func PARAMS((char *, char *, int)); */
+
+#if !defined (PARAMS)
+# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) || defined _MSC_VER
+# define PARAMS(protos) protos
+# else
+# define PARAMS(protos) ()
+# endif
+#endif
+
+#include "rldynlink.h" /* for export / import macros */
+
+typedef char *tilde_hook_func_t PARAMS((char *));
+
+/* If non-null, this contains the address of a function that the application
+ wants called before trying the standard tilde expansions. The function
+ is called with the text sans tilde, and returns a malloc()'ed string
+ which is the expansion, or a NULL pointer if the expansion fails. */
+RL_EXTERN tilde_hook_func_t *tilde_expansion_preexpansion_hook;
+
+/* If non-null, this contains the address of a function to call if the
+ standard meaning for expanding a tilde fails. The function is called
+ with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
+ which is the expansion, or a NULL pointer if there is no expansion. */
+RL_EXTERN tilde_hook_func_t *tilde_expansion_failure_hook;
+
+/* When non-null, this is a NULL terminated array of strings which
+ are duplicates for a tilde prefix. Bash uses this to expand
+ `=~' and `:~'. */
+RL_EXTERN char **tilde_additional_prefixes;
+
+/* When non-null, this is a NULL terminated array of strings which match
+ the end of a username, instead of just "/". Bash sets this to
+ `:' and `=~'. */
+RL_EXTERN char **tilde_additional_suffixes;
+
+/* Return a new string which is the result of tilde expanding STRING. */
+RL_EXTERN char *tilde_expand PARAMS((const char *));
+
+/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
+ tilde. If there is no expansion, call tilde_expansion_failure_hook. */
+RL_EXTERN char *tilde_expand_word PARAMS((const char *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TILDE_H_ */
diff --git a/MSVC/readline/undo.c b/MSVC/readline/undo.c
index 9b8cdb2..07002da 100644
--- a/MSVC/readline/undo.c
+++ b/MSVC/readline/undo.c
@@ -1,261 +1,261 @@
-/* readline.c -- a general facility for reading lines of input
- with emacs style editing and completion. */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h> /* for _POSIX_VERSION */
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-/* Non-zero tells rl_delete_text and rl_insert_text to not add to
- the undo list. */
-int _rl_doing_an_undo = 0;
-
-/* How many unclosed undo groups we currently have. */
-int _rl_undo_group_level = 0;
-
-/* The current undo list for THE_LINE. */
-UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
-
-/* **************************************************************** */
-/* */
-/* Undo, and Undoing */
-/* */
-/* **************************************************************** */
-
-/* Remember how to undo something. Concatenate some undos if that
- seems right. */
-void
-rl_add_undo (what, start, end, text)
- enum undo_code what;
- int start, end;
- char *text;
-{
- UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
- temp->what = what;
- temp->start = start;
- temp->end = end;
- temp->text = text;
- temp->next = rl_undo_list;
- rl_undo_list = temp;
-}
-
-/* Free the existing undo list. */
-void
-rl_free_undo_list ()
-{
- while (rl_undo_list)
- {
- UNDO_LIST *release = rl_undo_list;
- rl_undo_list = rl_undo_list->next;
-
- if (release->what == UNDO_DELETE)
- free (release->text);
-
- free (release);
- }
- rl_undo_list = (UNDO_LIST *)NULL;
-}
-
-/* Undo the next thing in the list. Return 0 if there
- is nothing to undo, or non-zero if there was. */
-int
-rl_do_undo ()
-{
- UNDO_LIST *release;
- int waiting_for_begin, start, end;
-
-#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i)))
-
- start = end = waiting_for_begin = 0;
- do
- {
- if (!rl_undo_list)
- return (0);
-
- _rl_doing_an_undo = 1;
- RL_SETSTATE(RL_STATE_UNDOING);
-
- /* To better support vi-mode, a start or end value of -1 means
- rl_point, and a value of -2 means rl_end. */
- if (rl_undo_list->what == UNDO_DELETE || rl_undo_list->what == UNDO_INSERT)
- {
- start = TRANS (rl_undo_list->start);
- end = TRANS (rl_undo_list->end);
- }
-
- switch (rl_undo_list->what)
- {
- /* Undoing deletes means inserting some text. */
- case UNDO_DELETE:
- rl_point = start;
- rl_insert_text (rl_undo_list->text);
- free (rl_undo_list->text);
- break;
-
- /* Undoing inserts means deleting some text. */
- case UNDO_INSERT:
- rl_delete_text (start, end);
- rl_point = start;
- break;
-
- /* Undoing an END means undoing everything 'til we get to a BEGIN. */
- case UNDO_END:
- waiting_for_begin++;
- break;
-
- /* Undoing a BEGIN means that we are done with this group. */
- case UNDO_BEGIN:
- if (waiting_for_begin)
- waiting_for_begin--;
- else
- rl_ding ();
- break;
- }
-
- _rl_doing_an_undo = 0;
- RL_UNSETSTATE(RL_STATE_UNDOING);
-
- release = rl_undo_list;
- rl_undo_list = rl_undo_list->next;
- free (release);
- }
- while (waiting_for_begin);
-
- return (1);
-}
-#undef TRANS
-
-int
-_rl_fix_last_undo_of_type (type, start, end)
- int type, start, end;
-{
- UNDO_LIST *rl;
-
- for (rl = rl_undo_list; rl; rl = rl->next)
- {
- if (rl->what == type)
- {
- rl->start = start;
- rl->end = end;
- return 0;
- }
- }
- return 1;
-}
-
-/* Begin a group. Subsequent undos are undone as an atomic operation. */
-int
-rl_begin_undo_group ()
-{
- rl_add_undo (UNDO_BEGIN, 0, 0, 0);
- _rl_undo_group_level++;
- return 0;
-}
-
-/* End an undo group started with rl_begin_undo_group (). */
-int
-rl_end_undo_group ()
-{
- rl_add_undo (UNDO_END, 0, 0, 0);
- _rl_undo_group_level--;
- return 0;
-}
-
-/* Save an undo entry for the text from START to END. */
-int
-rl_modifying (start, end)
- int start, end;
-{
- if (start > end)
- {
- SWAP (start, end);
- }
-
- if (start != end)
- {
- char *temp = rl_copy_text (start, end);
- rl_begin_undo_group ();
- rl_add_undo (UNDO_DELETE, start, end, temp);
- rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);
- rl_end_undo_group ();
- }
- return 0;
-}
-
-/* Revert the current line to its previous state. */
-int
-rl_revert_line (count, key)
- int count, key;
-{
- if (!rl_undo_list)
- rl_ding ();
- else
- {
- while (rl_undo_list)
- rl_do_undo ();
- }
- return 0;
-}
-
-/* Do some undoing of things that were done. */
-int
-rl_undo_command (count, key)
- int count, key;
-{
- if (count < 0)
- return 0; /* Nothing to do. */
-
- while (count)
- {
- if (rl_do_undo ())
- count--;
- else
- {
- rl_ding ();
- break;
- }
- }
- return 0;
-}
+/* readline.c -- a general facility for reading lines of input
+ with emacs style editing and completion. */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h> /* for _POSIX_VERSION */
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <stdio.h>
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "xmalloc.h"
+
+/* Non-zero tells rl_delete_text and rl_insert_text to not add to
+ the undo list. */
+int _rl_doing_an_undo = 0;
+
+/* How many unclosed undo groups we currently have. */
+int _rl_undo_group_level = 0;
+
+/* The current undo list for THE_LINE. */
+UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
+
+/* **************************************************************** */
+/* */
+/* Undo, and Undoing */
+/* */
+/* **************************************************************** */
+
+/* Remember how to undo something. Concatenate some undos if that
+ seems right. */
+void
+rl_add_undo (what, start, end, text)
+ enum undo_code what;
+ int start, end;
+ char *text;
+{
+ UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
+ temp->what = what;
+ temp->start = start;
+ temp->end = end;
+ temp->text = text;
+ temp->next = rl_undo_list;
+ rl_undo_list = temp;
+}
+
+/* Free the existing undo list. */
+void
+rl_free_undo_list ()
+{
+ while (rl_undo_list)
+ {
+ UNDO_LIST *release = rl_undo_list;
+ rl_undo_list = rl_undo_list->next;
+
+ if (release->what == UNDO_DELETE)
+ free (release->text);
+
+ free (release);
+ }
+ rl_undo_list = (UNDO_LIST *)NULL;
+}
+
+/* Undo the next thing in the list. Return 0 if there
+ is nothing to undo, or non-zero if there was. */
+int
+rl_do_undo ()
+{
+ UNDO_LIST *release;
+ int waiting_for_begin, start, end;
+
+#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i)))
+
+ start = end = waiting_for_begin = 0;
+ do
+ {
+ if (!rl_undo_list)
+ return (0);
+
+ _rl_doing_an_undo = 1;
+ RL_SETSTATE(RL_STATE_UNDOING);
+
+ /* To better support vi-mode, a start or end value of -1 means
+ rl_point, and a value of -2 means rl_end. */
+ if (rl_undo_list->what == UNDO_DELETE || rl_undo_list->what == UNDO_INSERT)
+ {
+ start = TRANS (rl_undo_list->start);
+ end = TRANS (rl_undo_list->end);
+ }
+
+ switch (rl_undo_list->what)
+ {
+ /* Undoing deletes means inserting some text. */
+ case UNDO_DELETE:
+ rl_point = start;
+ rl_insert_text (rl_undo_list->text);
+ free (rl_undo_list->text);
+ break;
+
+ /* Undoing inserts means deleting some text. */
+ case UNDO_INSERT:
+ rl_delete_text (start, end);
+ rl_point = start;
+ break;
+
+ /* Undoing an END means undoing everything 'til we get to a BEGIN. */
+ case UNDO_END:
+ waiting_for_begin++;
+ break;
+
+ /* Undoing a BEGIN means that we are done with this group. */
+ case UNDO_BEGIN:
+ if (waiting_for_begin)
+ waiting_for_begin--;
+ else
+ rl_ding ();
+ break;
+ }
+
+ _rl_doing_an_undo = 0;
+ RL_UNSETSTATE(RL_STATE_UNDOING);
+
+ release = rl_undo_list;
+ rl_undo_list = rl_undo_list->next;
+ free (release);
+ }
+ while (waiting_for_begin);
+
+ return (1);
+}
+#undef TRANS
+
+int
+_rl_fix_last_undo_of_type (type, start, end)
+ int type, start, end;
+{
+ UNDO_LIST *rl;
+
+ for (rl = rl_undo_list; rl; rl = rl->next)
+ {
+ if (rl->what == type)
+ {
+ rl->start = start;
+ rl->end = end;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* Begin a group. Subsequent undos are undone as an atomic operation. */
+int
+rl_begin_undo_group ()
+{
+ rl_add_undo (UNDO_BEGIN, 0, 0, 0);
+ _rl_undo_group_level++;
+ return 0;
+}
+
+/* End an undo group started with rl_begin_undo_group (). */
+int
+rl_end_undo_group ()
+{
+ rl_add_undo (UNDO_END, 0, 0, 0);
+ _rl_undo_group_level--;
+ return 0;
+}
+
+/* Save an undo entry for the text from START to END. */
+int
+rl_modifying (start, end)
+ int start, end;
+{
+ if (start > end)
+ {
+ SWAP (start, end);
+ }
+
+ if (start != end)
+ {
+ char *temp = rl_copy_text (start, end);
+ rl_begin_undo_group ();
+ rl_add_undo (UNDO_DELETE, start, end, temp);
+ rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);
+ rl_end_undo_group ();
+ }
+ return 0;
+}
+
+/* Revert the current line to its previous state. */
+int
+rl_revert_line (count, key)
+ int count, key;
+{
+ if (!rl_undo_list)
+ rl_ding ();
+ else
+ {
+ while (rl_undo_list)
+ rl_do_undo ();
+ }
+ return 0;
+}
+
+/* Do some undoing of things that were done. */
+int
+rl_undo_command (count, key)
+ int count, key;
+{
+ if (count < 0)
+ return 0; /* Nothing to do. */
+
+ while (count)
+ {
+ if (rl_do_undo ())
+ count--;
+ else
+ {
+ rl_ding ();
+ break;
+ }
+ }
+ return 0;
+}
diff --git a/MSVC/readline/util.c b/MSVC/readline/util.c
index dc4f7b8..37959dd 100644
--- a/MSVC/readline/util.c
+++ b/MSVC/readline/util.c
@@ -1,336 +1,336 @@
-/* util.c -- readline utility functions */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include "posixjmp.h"
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h> /* for _POSIX_VERSION */
-#endif /* HAVE_UNISTD_H */
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include <stdio.h>
-#include <ctype.h>
-
-/* System-specific feature definitions and include files. */
-#include "rldefs.h"
-
-#if defined (TIOCSTAT_IN_SYS_IOCTL)
-# include <sys/ioctl.h>
-#endif /* TIOCSTAT_IN_SYS_IOCTL */
-
-/* Some standard library routines. */
-#include "readline.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-/* **************************************************************** */
-/* */
-/* Utility Functions */
-/* */
-/* **************************************************************** */
-
-/* Return 0 if C is not a member of the class of characters that belong
- in words, or 1 if it is. */
-
-int _rl_allow_pathname_alphabetic_chars = 0;
-static const char *pathname_alphabetic_chars = "/-_=~.#$";
-
-int
-rl_alphabetic (c)
- int c;
-{
- if (ALPHABETIC (c))
- return (1);
-
- return (_rl_allow_pathname_alphabetic_chars &&
- strchr (pathname_alphabetic_chars, c) != NULL);
-}
-
-/* How to abort things. */
-int
-_rl_abort_internal ()
-{
- rl_ding ();
- rl_clear_message ();
- _rl_init_argument ();
- rl_clear_pending_input ();
-
- RL_UNSETSTATE (RL_STATE_MACRODEF);
- while (rl_executing_macro)
- _rl_pop_executing_macro ();
-
- rl_last_func = (rl_command_func_t *)NULL;
- longjmp (readline_top_level, 1);
- return (0);
-}
-
-int
-rl_abort (count, key)
- int count, key;
-{
- return (_rl_abort_internal ());
-}
-
-int
-rl_tty_status (count, key)
- int count, key;
-{
-#if defined (TIOCSTAT)
- ioctl (1, TIOCSTAT, (char *)0);
- rl_refresh_line (count, key);
-#else
- rl_ding ();
-#endif
- return 0;
-}
-
-/* Return a copy of the string between FROM and TO.
- FROM is inclusive, TO is not. */
-char *
-rl_copy_text (from, to)
- int from, to;
-{
- register int length;
- char *copy;
-
- /* Fix it if the caller is confused. */
- if (from > to)
- SWAP (from, to);
-
- length = to - from;
- copy = (char *)xmalloc (1 + length);
- strncpy (copy, rl_line_buffer + from, length);
- copy[length] = '\0';
- return (copy);
-}
-
-/* Increase the size of RL_LINE_BUFFER until it has enough space to hold
- LEN characters. */
-void
-rl_extend_line_buffer (len)
- int len;
-{
- while (len >= rl_line_buffer_len)
- {
- rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
- rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
- }
-
- _rl_set_the_line ();
-}
-
-
-/* A function for simple tilde expansion. */
-int
-rl_tilde_expand (ignore, key)
- int ignore, key;
-{
- register int start, end;
- char *homedir, *temp;
- int len;
-
- end = rl_point;
- start = end - 1;
-
- if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
- {
- homedir = tilde_expand ("~");
- _rl_replace_text (homedir, start, end);
- return (0);
- }
- else if (rl_line_buffer[start] != '~')
- {
- for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--)
- ;
- start++;
- }
-
- end = start;
- do
- end++;
- while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end);
-
- if (whitespace (rl_line_buffer[end]) || end >= rl_end)
- end--;
-
- /* If the first character of the current word is a tilde, perform
- tilde expansion and insert the result. If not a tilde, do
- nothing. */
- if (rl_line_buffer[start] == '~')
- {
- len = end - start + 1;
- temp = (char *)xmalloc (len + 1);
- strncpy (temp, rl_line_buffer + start, len);
- temp[len] = '\0';
- homedir = tilde_expand (temp);
- free (temp);
-
- _rl_replace_text (homedir, start, end);
- }
-
- return (0);
-}
-
-/* **************************************************************** */
-/* */
-/* String Utility Functions */
-/* */
-/* **************************************************************** */
-
-/* Determine if s2 occurs in s1. If so, return a pointer to the
- match in s1. The compare is case insensitive. */
-char *
-_rl_strindex (s1, s2)
- register const char *s1, *s2;
-{
- register int i, l, len;
-
- for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
- if (_rl_strnicmp (s1 + i, s2, l) == 0)
- return ((char *) (s1 + i));
- return ((char *)NULL);
-}
-
-#ifndef HAVE_STRPBRK
-/* Find the first occurrence in STRING1 of any character from STRING2.
- Return a pointer to the character in STRING1. */
-char *
-_rl_strpbrk (string1, string2)
- const char *string1, *string2;
-{
- register const char *scan;
-#if defined (HANDLE_MULTIBYTE)
- mbstate_t ps;
- register int i, v;
-
- memset (&ps, 0, sizeof (mbstate_t));
-#endif
-
- for (; *string1; string1++)
- {
- for (scan = string2; *scan; scan++)
- {
- if (*string1 == *scan)
- return ((char *)string1);
- }
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- v = _rl_get_char_len (string1, &ps);
- if (v > 1)
- string += v - 1; /* -1 to account for auto-increment in loop */
- }
-#endif
- }
- return ((char *)NULL);
-}
-#endif
-
-#if !defined (HAVE_STRCASECMP)
-/* Compare at most COUNT characters from string1 to string2. Case
- doesn't matter. */
-int
-_rl_strnicmp (string1, string2, count)
- const char *string1, *string2;
- int count;
-{
- register char ch1, ch2;
-
- while (count)
- {
- ch1 = *string1++;
- ch2 = *string2++;
- if (_rl_to_upper(ch1) == _rl_to_upper(ch2))
- count--;
- else
- break;
- }
- return (count);
-}
-
-/* strcmp (), but caseless. */
-int
-_rl_stricmp (string1, string2)
- const char *string1, *string2;
-{
- register char ch1, ch2;
-
- while (*string1 && *string2)
- {
- ch1 = *string1++;
- ch2 = *string2++;
- if (_rl_to_upper(ch1) != _rl_to_upper(ch2))
- return (1);
- }
- return (*string1 - *string2);
-}
-#endif /* !HAVE_STRCASECMP */
-
-/* Stupid comparison routine for qsort () ing strings. */
-int
-_rl_qsort_string_compare (s1, s2)
- char **s1, **s2;
-{
-#if defined (HAVE_STRCOLL)
- return (strcoll (*s1, *s2));
-#else
- int result;
-
- result = **s1 - **s2;
- if (result == 0)
- result = strcmp (*s1, *s2);
-
- return result;
-#endif
-}
-
-/* Function equivalents for the macros defined in chardefs.h. */
-#define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); }
-
-FUNCTION_FOR_MACRO (_rl_digit_p)
-FUNCTION_FOR_MACRO (_rl_digit_value)
-FUNCTION_FOR_MACRO (_rl_lowercase_p)
-FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
-FUNCTION_FOR_MACRO (_rl_to_lower)
-FUNCTION_FOR_MACRO (_rl_to_upper)
-FUNCTION_FOR_MACRO (_rl_uppercase_p)
-
-/* Backwards compatibility, now that savestring has been removed from
- all `public' readline header files. */
-#undef _rl_savestring
-char *
-_rl_savestring (s)
- const char *s;
-{
- return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
-}
+/* util.c -- readline utility functions */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "posixjmp.h"
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h> /* for _POSIX_VERSION */
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <stdio.h>
+#include <ctype.h>
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+#if defined (TIOCSTAT_IN_SYS_IOCTL)
+# include <sys/ioctl.h>
+#endif /* TIOCSTAT_IN_SYS_IOCTL */
+
+/* Some standard library routines. */
+#include "readline.h"
+
+#include "rlprivate.h"
+#include "xmalloc.h"
+
+/* **************************************************************** */
+/* */
+/* Utility Functions */
+/* */
+/* **************************************************************** */
+
+/* Return 0 if C is not a member of the class of characters that belong
+ in words, or 1 if it is. */
+
+int _rl_allow_pathname_alphabetic_chars = 0;
+static const char *pathname_alphabetic_chars = "/-_=~.#$";
+
+int
+rl_alphabetic (c)
+ int c;
+{
+ if (ALPHABETIC (c))
+ return (1);
+
+ return (_rl_allow_pathname_alphabetic_chars &&
+ strchr (pathname_alphabetic_chars, c) != NULL);
+}
+
+/* How to abort things. */
+int
+_rl_abort_internal ()
+{
+ rl_ding ();
+ rl_clear_message ();
+ _rl_init_argument ();
+ rl_clear_pending_input ();
+
+ RL_UNSETSTATE (RL_STATE_MACRODEF);
+ while (rl_executing_macro)
+ _rl_pop_executing_macro ();
+
+ rl_last_func = (rl_command_func_t *)NULL;
+ longjmp (readline_top_level, 1);
+ return (0);
+}
+
+int
+rl_abort (count, key)
+ int count, key;
+{
+ return (_rl_abort_internal ());
+}
+
+int
+rl_tty_status (count, key)
+ int count, key;
+{
+#if defined (TIOCSTAT)
+ ioctl (1, TIOCSTAT, (char *)0);
+ rl_refresh_line (count, key);
+#else
+ rl_ding ();
+#endif
+ return 0;
+}
+
+/* Return a copy of the string between FROM and TO.
+ FROM is inclusive, TO is not. */
+char *
+rl_copy_text (from, to)
+ int from, to;
+{
+ register int length;
+ char *copy;
+
+ /* Fix it if the caller is confused. */
+ if (from > to)
+ SWAP (from, to);
+
+ length = to - from;
+ copy = (char *)xmalloc (1 + length);
+ strncpy (copy, rl_line_buffer + from, length);
+ copy[length] = '\0';
+ return (copy);
+}
+
+/* Increase the size of RL_LINE_BUFFER until it has enough space to hold
+ LEN characters. */
+void
+rl_extend_line_buffer (len)
+ int len;
+{
+ while (len >= rl_line_buffer_len)
+ {
+ rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
+ rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
+ }
+
+ _rl_set_the_line ();
+}
+
+
+/* A function for simple tilde expansion. */
+int
+rl_tilde_expand (ignore, key)
+ int ignore, key;
+{
+ register int start, end;
+ char *homedir, *temp;
+ int len;
+
+ end = rl_point;
+ start = end - 1;
+
+ if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
+ {
+ homedir = tilde_expand ("~");
+ _rl_replace_text (homedir, start, end);
+ return (0);
+ }
+ else if (rl_line_buffer[start] != '~')
+ {
+ for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--)
+ ;
+ start++;
+ }
+
+ end = start;
+ do
+ end++;
+ while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end);
+
+ if (whitespace (rl_line_buffer[end]) || end >= rl_end)
+ end--;
+
+ /* If the first character of the current word is a tilde, perform
+ tilde expansion and insert the result. If not a tilde, do
+ nothing. */
+ if (rl_line_buffer[start] == '~')
+ {
+ len = end - start + 1;
+ temp = (char *)xmalloc (len + 1);
+ strncpy (temp, rl_line_buffer + start, len);
+ temp[len] = '\0';
+ homedir = tilde_expand (temp);
+ free (temp);
+
+ _rl_replace_text (homedir, start, end);
+ }
+
+ return (0);
+}
+
+/* **************************************************************** */
+/* */
+/* String Utility Functions */
+/* */
+/* **************************************************************** */
+
+/* Determine if s2 occurs in s1. If so, return a pointer to the
+ match in s1. The compare is case insensitive. */
+char *
+_rl_strindex (s1, s2)
+ register const char *s1, *s2;
+{
+ register int i, l, len;
+
+ for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
+ if (_rl_strnicmp (s1 + i, s2, l) == 0)
+ return ((char *) (s1 + i));
+ return ((char *)NULL);
+}
+
+#ifndef HAVE_STRPBRK
+/* Find the first occurrence in STRING1 of any character from STRING2.
+ Return a pointer to the character in STRING1. */
+char *
+_rl_strpbrk (string1, string2)
+ const char *string1, *string2;
+{
+ register const char *scan;
+#if defined (HANDLE_MULTIBYTE)
+ mbstate_t ps;
+ register int i, v;
+
+ memset (&ps, 0, sizeof (mbstate_t));
+#endif
+
+ for (; *string1; string1++)
+ {
+ for (scan = string2; *scan; scan++)
+ {
+ if (*string1 == *scan)
+ return ((char *)string1);
+ }
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ v = _rl_get_char_len (string1, &ps);
+ if (v > 1)
+ string += v - 1; /* -1 to account for auto-increment in loop */
+ }
+#endif
+ }
+ return ((char *)NULL);
+}
+#endif
+
+#if !defined (HAVE_STRCASECMP)
+/* Compare at most COUNT characters from string1 to string2. Case
+ doesn't matter. */
+int
+_rl_strnicmp (string1, string2, count)
+ const char *string1, *string2;
+ int count;
+{
+ register char ch1, ch2;
+
+ while (count)
+ {
+ ch1 = *string1++;
+ ch2 = *string2++;
+ if (_rl_to_upper(ch1) == _rl_to_upper(ch2))
+ count--;
+ else
+ break;
+ }
+ return (count);
+}
+
+/* strcmp (), but caseless. */
+int
+_rl_stricmp (string1, string2)
+ const char *string1, *string2;
+{
+ register char ch1, ch2;
+
+ while (*string1 && *string2)
+ {
+ ch1 = *string1++;
+ ch2 = *string2++;
+ if (_rl_to_upper(ch1) != _rl_to_upper(ch2))
+ return (1);
+ }
+ return (*string1 - *string2);
+}
+#endif /* !HAVE_STRCASECMP */
+
+/* Stupid comparison routine for qsort () ing strings. */
+int
+_rl_qsort_string_compare (s1, s2)
+ char **s1, **s2;
+{
+#if defined (HAVE_STRCOLL)
+ return (strcoll (*s1, *s2));
+#else
+ int result;
+
+ result = **s1 - **s2;
+ if (result == 0)
+ result = strcmp (*s1, *s2);
+
+ return result;
+#endif
+}
+
+/* Function equivalents for the macros defined in chardefs.h. */
+#define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); }
+
+FUNCTION_FOR_MACRO (_rl_digit_p)
+FUNCTION_FOR_MACRO (_rl_digit_value)
+FUNCTION_FOR_MACRO (_rl_lowercase_p)
+FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
+FUNCTION_FOR_MACRO (_rl_to_lower)
+FUNCTION_FOR_MACRO (_rl_to_upper)
+FUNCTION_FOR_MACRO (_rl_uppercase_p)
+
+/* Backwards compatibility, now that savestring has been removed from
+ all `public' readline header files. */
+#undef _rl_savestring
+char *
+_rl_savestring (s)
+ const char *s;
+{
+ return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
+}
diff --git a/MSVC/readline/vi_keymap.c b/MSVC/readline/vi_keymap.c
index 7962714..53a67c6 100644
--- a/MSVC/readline/vi_keymap.c
+++ b/MSVC/readline/vi_keymap.c
@@ -1,877 +1,877 @@
-/* vi_keymap.c -- the keymap for vi_mode in readline (). */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (BUFSIZ)
-#include <stdio.h>
-#endif /* !BUFSIZ */
-
-#include "readline.h"
-
-#if 0
-extern KEYMAP_ENTRY_ARRAY vi_escape_keymap;
-#endif
-
-/* The keymap arrays for handling vi mode. */
-KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
- /* The regular control keys come first. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */
- { ISFUNC, rl_vi_eof_maybe }, /* Control-d */
- { ISFUNC, rl_emacs_editing_mode }, /* Control-e */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */
- { ISFUNC, rl_abort }, /* Control-g */
- { ISFUNC, rl_backward_char }, /* Control-h */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-i */
- { ISFUNC, rl_newline }, /* Control-j */
- { ISFUNC, rl_kill_line }, /* Control-k */
- { ISFUNC, rl_clear_screen }, /* Control-l */
- { ISFUNC, rl_newline }, /* Control-m */
- { ISFUNC, rl_get_next_history }, /* Control-n */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */
- { ISFUNC, rl_get_previous_history }, /* Control-p */
- { ISFUNC, rl_quoted_insert }, /* Control-q */
- { ISFUNC, rl_reverse_search_history }, /* Control-r */
- { ISFUNC, rl_forward_search_history }, /* Control-s */
- { ISFUNC, rl_transpose_chars }, /* Control-t */
- { ISFUNC, rl_unix_line_discard }, /* Control-u */
- { ISFUNC, rl_quoted_insert }, /* Control-v */
- { ISFUNC, rl_unix_word_rubout }, /* Control-w */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */
- { ISFUNC, rl_yank }, /* Control-y */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
-
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-[ */ /* vi_escape_keymap */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
- { ISFUNC, rl_vi_undo }, /* Control-_ */
-
- /* The start of printing characters. */
- { ISFUNC, rl_forward_char }, /* SPACE */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* " */
- { ISFUNC, rl_insert_comment }, /* # */
- { ISFUNC, rl_end_of_line }, /* $ */
- { ISFUNC, rl_vi_match }, /* % */
- { ISFUNC, rl_vi_tilde_expand }, /* & */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ( */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ) */
- { ISFUNC, rl_vi_complete }, /* * */
- { ISFUNC, rl_get_next_history}, /* + */
- { ISFUNC, rl_vi_char_search }, /* , */
- { ISFUNC, rl_get_previous_history }, /* - */
- { ISFUNC, rl_vi_redo }, /* . */
- { ISFUNC, rl_vi_search }, /* / */
-
- /* Regular digits. */
- { ISFUNC, rl_beg_of_line }, /* 0 */
- { ISFUNC, rl_vi_arg_digit }, /* 1 */
- { ISFUNC, rl_vi_arg_digit }, /* 2 */
- { ISFUNC, rl_vi_arg_digit }, /* 3 */
- { ISFUNC, rl_vi_arg_digit }, /* 4 */
- { ISFUNC, rl_vi_arg_digit }, /* 5 */
- { ISFUNC, rl_vi_arg_digit }, /* 6 */
- { ISFUNC, rl_vi_arg_digit }, /* 7 */
- { ISFUNC, rl_vi_arg_digit }, /* 8 */
- { ISFUNC, rl_vi_arg_digit }, /* 9 */
-
- /* A little more punctuation. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* : */
- { ISFUNC, rl_vi_char_search }, /* ; */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* < */
- { ISFUNC, rl_vi_complete }, /* = */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* > */
- { ISFUNC, rl_vi_search }, /* ? */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */
-
- /* Uppercase alphabet. */
- { ISFUNC, rl_vi_append_eol }, /* A */
- { ISFUNC, rl_vi_prev_word}, /* B */
- { ISFUNC, rl_vi_change_to }, /* C */
- { ISFUNC, rl_vi_delete_to }, /* D */
- { ISFUNC, rl_vi_end_word }, /* E */
- { ISFUNC, rl_vi_char_search }, /* F */
- { ISFUNC, rl_vi_fetch_history }, /* G */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* H */
- { ISFUNC, rl_vi_insert_beg }, /* I */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* J */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* K */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* L */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* M */
- { ISFUNC, rl_vi_search_again }, /* N */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* O */
- { ISFUNC, rl_vi_put }, /* P */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Q */
- { ISFUNC, rl_vi_replace }, /* R */
- { ISFUNC, rl_vi_subst }, /* S */
- { ISFUNC, rl_vi_char_search }, /* T */
- { ISFUNC, rl_revert_line }, /* U */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* V */
- { ISFUNC, rl_vi_next_word }, /* W */
- { ISFUNC, rl_rubout }, /* X */
- { ISFUNC, rl_vi_yank_to }, /* Y */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Z */
-
- /* Some more punctuation. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* [ */
- { ISFUNC, rl_vi_complete }, /* \ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */
- { ISFUNC, rl_vi_first_print }, /* ^ */
- { ISFUNC, rl_vi_yank_arg }, /* _ */
- { ISFUNC, rl_vi_goto_mark }, /* ` */
-
- /* Lowercase alphabet. */
- { ISFUNC, rl_vi_append_mode }, /* a */
- { ISFUNC, rl_vi_prev_word }, /* b */
- { ISFUNC, rl_vi_change_to }, /* c */
- { ISFUNC, rl_vi_delete_to }, /* d */
- { ISFUNC, rl_vi_end_word }, /* e */
- { ISFUNC, rl_vi_char_search }, /* f */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* g */
- { ISFUNC, rl_backward_char }, /* h */
- { ISFUNC, rl_vi_insertion_mode }, /* i */
- { ISFUNC, rl_get_next_history }, /* j */
- { ISFUNC, rl_get_previous_history }, /* k */
- { ISFUNC, rl_forward_char }, /* l */
- { ISFUNC, rl_vi_set_mark }, /* m */
- { ISFUNC, rl_vi_search_again }, /* n */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* o */
- { ISFUNC, rl_vi_put }, /* p */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* q */
- { ISFUNC, rl_vi_change_char }, /* r */
- { ISFUNC, rl_vi_subst }, /* s */
- { ISFUNC, rl_vi_char_search }, /* t */
- { ISFUNC, rl_vi_undo }, /* u */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* v */
- { ISFUNC, rl_vi_next_word }, /* w */
- { ISFUNC, rl_vi_delete }, /* x */
- { ISFUNC, rl_vi_yank_to }, /* y */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* z */
-
- /* Final punctuation. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* { */
- { ISFUNC, rl_vi_column }, /* | */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* } */
- { ISFUNC, rl_vi_change_case }, /* ~ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* RUBOUT */
-
-#if KEYMAP_SIZE > 128
- /* Undefined keys. */
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 }
-#endif /* KEYMAP_SIZE > 128 */
-};
-
-
-KEYMAP_ENTRY_ARRAY vi_insertion_keymap = {
- /* The regular control keys come first. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */
- { ISFUNC, rl_insert }, /* Control-a */
- { ISFUNC, rl_insert }, /* Control-b */
- { ISFUNC, rl_insert }, /* Control-c */
- { ISFUNC, rl_vi_eof_maybe }, /* Control-d */
- { ISFUNC, rl_insert }, /* Control-e */
- { ISFUNC, rl_insert }, /* Control-f */
- { ISFUNC, rl_insert }, /* Control-g */
- { ISFUNC, rl_rubout }, /* Control-h */
- { ISFUNC, rl_complete }, /* Control-i */
- { ISFUNC, rl_newline }, /* Control-j */
- { ISFUNC, rl_insert }, /* Control-k */
- { ISFUNC, rl_insert }, /* Control-l */
- { ISFUNC, rl_newline }, /* Control-m */
- { ISFUNC, rl_insert }, /* Control-n */
- { ISFUNC, rl_insert }, /* Control-o */
- { ISFUNC, rl_insert }, /* Control-p */
- { ISFUNC, rl_insert }, /* Control-q */
- { ISFUNC, rl_reverse_search_history }, /* Control-r */
- { ISFUNC, rl_forward_search_history }, /* Control-s */
- { ISFUNC, rl_transpose_chars }, /* Control-t */
- { ISFUNC, rl_unix_line_discard }, /* Control-u */
- { ISFUNC, rl_quoted_insert }, /* Control-v */
- { ISFUNC, rl_unix_word_rubout }, /* Control-w */
- { ISFUNC, rl_insert }, /* Control-x */
- { ISFUNC, rl_yank }, /* Control-y */
- { ISFUNC, rl_insert }, /* Control-z */
-
- { ISFUNC, rl_vi_movement_mode }, /* Control-[ */
- { ISFUNC, rl_insert }, /* Control-\ */
- { ISFUNC, rl_insert }, /* Control-] */
- { ISFUNC, rl_insert }, /* Control-^ */
- { ISFUNC, rl_vi_undo }, /* Control-_ */
-
- /* The start of printing characters. */
- { ISFUNC, rl_insert }, /* SPACE */
- { ISFUNC, rl_insert }, /* ! */
- { ISFUNC, rl_insert }, /* " */
- { ISFUNC, rl_insert }, /* # */
- { ISFUNC, rl_insert }, /* $ */
- { ISFUNC, rl_insert }, /* % */
- { ISFUNC, rl_insert }, /* & */
- { ISFUNC, rl_insert }, /* ' */
- { ISFUNC, rl_insert }, /* ( */
- { ISFUNC, rl_insert }, /* ) */
- { ISFUNC, rl_insert }, /* * */
- { ISFUNC, rl_insert }, /* + */
- { ISFUNC, rl_insert }, /* , */
- { ISFUNC, rl_insert }, /* - */
- { ISFUNC, rl_insert }, /* . */
- { ISFUNC, rl_insert }, /* / */
-
- /* Regular digits. */
- { ISFUNC, rl_insert }, /* 0 */
- { ISFUNC, rl_insert }, /* 1 */
- { ISFUNC, rl_insert }, /* 2 */
- { ISFUNC, rl_insert }, /* 3 */
- { ISFUNC, rl_insert }, /* 4 */
- { ISFUNC, rl_insert }, /* 5 */
- { ISFUNC, rl_insert }, /* 6 */
- { ISFUNC, rl_insert }, /* 7 */
- { ISFUNC, rl_insert }, /* 8 */
- { ISFUNC, rl_insert }, /* 9 */
-
- /* A little more punctuation. */
- { ISFUNC, rl_insert }, /* : */
- { ISFUNC, rl_insert }, /* ; */
- { ISFUNC, rl_insert }, /* < */
- { ISFUNC, rl_insert }, /* = */
- { ISFUNC, rl_insert }, /* > */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* @ */
-
- /* Uppercase alphabet. */
- { ISFUNC, rl_insert }, /* A */
- { ISFUNC, rl_insert }, /* B */
- { ISFUNC, rl_insert }, /* C */
- { ISFUNC, rl_insert }, /* D */
- { ISFUNC, rl_insert }, /* E */
- { ISFUNC, rl_insert }, /* F */
- { ISFUNC, rl_insert }, /* G */
- { ISFUNC, rl_insert }, /* H */
- { ISFUNC, rl_insert }, /* I */
- { ISFUNC, rl_insert }, /* J */
- { ISFUNC, rl_insert }, /* K */
- { ISFUNC, rl_insert }, /* L */
- { ISFUNC, rl_insert }, /* M */
- { ISFUNC, rl_insert }, /* N */
- { ISFUNC, rl_insert }, /* O */
- { ISFUNC, rl_insert }, /* P */
- { ISFUNC, rl_insert }, /* Q */
- { ISFUNC, rl_insert }, /* R */
- { ISFUNC, rl_insert }, /* S */
- { ISFUNC, rl_insert }, /* T */
- { ISFUNC, rl_insert }, /* U */
- { ISFUNC, rl_insert }, /* V */
- { ISFUNC, rl_insert }, /* W */
- { ISFUNC, rl_insert }, /* X */
- { ISFUNC, rl_insert }, /* Y */
- { ISFUNC, rl_insert }, /* Z */
-
- /* Some more punctuation. */
- { ISFUNC, rl_insert }, /* [ */
- { ISFUNC, rl_insert }, /* \ */
- { ISFUNC, rl_insert }, /* ] */
- { ISFUNC, rl_insert }, /* ^ */
- { ISFUNC, rl_insert }, /* _ */
- { ISFUNC, rl_insert }, /* ` */
-
- /* Lowercase alphabet. */
- { ISFUNC, rl_insert }, /* a */
- { ISFUNC, rl_insert }, /* b */
- { ISFUNC, rl_insert }, /* c */
- { ISFUNC, rl_insert }, /* d */
- { ISFUNC, rl_insert }, /* e */
- { ISFUNC, rl_insert }, /* f */
- { ISFUNC, rl_insert }, /* g */
- { ISFUNC, rl_insert }, /* h */
- { ISFUNC, rl_insert }, /* i */
- { ISFUNC, rl_insert }, /* j */
- { ISFUNC, rl_insert }, /* k */
- { ISFUNC, rl_insert }, /* l */
- { ISFUNC, rl_insert }, /* m */
- { ISFUNC, rl_insert }, /* n */
- { ISFUNC, rl_insert }, /* o */
- { ISFUNC, rl_insert }, /* p */
- { ISFUNC, rl_insert }, /* q */
- { ISFUNC, rl_insert }, /* r */
- { ISFUNC, rl_insert }, /* s */
- { ISFUNC, rl_insert }, /* t */
- { ISFUNC, rl_insert }, /* u */
- { ISFUNC, rl_insert }, /* v */
- { ISFUNC, rl_insert }, /* w */
- { ISFUNC, rl_insert }, /* x */
- { ISFUNC, rl_insert }, /* y */
- { ISFUNC, rl_insert }, /* z */
-
- /* Final punctuation. */
- { ISFUNC, rl_insert }, /* { */
- { ISFUNC, rl_insert }, /* | */
- { ISFUNC, rl_insert }, /* } */
- { ISFUNC, rl_insert }, /* ~ */
- { ISFUNC, rl_rubout }, /* RUBOUT */
-
-#if KEYMAP_SIZE > 128
- /* Pure 8-bit characters (128 - 159).
- These might be used in some
- character sets. */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
- { ISFUNC, rl_insert }, /* ? */
-
- /* ISO Latin-1 characters (160 - 255) */
- { ISFUNC, rl_insert }, /* No-break space */
- { ISFUNC, rl_insert }, /* Inverted exclamation mark */
- { ISFUNC, rl_insert }, /* Cent sign */
- { ISFUNC, rl_insert }, /* Pound sign */
- { ISFUNC, rl_insert }, /* Currency sign */
- { ISFUNC, rl_insert }, /* Yen sign */
- { ISFUNC, rl_insert }, /* Broken bar */
- { ISFUNC, rl_insert }, /* Section sign */
- { ISFUNC, rl_insert }, /* Diaeresis */
- { ISFUNC, rl_insert }, /* Copyright sign */
- { ISFUNC, rl_insert }, /* Feminine ordinal indicator */
- { ISFUNC, rl_insert }, /* Left pointing double angle quotation mark */
- { ISFUNC, rl_insert }, /* Not sign */
- { ISFUNC, rl_insert }, /* Soft hyphen */
- { ISFUNC, rl_insert }, /* Registered sign */
- { ISFUNC, rl_insert }, /* Macron */
- { ISFUNC, rl_insert }, /* Degree sign */
- { ISFUNC, rl_insert }, /* Plus-minus sign */
- { ISFUNC, rl_insert }, /* Superscript two */
- { ISFUNC, rl_insert }, /* Superscript three */
- { ISFUNC, rl_insert }, /* Acute accent */
- { ISFUNC, rl_insert }, /* Micro sign */
- { ISFUNC, rl_insert }, /* Pilcrow sign */
- { ISFUNC, rl_insert }, /* Middle dot */
- { ISFUNC, rl_insert }, /* Cedilla */
- { ISFUNC, rl_insert }, /* Superscript one */
- { ISFUNC, rl_insert }, /* Masculine ordinal indicator */
- { ISFUNC, rl_insert }, /* Right pointing double angle quotation mark */
- { ISFUNC, rl_insert }, /* Vulgar fraction one quarter */
- { ISFUNC, rl_insert }, /* Vulgar fraction one half */
- { ISFUNC, rl_insert }, /* Vulgar fraction three quarters */
- { ISFUNC, rl_insert }, /* Inverted questionk mark */
- { ISFUNC, rl_insert }, /* Latin capital letter a with grave */
- { ISFUNC, rl_insert }, /* Latin capital letter a with acute */
- { ISFUNC, rl_insert }, /* Latin capital letter a with circumflex */
- { ISFUNC, rl_insert }, /* Latin capital letter a with tilde */
- { ISFUNC, rl_insert }, /* Latin capital letter a with diaeresis */
- { ISFUNC, rl_insert }, /* Latin capital letter a with ring above */
- { ISFUNC, rl_insert }, /* Latin capital letter ae */
- { ISFUNC, rl_insert }, /* Latin capital letter c with cedilla */
- { ISFUNC, rl_insert }, /* Latin capital letter e with grave */
- { ISFUNC, rl_insert }, /* Latin capital letter e with acute */
- { ISFUNC, rl_insert }, /* Latin capital letter e with circumflex */
- { ISFUNC, rl_insert }, /* Latin capital letter e with diaeresis */
- { ISFUNC, rl_insert }, /* Latin capital letter i with grave */
- { ISFUNC, rl_insert }, /* Latin capital letter i with acute */
- { ISFUNC, rl_insert }, /* Latin capital letter i with circumflex */
- { ISFUNC, rl_insert }, /* Latin capital letter i with diaeresis */
- { ISFUNC, rl_insert }, /* Latin capital letter eth (Icelandic) */
- { ISFUNC, rl_insert }, /* Latin capital letter n with tilde */
- { ISFUNC, rl_insert }, /* Latin capital letter o with grave */
- { ISFUNC, rl_insert }, /* Latin capital letter o with acute */
- { ISFUNC, rl_insert }, /* Latin capital letter o with circumflex */
- { ISFUNC, rl_insert }, /* Latin capital letter o with tilde */
- { ISFUNC, rl_insert }, /* Latin capital letter o with diaeresis */
- { ISFUNC, rl_insert }, /* Multiplication sign */
- { ISFUNC, rl_insert }, /* Latin capital letter o with stroke */
- { ISFUNC, rl_insert }, /* Latin capital letter u with grave */
- { ISFUNC, rl_insert }, /* Latin capital letter u with acute */
- { ISFUNC, rl_insert }, /* Latin capital letter u with circumflex */
- { ISFUNC, rl_insert }, /* Latin capital letter u with diaeresis */
- { ISFUNC, rl_insert }, /* Latin capital letter Y with acute */
- { ISFUNC, rl_insert }, /* Latin capital letter thorn (Icelandic) */
- { ISFUNC, rl_insert }, /* Latin small letter sharp s (German) */
- { ISFUNC, rl_insert }, /* Latin small letter a with grave */
- { ISFUNC, rl_insert }, /* Latin small letter a with acute */
- { ISFUNC, rl_insert }, /* Latin small letter a with circumflex */
- { ISFUNC, rl_insert }, /* Latin small letter a with tilde */
- { ISFUNC, rl_insert }, /* Latin small letter a with diaeresis */
- { ISFUNC, rl_insert }, /* Latin small letter a with ring above */
- { ISFUNC, rl_insert }, /* Latin small letter ae */
- { ISFUNC, rl_insert }, /* Latin small letter c with cedilla */
- { ISFUNC, rl_insert }, /* Latin small letter e with grave */
- { ISFUNC, rl_insert }, /* Latin small letter e with acute */
- { ISFUNC, rl_insert }, /* Latin small letter e with circumflex */
- { ISFUNC, rl_insert }, /* Latin small letter e with diaeresis */
- { ISFUNC, rl_insert }, /* Latin small letter i with grave */
- { ISFUNC, rl_insert }, /* Latin small letter i with acute */
- { ISFUNC, rl_insert }, /* Latin small letter i with circumflex */
- { ISFUNC, rl_insert }, /* Latin small letter i with diaeresis */
- { ISFUNC, rl_insert }, /* Latin small letter eth (Icelandic) */
- { ISFUNC, rl_insert }, /* Latin small letter n with tilde */
- { ISFUNC, rl_insert }, /* Latin small letter o with grave */
- { ISFUNC, rl_insert }, /* Latin small letter o with acute */
- { ISFUNC, rl_insert }, /* Latin small letter o with circumflex */
- { ISFUNC, rl_insert }, /* Latin small letter o with tilde */
- { ISFUNC, rl_insert }, /* Latin small letter o with diaeresis */
- { ISFUNC, rl_insert }, /* Division sign */
- { ISFUNC, rl_insert }, /* Latin small letter o with stroke */
- { ISFUNC, rl_insert }, /* Latin small letter u with grave */
- { ISFUNC, rl_insert }, /* Latin small letter u with acute */
- { ISFUNC, rl_insert }, /* Latin small letter u with circumflex */
- { ISFUNC, rl_insert }, /* Latin small letter u with diaeresis */
- { ISFUNC, rl_insert }, /* Latin small letter y with acute */
- { ISFUNC, rl_insert }, /* Latin small letter thorn (Icelandic) */
- { ISFUNC, rl_insert } /* Latin small letter y with diaeresis */
-#endif /* KEYMAP_SIZE > 128 */
-};
-
-/* Unused for the time being. */
-#if 0
-KEYMAP_ENTRY_ARRAY vi_escape_keymap = {
- /* The regular control keys come first. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-d */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-e */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-g */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-h */
- { ISFUNC, rl_tab_insert}, /* Control-i */
- { ISFUNC, rl_emacs_editing_mode}, /* Control-j */
- { ISFUNC, rl_kill_line }, /* Control-k */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-l */
- { ISFUNC, rl_emacs_editing_mode}, /* Control-m */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-n */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-p */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-q */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-r */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-s */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-t */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-u */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-v */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-w */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-y */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
-
- { ISFUNC, rl_vi_movement_mode }, /* Control-[ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
- { ISFUNC, rl_vi_undo }, /* Control-_ */
-
- /* The start of printing characters. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* SPACE */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* " */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* # */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* $ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* % */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* & */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ( */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ) */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* * */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* + */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* , */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* - */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* . */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* / */
-
- /* Regular digits. */
- { ISFUNC, rl_vi_arg_digit }, /* 0 */
- { ISFUNC, rl_vi_arg_digit }, /* 1 */
- { ISFUNC, rl_vi_arg_digit }, /* 2 */
- { ISFUNC, rl_vi_arg_digit }, /* 3 */
- { ISFUNC, rl_vi_arg_digit }, /* 4 */
- { ISFUNC, rl_vi_arg_digit }, /* 5 */
- { ISFUNC, rl_vi_arg_digit }, /* 6 */
- { ISFUNC, rl_vi_arg_digit }, /* 7 */
- { ISFUNC, rl_vi_arg_digit }, /* 8 */
- { ISFUNC, rl_vi_arg_digit }, /* 9 */
-
- /* A little more punctuation. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* : */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ; */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* < */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* = */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* > */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ? */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */
-
- /* Uppercase alphabet. */
- { ISFUNC, rl_do_lowercase_version }, /* A */
- { ISFUNC, rl_do_lowercase_version }, /* B */
- { ISFUNC, rl_do_lowercase_version }, /* C */
- { ISFUNC, rl_do_lowercase_version }, /* D */
- { ISFUNC, rl_do_lowercase_version }, /* E */
- { ISFUNC, rl_do_lowercase_version }, /* F */
- { ISFUNC, rl_do_lowercase_version }, /* G */
- { ISFUNC, rl_do_lowercase_version }, /* H */
- { ISFUNC, rl_do_lowercase_version }, /* I */
- { ISFUNC, rl_do_lowercase_version }, /* J */
- { ISFUNC, rl_do_lowercase_version }, /* K */
- { ISFUNC, rl_do_lowercase_version }, /* L */
- { ISFUNC, rl_do_lowercase_version }, /* M */
- { ISFUNC, rl_do_lowercase_version }, /* N */
- { ISFUNC, rl_do_lowercase_version }, /* O */
- { ISFUNC, rl_do_lowercase_version }, /* P */
- { ISFUNC, rl_do_lowercase_version }, /* Q */
- { ISFUNC, rl_do_lowercase_version }, /* R */
- { ISFUNC, rl_do_lowercase_version }, /* S */
- { ISFUNC, rl_do_lowercase_version }, /* T */
- { ISFUNC, rl_do_lowercase_version }, /* U */
- { ISFUNC, rl_do_lowercase_version }, /* V */
- { ISFUNC, rl_do_lowercase_version }, /* W */
- { ISFUNC, rl_do_lowercase_version }, /* X */
- { ISFUNC, rl_do_lowercase_version }, /* Y */
- { ISFUNC, rl_do_lowercase_version }, /* Z */
-
- /* Some more punctuation. */
- { ISFUNC, rl_arrow_keys }, /* [ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* \ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ^ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* _ */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ` */
-
- /* Lowercase alphabet. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* a */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* b */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* c */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* d */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* e */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* f */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* g */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* h */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* i */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* j */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* k */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* l */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* m */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* n */
- { ISFUNC, rl_arrow_keys }, /* o */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* p */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* q */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* r */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* s */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* t */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* u */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* v */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* w */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* x */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* y */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* z */
-
- /* Final punctuation. */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* { */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* | */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* } */
- { ISFUNC, (rl_command_func_t *)0x0 }, /* ~ */
- { ISFUNC, rl_backward_kill_word }, /* RUBOUT */
-
-#if KEYMAP_SIZE > 128
- /* Undefined keys. */
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 },
- { ISFUNC, (rl_command_func_t *)0x0 }
-#endif /* KEYMAP_SIZE > 128 */
-};
-#endif
+/* vi_keymap.c -- the keymap for vi_mode in readline (). */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (BUFSIZ)
+#include <stdio.h>
+#endif /* !BUFSIZ */
+
+#include "readline.h"
+
+#if 0
+extern KEYMAP_ENTRY_ARRAY vi_escape_keymap;
+#endif
+
+/* The keymap arrays for handling vi mode. */
+KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
+ /* The regular control keys come first. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */
+ { ISFUNC, rl_vi_eof_maybe }, /* Control-d */
+ { ISFUNC, rl_emacs_editing_mode }, /* Control-e */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */
+ { ISFUNC, rl_abort }, /* Control-g */
+ { ISFUNC, rl_backward_char }, /* Control-h */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-i */
+ { ISFUNC, rl_newline }, /* Control-j */
+ { ISFUNC, rl_kill_line }, /* Control-k */
+ { ISFUNC, rl_clear_screen }, /* Control-l */
+ { ISFUNC, rl_newline }, /* Control-m */
+ { ISFUNC, rl_get_next_history }, /* Control-n */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */
+ { ISFUNC, rl_get_previous_history }, /* Control-p */
+ { ISFUNC, rl_quoted_insert }, /* Control-q */
+ { ISFUNC, rl_reverse_search_history }, /* Control-r */
+ { ISFUNC, rl_forward_search_history }, /* Control-s */
+ { ISFUNC, rl_transpose_chars }, /* Control-t */
+ { ISFUNC, rl_unix_line_discard }, /* Control-u */
+ { ISFUNC, rl_quoted_insert }, /* Control-v */
+ { ISFUNC, rl_unix_word_rubout }, /* Control-w */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */
+ { ISFUNC, rl_yank }, /* Control-y */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
+
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-[ */ /* vi_escape_keymap */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
+ { ISFUNC, rl_vi_undo }, /* Control-_ */
+
+ /* The start of printing characters. */
+ { ISFUNC, rl_forward_char }, /* SPACE */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* " */
+ { ISFUNC, rl_insert_comment }, /* # */
+ { ISFUNC, rl_end_of_line }, /* $ */
+ { ISFUNC, rl_vi_match }, /* % */
+ { ISFUNC, rl_vi_tilde_expand }, /* & */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ( */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ) */
+ { ISFUNC, rl_vi_complete }, /* * */
+ { ISFUNC, rl_get_next_history}, /* + */
+ { ISFUNC, rl_vi_char_search }, /* , */
+ { ISFUNC, rl_get_previous_history }, /* - */
+ { ISFUNC, rl_vi_redo }, /* . */
+ { ISFUNC, rl_vi_search }, /* / */
+
+ /* Regular digits. */
+ { ISFUNC, rl_beg_of_line }, /* 0 */
+ { ISFUNC, rl_vi_arg_digit }, /* 1 */
+ { ISFUNC, rl_vi_arg_digit }, /* 2 */
+ { ISFUNC, rl_vi_arg_digit }, /* 3 */
+ { ISFUNC, rl_vi_arg_digit }, /* 4 */
+ { ISFUNC, rl_vi_arg_digit }, /* 5 */
+ { ISFUNC, rl_vi_arg_digit }, /* 6 */
+ { ISFUNC, rl_vi_arg_digit }, /* 7 */
+ { ISFUNC, rl_vi_arg_digit }, /* 8 */
+ { ISFUNC, rl_vi_arg_digit }, /* 9 */
+
+ /* A little more punctuation. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* : */
+ { ISFUNC, rl_vi_char_search }, /* ; */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* < */
+ { ISFUNC, rl_vi_complete }, /* = */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* > */
+ { ISFUNC, rl_vi_search }, /* ? */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */
+
+ /* Uppercase alphabet. */
+ { ISFUNC, rl_vi_append_eol }, /* A */
+ { ISFUNC, rl_vi_prev_word}, /* B */
+ { ISFUNC, rl_vi_change_to }, /* C */
+ { ISFUNC, rl_vi_delete_to }, /* D */
+ { ISFUNC, rl_vi_end_word }, /* E */
+ { ISFUNC, rl_vi_char_search }, /* F */
+ { ISFUNC, rl_vi_fetch_history }, /* G */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* H */
+ { ISFUNC, rl_vi_insert_beg }, /* I */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* J */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* K */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* L */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* M */
+ { ISFUNC, rl_vi_search_again }, /* N */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* O */
+ { ISFUNC, rl_vi_put }, /* P */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Q */
+ { ISFUNC, rl_vi_replace }, /* R */
+ { ISFUNC, rl_vi_subst }, /* S */
+ { ISFUNC, rl_vi_char_search }, /* T */
+ { ISFUNC, rl_revert_line }, /* U */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* V */
+ { ISFUNC, rl_vi_next_word }, /* W */
+ { ISFUNC, rl_rubout }, /* X */
+ { ISFUNC, rl_vi_yank_to }, /* Y */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Z */
+
+ /* Some more punctuation. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* [ */
+ { ISFUNC, rl_vi_complete }, /* \ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */
+ { ISFUNC, rl_vi_first_print }, /* ^ */
+ { ISFUNC, rl_vi_yank_arg }, /* _ */
+ { ISFUNC, rl_vi_goto_mark }, /* ` */
+
+ /* Lowercase alphabet. */
+ { ISFUNC, rl_vi_append_mode }, /* a */
+ { ISFUNC, rl_vi_prev_word }, /* b */
+ { ISFUNC, rl_vi_change_to }, /* c */
+ { ISFUNC, rl_vi_delete_to }, /* d */
+ { ISFUNC, rl_vi_end_word }, /* e */
+ { ISFUNC, rl_vi_char_search }, /* f */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* g */
+ { ISFUNC, rl_backward_char }, /* h */
+ { ISFUNC, rl_vi_insertion_mode }, /* i */
+ { ISFUNC, rl_get_next_history }, /* j */
+ { ISFUNC, rl_get_previous_history }, /* k */
+ { ISFUNC, rl_forward_char }, /* l */
+ { ISFUNC, rl_vi_set_mark }, /* m */
+ { ISFUNC, rl_vi_search_again }, /* n */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* o */
+ { ISFUNC, rl_vi_put }, /* p */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* q */
+ { ISFUNC, rl_vi_change_char }, /* r */
+ { ISFUNC, rl_vi_subst }, /* s */
+ { ISFUNC, rl_vi_char_search }, /* t */
+ { ISFUNC, rl_vi_undo }, /* u */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* v */
+ { ISFUNC, rl_vi_next_word }, /* w */
+ { ISFUNC, rl_vi_delete }, /* x */
+ { ISFUNC, rl_vi_yank_to }, /* y */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* z */
+
+ /* Final punctuation. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* { */
+ { ISFUNC, rl_vi_column }, /* | */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* } */
+ { ISFUNC, rl_vi_change_case }, /* ~ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* RUBOUT */
+
+#if KEYMAP_SIZE > 128
+ /* Undefined keys. */
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 }
+#endif /* KEYMAP_SIZE > 128 */
+};
+
+
+KEYMAP_ENTRY_ARRAY vi_insertion_keymap = {
+ /* The regular control keys come first. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */
+ { ISFUNC, rl_insert }, /* Control-a */
+ { ISFUNC, rl_insert }, /* Control-b */
+ { ISFUNC, rl_insert }, /* Control-c */
+ { ISFUNC, rl_vi_eof_maybe }, /* Control-d */
+ { ISFUNC, rl_insert }, /* Control-e */
+ { ISFUNC, rl_insert }, /* Control-f */
+ { ISFUNC, rl_insert }, /* Control-g */
+ { ISFUNC, rl_rubout }, /* Control-h */
+ { ISFUNC, rl_complete }, /* Control-i */
+ { ISFUNC, rl_newline }, /* Control-j */
+ { ISFUNC, rl_insert }, /* Control-k */
+ { ISFUNC, rl_insert }, /* Control-l */
+ { ISFUNC, rl_newline }, /* Control-m */
+ { ISFUNC, rl_insert }, /* Control-n */
+ { ISFUNC, rl_insert }, /* Control-o */
+ { ISFUNC, rl_insert }, /* Control-p */
+ { ISFUNC, rl_insert }, /* Control-q */
+ { ISFUNC, rl_reverse_search_history }, /* Control-r */
+ { ISFUNC, rl_forward_search_history }, /* Control-s */
+ { ISFUNC, rl_transpose_chars }, /* Control-t */
+ { ISFUNC, rl_unix_line_discard }, /* Control-u */
+ { ISFUNC, rl_quoted_insert }, /* Control-v */
+ { ISFUNC, rl_unix_word_rubout }, /* Control-w */
+ { ISFUNC, rl_insert }, /* Control-x */
+ { ISFUNC, rl_yank }, /* Control-y */
+ { ISFUNC, rl_insert }, /* Control-z */
+
+ { ISFUNC, rl_vi_movement_mode }, /* Control-[ */
+ { ISFUNC, rl_insert }, /* Control-\ */
+ { ISFUNC, rl_insert }, /* Control-] */
+ { ISFUNC, rl_insert }, /* Control-^ */
+ { ISFUNC, rl_vi_undo }, /* Control-_ */
+
+ /* The start of printing characters. */
+ { ISFUNC, rl_insert }, /* SPACE */
+ { ISFUNC, rl_insert }, /* ! */
+ { ISFUNC, rl_insert }, /* " */
+ { ISFUNC, rl_insert }, /* # */
+ { ISFUNC, rl_insert }, /* $ */
+ { ISFUNC, rl_insert }, /* % */
+ { ISFUNC, rl_insert }, /* & */
+ { ISFUNC, rl_insert }, /* ' */
+ { ISFUNC, rl_insert }, /* ( */
+ { ISFUNC, rl_insert }, /* ) */
+ { ISFUNC, rl_insert }, /* * */
+ { ISFUNC, rl_insert }, /* + */
+ { ISFUNC, rl_insert }, /* , */
+ { ISFUNC, rl_insert }, /* - */
+ { ISFUNC, rl_insert }, /* . */
+ { ISFUNC, rl_insert }, /* / */
+
+ /* Regular digits. */
+ { ISFUNC, rl_insert }, /* 0 */
+ { ISFUNC, rl_insert }, /* 1 */
+ { ISFUNC, rl_insert }, /* 2 */
+ { ISFUNC, rl_insert }, /* 3 */
+ { ISFUNC, rl_insert }, /* 4 */
+ { ISFUNC, rl_insert }, /* 5 */
+ { ISFUNC, rl_insert }, /* 6 */
+ { ISFUNC, rl_insert }, /* 7 */
+ { ISFUNC, rl_insert }, /* 8 */
+ { ISFUNC, rl_insert }, /* 9 */
+
+ /* A little more punctuation. */
+ { ISFUNC, rl_insert }, /* : */
+ { ISFUNC, rl_insert }, /* ; */
+ { ISFUNC, rl_insert }, /* < */
+ { ISFUNC, rl_insert }, /* = */
+ { ISFUNC, rl_insert }, /* > */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* @ */
+
+ /* Uppercase alphabet. */
+ { ISFUNC, rl_insert }, /* A */
+ { ISFUNC, rl_insert }, /* B */
+ { ISFUNC, rl_insert }, /* C */
+ { ISFUNC, rl_insert }, /* D */
+ { ISFUNC, rl_insert }, /* E */
+ { ISFUNC, rl_insert }, /* F */
+ { ISFUNC, rl_insert }, /* G */
+ { ISFUNC, rl_insert }, /* H */
+ { ISFUNC, rl_insert }, /* I */
+ { ISFUNC, rl_insert }, /* J */
+ { ISFUNC, rl_insert }, /* K */
+ { ISFUNC, rl_insert }, /* L */
+ { ISFUNC, rl_insert }, /* M */
+ { ISFUNC, rl_insert }, /* N */
+ { ISFUNC, rl_insert }, /* O */
+ { ISFUNC, rl_insert }, /* P */
+ { ISFUNC, rl_insert }, /* Q */
+ { ISFUNC, rl_insert }, /* R */
+ { ISFUNC, rl_insert }, /* S */
+ { ISFUNC, rl_insert }, /* T */
+ { ISFUNC, rl_insert }, /* U */
+ { ISFUNC, rl_insert }, /* V */
+ { ISFUNC, rl_insert }, /* W */
+ { ISFUNC, rl_insert }, /* X */
+ { ISFUNC, rl_insert }, /* Y */
+ { ISFUNC, rl_insert }, /* Z */
+
+ /* Some more punctuation. */
+ { ISFUNC, rl_insert }, /* [ */
+ { ISFUNC, rl_insert }, /* \ */
+ { ISFUNC, rl_insert }, /* ] */
+ { ISFUNC, rl_insert }, /* ^ */
+ { ISFUNC, rl_insert }, /* _ */
+ { ISFUNC, rl_insert }, /* ` */
+
+ /* Lowercase alphabet. */
+ { ISFUNC, rl_insert }, /* a */
+ { ISFUNC, rl_insert }, /* b */
+ { ISFUNC, rl_insert }, /* c */
+ { ISFUNC, rl_insert }, /* d */
+ { ISFUNC, rl_insert }, /* e */
+ { ISFUNC, rl_insert }, /* f */
+ { ISFUNC, rl_insert }, /* g */
+ { ISFUNC, rl_insert }, /* h */
+ { ISFUNC, rl_insert }, /* i */
+ { ISFUNC, rl_insert }, /* j */
+ { ISFUNC, rl_insert }, /* k */
+ { ISFUNC, rl_insert }, /* l */
+ { ISFUNC, rl_insert }, /* m */
+ { ISFUNC, rl_insert }, /* n */
+ { ISFUNC, rl_insert }, /* o */
+ { ISFUNC, rl_insert }, /* p */
+ { ISFUNC, rl_insert }, /* q */
+ { ISFUNC, rl_insert }, /* r */
+ { ISFUNC, rl_insert }, /* s */
+ { ISFUNC, rl_insert }, /* t */
+ { ISFUNC, rl_insert }, /* u */
+ { ISFUNC, rl_insert }, /* v */
+ { ISFUNC, rl_insert }, /* w */
+ { ISFUNC, rl_insert }, /* x */
+ { ISFUNC, rl_insert }, /* y */
+ { ISFUNC, rl_insert }, /* z */
+
+ /* Final punctuation. */
+ { ISFUNC, rl_insert }, /* { */
+ { ISFUNC, rl_insert }, /* | */
+ { ISFUNC, rl_insert }, /* } */
+ { ISFUNC, rl_insert }, /* ~ */
+ { ISFUNC, rl_rubout }, /* RUBOUT */
+
+#if KEYMAP_SIZE > 128
+ /* Pure 8-bit characters (128 - 159).
+ These might be used in some
+ character sets. */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+ { ISFUNC, rl_insert }, /* ? */
+
+ /* ISO Latin-1 characters (160 - 255) */
+ { ISFUNC, rl_insert }, /* No-break space */
+ { ISFUNC, rl_insert }, /* Inverted exclamation mark */
+ { ISFUNC, rl_insert }, /* Cent sign */
+ { ISFUNC, rl_insert }, /* Pound sign */
+ { ISFUNC, rl_insert }, /* Currency sign */
+ { ISFUNC, rl_insert }, /* Yen sign */
+ { ISFUNC, rl_insert }, /* Broken bar */
+ { ISFUNC, rl_insert }, /* Section sign */
+ { ISFUNC, rl_insert }, /* Diaeresis */
+ { ISFUNC, rl_insert }, /* Copyright sign */
+ { ISFUNC, rl_insert }, /* Feminine ordinal indicator */
+ { ISFUNC, rl_insert }, /* Left pointing double angle quotation mark */
+ { ISFUNC, rl_insert }, /* Not sign */
+ { ISFUNC, rl_insert }, /* Soft hyphen */
+ { ISFUNC, rl_insert }, /* Registered sign */
+ { ISFUNC, rl_insert }, /* Macron */
+ { ISFUNC, rl_insert }, /* Degree sign */
+ { ISFUNC, rl_insert }, /* Plus-minus sign */
+ { ISFUNC, rl_insert }, /* Superscript two */
+ { ISFUNC, rl_insert }, /* Superscript three */
+ { ISFUNC, rl_insert }, /* Acute accent */
+ { ISFUNC, rl_insert }, /* Micro sign */
+ { ISFUNC, rl_insert }, /* Pilcrow sign */
+ { ISFUNC, rl_insert }, /* Middle dot */
+ { ISFUNC, rl_insert }, /* Cedilla */
+ { ISFUNC, rl_insert }, /* Superscript one */
+ { ISFUNC, rl_insert }, /* Masculine ordinal indicator */
+ { ISFUNC, rl_insert }, /* Right pointing double angle quotation mark */
+ { ISFUNC, rl_insert }, /* Vulgar fraction one quarter */
+ { ISFUNC, rl_insert }, /* Vulgar fraction one half */
+ { ISFUNC, rl_insert }, /* Vulgar fraction three quarters */
+ { ISFUNC, rl_insert }, /* Inverted questionk mark */
+ { ISFUNC, rl_insert }, /* Latin capital letter a with grave */
+ { ISFUNC, rl_insert }, /* Latin capital letter a with acute */
+ { ISFUNC, rl_insert }, /* Latin capital letter a with circumflex */
+ { ISFUNC, rl_insert }, /* Latin capital letter a with tilde */
+ { ISFUNC, rl_insert }, /* Latin capital letter a with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin capital letter a with ring above */
+ { ISFUNC, rl_insert }, /* Latin capital letter ae */
+ { ISFUNC, rl_insert }, /* Latin capital letter c with cedilla */
+ { ISFUNC, rl_insert }, /* Latin capital letter e with grave */
+ { ISFUNC, rl_insert }, /* Latin capital letter e with acute */
+ { ISFUNC, rl_insert }, /* Latin capital letter e with circumflex */
+ { ISFUNC, rl_insert }, /* Latin capital letter e with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin capital letter i with grave */
+ { ISFUNC, rl_insert }, /* Latin capital letter i with acute */
+ { ISFUNC, rl_insert }, /* Latin capital letter i with circumflex */
+ { ISFUNC, rl_insert }, /* Latin capital letter i with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin capital letter eth (Icelandic) */
+ { ISFUNC, rl_insert }, /* Latin capital letter n with tilde */
+ { ISFUNC, rl_insert }, /* Latin capital letter o with grave */
+ { ISFUNC, rl_insert }, /* Latin capital letter o with acute */
+ { ISFUNC, rl_insert }, /* Latin capital letter o with circumflex */
+ { ISFUNC, rl_insert }, /* Latin capital letter o with tilde */
+ { ISFUNC, rl_insert }, /* Latin capital letter o with diaeresis */
+ { ISFUNC, rl_insert }, /* Multiplication sign */
+ { ISFUNC, rl_insert }, /* Latin capital letter o with stroke */
+ { ISFUNC, rl_insert }, /* Latin capital letter u with grave */
+ { ISFUNC, rl_insert }, /* Latin capital letter u with acute */
+ { ISFUNC, rl_insert }, /* Latin capital letter u with circumflex */
+ { ISFUNC, rl_insert }, /* Latin capital letter u with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin capital letter Y with acute */
+ { ISFUNC, rl_insert }, /* Latin capital letter thorn (Icelandic) */
+ { ISFUNC, rl_insert }, /* Latin small letter sharp s (German) */
+ { ISFUNC, rl_insert }, /* Latin small letter a with grave */
+ { ISFUNC, rl_insert }, /* Latin small letter a with acute */
+ { ISFUNC, rl_insert }, /* Latin small letter a with circumflex */
+ { ISFUNC, rl_insert }, /* Latin small letter a with tilde */
+ { ISFUNC, rl_insert }, /* Latin small letter a with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin small letter a with ring above */
+ { ISFUNC, rl_insert }, /* Latin small letter ae */
+ { ISFUNC, rl_insert }, /* Latin small letter c with cedilla */
+ { ISFUNC, rl_insert }, /* Latin small letter e with grave */
+ { ISFUNC, rl_insert }, /* Latin small letter e with acute */
+ { ISFUNC, rl_insert }, /* Latin small letter e with circumflex */
+ { ISFUNC, rl_insert }, /* Latin small letter e with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin small letter i with grave */
+ { ISFUNC, rl_insert }, /* Latin small letter i with acute */
+ { ISFUNC, rl_insert }, /* Latin small letter i with circumflex */
+ { ISFUNC, rl_insert }, /* Latin small letter i with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin small letter eth (Icelandic) */
+ { ISFUNC, rl_insert }, /* Latin small letter n with tilde */
+ { ISFUNC, rl_insert }, /* Latin small letter o with grave */
+ { ISFUNC, rl_insert }, /* Latin small letter o with acute */
+ { ISFUNC, rl_insert }, /* Latin small letter o with circumflex */
+ { ISFUNC, rl_insert }, /* Latin small letter o with tilde */
+ { ISFUNC, rl_insert }, /* Latin small letter o with diaeresis */
+ { ISFUNC, rl_insert }, /* Division sign */
+ { ISFUNC, rl_insert }, /* Latin small letter o with stroke */
+ { ISFUNC, rl_insert }, /* Latin small letter u with grave */
+ { ISFUNC, rl_insert }, /* Latin small letter u with acute */
+ { ISFUNC, rl_insert }, /* Latin small letter u with circumflex */
+ { ISFUNC, rl_insert }, /* Latin small letter u with diaeresis */
+ { ISFUNC, rl_insert }, /* Latin small letter y with acute */
+ { ISFUNC, rl_insert }, /* Latin small letter thorn (Icelandic) */
+ { ISFUNC, rl_insert } /* Latin small letter y with diaeresis */
+#endif /* KEYMAP_SIZE > 128 */
+};
+
+/* Unused for the time being. */
+#if 0
+KEYMAP_ENTRY_ARRAY vi_escape_keymap = {
+ /* The regular control keys come first. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-d */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-e */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-g */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-h */
+ { ISFUNC, rl_tab_insert}, /* Control-i */
+ { ISFUNC, rl_emacs_editing_mode}, /* Control-j */
+ { ISFUNC, rl_kill_line }, /* Control-k */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-l */
+ { ISFUNC, rl_emacs_editing_mode}, /* Control-m */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-n */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-p */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-q */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-r */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-s */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-t */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-u */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-v */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-w */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-y */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
+
+ { ISFUNC, rl_vi_movement_mode }, /* Control-[ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
+ { ISFUNC, rl_vi_undo }, /* Control-_ */
+
+ /* The start of printing characters. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* SPACE */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ! */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* " */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* # */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* $ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* % */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* & */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ' */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ( */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ) */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* * */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* + */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* , */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* - */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* . */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* / */
+
+ /* Regular digits. */
+ { ISFUNC, rl_vi_arg_digit }, /* 0 */
+ { ISFUNC, rl_vi_arg_digit }, /* 1 */
+ { ISFUNC, rl_vi_arg_digit }, /* 2 */
+ { ISFUNC, rl_vi_arg_digit }, /* 3 */
+ { ISFUNC, rl_vi_arg_digit }, /* 4 */
+ { ISFUNC, rl_vi_arg_digit }, /* 5 */
+ { ISFUNC, rl_vi_arg_digit }, /* 6 */
+ { ISFUNC, rl_vi_arg_digit }, /* 7 */
+ { ISFUNC, rl_vi_arg_digit }, /* 8 */
+ { ISFUNC, rl_vi_arg_digit }, /* 9 */
+
+ /* A little more punctuation. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* : */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ; */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* < */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* = */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* > */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ? */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* @ */
+
+ /* Uppercase alphabet. */
+ { ISFUNC, rl_do_lowercase_version }, /* A */
+ { ISFUNC, rl_do_lowercase_version }, /* B */
+ { ISFUNC, rl_do_lowercase_version }, /* C */
+ { ISFUNC, rl_do_lowercase_version }, /* D */
+ { ISFUNC, rl_do_lowercase_version }, /* E */
+ { ISFUNC, rl_do_lowercase_version }, /* F */
+ { ISFUNC, rl_do_lowercase_version }, /* G */
+ { ISFUNC, rl_do_lowercase_version }, /* H */
+ { ISFUNC, rl_do_lowercase_version }, /* I */
+ { ISFUNC, rl_do_lowercase_version }, /* J */
+ { ISFUNC, rl_do_lowercase_version }, /* K */
+ { ISFUNC, rl_do_lowercase_version }, /* L */
+ { ISFUNC, rl_do_lowercase_version }, /* M */
+ { ISFUNC, rl_do_lowercase_version }, /* N */
+ { ISFUNC, rl_do_lowercase_version }, /* O */
+ { ISFUNC, rl_do_lowercase_version }, /* P */
+ { ISFUNC, rl_do_lowercase_version }, /* Q */
+ { ISFUNC, rl_do_lowercase_version }, /* R */
+ { ISFUNC, rl_do_lowercase_version }, /* S */
+ { ISFUNC, rl_do_lowercase_version }, /* T */
+ { ISFUNC, rl_do_lowercase_version }, /* U */
+ { ISFUNC, rl_do_lowercase_version }, /* V */
+ { ISFUNC, rl_do_lowercase_version }, /* W */
+ { ISFUNC, rl_do_lowercase_version }, /* X */
+ { ISFUNC, rl_do_lowercase_version }, /* Y */
+ { ISFUNC, rl_do_lowercase_version }, /* Z */
+
+ /* Some more punctuation. */
+ { ISFUNC, rl_arrow_keys }, /* [ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* \ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ] */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ^ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* _ */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ` */
+
+ /* Lowercase alphabet. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* a */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* b */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* c */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* d */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* e */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* f */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* g */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* h */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* i */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* j */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* k */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* l */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* m */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* n */
+ { ISFUNC, rl_arrow_keys }, /* o */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* p */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* q */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* r */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* s */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* t */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* u */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* v */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* w */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* x */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* y */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* z */
+
+ /* Final punctuation. */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* { */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* | */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* } */
+ { ISFUNC, (rl_command_func_t *)0x0 }, /* ~ */
+ { ISFUNC, rl_backward_kill_word }, /* RUBOUT */
+
+#if KEYMAP_SIZE > 128
+ /* Undefined keys. */
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 },
+ { ISFUNC, (rl_command_func_t *)0x0 }
+#endif /* KEYMAP_SIZE > 128 */
+};
+#endif
diff --git a/MSVC/readline/vi_mode.c b/MSVC/readline/vi_mode.c
index b879f07..6ea2161 100644
--- a/MSVC/readline/vi_mode.c
+++ b/MSVC/readline/vi_mode.c
@@ -1,1483 +1,1483 @@
-/* vi_mode.c -- A vi emulation mode for Bash.
- Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
-
-/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY
-
-/* **************************************************************** */
-/* */
-/* VI Emulation Mode */
-/* */
-/* **************************************************************** */
-#include "rlconf.h"
-
-#if defined (VI_MODE)
-
-#include "config.h"
-
-#include <sys/types.h>
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif
-
-#include <stdio.h>
-
-/* Some standard library routines. */
-#include "rldefs.h"
-#include "rlmbutil.h"
-
-#include "readline.h"
-#include "history.h"
-
-#include "rlprivate.h"
-#include "xmalloc.h"
-
-#ifndef member
-#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
-#endif
-
-/* Non-zero means enter insertion mode. */
-static int _rl_vi_doing_insert;
-
-/* Command keys which do movement for xxx_to commands. */
-static const char *vi_motion = " hl^$0ftFT;,%wbeWBE|";
-
-/* Keymap used for vi replace characters. Created dynamically since
- rarely used. */
-static Keymap vi_replace_map;
-
-/* The number of characters inserted in the last replace operation. */
-static int vi_replace_count;
-
-/* If non-zero, we have text inserted after a c[motion] command that put
- us implicitly into insert mode. Some people want this text to be
- attached to the command so that it is `redoable' with `.'. */
-static int vi_continued_command;
-static char *vi_insert_buffer;
-static int vi_insert_buffer_size;
-
-static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
-static int _rl_vi_last_repeat = 1;
-static int _rl_vi_last_arg_sign = 1;
-static int _rl_vi_last_motion;
-#if defined (HANDLE_MULTIBYTE)
-static char _rl_vi_last_search_mbchar[MB_LEN_MAX];
-#else
-static int _rl_vi_last_search_char;
-#endif
-static int _rl_vi_last_replacement;
-
-static int _rl_vi_last_key_before_insert;
-
-static int vi_redoing;
-
-/* Text modification commands. These are the `redoable' commands. */
-static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
-
-/* Arrays for the saved marks. */
-static int vi_mark_chars['z' - 'a' + 1];
-
-static void _rl_vi_stuff_insert PARAMS((int));
-static void _rl_vi_save_insert PARAMS((UNDO_LIST *));
-static int rl_digit_loop1 PARAMS((void));
-
-void
-_rl_vi_initialize_line ()
-{
- register int i;
-
- for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
- vi_mark_chars[i] = -1;
-}
-
-void
-_rl_vi_reset_last ()
-{
- _rl_vi_last_command = 'i';
- _rl_vi_last_repeat = 1;
- _rl_vi_last_arg_sign = 1;
- _rl_vi_last_motion = 0;
-}
-
-void
-_rl_vi_set_last (key, repeat, sign)
- int key, repeat, sign;
-{
- _rl_vi_last_command = key;
- _rl_vi_last_repeat = repeat;
- _rl_vi_last_arg_sign = sign;
-}
-
-/* Is the command C a VI mode text modification command? */
-int
-_rl_vi_textmod_command (c)
- int c;
-{
- return (member (c, vi_textmod));
-}
-
-static void
-_rl_vi_stuff_insert (count)
- int count;
-{
- rl_begin_undo_group ();
- while (count--)
- rl_insert_text (vi_insert_buffer);
- rl_end_undo_group ();
-}
-
-/* Bound to `.'. Called from command mode, so we know that we have to
- redo a text modification command. The default for _rl_vi_last_command
- puts you back into insert mode. */
-int
-rl_vi_redo (count, c)
- int count, c;
-{
- int r;
-
- if (!rl_explicit_arg)
- {
- rl_numeric_arg = _rl_vi_last_repeat;
- rl_arg_sign = _rl_vi_last_arg_sign;
- }
-
- r = 0;
- vi_redoing = 1;
- /* If we're redoing an insert with `i', stuff in the inserted text
- and do not go into insertion mode. */
- if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
- {
- _rl_vi_stuff_insert (count);
- /* And back up point over the last character inserted. */
- if (rl_point > 0)
- rl_point--;
- }
- else
- r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);
- vi_redoing = 0;
-
- return (r);
-}
-
-/* A placeholder for further expansion. */
-int
-rl_vi_undo (count, key)
- int count, key;
-{
- return (rl_undo_command (count, key));
-}
-
-/* Yank the nth arg from the previous line into this line at point. */
-int
-rl_vi_yank_arg (count, key)
- int count, key;
-{
- /* Readline thinks that the first word on a line is the 0th, while vi
- thinks the first word on a line is the 1st. Compensate. */
- if (rl_explicit_arg)
- rl_yank_nth_arg (count - 1, 0);
- else
- rl_yank_nth_arg ('$', 0);
-
- return (0);
-}
-
-/* With an argument, move back that many history lines, else move to the
- beginning of history. */
-int
-rl_vi_fetch_history (count, c)
- int count, c;
-{
- int wanted;
-
- /* Giving an argument of n means we want the nth command in the history
- file. The command number is interpreted the same way that the bash
- `history' command does it -- that is, giving an argument count of 450
- to this command would get the command listed as number 450 in the
- output of `history'. */
- if (rl_explicit_arg)
- {
- wanted = history_base + where_history () - count;
- if (wanted <= 0)
- rl_beginning_of_history (0, 0);
- else
- rl_get_previous_history (wanted, c);
- }
- else
- rl_beginning_of_history (count, 0);
- return (0);
-}
-
-/* Search again for the last thing searched for. */
-int
-rl_vi_search_again (count, key)
- int count, key;
-{
- switch (key)
- {
- case 'n':
- rl_noninc_reverse_search_again (count, key);
- break;
-
- case 'N':
- rl_noninc_forward_search_again (count, key);
- break;
- }
- return (0);
-}
-
-/* Do a vi style search. */
-int
-rl_vi_search (count, key)
- int count, key;
-{
- switch (key)
- {
- case '?':
- rl_noninc_forward_search (count, key);
- break;
-
- case '/':
- rl_noninc_reverse_search (count, key);
- break;
-
- default:
- rl_ding ();
- break;
- }
- return (0);
-}
-
-/* Completion, from vi's point of view. */
-int
-rl_vi_complete (ignore, key)
- int ignore, key;
-{
- if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
- {
- if (!whitespace (rl_line_buffer[rl_point + 1]))
- rl_vi_end_word (1, 'E');
- rl_point++;
- }
-
- if (key == '*')
- rl_complete_internal ('*'); /* Expansion and replacement. */
- else if (key == '=')
- rl_complete_internal ('?'); /* List possible completions. */
- else if (key == '\\')
- rl_complete_internal (TAB); /* Standard Readline completion. */
- else
- rl_complete (0, key);
-
- if (key == '*' || key == '\\')
- {
- _rl_vi_set_last (key, 1, rl_arg_sign);
- rl_vi_insertion_mode (1, key);
- }
- return (0);
-}
-
-/* Tilde expansion for vi mode. */
-int
-rl_vi_tilde_expand (ignore, key)
- int ignore, key;
-{
- rl_tilde_expand (0, key);
- _rl_vi_set_last (key, 1, rl_arg_sign); /* XXX */
- rl_vi_insertion_mode (1, key);
- return (0);
-}
-
-/* Previous word in vi mode. */
-int
-rl_vi_prev_word (count, key)
- int count, key;
-{
- if (count < 0)
- return (rl_vi_next_word (-count, key));
-
- if (rl_point == 0)
- {
- rl_ding ();
- return (0);
- }
-
- if (_rl_uppercase_p (key))
- rl_vi_bWord (count, key);
- else
- rl_vi_bword (count, key);
-
- return (0);
-}
-
-/* Next word in vi mode. */
-int
-rl_vi_next_word (count, key)
- int count, key;
-{
- if (count < 0)
- return (rl_vi_prev_word (-count, key));
-
- if (rl_point >= (rl_end - 1))
- {
- rl_ding ();
- return (0);
- }
-
- if (_rl_uppercase_p (key))
- rl_vi_fWord (count, key);
- else
- rl_vi_fword (count, key);
- return (0);
-}
-
-/* Move to the end of the ?next? word. */
-int
-rl_vi_end_word (count, key)
- int count, key;
-{
- if (count < 0)
- {
- rl_ding ();
- return -1;
- }
-
- if (_rl_uppercase_p (key))
- rl_vi_eWord (count, key);
- else
- rl_vi_eword (count, key);
- return (0);
-}
-
-/* Move forward a word the way that 'W' does. */
-int
-rl_vi_fWord (count, ignore)
- int count, ignore;
-{
- while (count-- && rl_point < (rl_end - 1))
- {
- /* Skip until whitespace. */
- while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
- rl_point++;
-
- /* Now skip whitespace. */
- while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
- rl_point++;
- }
- return (0);
-}
-
-int
-rl_vi_bWord (count, ignore)
- int count, ignore;
-{
- while (count-- && rl_point > 0)
- {
- /* If we are at the start of a word, move back to whitespace so
- we will go back to the start of the previous word. */
- if (!whitespace (rl_line_buffer[rl_point]) &&
- whitespace (rl_line_buffer[rl_point - 1]))
- rl_point--;
-
- while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
- rl_point--;
-
- if (rl_point > 0)
- {
- while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point]));
- rl_point++;
- }
- }
- return (0);
-}
-
-int
-rl_vi_eWord (count, ignore)
- int count, ignore;
-{
- while (count-- && rl_point < (rl_end - 1))
- {
- if (!whitespace (rl_line_buffer[rl_point]))
- rl_point++;
-
- /* Move to the next non-whitespace character (to the start of the
- next word). */
- while (++rl_point < rl_end && whitespace (rl_line_buffer[rl_point]));
-
- if (rl_point && rl_point < rl_end)
- {
- /* Skip whitespace. */
- while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
- rl_point++;
-
- /* Skip until whitespace. */
- while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point]))
- rl_point++;
-
- /* Move back to the last character of the word. */
- rl_point--;
- }
- }
- return (0);
-}
-
-int
-rl_vi_fword (count, ignore)
- int count, ignore;
-{
- while (count-- && rl_point < (rl_end - 1))
- {
- /* Move to white space (really non-identifer). */
- if (_rl_isident (rl_line_buffer[rl_point]))
- {
- while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
- rl_point++;
- }
- else /* if (!whitespace (rl_line_buffer[rl_point])) */
- {
- while (!_rl_isident (rl_line_buffer[rl_point]) &&
- !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
- rl_point++;
- }
-
- /* Move past whitespace. */
- while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
- rl_point++;
- }
- return (0);
-}
-
-int
-rl_vi_bword (count, ignore)
- int count, ignore;
-{
- while (count-- && rl_point > 0)
- {
- int last_is_ident;
-
- /* If we are at the start of a word, move back to whitespace
- so we will go back to the start of the previous word. */
- if (!whitespace (rl_line_buffer[rl_point]) &&
- whitespace (rl_line_buffer[rl_point - 1]))
- rl_point--;
-
- /* If this character and the previous character are `opposite', move
- back so we don't get messed up by the rl_point++ down there in
- the while loop. Without this code, words like `l;' screw up the
- function. */
- last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]);
- if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
- (!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident))
- rl_point--;
-
- while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
- rl_point--;
-
- if (rl_point > 0)
- {
- if (_rl_isident (rl_line_buffer[rl_point]))
- while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point]));
- else
- while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) &&
- !whitespace (rl_line_buffer[rl_point]));
- rl_point++;
- }
- }
- return (0);
-}
-
-int
-rl_vi_eword (count, ignore)
- int count, ignore;
-{
- while (count-- && rl_point < rl_end - 1)
- {
- if (!whitespace (rl_line_buffer[rl_point]))
- rl_point++;
-
- while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
- rl_point++;
-
- if (rl_point < rl_end)
- {
- if (_rl_isident (rl_line_buffer[rl_point]))
- while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point]));
- else
- while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point])
- && !whitespace (rl_line_buffer[rl_point]));
- }
- rl_point--;
- }
- return (0);
-}
-
-int
-rl_vi_insert_beg (count, key)
- int count, key;
-{
- rl_beg_of_line (1, key);
- rl_vi_insertion_mode (1, key);
- return (0);
-}
-
-int
-rl_vi_append_mode (count, key)
- int count, key;
-{
- if (rl_point < rl_end)
- {
- if (MB_CUR_MAX == 1 || rl_byte_oriented)
- rl_point++;
- else
- {
- int point = rl_point;
- rl_forward_char (1, key);
- if (point == rl_point)
- rl_point = rl_end;
- }
- }
- rl_vi_insertion_mode (1, key);
- return (0);
-}
-
-int
-rl_vi_append_eol (count, key)
- int count, key;
-{
- rl_end_of_line (1, key);
- rl_vi_append_mode (1, key);
- return (0);
-}
-
-/* What to do in the case of C-d. */
-int
-rl_vi_eof_maybe (count, c)
- int count, c;
-{
- return (rl_newline (1, '\n'));
-}
-
-/* Insertion mode stuff. */
-
-/* Switching from one mode to the other really just involves
- switching keymaps. */
-int
-rl_vi_insertion_mode (count, key)
- int count, key;
-{
- _rl_keymap = vi_insertion_keymap;
- _rl_vi_last_key_before_insert = key;
- return (0);
-}
-
-static void
-_rl_vi_save_insert (up)
- UNDO_LIST *up;
-{
- int len, start, end;
-
- if (up == 0)
- {
- if (vi_insert_buffer_size >= 1)
- vi_insert_buffer[0] = '\0';
- return;
- }
-
- start = up->start;
- end = up->end;
- len = end - start + 1;
- if (len >= vi_insert_buffer_size)
- {
- vi_insert_buffer_size += (len + 32) - (len % 32);
- vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size);
- }
- strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
- vi_insert_buffer[len-1] = '\0';
-}
-
-void
-_rl_vi_done_inserting ()
-{
- if (_rl_vi_doing_insert)
- {
- /* The `C', `s', and `S' commands set this. */
- rl_end_undo_group ();
- /* Now, the text between rl_undo_list->next->start and
- rl_undo_list->next->end is what was inserted while in insert
- mode. It gets copied to VI_INSERT_BUFFER because it depends
- on absolute indices into the line which may change (though they
- probably will not). */
- _rl_vi_doing_insert = 0;
- _rl_vi_save_insert (rl_undo_list->next);
- vi_continued_command = 1;
- }
- else
- {
- if (_rl_vi_last_key_before_insert == 'i' && rl_undo_list)
- _rl_vi_save_insert (rl_undo_list);
- /* XXX - Other keys probably need to be checked. */
- else if (_rl_vi_last_key_before_insert == 'C')
- rl_end_undo_group ();
- while (_rl_undo_group_level > 0)
- rl_end_undo_group ();
- vi_continued_command = 0;
- }
-}
-
-int
-rl_vi_movement_mode (count, key)
- int count, key;
-{
- if (rl_point > 0)
- rl_backward_char (1, key);
-
- _rl_keymap = vi_movement_keymap;
- _rl_vi_done_inserting ();
- return (0);
-}
-
-int
-rl_vi_arg_digit (count, c)
- int count, c;
-{
- if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
- return (rl_beg_of_line (1, c));
- else
- return (rl_digit_argument (count, c));
-}
-
-/* Change the case of the next COUNT characters. */
-#if defined (HANDLE_MULTIBYTE)
-static int
-_rl_vi_change_mbchar_case (count)
- int count;
-{
- wchar_t wc;
- char mb[MB_LEN_MAX];
- mbstate_t ps;
-
- memset (&ps, 0, sizeof (mbstate_t));
- if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0)
- count--;
- while (count-- && rl_point < rl_end)
- {
- mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps);
- if (iswupper (wc))
- wc = towlower (wc);
- else if (iswlower (wc))
- wc = towupper (wc);
- else
- {
- /* Just skip over chars neither upper nor lower case */
- rl_forward_char (1, 0);
- continue;
- }
-
- /* Vi is kind of strange here. */
- if (wc)
- {
- wctomb (mb, wc);
- rl_begin_undo_group ();
- rl_delete (1, 0);
- rl_insert_text (mb);
- rl_end_undo_group ();
- rl_vi_check ();
- }
- else
- rl_forward_char (1, 0);
- }
-
- return 0;
-}
-#endif
-
-int
-rl_vi_change_case (count, ignore)
- int count, ignore;
-{
- char c = 0;
-
- /* Don't try this on an empty line. */
- if (rl_point >= rl_end)
- return (0);
-
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- return (_rl_vi_change_mbchar_case (count));
-#endif
-
- while (count-- && rl_point < rl_end)
- {
- if (_rl_uppercase_p (rl_line_buffer[rl_point]))
- c = _rl_to_lower (rl_line_buffer[rl_point]);
- else if (_rl_lowercase_p (rl_line_buffer[rl_point]))
- c = _rl_to_upper (rl_line_buffer[rl_point]);
- else
- {
- /* Just skip over characters neither upper nor lower case. */
- rl_forward_char (1, c);
- continue;
- }
-
- /* Vi is kind of strange here. */
- if (c)
- {
- rl_begin_undo_group ();
- rl_delete (1, c);
- _rl_insert_char (1, c);
- rl_end_undo_group ();
- rl_vi_check ();
- }
- else
- rl_forward_char (1, c);
- }
- return (0);
-}
-
-int
-rl_vi_put (count, key)
- int count, key;
-{
- if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
- rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
-
- rl_yank (1, key);
- rl_backward_char (1, key);
- return (0);
-}
-
-int
-rl_vi_check ()
-{
- if (rl_point && rl_point == rl_end)
- {
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
- else
- rl_point--;
- }
- return (0);
-}
-
-int
-rl_vi_column (count, key)
- int count, key;
-{
- if (count > rl_end)
- rl_end_of_line (1, key);
- else
- rl_point = count - 1;
- return (0);
-}
-
-int
-rl_vi_domove (key, nextkey)
- int key, *nextkey;
-{
- int c, save;
- int old_end;
-
- rl_mark = rl_point;
- RL_SETSTATE(RL_STATE_MOREINPUT);
- c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
- *nextkey = c;
-
- if (!member (c, vi_motion))
- {
- if (_rl_digit_p (c))
- {
- save = rl_numeric_arg;
- rl_numeric_arg = _rl_digit_value (c);
- rl_digit_loop1 ();
- rl_numeric_arg *= save;
- RL_SETSTATE(RL_STATE_MOREINPUT);
- c = rl_read_key (); /* real command */
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
- *nextkey = c;
- }
- else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
- {
- rl_mark = rl_end;
- rl_beg_of_line (1, c);
- _rl_vi_last_motion = c;
- return (0);
- }
- else
- return (-1);
- }
-
- _rl_vi_last_motion = c;
-
- /* Append a blank character temporarily so that the motion routines
- work right at the end of the line. */
- old_end = rl_end;
- rl_line_buffer[rl_end++] = ' ';
- rl_line_buffer[rl_end] = '\0';
-
- _rl_dispatch (c, _rl_keymap);
-
- /* Remove the blank that we added. */
- rl_end = old_end;
- rl_line_buffer[rl_end] = '\0';
- if (rl_point > rl_end)
- rl_point = rl_end;
-
- /* No change in position means the command failed. */
- if (rl_mark == rl_point)
- return (-1);
-
- /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
- word. If we are not at the end of the line, and we are on a
- non-whitespace character, move back one (presumably to whitespace). */
- if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
- !whitespace (rl_line_buffer[rl_point]))
- rl_point--;
-
- /* If cw or cW, back up to the end of a word, so the behaviour of ce
- or cE is the actual result. Brute-force, no subtlety. */
- if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
- {
- /* Don't move farther back than where we started. */
- while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
- rl_point--;
-
- /* Posix.2 says that if cw or cW moves the cursor towards the end of
- the line, the character under the cursor should be deleted. */
- if (rl_point == rl_mark)
- rl_point++;
- else
- {
- /* Move past the end of the word so that the kill doesn't
- remove the last letter of the previous word. Only do this
- if we are not at the end of the line. */
- if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
- rl_point++;
- }
- }
-
- if (rl_mark < rl_point)
- SWAP (rl_point, rl_mark);
-
- return (0);
-}
-
-/* A simplified loop for vi. Don't dispatch key at end.
- Don't recognize minus sign?
- Should this do rl_save_prompt/rl_restore_prompt? */
-static int
-rl_digit_loop1 ()
-{
- int key, c;
-
- RL_SETSTATE(RL_STATE_NUMERICARG);
- while (1)
- {
- if (rl_numeric_arg > 1000000)
- {
- rl_explicit_arg = rl_numeric_arg = 0;
- rl_ding ();
- rl_clear_message ();
- RL_UNSETSTATE(RL_STATE_NUMERICARG);
- return 1;
- }
- rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
- RL_SETSTATE(RL_STATE_MOREINPUT);
- key = c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
- if (c >= 0 && _rl_keymap[c].type == ISFUNC &&
- _rl_keymap[c].function == rl_universal_argument)
- {
- rl_numeric_arg *= 4;
- continue;
- }
-
- c = UNMETA (c);
- if (_rl_digit_p (c))
- {
- if (rl_explicit_arg)
- rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
- else
- rl_numeric_arg = _rl_digit_value (c);
- rl_explicit_arg = 1;
- }
- else
- {
- rl_clear_message ();
- rl_stuff_char (key);
- break;
- }
- }
-
- RL_UNSETSTATE(RL_STATE_NUMERICARG);
- return (0);
-}
-
-int
-rl_vi_delete_to (count, key)
- int count, key;
-{
- int c;
-
- if (_rl_uppercase_p (key))
- rl_stuff_char ('$');
- else if (vi_redoing)
- rl_stuff_char (_rl_vi_last_motion);
-
- if (rl_vi_domove (key, &c))
- {
- rl_ding ();
- return -1;
- }
-
- /* These are the motion commands that do not require adjusting the
- mark. */
- if ((strchr (" l|h^0bB", c) == 0) && (rl_mark < rl_end))
- rl_mark++;
-
- rl_kill_text (rl_point, rl_mark);
- return (0);
-}
-
-int
-rl_vi_change_to (count, key)
- int count, key;
-{
- int c, start_pos;
-
- if (_rl_uppercase_p (key))
- rl_stuff_char ('$');
- else if (vi_redoing)
- rl_stuff_char (_rl_vi_last_motion);
-
- start_pos = rl_point;
-
- if (rl_vi_domove (key, &c))
- {
- rl_ding ();
- return -1;
- }
-
- /* These are the motion commands that do not require adjusting the
- mark. c[wW] are handled by special-case code in rl_vi_domove(),
- and already leave the mark at the correct location. */
- if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end))
- rl_mark++;
-
- /* The cursor never moves with c[wW]. */
- if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
- rl_point = start_pos;
-
- if (vi_redoing)
- {
- if (vi_insert_buffer && *vi_insert_buffer)
- rl_begin_undo_group ();
- rl_delete_text (rl_point, rl_mark);
- if (vi_insert_buffer && *vi_insert_buffer)
- {
- rl_insert_text (vi_insert_buffer);
- rl_end_undo_group ();
- }
- }
- else
- {
- rl_begin_undo_group (); /* to make the `u' command work */
- rl_kill_text (rl_point, rl_mark);
- /* `C' does not save the text inserted for undoing or redoing. */
- if (_rl_uppercase_p (key) == 0)
- _rl_vi_doing_insert = 1;
- _rl_vi_set_last (key, count, rl_arg_sign);
- rl_vi_insertion_mode (1, key);
- }
-
- return (0);
-}
-
-int
-rl_vi_yank_to (count, key)
- int count, key;
-{
- int c, save = rl_point;
-
- if (_rl_uppercase_p (key))
- rl_stuff_char ('$');
-
- if (rl_vi_domove (key, &c))
- {
- rl_ding ();
- return -1;
- }
-
- /* These are the motion commands that do not require adjusting the
- mark. */
- if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end))
- rl_mark++;
-
- rl_begin_undo_group ();
- rl_kill_text (rl_point, rl_mark);
- rl_end_undo_group ();
- rl_do_undo ();
- rl_point = save;
-
- return (0);
-}
-
-int
-rl_vi_delete (count, key)
- int count, key;
-{
- int end;
-
- if (rl_end == 0)
- {
- rl_ding ();
- return -1;
- }
-
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
- else
- end = rl_point + count;
-
- if (end >= rl_end)
- end = rl_end;
-
- rl_kill_text (rl_point, end);
-
- if (rl_point > 0 && rl_point == rl_end)
- rl_backward_char (1, key);
- return (0);
-}
-
-int
-rl_vi_back_to_indent (count, key)
- int count, key;
-{
- rl_beg_of_line (1, key);
- while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
- rl_point++;
- return (0);
-}
-
-int
-rl_vi_first_print (count, key)
- int count, key;
-{
- return (rl_vi_back_to_indent (1, key));
-}
-
-int
-rl_vi_char_search (count, key)
- int count, key;
-{
-#if defined (HANDLE_MULTIBYTE)
- static char *target;
- static int mb_len;
-#else
- static char target;
-#endif
- static int orig_dir, dir;
-
- if (key == ';' || key == ',')
- dir = key == ';' ? orig_dir : -orig_dir;
- else
- {
- if (vi_redoing)
-#if defined (HANDLE_MULTIBYTE)
- target = _rl_vi_last_search_mbchar;
-#else
- target = _rl_vi_last_search_char;
-#endif
- else
- {
-#if defined (HANDLE_MULTIBYTE)
- mb_len = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
- target = _rl_vi_last_search_mbchar;
-#else
- RL_SETSTATE(RL_STATE_MOREINPUT);
- _rl_vi_last_search_char = target = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-#endif
- }
-
- switch (key)
- {
- case 't':
- orig_dir = dir = FTO;
- break;
-
- case 'T':
- orig_dir = dir = BTO;
- break;
-
- case 'f':
- orig_dir = dir = FFIND;
- break;
-
- case 'F':
- orig_dir = dir = BFIND;
- break;
- }
- }
-
-#if defined (HANDLE_MULTIBYTE)
- return (_rl_char_search_internal (count, dir, target, mb_len));
-#else
- return (_rl_char_search_internal (count, dir, target));
-#endif
-}
-
-/* Match brackets */
-int
-rl_vi_match (ignore, key)
- int ignore, key;
-{
- int count = 1, brack, pos, tmp, pre;
-
- pos = rl_point;
- if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
- {
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
- {
- pre = rl_point;
- rl_forward_char (1, key);
- if (pre == rl_point)
- break;
- }
- }
- else
- while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
- rl_point < rl_end - 1)
- rl_forward_char (1, key);
-
- if (brack <= 0)
- {
- rl_point = pos;
- rl_ding ();
- return -1;
- }
- }
-
- pos = rl_point;
-
- if (brack < 0)
- {
- while (count)
- {
- tmp = pos;
- if (MB_CUR_MAX == 1 || rl_byte_oriented)
- pos--;
- else
- {
- pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
- if (tmp == pos)
- pos--;
- }
- if (pos >= 0)
- {
- int b = rl_vi_bracktype (rl_line_buffer[pos]);
- if (b == -brack)
- count--;
- else if (b == brack)
- count++;
- }
- else
- {
- rl_ding ();
- return -1;
- }
- }
- }
- else
- { /* brack > 0 */
- while (count)
- {
- if (MB_CUR_MAX == 1 || rl_byte_oriented)
- pos++;
- else
- pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY);
-
- if (pos < rl_end)
- {
- int b = rl_vi_bracktype (rl_line_buffer[pos]);
- if (b == -brack)
- count--;
- else if (b == brack)
- count++;
- }
- else
- {
- rl_ding ();
- return -1;
- }
- }
- }
- rl_point = pos;
- return (0);
-}
-
-int
-rl_vi_bracktype (c)
- int c;
-{
- switch (c)
- {
- case '(': return 1;
- case ')': return -1;
- case '[': return 2;
- case ']': return -2;
- case '{': return 3;
- case '}': return -3;
- default: return 0;
- }
-}
-
-/* XXX - think about reading an entire mbchar with _rl_read_mbchar and
- inserting it in one bunch instead of the loop below (like in
- rl_vi_char_search or _rl_vi_change_mbchar_case. Set c to mbchar[0]
- for test against 033 or ^C. Make sure that _rl_read_mbchar does
- this right. */
-int
-rl_vi_change_char (count, key)
- int count, key;
-{
- int c;
-
- if (vi_redoing)
- c = _rl_vi_last_replacement;
- else
- {
- RL_SETSTATE(RL_STATE_MOREINPUT);
- _rl_vi_last_replacement = c = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
- }
-
- if (c == '\033' || c == CTRL ('C'))
- return -1;
-
- while (count-- && rl_point < rl_end)
- {
- rl_begin_undo_group ();
-
- rl_delete (1, c);
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- while (_rl_insert_char (1, c))
- {
- RL_SETSTATE (RL_STATE_MOREINPUT);
- c = rl_read_key ();
- RL_UNSETSTATE (RL_STATE_MOREINPUT);
- }
- else
-#endif
- _rl_insert_char (1, c);
- if (count == 0)
- rl_backward_char (1, c);
-
- rl_end_undo_group ();
- }
- return (0);
-}
-
-int
-rl_vi_subst (count, key)
- int count, key;
-{
- /* If we are redoing, rl_vi_change_to will stuff the last motion char */
- if (vi_redoing == 0)
- rl_stuff_char ((key == 'S') ? 'c' : ' '); /* `S' == `cc', `s' == `c ' */
-
- return (rl_vi_change_to (count, 'c'));
-}
-
-int
-rl_vi_overstrike (count, key)
- int count, key;
-{
- if (_rl_vi_doing_insert == 0)
- {
- _rl_vi_doing_insert = 1;
- rl_begin_undo_group ();
- }
-
- if (count > 0)
- {
- _rl_overwrite_char (count, key);
- vi_replace_count += count;
- }
-
- return (0);
-}
-
-int
-rl_vi_overstrike_delete (count, key)
- int count, key;
-{
- int i, s;
-
- for (i = 0; i < count; i++)
- {
- if (vi_replace_count == 0)
- {
- rl_ding ();
- break;
- }
- s = rl_point;
-
- if (rl_do_undo ())
- vi_replace_count--;
-
- if (rl_point == s)
- rl_backward_char (1, key);
- }
-
- if (vi_replace_count == 0 && _rl_vi_doing_insert)
- {
- rl_end_undo_group ();
- rl_do_undo ();
- _rl_vi_doing_insert = 0;
- }
- return (0);
-}
-
-int
-rl_vi_replace (count, key)
- int count, key;
-{
- int i;
-
- vi_replace_count = 0;
-
- if (!vi_replace_map)
- {
- vi_replace_map = rl_make_bare_keymap ();
-
- for (i = ' '; i < KEYMAP_SIZE; i++)
- vi_replace_map[i].function = rl_vi_overstrike;
-
- vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
- vi_replace_map[ESC].function = rl_vi_movement_mode;
- vi_replace_map[RETURN].function = rl_newline;
- vi_replace_map[NEWLINE].function = rl_newline;
-
- /* If the normal vi insertion keymap has ^H bound to erase, do the
- same here. Probably should remove the assignment to RUBOUT up
- there, but I don't think it will make a difference in real life. */
- if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC &&
- vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
- vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
-
- }
- _rl_keymap = vi_replace_map;
- return (0);
-}
-
-#if 0
-/* Try to complete the word we are standing on or the word that ends with
- the previous character. A space matches everything. Word delimiters are
- space and ;. */
-int
-rl_vi_possible_completions()
-{
- int save_pos = rl_point;
-
- if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';')
- {
- while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&
- rl_line_buffer[rl_point] != ';')
- rl_point++;
- }
- else if (rl_line_buffer[rl_point - 1] == ';')
- {
- rl_ding ();
- return (0);
- }
-
- rl_possible_completions ();
- rl_point = save_pos;
-
- return (0);
-}
-#endif
-
-/* Functions to save and restore marks. */
-int
-rl_vi_set_mark (count, key)
- int count, key;
-{
- int ch;
-
- RL_SETSTATE(RL_STATE_MOREINPUT);
- ch = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
- if (ch < 'a' || ch > 'z')
- {
- rl_ding ();
- return -1;
- }
- ch -= 'a';
- vi_mark_chars[ch] = rl_point;
- return 0;
-}
-
-int
-rl_vi_goto_mark (count, key)
- int count, key;
-{
- int ch;
-
- RL_SETSTATE(RL_STATE_MOREINPUT);
- ch = rl_read_key ();
- RL_UNSETSTATE(RL_STATE_MOREINPUT);
-
- if (ch == '`')
- {
- rl_point = rl_mark;
- return 0;
- }
- else if (ch < 'a' || ch > 'z')
- {
- rl_ding ();
- return -1;
- }
-
- ch -= 'a';
- if (vi_mark_chars[ch] == -1)
- {
- rl_ding ();
- return -1;
- }
- rl_point = vi_mark_chars[ch];
- return 0;
-}
-
-#endif /* VI_MODE */
+/* vi_mode.c -- A vi emulation mode for Bash.
+ Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
+
+/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+/* **************************************************************** */
+/* */
+/* VI Emulation Mode */
+/* */
+/* **************************************************************** */
+#include "rlconf.h"
+
+#if defined (VI_MODE)
+
+#include "config.h"
+
+#include <sys/types.h>
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#include <stdio.h>
+
+/* Some standard library routines. */
+#include "rldefs.h"
+#include "rlmbutil.h"
+
+#include "readline.h"
+#include "history.h"
+
+#include "rlprivate.h"
+#include "xmalloc.h"
+
+#ifndef member
+#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
+#endif
+
+/* Non-zero means enter insertion mode. */
+static int _rl_vi_doing_insert;
+
+/* Command keys which do movement for xxx_to commands. */
+static const char *vi_motion = " hl^$0ftFT;,%wbeWBE|";
+
+/* Keymap used for vi replace characters. Created dynamically since
+ rarely used. */
+static Keymap vi_replace_map;
+
+/* The number of characters inserted in the last replace operation. */
+static int vi_replace_count;
+
+/* If non-zero, we have text inserted after a c[motion] command that put
+ us implicitly into insert mode. Some people want this text to be
+ attached to the command so that it is `redoable' with `.'. */
+static int vi_continued_command;
+static char *vi_insert_buffer;
+static int vi_insert_buffer_size;
+
+static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
+static int _rl_vi_last_repeat = 1;
+static int _rl_vi_last_arg_sign = 1;
+static int _rl_vi_last_motion;
+#if defined (HANDLE_MULTIBYTE)
+static char _rl_vi_last_search_mbchar[MB_LEN_MAX];
+#else
+static int _rl_vi_last_search_char;
+#endif
+static int _rl_vi_last_replacement;
+
+static int _rl_vi_last_key_before_insert;
+
+static int vi_redoing;
+
+/* Text modification commands. These are the `redoable' commands. */
+static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
+
+/* Arrays for the saved marks. */
+static int vi_mark_chars['z' - 'a' + 1];
+
+static void _rl_vi_stuff_insert PARAMS((int));
+static void _rl_vi_save_insert PARAMS((UNDO_LIST *));
+static int rl_digit_loop1 PARAMS((void));
+
+void
+_rl_vi_initialize_line ()
+{
+ register int i;
+
+ for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
+ vi_mark_chars[i] = -1;
+}
+
+void
+_rl_vi_reset_last ()
+{
+ _rl_vi_last_command = 'i';
+ _rl_vi_last_repeat = 1;
+ _rl_vi_last_arg_sign = 1;
+ _rl_vi_last_motion = 0;
+}
+
+void
+_rl_vi_set_last (key, repeat, sign)
+ int key, repeat, sign;
+{
+ _rl_vi_last_command = key;
+ _rl_vi_last_repeat = repeat;
+ _rl_vi_last_arg_sign = sign;
+}
+
+/* Is the command C a VI mode text modification command? */
+int
+_rl_vi_textmod_command (c)
+ int c;
+{
+ return (member (c, vi_textmod));
+}
+
+static void
+_rl_vi_stuff_insert (count)
+ int count;
+{
+ rl_begin_undo_group ();
+ while (count--)
+ rl_insert_text (vi_insert_buffer);
+ rl_end_undo_group ();
+}
+
+/* Bound to `.'. Called from command mode, so we know that we have to
+ redo a text modification command. The default for _rl_vi_last_command
+ puts you back into insert mode. */
+int
+rl_vi_redo (count, c)
+ int count, c;
+{
+ int r;
+
+ if (!rl_explicit_arg)
+ {
+ rl_numeric_arg = _rl_vi_last_repeat;
+ rl_arg_sign = _rl_vi_last_arg_sign;
+ }
+
+ r = 0;
+ vi_redoing = 1;
+ /* If we're redoing an insert with `i', stuff in the inserted text
+ and do not go into insertion mode. */
+ if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
+ {
+ _rl_vi_stuff_insert (count);
+ /* And back up point over the last character inserted. */
+ if (rl_point > 0)
+ rl_point--;
+ }
+ else
+ r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);
+ vi_redoing = 0;
+
+ return (r);
+}
+
+/* A placeholder for further expansion. */
+int
+rl_vi_undo (count, key)
+ int count, key;
+{
+ return (rl_undo_command (count, key));
+}
+
+/* Yank the nth arg from the previous line into this line at point. */
+int
+rl_vi_yank_arg (count, key)
+ int count, key;
+{
+ /* Readline thinks that the first word on a line is the 0th, while vi
+ thinks the first word on a line is the 1st. Compensate. */
+ if (rl_explicit_arg)
+ rl_yank_nth_arg (count - 1, 0);
+ else
+ rl_yank_nth_arg ('$', 0);
+
+ return (0);
+}
+
+/* With an argument, move back that many history lines, else move to the
+ beginning of history. */
+int
+rl_vi_fetch_history (count, c)
+ int count, c;
+{
+ int wanted;
+
+ /* Giving an argument of n means we want the nth command in the history
+ file. The command number is interpreted the same way that the bash
+ `history' command does it -- that is, giving an argument count of 450
+ to this command would get the command listed as number 450 in the
+ output of `history'. */
+ if (rl_explicit_arg)
+ {
+ wanted = history_base + where_history () - count;
+ if (wanted <= 0)
+ rl_beginning_of_history (0, 0);
+ else
+ rl_get_previous_history (wanted, c);
+ }
+ else
+ rl_beginning_of_history (count, 0);
+ return (0);
+}
+
+/* Search again for the last thing searched for. */
+int
+rl_vi_search_again (count, key)
+ int count, key;
+{
+ switch (key)
+ {
+ case 'n':
+ rl_noninc_reverse_search_again (count, key);
+ break;
+
+ case 'N':
+ rl_noninc_forward_search_again (count, key);
+ break;
+ }
+ return (0);
+}
+
+/* Do a vi style search. */
+int
+rl_vi_search (count, key)
+ int count, key;
+{
+ switch (key)
+ {
+ case '?':
+ rl_noninc_forward_search (count, key);
+ break;
+
+ case '/':
+ rl_noninc_reverse_search (count, key);
+ break;
+
+ default:
+ rl_ding ();
+ break;
+ }
+ return (0);
+}
+
+/* Completion, from vi's point of view. */
+int
+rl_vi_complete (ignore, key)
+ int ignore, key;
+{
+ if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
+ {
+ if (!whitespace (rl_line_buffer[rl_point + 1]))
+ rl_vi_end_word (1, 'E');
+ rl_point++;
+ }
+
+ if (key == '*')
+ rl_complete_internal ('*'); /* Expansion and replacement. */
+ else if (key == '=')
+ rl_complete_internal ('?'); /* List possible completions. */
+ else if (key == '\\')
+ rl_complete_internal (TAB); /* Standard Readline completion. */
+ else
+ rl_complete (0, key);
+
+ if (key == '*' || key == '\\')
+ {
+ _rl_vi_set_last (key, 1, rl_arg_sign);
+ rl_vi_insertion_mode (1, key);
+ }
+ return (0);
+}
+
+/* Tilde expansion for vi mode. */
+int
+rl_vi_tilde_expand (ignore, key)
+ int ignore, key;
+{
+ rl_tilde_expand (0, key);
+ _rl_vi_set_last (key, 1, rl_arg_sign); /* XXX */
+ rl_vi_insertion_mode (1, key);
+ return (0);
+}
+
+/* Previous word in vi mode. */
+int
+rl_vi_prev_word (count, key)
+ int count, key;
+{
+ if (count < 0)
+ return (rl_vi_next_word (-count, key));
+
+ if (rl_point == 0)
+ {
+ rl_ding ();
+ return (0);
+ }
+
+ if (_rl_uppercase_p (key))
+ rl_vi_bWord (count, key);
+ else
+ rl_vi_bword (count, key);
+
+ return (0);
+}
+
+/* Next word in vi mode. */
+int
+rl_vi_next_word (count, key)
+ int count, key;
+{
+ if (count < 0)
+ return (rl_vi_prev_word (-count, key));
+
+ if (rl_point >= (rl_end - 1))
+ {
+ rl_ding ();
+ return (0);
+ }
+
+ if (_rl_uppercase_p (key))
+ rl_vi_fWord (count, key);
+ else
+ rl_vi_fword (count, key);
+ return (0);
+}
+
+/* Move to the end of the ?next? word. */
+int
+rl_vi_end_word (count, key)
+ int count, key;
+{
+ if (count < 0)
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ if (_rl_uppercase_p (key))
+ rl_vi_eWord (count, key);
+ else
+ rl_vi_eword (count, key);
+ return (0);
+}
+
+/* Move forward a word the way that 'W' does. */
+int
+rl_vi_fWord (count, ignore)
+ int count, ignore;
+{
+ while (count-- && rl_point < (rl_end - 1))
+ {
+ /* Skip until whitespace. */
+ while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
+ rl_point++;
+
+ /* Now skip whitespace. */
+ while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
+ rl_point++;
+ }
+ return (0);
+}
+
+int
+rl_vi_bWord (count, ignore)
+ int count, ignore;
+{
+ while (count-- && rl_point > 0)
+ {
+ /* If we are at the start of a word, move back to whitespace so
+ we will go back to the start of the previous word. */
+ if (!whitespace (rl_line_buffer[rl_point]) &&
+ whitespace (rl_line_buffer[rl_point - 1]))
+ rl_point--;
+
+ while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
+ rl_point--;
+
+ if (rl_point > 0)
+ {
+ while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point]));
+ rl_point++;
+ }
+ }
+ return (0);
+}
+
+int
+rl_vi_eWord (count, ignore)
+ int count, ignore;
+{
+ while (count-- && rl_point < (rl_end - 1))
+ {
+ if (!whitespace (rl_line_buffer[rl_point]))
+ rl_point++;
+
+ /* Move to the next non-whitespace character (to the start of the
+ next word). */
+ while (++rl_point < rl_end && whitespace (rl_line_buffer[rl_point]));
+
+ if (rl_point && rl_point < rl_end)
+ {
+ /* Skip whitespace. */
+ while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
+ rl_point++;
+
+ /* Skip until whitespace. */
+ while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point]))
+ rl_point++;
+
+ /* Move back to the last character of the word. */
+ rl_point--;
+ }
+ }
+ return (0);
+}
+
+int
+rl_vi_fword (count, ignore)
+ int count, ignore;
+{
+ while (count-- && rl_point < (rl_end - 1))
+ {
+ /* Move to white space (really non-identifer). */
+ if (_rl_isident (rl_line_buffer[rl_point]))
+ {
+ while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
+ rl_point++;
+ }
+ else /* if (!whitespace (rl_line_buffer[rl_point])) */
+ {
+ while (!_rl_isident (rl_line_buffer[rl_point]) &&
+ !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
+ rl_point++;
+ }
+
+ /* Move past whitespace. */
+ while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
+ rl_point++;
+ }
+ return (0);
+}
+
+int
+rl_vi_bword (count, ignore)
+ int count, ignore;
+{
+ while (count-- && rl_point > 0)
+ {
+ int last_is_ident;
+
+ /* If we are at the start of a word, move back to whitespace
+ so we will go back to the start of the previous word. */
+ if (!whitespace (rl_line_buffer[rl_point]) &&
+ whitespace (rl_line_buffer[rl_point - 1]))
+ rl_point--;
+
+ /* If this character and the previous character are `opposite', move
+ back so we don't get messed up by the rl_point++ down there in
+ the while loop. Without this code, words like `l;' screw up the
+ function. */
+ last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]);
+ if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
+ (!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident))
+ rl_point--;
+
+ while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
+ rl_point--;
+
+ if (rl_point > 0)
+ {
+ if (_rl_isident (rl_line_buffer[rl_point]))
+ while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point]));
+ else
+ while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) &&
+ !whitespace (rl_line_buffer[rl_point]));
+ rl_point++;
+ }
+ }
+ return (0);
+}
+
+int
+rl_vi_eword (count, ignore)
+ int count, ignore;
+{
+ while (count-- && rl_point < rl_end - 1)
+ {
+ if (!whitespace (rl_line_buffer[rl_point]))
+ rl_point++;
+
+ while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
+ rl_point++;
+
+ if (rl_point < rl_end)
+ {
+ if (_rl_isident (rl_line_buffer[rl_point]))
+ while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point]));
+ else
+ while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point])
+ && !whitespace (rl_line_buffer[rl_point]));
+ }
+ rl_point--;
+ }
+ return (0);
+}
+
+int
+rl_vi_insert_beg (count, key)
+ int count, key;
+{
+ rl_beg_of_line (1, key);
+ rl_vi_insertion_mode (1, key);
+ return (0);
+}
+
+int
+rl_vi_append_mode (count, key)
+ int count, key;
+{
+ if (rl_point < rl_end)
+ {
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ rl_point++;
+ else
+ {
+ int point = rl_point;
+ rl_forward_char (1, key);
+ if (point == rl_point)
+ rl_point = rl_end;
+ }
+ }
+ rl_vi_insertion_mode (1, key);
+ return (0);
+}
+
+int
+rl_vi_append_eol (count, key)
+ int count, key;
+{
+ rl_end_of_line (1, key);
+ rl_vi_append_mode (1, key);
+ return (0);
+}
+
+/* What to do in the case of C-d. */
+int
+rl_vi_eof_maybe (count, c)
+ int count, c;
+{
+ return (rl_newline (1, '\n'));
+}
+
+/* Insertion mode stuff. */
+
+/* Switching from one mode to the other really just involves
+ switching keymaps. */
+int
+rl_vi_insertion_mode (count, key)
+ int count, key;
+{
+ _rl_keymap = vi_insertion_keymap;
+ _rl_vi_last_key_before_insert = key;
+ return (0);
+}
+
+static void
+_rl_vi_save_insert (up)
+ UNDO_LIST *up;
+{
+ int len, start, end;
+
+ if (up == 0)
+ {
+ if (vi_insert_buffer_size >= 1)
+ vi_insert_buffer[0] = '\0';
+ return;
+ }
+
+ start = up->start;
+ end = up->end;
+ len = end - start + 1;
+ if (len >= vi_insert_buffer_size)
+ {
+ vi_insert_buffer_size += (len + 32) - (len % 32);
+ vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size);
+ }
+ strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
+ vi_insert_buffer[len-1] = '\0';
+}
+
+void
+_rl_vi_done_inserting ()
+{
+ if (_rl_vi_doing_insert)
+ {
+ /* The `C', `s', and `S' commands set this. */
+ rl_end_undo_group ();
+ /* Now, the text between rl_undo_list->next->start and
+ rl_undo_list->next->end is what was inserted while in insert
+ mode. It gets copied to VI_INSERT_BUFFER because it depends
+ on absolute indices into the line which may change (though they
+ probably will not). */
+ _rl_vi_doing_insert = 0;
+ _rl_vi_save_insert (rl_undo_list->next);
+ vi_continued_command = 1;
+ }
+ else
+ {
+ if (_rl_vi_last_key_before_insert == 'i' && rl_undo_list)
+ _rl_vi_save_insert (rl_undo_list);
+ /* XXX - Other keys probably need to be checked. */
+ else if (_rl_vi_last_key_before_insert == 'C')
+ rl_end_undo_group ();
+ while (_rl_undo_group_level > 0)
+ rl_end_undo_group ();
+ vi_continued_command = 0;
+ }
+}
+
+int
+rl_vi_movement_mode (count, key)
+ int count, key;
+{
+ if (rl_point > 0)
+ rl_backward_char (1, key);
+
+ _rl_keymap = vi_movement_keymap;
+ _rl_vi_done_inserting ();
+ return (0);
+}
+
+int
+rl_vi_arg_digit (count, c)
+ int count, c;
+{
+ if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
+ return (rl_beg_of_line (1, c));
+ else
+ return (rl_digit_argument (count, c));
+}
+
+/* Change the case of the next COUNT characters. */
+#if defined (HANDLE_MULTIBYTE)
+static int
+_rl_vi_change_mbchar_case (count)
+ int count;
+{
+ wchar_t wc;
+ char mb[MB_LEN_MAX];
+ mbstate_t ps;
+
+ memset (&ps, 0, sizeof (mbstate_t));
+ if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0)
+ count--;
+ while (count-- && rl_point < rl_end)
+ {
+ mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps);
+ if (iswupper (wc))
+ wc = towlower (wc);
+ else if (iswlower (wc))
+ wc = towupper (wc);
+ else
+ {
+ /* Just skip over chars neither upper nor lower case */
+ rl_forward_char (1, 0);
+ continue;
+ }
+
+ /* Vi is kind of strange here. */
+ if (wc)
+ {
+ wctomb (mb, wc);
+ rl_begin_undo_group ();
+ rl_delete (1, 0);
+ rl_insert_text (mb);
+ rl_end_undo_group ();
+ rl_vi_check ();
+ }
+ else
+ rl_forward_char (1, 0);
+ }
+
+ return 0;
+}
+#endif
+
+int
+rl_vi_change_case (count, ignore)
+ int count, ignore;
+{
+ char c = 0;
+
+ /* Don't try this on an empty line. */
+ if (rl_point >= rl_end)
+ return (0);
+
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ return (_rl_vi_change_mbchar_case (count));
+#endif
+
+ while (count-- && rl_point < rl_end)
+ {
+ if (_rl_uppercase_p (rl_line_buffer[rl_point]))
+ c = _rl_to_lower (rl_line_buffer[rl_point]);
+ else if (_rl_lowercase_p (rl_line_buffer[rl_point]))
+ c = _rl_to_upper (rl_line_buffer[rl_point]);
+ else
+ {
+ /* Just skip over characters neither upper nor lower case. */
+ rl_forward_char (1, c);
+ continue;
+ }
+
+ /* Vi is kind of strange here. */
+ if (c)
+ {
+ rl_begin_undo_group ();
+ rl_delete (1, c);
+ _rl_insert_char (1, c);
+ rl_end_undo_group ();
+ rl_vi_check ();
+ }
+ else
+ rl_forward_char (1, c);
+ }
+ return (0);
+}
+
+int
+rl_vi_put (count, key)
+ int count, key;
+{
+ if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
+ rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
+
+ rl_yank (1, key);
+ rl_backward_char (1, key);
+ return (0);
+}
+
+int
+rl_vi_check ()
+{
+ if (rl_point && rl_point == rl_end)
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
+ else
+ rl_point--;
+ }
+ return (0);
+}
+
+int
+rl_vi_column (count, key)
+ int count, key;
+{
+ if (count > rl_end)
+ rl_end_of_line (1, key);
+ else
+ rl_point = count - 1;
+ return (0);
+}
+
+int
+rl_vi_domove (key, nextkey)
+ int key, *nextkey;
+{
+ int c, save;
+ int old_end;
+
+ rl_mark = rl_point;
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+ *nextkey = c;
+
+ if (!member (c, vi_motion))
+ {
+ if (_rl_digit_p (c))
+ {
+ save = rl_numeric_arg;
+ rl_numeric_arg = _rl_digit_value (c);
+ rl_digit_loop1 ();
+ rl_numeric_arg *= save;
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ c = rl_read_key (); /* real command */
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+ *nextkey = c;
+ }
+ else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
+ {
+ rl_mark = rl_end;
+ rl_beg_of_line (1, c);
+ _rl_vi_last_motion = c;
+ return (0);
+ }
+ else
+ return (-1);
+ }
+
+ _rl_vi_last_motion = c;
+
+ /* Append a blank character temporarily so that the motion routines
+ work right at the end of the line. */
+ old_end = rl_end;
+ rl_line_buffer[rl_end++] = ' ';
+ rl_line_buffer[rl_end] = '\0';
+
+ _rl_dispatch (c, _rl_keymap);
+
+ /* Remove the blank that we added. */
+ rl_end = old_end;
+ rl_line_buffer[rl_end] = '\0';
+ if (rl_point > rl_end)
+ rl_point = rl_end;
+
+ /* No change in position means the command failed. */
+ if (rl_mark == rl_point)
+ return (-1);
+
+ /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
+ word. If we are not at the end of the line, and we are on a
+ non-whitespace character, move back one (presumably to whitespace). */
+ if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
+ !whitespace (rl_line_buffer[rl_point]))
+ rl_point--;
+
+ /* If cw or cW, back up to the end of a word, so the behaviour of ce
+ or cE is the actual result. Brute-force, no subtlety. */
+ if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
+ {
+ /* Don't move farther back than where we started. */
+ while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
+ rl_point--;
+
+ /* Posix.2 says that if cw or cW moves the cursor towards the end of
+ the line, the character under the cursor should be deleted. */
+ if (rl_point == rl_mark)
+ rl_point++;
+ else
+ {
+ /* Move past the end of the word so that the kill doesn't
+ remove the last letter of the previous word. Only do this
+ if we are not at the end of the line. */
+ if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
+ rl_point++;
+ }
+ }
+
+ if (rl_mark < rl_point)
+ SWAP (rl_point, rl_mark);
+
+ return (0);
+}
+
+/* A simplified loop for vi. Don't dispatch key at end.
+ Don't recognize minus sign?
+ Should this do rl_save_prompt/rl_restore_prompt? */
+static int
+rl_digit_loop1 ()
+{
+ int key, c;
+
+ RL_SETSTATE(RL_STATE_NUMERICARG);
+ while (1)
+ {
+ if (rl_numeric_arg > 1000000)
+ {
+ rl_explicit_arg = rl_numeric_arg = 0;
+ rl_ding ();
+ rl_clear_message ();
+ RL_UNSETSTATE(RL_STATE_NUMERICARG);
+ return 1;
+ }
+ rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ key = c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+ if (c >= 0 && _rl_keymap[c].type == ISFUNC &&
+ _rl_keymap[c].function == rl_universal_argument)
+ {
+ rl_numeric_arg *= 4;
+ continue;
+ }
+
+ c = UNMETA (c);
+ if (_rl_digit_p (c))
+ {
+ if (rl_explicit_arg)
+ rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
+ else
+ rl_numeric_arg = _rl_digit_value (c);
+ rl_explicit_arg = 1;
+ }
+ else
+ {
+ rl_clear_message ();
+ rl_stuff_char (key);
+ break;
+ }
+ }
+
+ RL_UNSETSTATE(RL_STATE_NUMERICARG);
+ return (0);
+}
+
+int
+rl_vi_delete_to (count, key)
+ int count, key;
+{
+ int c;
+
+ if (_rl_uppercase_p (key))
+ rl_stuff_char ('$');
+ else if (vi_redoing)
+ rl_stuff_char (_rl_vi_last_motion);
+
+ if (rl_vi_domove (key, &c))
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ /* These are the motion commands that do not require adjusting the
+ mark. */
+ if ((strchr (" l|h^0bB", c) == 0) && (rl_mark < rl_end))
+ rl_mark++;
+
+ rl_kill_text (rl_point, rl_mark);
+ return (0);
+}
+
+int
+rl_vi_change_to (count, key)
+ int count, key;
+{
+ int c, start_pos;
+
+ if (_rl_uppercase_p (key))
+ rl_stuff_char ('$');
+ else if (vi_redoing)
+ rl_stuff_char (_rl_vi_last_motion);
+
+ start_pos = rl_point;
+
+ if (rl_vi_domove (key, &c))
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ /* These are the motion commands that do not require adjusting the
+ mark. c[wW] are handled by special-case code in rl_vi_domove(),
+ and already leave the mark at the correct location. */
+ if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end))
+ rl_mark++;
+
+ /* The cursor never moves with c[wW]. */
+ if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
+ rl_point = start_pos;
+
+ if (vi_redoing)
+ {
+ if (vi_insert_buffer && *vi_insert_buffer)
+ rl_begin_undo_group ();
+ rl_delete_text (rl_point, rl_mark);
+ if (vi_insert_buffer && *vi_insert_buffer)
+ {
+ rl_insert_text (vi_insert_buffer);
+ rl_end_undo_group ();
+ }
+ }
+ else
+ {
+ rl_begin_undo_group (); /* to make the `u' command work */
+ rl_kill_text (rl_point, rl_mark);
+ /* `C' does not save the text inserted for undoing or redoing. */
+ if (_rl_uppercase_p (key) == 0)
+ _rl_vi_doing_insert = 1;
+ _rl_vi_set_last (key, count, rl_arg_sign);
+ rl_vi_insertion_mode (1, key);
+ }
+
+ return (0);
+}
+
+int
+rl_vi_yank_to (count, key)
+ int count, key;
+{
+ int c, save = rl_point;
+
+ if (_rl_uppercase_p (key))
+ rl_stuff_char ('$');
+
+ if (rl_vi_domove (key, &c))
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ /* These are the motion commands that do not require adjusting the
+ mark. */
+ if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end))
+ rl_mark++;
+
+ rl_begin_undo_group ();
+ rl_kill_text (rl_point, rl_mark);
+ rl_end_undo_group ();
+ rl_do_undo ();
+ rl_point = save;
+
+ return (0);
+}
+
+int
+rl_vi_delete (count, key)
+ int count, key;
+{
+ int end;
+
+ if (rl_end == 0)
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
+ else
+ end = rl_point + count;
+
+ if (end >= rl_end)
+ end = rl_end;
+
+ rl_kill_text (rl_point, end);
+
+ if (rl_point > 0 && rl_point == rl_end)
+ rl_backward_char (1, key);
+ return (0);
+}
+
+int
+rl_vi_back_to_indent (count, key)
+ int count, key;
+{
+ rl_beg_of_line (1, key);
+ while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
+ rl_point++;
+ return (0);
+}
+
+int
+rl_vi_first_print (count, key)
+ int count, key;
+{
+ return (rl_vi_back_to_indent (1, key));
+}
+
+int
+rl_vi_char_search (count, key)
+ int count, key;
+{
+#if defined (HANDLE_MULTIBYTE)
+ static char *target;
+ static int mb_len;
+#else
+ static char target;
+#endif
+ static int orig_dir, dir;
+
+ if (key == ';' || key == ',')
+ dir = key == ';' ? orig_dir : -orig_dir;
+ else
+ {
+ if (vi_redoing)
+#if defined (HANDLE_MULTIBYTE)
+ target = _rl_vi_last_search_mbchar;
+#else
+ target = _rl_vi_last_search_char;
+#endif
+ else
+ {
+#if defined (HANDLE_MULTIBYTE)
+ mb_len = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
+ target = _rl_vi_last_search_mbchar;
+#else
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ _rl_vi_last_search_char = target = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+#endif
+ }
+
+ switch (key)
+ {
+ case 't':
+ orig_dir = dir = FTO;
+ break;
+
+ case 'T':
+ orig_dir = dir = BTO;
+ break;
+
+ case 'f':
+ orig_dir = dir = FFIND;
+ break;
+
+ case 'F':
+ orig_dir = dir = BFIND;
+ break;
+ }
+ }
+
+#if defined (HANDLE_MULTIBYTE)
+ return (_rl_char_search_internal (count, dir, target, mb_len));
+#else
+ return (_rl_char_search_internal (count, dir, target));
+#endif
+}
+
+/* Match brackets */
+int
+rl_vi_match (ignore, key)
+ int ignore, key;
+{
+ int count = 1, brack, pos, tmp, pre;
+
+ pos = rl_point;
+ if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
+ {
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ {
+ while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
+ {
+ pre = rl_point;
+ rl_forward_char (1, key);
+ if (pre == rl_point)
+ break;
+ }
+ }
+ else
+ while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
+ rl_point < rl_end - 1)
+ rl_forward_char (1, key);
+
+ if (brack <= 0)
+ {
+ rl_point = pos;
+ rl_ding ();
+ return -1;
+ }
+ }
+
+ pos = rl_point;
+
+ if (brack < 0)
+ {
+ while (count)
+ {
+ tmp = pos;
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ pos--;
+ else
+ {
+ pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
+ if (tmp == pos)
+ pos--;
+ }
+ if (pos >= 0)
+ {
+ int b = rl_vi_bracktype (rl_line_buffer[pos]);
+ if (b == -brack)
+ count--;
+ else if (b == brack)
+ count++;
+ }
+ else
+ {
+ rl_ding ();
+ return -1;
+ }
+ }
+ }
+ else
+ { /* brack > 0 */
+ while (count)
+ {
+ if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ pos++;
+ else
+ pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY);
+
+ if (pos < rl_end)
+ {
+ int b = rl_vi_bracktype (rl_line_buffer[pos]);
+ if (b == -brack)
+ count--;
+ else if (b == brack)
+ count++;
+ }
+ else
+ {
+ rl_ding ();
+ return -1;
+ }
+ }
+ }
+ rl_point = pos;
+ return (0);
+}
+
+int
+rl_vi_bracktype (c)
+ int c;
+{
+ switch (c)
+ {
+ case '(': return 1;
+ case ')': return -1;
+ case '[': return 2;
+ case ']': return -2;
+ case '{': return 3;
+ case '}': return -3;
+ default: return 0;
+ }
+}
+
+/* XXX - think about reading an entire mbchar with _rl_read_mbchar and
+ inserting it in one bunch instead of the loop below (like in
+ rl_vi_char_search or _rl_vi_change_mbchar_case. Set c to mbchar[0]
+ for test against 033 or ^C. Make sure that _rl_read_mbchar does
+ this right. */
+int
+rl_vi_change_char (count, key)
+ int count, key;
+{
+ int c;
+
+ if (vi_redoing)
+ c = _rl_vi_last_replacement;
+ else
+ {
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ _rl_vi_last_replacement = c = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+ }
+
+ if (c == '\033' || c == CTRL ('C'))
+ return -1;
+
+ while (count-- && rl_point < rl_end)
+ {
+ rl_begin_undo_group ();
+
+ rl_delete (1, c);
+#if defined (HANDLE_MULTIBYTE)
+ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+ while (_rl_insert_char (1, c))
+ {
+ RL_SETSTATE (RL_STATE_MOREINPUT);
+ c = rl_read_key ();
+ RL_UNSETSTATE (RL_STATE_MOREINPUT);
+ }
+ else
+#endif
+ _rl_insert_char (1, c);
+ if (count == 0)
+ rl_backward_char (1, c);
+
+ rl_end_undo_group ();
+ }
+ return (0);
+}
+
+int
+rl_vi_subst (count, key)
+ int count, key;
+{
+ /* If we are redoing, rl_vi_change_to will stuff the last motion char */
+ if (vi_redoing == 0)
+ rl_stuff_char ((key == 'S') ? 'c' : ' '); /* `S' == `cc', `s' == `c ' */
+
+ return (rl_vi_change_to (count, 'c'));
+}
+
+int
+rl_vi_overstrike (count, key)
+ int count, key;
+{
+ if (_rl_vi_doing_insert == 0)
+ {
+ _rl_vi_doing_insert = 1;
+ rl_begin_undo_group ();
+ }
+
+ if (count > 0)
+ {
+ _rl_overwrite_char (count, key);
+ vi_replace_count += count;
+ }
+
+ return (0);
+}
+
+int
+rl_vi_overstrike_delete (count, key)
+ int count, key;
+{
+ int i, s;
+
+ for (i = 0; i < count; i++)
+ {
+ if (vi_replace_count == 0)
+ {
+ rl_ding ();
+ break;
+ }
+ s = rl_point;
+
+ if (rl_do_undo ())
+ vi_replace_count--;
+
+ if (rl_point == s)
+ rl_backward_char (1, key);
+ }
+
+ if (vi_replace_count == 0 && _rl_vi_doing_insert)
+ {
+ rl_end_undo_group ();
+ rl_do_undo ();
+ _rl_vi_doing_insert = 0;
+ }
+ return (0);
+}
+
+int
+rl_vi_replace (count, key)
+ int count, key;
+{
+ int i;
+
+ vi_replace_count = 0;
+
+ if (!vi_replace_map)
+ {
+ vi_replace_map = rl_make_bare_keymap ();
+
+ for (i = ' '; i < KEYMAP_SIZE; i++)
+ vi_replace_map[i].function = rl_vi_overstrike;
+
+ vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
+ vi_replace_map[ESC].function = rl_vi_movement_mode;
+ vi_replace_map[RETURN].function = rl_newline;
+ vi_replace_map[NEWLINE].function = rl_newline;
+
+ /* If the normal vi insertion keymap has ^H bound to erase, do the
+ same here. Probably should remove the assignment to RUBOUT up
+ there, but I don't think it will make a difference in real life. */
+ if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC &&
+ vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
+ vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
+
+ }
+ _rl_keymap = vi_replace_map;
+ return (0);
+}
+
+#if 0
+/* Try to complete the word we are standing on or the word that ends with
+ the previous character. A space matches everything. Word delimiters are
+ space and ;. */
+int
+rl_vi_possible_completions()
+{
+ int save_pos = rl_point;
+
+ if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';')
+ {
+ while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&
+ rl_line_buffer[rl_point] != ';')
+ rl_point++;
+ }
+ else if (rl_line_buffer[rl_point - 1] == ';')
+ {
+ rl_ding ();
+ return (0);
+ }
+
+ rl_possible_completions ();
+ rl_point = save_pos;
+
+ return (0);
+}
+#endif
+
+/* Functions to save and restore marks. */
+int
+rl_vi_set_mark (count, key)
+ int count, key;
+{
+ int ch;
+
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ ch = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+ if (ch < 'a' || ch > 'z')
+ {
+ rl_ding ();
+ return -1;
+ }
+ ch -= 'a';
+ vi_mark_chars[ch] = rl_point;
+ return 0;
+}
+
+int
+rl_vi_goto_mark (count, key)
+ int count, key;
+{
+ int ch;
+
+ RL_SETSTATE(RL_STATE_MOREINPUT);
+ ch = rl_read_key ();
+ RL_UNSETSTATE(RL_STATE_MOREINPUT);
+
+ if (ch == '`')
+ {
+ rl_point = rl_mark;
+ return 0;
+ }
+ else if (ch < 'a' || ch > 'z')
+ {
+ rl_ding ();
+ return -1;
+ }
+
+ ch -= 'a';
+ if (vi_mark_chars[ch] == -1)
+ {
+ rl_ding ();
+ return -1;
+ }
+ rl_point = vi_mark_chars[ch];
+ return 0;
+}
+
+#endif /* VI_MODE */
diff --git a/MSVC/readline/xmalloc.c b/MSVC/readline/xmalloc.c
index e111d1b..a5b526e 100644
--- a/MSVC/readline/xmalloc.c
+++ b/MSVC/readline/xmalloc.c
@@ -1,86 +1,86 @@
-/* xmalloc.c -- safe versions of malloc and realloc */
-
-/* Copyright (C) 1991 Free Software Foundation, Inc.
-
- This file is part of GNU Readline, a library for reading lines
- of text with interactive input and history editing.
-
- Readline 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, or (at your option) any
- later version.
-
- Readline 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 Readline; see the file COPYING. If not, write to the Free
- Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-#define READLINE_LIBRARY 1
-
-#include "config.h"
-
-#include <stdio.h>
-
-#if defined (HAVE_STDLIB_H)
-# include <stdlib.h>
-#else
-# include "ansi_stdlib.h"
-#endif /* HAVE_STDLIB_H */
-
-#include "xmalloc.h"
-
-/* **************************************************************** */
-/* */
-/* Memory Allocation and Deallocation. */
-/* */
-/* **************************************************************** */
-
-static void
-memory_error_and_abort (fname)
- char *fname;
-{
- fprintf (stderr, "%s: out of virtual memory\n", fname);
- exit (2);
-}
-
-/* Return a pointer to free()able block of memory large enough
- to hold BYTES number of bytes. If the memory cannot be allocated,
- print an error message and abort. */
-PTR_T
-xmalloc (bytes)
- size_t bytes;
-{
- PTR_T temp;
-
- temp = malloc (bytes);
- if (temp == 0)
- memory_error_and_abort ("xmalloc");
- return (temp);
-}
-
-PTR_T
-xrealloc (pointer, bytes)
- PTR_T pointer;
- size_t bytes;
-{
- PTR_T temp;
-
- temp = pointer ? realloc (pointer, bytes) : malloc (bytes);
-
- if (temp == 0)
- memory_error_and_abort ("xrealloc");
- return (temp);
-}
-
-/* Use this as the function to call when adding unwind protects so we
- don't need to know what free() returns. */
-void
-xfree (string)
- PTR_T string;
-{
- if (string)
- free (string);
-}
+/* xmalloc.c -- safe versions of malloc and realloc */
+
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+
+ This file is part of GNU Readline, a library for reading lines
+ of text with interactive input and history editing.
+
+ Readline 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, or (at your option) any
+ later version.
+
+ Readline 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 Readline; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY 1
+
+#include "config.h"
+
+#include <stdio.h>
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include "xmalloc.h"
+
+/* **************************************************************** */
+/* */
+/* Memory Allocation and Deallocation. */
+/* */
+/* **************************************************************** */
+
+static void
+memory_error_and_abort (fname)
+ char *fname;
+{
+ fprintf (stderr, "%s: out of virtual memory\n", fname);
+ exit (2);
+}
+
+/* Return a pointer to free()able block of memory large enough
+ to hold BYTES number of bytes. If the memory cannot be allocated,
+ print an error message and abort. */
+PTR_T
+xmalloc (bytes)
+ size_t bytes;
+{
+ PTR_T temp;
+
+ temp = malloc (bytes);
+ if (temp == 0)
+ memory_error_and_abort ("xmalloc");
+ return (temp);
+}
+
+PTR_T
+xrealloc (pointer, bytes)
+ PTR_T pointer;
+ size_t bytes;
+{
+ PTR_T temp;
+
+ temp = pointer ? realloc (pointer, bytes) : malloc (bytes);
+
+ if (temp == 0)
+ memory_error_and_abort ("xrealloc");
+ return (temp);
+}
+
+/* Use this as the function to call when adding unwind protects so we
+ don't need to know what free() returns. */
+void
+xfree (string)
+ PTR_T string;
+{
+ if (string)
+ free (string);
+}
diff --git a/MSVC/readline/xmalloc.h b/MSVC/readline/xmalloc.h
index acf5568..9cb08ba 100644
--- a/MSVC/readline/xmalloc.h
+++ b/MSVC/readline/xmalloc.h
@@ -1,46 +1,46 @@
-/* xmalloc.h -- memory allocation that aborts on errors. */
-
-/* Copyright (C) 1999 Free Software Foundation, Inc.
-
- This file is part of the GNU Readline Library, a library for
- reading lines of text with interactive input and history editing.
-
- The GNU Readline Library 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, or
- (at your option) any later version.
-
- The GNU Readline Library 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.
-
- The GNU General Public License is often shipped with GNU software, and
- is generally kept in a file called COPYING or LICENSE. If you do not
- have a copy of the license, write to the Free Software Foundation,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-#if !defined (_XMALLOC_H_)
-#define _XMALLOC_H_
-
-#if defined (READLINE_LIBRARY)
-# include "rlstdc.h"
-#else
-# include <readline/rlstdc.h>
-#endif
-
-#ifndef PTR_T
-
-#ifdef __STDC__
-# define PTR_T void *
-#else
-# define PTR_T char *
-#endif
-
-#endif /* !PTR_T */
-
-extern PTR_T xmalloc PARAMS((size_t));
-extern PTR_T xrealloc PARAMS((void *, size_t));
-extern void xfree PARAMS((void *));
-
-#endif /* _XMALLOC_H_ */
+/* xmalloc.h -- memory allocation that aborts on errors. */
+
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library, a library for
+ reading lines of text with interactive input and history editing.
+
+ The GNU Readline Library 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, or
+ (at your option) any later version.
+
+ The GNU Readline Library 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.
+
+ The GNU General Public License is often shipped with GNU software, and
+ is generally kept in a file called COPYING or LICENSE. If you do not
+ have a copy of the license, write to the Free Software Foundation,
+ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#if !defined (_XMALLOC_H_)
+#define _XMALLOC_H_
+
+#if defined (READLINE_LIBRARY)
+# include "rlstdc.h"
+#else
+# include <readline/rlstdc.h>
+#endif
+
+#ifndef PTR_T
+
+#ifdef __STDC__
+# define PTR_T void *
+#else
+# define PTR_T char *
+#endif
+
+#endif /* !PTR_T */
+
+extern PTR_T xmalloc PARAMS((size_t));
+extern PTR_T xrealloc PARAMS((void *, size_t));
+extern void xfree PARAMS((void *));
+
+#endif /* _XMALLOC_H_ */
diff --git a/MSVC/regex/regex.c b/MSVC/regex/regex.c
index 0c92cb4..8169880 100644
--- a/MSVC/regex/regex.c
+++ b/MSVC/regex/regex.c
@@ -1,4948 +1,4948 @@
-/* Extended regular expression matching and search library,
- version 0.12.
- (Implements POSIX draft P10003.2/D11.2, except for
- internationalization features.)
-
- Copyright (C) 1993 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* AIX requires this to be the first thing in the file. */
-#if defined (_AIX) && !defined (REGEX_MALLOC)
- #pragma alloca
-#endif
-
-#define _GNU_SOURCE
-
-/* We need this for `regex.h', and perhaps for the Emacs include files. */
-#include <sys/types.h>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* The `emacs' switch turns on certain matching commands
- that make sense only in Emacs. */
-#ifdef emacs
-
-#include "lisp.h"
-#include "buffer.h"
-#include "syntax.h"
-
-/* Emacs uses `NULL' as a predicate. */
-#undef NULL
-
-#else /* not emacs */
-
-/* We used to test for `BSTRING' here, but only GCC and Emacs define
- `BSTRING', as far as I know, and neither of them use this code. */
-#if HAVE_STRING_H || STDC_HEADERS
-#include <string.h>
-#ifndef bcmp
-#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
-#endif
-#ifndef bcopy
-#define bcopy(s, d, n) memcpy ((d), (s), (n))
-#endif
-#ifndef bzero
-#define bzero(s, n) memset ((s), 0, (n))
-#endif
-#else
-#include <strings.h>
-#endif
-
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#else
-char *malloc ();
-char *realloc ();
-#endif
-
-
-/* Define the syntax stuff for \<, \>, etc. */
-
-/* This must be nonzero for the wordchar and notwordchar pattern
- commands in re_match_2. */
-#ifndef Sword
-#define Sword 1
-#endif
-
-#ifdef SYNTAX_TABLE
-
-extern char *re_syntax_table;
-
-#else /* not SYNTAX_TABLE */
-
-/* How many characters in the character set. */
-#define CHAR_SET_SIZE 256
-
-static char re_syntax_table[CHAR_SET_SIZE];
-
-static void
-init_syntax_once ()
-{
- register int c;
- static int done = 0;
-
- if (done)
- return;
-
- bzero (re_syntax_table, sizeof re_syntax_table);
-
- for (c = 'a'; c <= 'z'; c++)
- re_syntax_table[c] = Sword;
-
- for (c = 'A'; c <= 'Z'; c++)
- re_syntax_table[c] = Sword;
-
- for (c = '0'; c <= '9'; c++)
- re_syntax_table[c] = Sword;
-
- re_syntax_table['_'] = Sword;
-
- done = 1;
-}
-
-#endif /* not SYNTAX_TABLE */
-
-#define SYNTAX(c) re_syntax_table[c]
-
-#endif /* not emacs */
-
-/* Get the interface, including the syntax bits. */
-#include "regex.h"
-
-/* isalpha etc. are used for the character classes. */
-#include <ctype.h>
-
-#ifndef isascii
-#define isascii(c) 1
-#endif
-
-#ifdef isblank
-#define ISBLANK(c) (isascii (c) && isblank (c))
-#else
-#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
-#endif
-#ifdef isgraph
-#define ISGRAPH(c) (isascii (c) && isgraph (c))
-#else
-#define ISGRAPH(c) (isascii (c) && isprint (c) && !isspace (c))
-#endif
-
-#define ISPRINT(c) (isascii (c) && isprint (c))
-#define ISDIGIT(c) (isascii (c) && isdigit (c))
-#define ISALNUM(c) (isascii (c) && isalnum (c))
-#define ISALPHA(c) (isascii (c) && isalpha (c))
-#define ISCNTRL(c) (isascii (c) && iscntrl (c))
-#define ISLOWER(c) (isascii (c) && islower (c))
-#define ISPUNCT(c) (isascii (c) && ispunct (c))
-#define ISSPACE(c) (isascii (c) && isspace (c))
-#define ISUPPER(c) (isascii (c) && isupper (c))
-#define ISXDIGIT(c) (isascii (c) && isxdigit (c))
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* We remove any previous definition of `SIGN_EXTEND_CHAR',
- since ours (we hope) works properly with all combinations of
- machines, compilers, `char' and `unsigned char' argument types.
- (Per Bothner suggested the basic approach.) */
-#undef SIGN_EXTEND_CHAR
-#if __STDC__
-#define SIGN_EXTEND_CHAR(c) ((signed char) (c))
-#else /* not __STDC__ */
-/* As in Harbison and Steele. */
-#define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
-#endif
-
-/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we
- use `alloca' instead of `malloc'. This is because using malloc in
- re_search* or re_match* could cause memory leaks when C-g is used in
- Emacs; also, malloc is slower and causes storage fragmentation. On
- the other hand, malloc is more portable, and easier to debug.
-
- Because we sometimes use alloca, some routines have to be macros,
- not functions -- `alloca'-allocated space disappears at the end of the
- function it is called in. */
-
-#ifdef REGEX_MALLOC
-
-#define REGEX_ALLOCATE malloc
-#define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
-
-#else /* not REGEX_MALLOC */
-
-/* Emacs already defines alloca, sometimes. */
-#ifndef alloca
-
-/* Make alloca work the best possible way. */
-#ifdef __GNUC__
-#define alloca __builtin_alloca
-#else /* not __GNUC__ */
-#if HAVE_ALLOCA_H
-#include <alloca.h>
-#else /* not __GNUC__ or HAVE_ALLOCA_H */
-#ifndef _AIX /* Already did AIX, up at the top. */
-char *alloca ();
-#endif /* not _AIX */
-#endif /* not HAVE_ALLOCA_H */
-#endif /* not __GNUC__ */
-
-#endif /* not alloca */
-
-#define REGEX_ALLOCATE alloca
-
-/* Assumes a `char *destination' variable. */
-#define REGEX_REALLOCATE(source, osize, nsize) \
- (destination = (char *) alloca (nsize), \
- bcopy (source, destination, osize), \
- destination)
-
-#endif /* not REGEX_MALLOC */
-
-
-/* True if `size1' is non-NULL and PTR is pointing anywhere inside
- `string1' or just past its end. This works if PTR is NULL, which is
- a good thing. */
-#define FIRST_STRING_P(ptr) \
- (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
-
-/* (Re)Allocate N items of type T using malloc, or fail. */
-#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
-#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
-#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
-
-#define BYTEWIDTH 8 /* In bits. */
-
-#define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
-
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-typedef char boolean;
-#define false 0
-#define true 1
-
-/* These are the command codes that appear in compiled regular
- expressions. Some opcodes are followed by argument bytes. A
- command code can specify any interpretation whatsoever for its
- arguments. Zero bytes may appear in the compiled regular expression.
-
- The value of `exactn' is needed in search.c (search_buffer) in Emacs.
- So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of
- `exactn' we use here must also be 1. */
-
-typedef enum
-{
- no_op = 0,
-
- /* Followed by one byte giving n, then by n literal bytes. */
- exactn = 1,
-
- /* Matches any (more or less) character. */
- anychar,
-
- /* Matches any one char belonging to specified set. First
- following byte is number of bitmap bytes. Then come bytes
- for a bitmap saying which chars are in. Bits in each byte
- are ordered low-bit-first. A character is in the set if its
- bit is 1. A character too large to have a bit in the map is
- automatically not in the set. */
- charset,
-
- /* Same parameters as charset, but match any character that is
- not one of those specified. */
- charset_not,
-
- /* Start remembering the text that is matched, for storing in a
- register. Followed by one byte with the register number, in
- the range 0 to one less than the pattern buffer's re_nsub
- field. Then followed by one byte with the number of groups
- inner to this one. (This last has to be part of the
- start_memory only because we need it in the on_failure_jump
- of re_match_2.) */
- start_memory,
-
- /* Stop remembering the text that is matched and store it in a
- memory register. Followed by one byte with the register
- number, in the range 0 to one less than `re_nsub' in the
- pattern buffer, and one byte with the number of inner groups,
- just like `start_memory'. (We need the number of inner
- groups here because we don't have any easy way of finding the
- corresponding start_memory when we're at a stop_memory.) */
- stop_memory,
-
- /* Match a duplicate of something remembered. Followed by one
- byte containing the register number. */
- duplicate,
-
- /* Fail unless at beginning of line. */
- begline,
-
- /* Fail unless at end of line. */
- endline,
-
- /* Succeeds if at beginning of buffer (if emacs) or at beginning
- of string to be matched (if not). */
- begbuf,
-
- /* Analogously, for end of buffer/string. */
- endbuf,
-
- /* Followed by two byte relative address to which to jump. */
- jump,
-
- /* Same as jump, but marks the end of an alternative. */
- jump_past_alt,
-
- /* Followed by two-byte relative address of place to resume at
- in case of failure. */
- on_failure_jump,
-
- /* Like on_failure_jump, but pushes a placeholder instead of the
- current string position when executed. */
- on_failure_keep_string_jump,
-
- /* Throw away latest failure point and then jump to following
- two-byte relative address. */
- pop_failure_jump,
-
- /* Change to pop_failure_jump if know won't have to backtrack to
- match; otherwise change to jump. This is used to jump
- back to the beginning of a repeat. If what follows this jump
- clearly won't match what the repeat does, such that we can be
- sure that there is no use backtracking out of repetitions
- already matched, then we change it to a pop_failure_jump.
- Followed by two-byte address. */
- maybe_pop_jump,
-
- /* Jump to following two-byte address, and push a dummy failure
- point. This failure point will be thrown away if an attempt
- is made to use it for a failure. A `+' construct makes this
- before the first repeat. Also used as an intermediary kind
- of jump when compiling an alternative. */
- dummy_failure_jump,
-
- /* Push a dummy failure point and continue. Used at the end of
- alternatives. */
- push_dummy_failure,
-
- /* Followed by two-byte relative address and two-byte number n.
- After matching N times, jump to the address upon failure. */
- succeed_n,
-
- /* Followed by two-byte relative address, and two-byte number n.
- Jump to the address N times, then fail. */
- jump_n,
-
- /* Set the following two-byte relative address to the
- subsequent two-byte number. The address *includes* the two
- bytes of number. */
- set_number_at,
-
- wordchar, /* Matches any word-constituent character. */
- notwordchar, /* Matches any char that is not a word-constituent. */
-
- wordbeg, /* Succeeds if at word beginning. */
- wordend, /* Succeeds if at word end. */
-
- wordbound, /* Succeeds if at a word boundary. */
- notwordbound /* Succeeds if not at a word boundary. */
-
-#ifdef emacs
- ,before_dot, /* Succeeds if before point. */
- at_dot, /* Succeeds if at point. */
- after_dot, /* Succeeds if after point. */
-
- /* Matches any character whose syntax is specified. Followed by
- a byte which contains a syntax code, e.g., Sword. */
- syntaxspec,
-
- /* Matches any character whose syntax is not that specified. */
- notsyntaxspec
-#endif /* emacs */
-} re_opcode_t;
-
-/* Common operations on the compiled pattern. */
-
-/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
-
-#define STORE_NUMBER(destination, number) \
- do { \
- (destination)[0] = (number) & 0377; \
- (destination)[1] = (number) >> 8; \
- } while (0)
-
-/* Same as STORE_NUMBER, except increment DESTINATION to
- the byte after where the number is stored. Therefore, DESTINATION
- must be an lvalue. */
-
-#define STORE_NUMBER_AND_INCR(destination, number) \
- do { \
- STORE_NUMBER (destination, number); \
- (destination) += 2; \
- } while (0)
-
-/* Put into DESTINATION a number stored in two contiguous bytes starting
- at SOURCE. */
-
-#define EXTRACT_NUMBER(destination, source) \
- do { \
- (destination) = *(source) & 0377; \
- (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \
- } while (0)
-
-#ifdef DEBUG
-static void
-extract_number (dest, source)
- int *dest;
- unsigned char *source;
-{
- int temp = SIGN_EXTEND_CHAR (*(source + 1));
- *dest = *source & 0377;
- *dest += temp << 8;
-}
-
-#ifndef EXTRACT_MACROS /* To debug the macros. */
-#undef EXTRACT_NUMBER
-#define EXTRACT_NUMBER(dest, src) extract_number (&dest, src)
-#endif /* not EXTRACT_MACROS */
-
-#endif /* DEBUG */
-
-/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
- SOURCE must be an lvalue. */
-
-#define EXTRACT_NUMBER_AND_INCR(destination, source) \
- do { \
- EXTRACT_NUMBER (destination, source); \
- (source) += 2; \
- } while (0)
-
-#ifdef DEBUG
-static void
-extract_number_and_incr (destination, source)
- int *destination;
- unsigned char **source;
-{
- extract_number (destination, *source);
- *source += 2;
-}
-
-#ifndef EXTRACT_MACROS
-#undef EXTRACT_NUMBER_AND_INCR
-#define EXTRACT_NUMBER_AND_INCR(dest, src) \
- extract_number_and_incr (&dest, &src)
-#endif /* not EXTRACT_MACROS */
-
-#endif /* DEBUG */
-
-/* If DEBUG is defined, Regex prints many voluminous messages about what
- it is doing (if the variable `debug' is nonzero). If linked with the
- main program in `iregex.c', you can enter patterns and strings
- interactively. And if linked with the main program in `main.c' and
- the other test files, you can run the already-written tests. */
-
-#ifdef DEBUG
-
-/* We use standard I/O for debugging. */
-#include <stdio.h>
-
-/* It is useful to test things that ``must'' be true when debugging. */
-#include <assert.h>
-
-static int debug = 0;
-
-#define DEBUG_STATEMENT(e) e
-#define DEBUG_PRINT1(x) if (debug) printf (x)
-#define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
-#define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
-#define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
-#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
- if (debug) print_partial_compiled_pattern (s, e)
-#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
- if (debug) print_double_string (w, s1, sz1, s2, sz2)
-
-
-extern void printchar ();
-
-/* Print the fastmap in human-readable form. */
-
-void
-print_fastmap (fastmap)
- char *fastmap;
-{
- unsigned was_a_range = 0;
- unsigned i = 0;
-
- while (i < (1 << BYTEWIDTH))
- {
- if (fastmap[i++])
- {
- was_a_range = 0;
- printchar (i - 1);
- while (i < (1 << BYTEWIDTH) && fastmap[i])
- {
- was_a_range = 1;
- i++;
- }
- if (was_a_range)
- {
- printf ("-");
- printchar (i - 1);
- }
- }
- }
- putchar ('\n');
-}
-
-
-/* Print a compiled pattern string in human-readable form, starting at
- the START pointer into it and ending just before the pointer END. */
-
-void
-print_partial_compiled_pattern (start, end)
- unsigned char *start;
- unsigned char *end;
-{
- int mcnt, mcnt2;
- unsigned char *p = start;
- unsigned char *pend = end;
-
- if (start == NULL)
- {
- printf ("(null)\n");
- return;
- }
-
- /* Loop over pattern commands. */
- while (p < pend)
- {
- switch ((re_opcode_t) *p++)
- {
- case no_op:
- printf ("/no_op");
- break;
-
- case exactn:
- mcnt = *p++;
- printf ("/exactn/%d", mcnt);
- do
- {
- putchar ('/');
- printchar (*p++);
- }
- while (--mcnt);
- break;
-
- case start_memory:
- mcnt = *p++;
- printf ("/start_memory/%d/%d", mcnt, *p++);
- break;
-
- case stop_memory:
- mcnt = *p++;
- printf ("/stop_memory/%d/%d", mcnt, *p++);
- break;
-
- case duplicate:
- printf ("/duplicate/%d", *p++);
- break;
-
- case anychar:
- printf ("/anychar");
- break;
-
- case charset:
- case charset_not:
- {
- register int c;
-
- printf ("/charset%s",
- (re_opcode_t) *(p - 1) == charset_not ? "_not" : "");
-
- assert (p + *p < pend);
-
- for (c = 0; c < *p; c++)
- {
- unsigned bit;
- unsigned char map_byte = p[1 + c];
-
- putchar ('/');
-
- for (bit = 0; bit < BYTEWIDTH; bit++)
- if (map_byte & (1 << bit))
- printchar (c * BYTEWIDTH + bit);
- }
- p += 1 + *p;
- break;
- }
-
- case begline:
- printf ("/begline");
- break;
-
- case endline:
- printf ("/endline");
- break;
-
- case on_failure_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/on_failure_jump/0/%d", mcnt);
- break;
-
- case on_failure_keep_string_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/on_failure_keep_string_jump/0/%d", mcnt);
- break;
-
- case dummy_failure_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/dummy_failure_jump/0/%d", mcnt);
- break;
-
- case push_dummy_failure:
- printf ("/push_dummy_failure");
- break;
-
- case maybe_pop_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/maybe_pop_jump/0/%d", mcnt);
- break;
-
- case pop_failure_jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/pop_failure_jump/0/%d", mcnt);
- break;
-
- case jump_past_alt:
- extract_number_and_incr (&mcnt, &p);
- printf ("/jump_past_alt/0/%d", mcnt);
- break;
-
- case jump:
- extract_number_and_incr (&mcnt, &p);
- printf ("/jump/0/%d", mcnt);
- break;
-
- case succeed_n:
- extract_number_and_incr (&mcnt, &p);
- extract_number_and_incr (&mcnt2, &p);
- printf ("/succeed_n/0/%d/0/%d", mcnt, mcnt2);
- break;
-
- case jump_n:
- extract_number_and_incr (&mcnt, &p);
- extract_number_and_incr (&mcnt2, &p);
- printf ("/jump_n/0/%d/0/%d", mcnt, mcnt2);
- break;
-
- case set_number_at:
- extract_number_and_incr (&mcnt, &p);
- extract_number_and_incr (&mcnt2, &p);
- printf ("/set_number_at/0/%d/0/%d", mcnt, mcnt2);
- break;
-
- case wordbound:
- printf ("/wordbound");
- break;
-
- case notwordbound:
- printf ("/notwordbound");
- break;
-
- case wordbeg:
- printf ("/wordbeg");
- break;
-
- case wordend:
- printf ("/wordend");
-
-#ifdef emacs
- case before_dot:
- printf ("/before_dot");
- break;
-
- case at_dot:
- printf ("/at_dot");
- break;
-
- case after_dot:
- printf ("/after_dot");
- break;
-
- case syntaxspec:
- printf ("/syntaxspec");
- mcnt = *p++;
- printf ("/%d", mcnt);
- break;
-
- case notsyntaxspec:
- printf ("/notsyntaxspec");
- mcnt = *p++;
- printf ("/%d", mcnt);
- break;
-#endif /* emacs */
-
- case wordchar:
- printf ("/wordchar");
- break;
-
- case notwordchar:
- printf ("/notwordchar");
- break;
-
- case begbuf:
- printf ("/begbuf");
- break;
-
- case endbuf:
- printf ("/endbuf");
- break;
-
- default:
- printf ("?%d", *(p-1));
- }
- }
- printf ("/\n");
-}
-
-
-void
-print_compiled_pattern (bufp)
- struct re_pattern_buffer *bufp;
-{
- unsigned char *buffer = bufp->buffer;
-
- print_partial_compiled_pattern (buffer, buffer + bufp->used);
- printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated);
-
- if (bufp->fastmap_accurate && bufp->fastmap)
- {
- printf ("fastmap: ");
- print_fastmap (bufp->fastmap);
- }
-
- printf ("re_nsub: %d\t", bufp->re_nsub);
- printf ("regs_alloc: %d\t", bufp->regs_allocated);
- printf ("can_be_null: %d\t", bufp->can_be_null);
- printf ("newline_anchor: %d\n", bufp->newline_anchor);
- printf ("no_sub: %d\t", bufp->no_sub);
- printf ("not_bol: %d\t", bufp->not_bol);
- printf ("not_eol: %d\t", bufp->not_eol);
- printf ("syntax: %d\n", bufp->syntax);
- /* Perhaps we should print the translate table? */
-}
-
-
-void
-print_double_string (where, string1, size1, string2, size2)
- const char *where;
- const char *string1;
- const char *string2;
- int size1;
- int size2;
-{
- unsigned this_char;
-
- if (where == NULL)
- printf ("(null)");
- else
- {
- if (FIRST_STRING_P (where))
- {
- for (this_char = where - string1; this_char < size1; this_char++)
- printchar (string1[this_char]);
-
- where = string2;
- }
-
- for (this_char = where - string2; this_char < size2; this_char++)
- printchar (string2[this_char]);
- }
-}
-
-#else /* not DEBUG */
-
-#undef assert
-#define assert(e)
-
-#define DEBUG_STATEMENT(e)
-#define DEBUG_PRINT1(x)
-#define DEBUG_PRINT2(x1, x2)
-#define DEBUG_PRINT3(x1, x2, x3)
-#define DEBUG_PRINT4(x1, x2, x3, x4)
-#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
-#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
-
-#endif /* not DEBUG */
-
-/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
- also be assigned to arbitrarily: each pattern buffer stores its own
- syntax, so it can be changed between regex compilations. */
-reg_syntax_t re_syntax_options = RE_SYNTAX_EMACS;
-
-
-/* Specify the precise syntax of regexps for compilation. This provides
- for compatibility for various utilities which historically have
- different, incompatible syntaxes.
-
- The argument SYNTAX is a bit mask comprised of the various bits
- defined in regex.h. We return the old syntax. */
-
-reg_syntax_t
-re_set_syntax (syntax)
- reg_syntax_t syntax;
-{
- reg_syntax_t ret = re_syntax_options;
-
- re_syntax_options = syntax;
- return ret;
-}
-
-/* This table gives an error message for each of the error codes listed
- in regex.h. Obviously the order here has to be same as there. */
-
-static const char *re_error_msg[] =
- { NULL, /* REG_NOERROR */
- "No match", /* REG_NOMATCH */
- "Invalid regular expression", /* REG_BADPAT */
- "Invalid collation character", /* REG_ECOLLATE */
- "Invalid character class name", /* REG_ECTYPE */
- "Trailing backslash", /* REG_EESCAPE */
- "Invalid back reference", /* REG_ESUBREG */
- "Unmatched [ or [^", /* REG_EBRACK */
- "Unmatched ( or \\(", /* REG_EPAREN */
- "Unmatched \\{", /* REG_EBRACE */
- "Invalid content of \\{\\}", /* REG_BADBR */
- "Invalid range end", /* REG_ERANGE */
- "Memory exhausted", /* REG_ESPACE */
- "Invalid preceding regular expression", /* REG_BADRPT */
- "Premature end of regular expression", /* REG_EEND */
- "Regular expression too big", /* REG_ESIZE */
- "Unmatched ) or \\)", /* REG_ERPAREN */
- };
-
-/* Subroutine declarations and macros for regex_compile. */
-
-static void store_op1 (), store_op2 ();
-static void insert_op1 (), insert_op2 ();
-static boolean at_begline_loc_p (), at_endline_loc_p ();
-static boolean group_in_compile_stack ();
-static reg_errcode_t compile_range ();
-
-/* Fetch the next character in the uncompiled pattern---translating it
- if necessary. Also cast from a signed character in the constant
- string passed to us by the user to an unsigned char that we can use
- as an array index (in, e.g., `translate'). */
-#define PATFETCH(c) \
- do {if (p == pend) return REG_EEND; \
- c = (unsigned char) *p++; \
- if (translate) c = translate[c]; \
- } while (0)
-
-/* Fetch the next character in the uncompiled pattern, with no
- translation. */
-#define PATFETCH_RAW(c) \
- do {if (p == pend) return REG_EEND; \
- c = (unsigned char) *p++; \
- } while (0)
-
-/* Go backwards one character in the pattern. */
-#define PATUNFETCH p--
-
-
-/* If `translate' is non-null, return translate[D], else just D. We
- cast the subscript to translate because some data is declared as
- `char *', to avoid warnings when a string constant is passed. But
- when we use a character as a subscript we must make it unsigned. */
-#define TRANSLATE(d) (translate ? translate[(unsigned char) (d)] : (d))
-
-
-/* Macros for outputting the compiled pattern into `buffer'. */
-
-/* If the buffer isn't allocated when it comes in, use this. */
-#define INIT_BUF_SIZE 32
-
-/* Make sure we have at least N more bytes of space in buffer. */
-#define GET_BUFFER_SPACE(n) \
- while (b - bufp->buffer + (n) > bufp->allocated) \
- EXTEND_BUFFER ()
-
-/* Make sure we have one more byte of buffer space and then add C to it. */
-#define BUF_PUSH(c) \
- do { \
- GET_BUFFER_SPACE (1); \
- *b++ = (unsigned char) (c); \
- } while (0)
-
-
-/* Ensure we have two more bytes of buffer space and then append C1 and C2. */
-#define BUF_PUSH_2(c1, c2) \
- do { \
- GET_BUFFER_SPACE (2); \
- *b++ = (unsigned char) (c1); \
- *b++ = (unsigned char) (c2); \
- } while (0)
-
-
-/* As with BUF_PUSH_2, except for three bytes. */
-#define BUF_PUSH_3(c1, c2, c3) \
- do { \
- GET_BUFFER_SPACE (3); \
- *b++ = (unsigned char) (c1); \
- *b++ = (unsigned char) (c2); \
- *b++ = (unsigned char) (c3); \
- } while (0)
-
-
-/* Store a jump with opcode OP at LOC to location TO. We store a
- relative address offset by the three bytes the jump itself occupies. */
-#define STORE_JUMP(op, loc, to) \
- store_op1 (op, loc, (to) - (loc) - 3)
-
-/* Likewise, for a two-argument jump. */
-#define STORE_JUMP2(op, loc, to, arg) \
- store_op2 (op, loc, (to) - (loc) - 3, arg)
-
-/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */
-#define INSERT_JUMP(op, loc, to) \
- insert_op1 (op, loc, (to) - (loc) - 3, b)
-
-/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */
-#define INSERT_JUMP2(op, loc, to, arg) \
- insert_op2 (op, loc, (to) - (loc) - 3, arg, b)
-
-
-/* This is not an arbitrary limit: the arguments which represent offsets
- into the pattern are two bytes long. So if 2^16 bytes turns out to
- be too small, many things would have to change. */
-#define MAX_BUF_SIZE (1L << 16)
-
-
-/* Extend the buffer by twice its current size via realloc and
- reset the pointers that pointed into the old block to point to the
- correct places in the new one. If extending the buffer results in it
- being larger than MAX_BUF_SIZE, then flag memory exhausted. */
-#define EXTEND_BUFFER() \
- do { \
- unsigned char *old_buffer = bufp->buffer; \
- if (bufp->allocated == MAX_BUF_SIZE) \
- return REG_ESIZE; \
- bufp->allocated <<= 1; \
- if (bufp->allocated > MAX_BUF_SIZE) \
- bufp->allocated = MAX_BUF_SIZE; \
- bufp->buffer = (unsigned char *) realloc (bufp->buffer, bufp->allocated);\
- if (bufp->buffer == NULL) \
- return REG_ESPACE; \
- /* If the buffer moved, move all the pointers into it. */ \
- if (old_buffer != bufp->buffer) \
- { \
- b = (b - old_buffer) + bufp->buffer; \
- begalt = (begalt - old_buffer) + bufp->buffer; \
- if (fixup_alt_jump) \
- fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\
- if (laststart) \
- laststart = (laststart - old_buffer) + bufp->buffer; \
- if (pending_exact) \
- pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
- } \
- } while (0)
-
-
-/* Since we have one byte reserved for the register number argument to
- {start,stop}_memory, the maximum number of groups we can report
- things about is what fits in that byte. */
-#define MAX_REGNUM 255
-
-/* But patterns can have more than `MAX_REGNUM' registers. We just
- ignore the excess. */
-typedef unsigned regnum_t;
-
-
-/* Macros for the compile stack. */
-
-/* Since offsets can go either forwards or backwards, this type needs to
- be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */
-typedef int pattern_offset_t;
-
-typedef struct
-{
- pattern_offset_t begalt_offset;
- pattern_offset_t fixup_alt_jump;
- pattern_offset_t inner_group_offset;
- pattern_offset_t laststart_offset;
- regnum_t regnum;
-} compile_stack_elt_t;
-
-
-typedef struct
-{
- compile_stack_elt_t *stack;
- unsigned size;
- unsigned avail; /* Offset of next open position. */
-} compile_stack_type;
-
-
-#define INIT_COMPILE_STACK_SIZE 32
-
-#define COMPILE_STACK_EMPTY (compile_stack.avail == 0)
-#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size)
-
-/* The next available element. */
-#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
-
-
-/* Set the bit for character C in a list. */
-#define SET_LIST_BIT(c) \
- (b[((unsigned char) (c)) / BYTEWIDTH] \
- |= 1 << (((unsigned char) c) % BYTEWIDTH))
-
-
-/* Get the next unsigned number in the uncompiled pattern. */
-#define GET_UNSIGNED_NUMBER(num) \
- { if (p != pend) \
- { \
- PATFETCH (c); \
- while (ISDIGIT (c)) \
- { \
- if (num < 0) \
- num = 0; \
- num = num * 10 + c - '0'; \
- if (p == pend) \
- break; \
- PATFETCH (c); \
- } \
- } \
- }
-
-#define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
-
-#define IS_CHAR_CLASS(string) \
- (STREQ (string, "alpha") || STREQ (string, "upper") \
- || STREQ (string, "lower") || STREQ (string, "digit") \
- || STREQ (string, "alnum") || STREQ (string, "xdigit") \
- || STREQ (string, "space") || STREQ (string, "print") \
- || STREQ (string, "punct") || STREQ (string, "graph") \
- || STREQ (string, "cntrl") || STREQ (string, "blank"))
-
-/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
- Returns one of error codes defined in `regex.h', or zero for success.
-
- Assumes the `allocated' (and perhaps `buffer') and `translate'
- fields are set in BUFP on entry.
-
- If it succeeds, results are put in BUFP (if it returns an error, the
- contents of BUFP are undefined):
- `buffer' is the compiled pattern;
- `syntax' is set to SYNTAX;
- `used' is set to the length of the compiled pattern;
- `fastmap_accurate' is zero;
- `re_nsub' is the number of subexpressions in PATTERN;
- `not_bol' and `not_eol' are zero;
-
- The `fastmap' and `newline_anchor' fields are neither
- examined nor set. */
-
-static reg_errcode_t
-regex_compile (pattern, size, syntax, bufp)
- const char *pattern;
- int size;
- reg_syntax_t syntax;
- struct re_pattern_buffer *bufp;
-{
- /* We fetch characters from PATTERN here. Even though PATTERN is
- `char *' (i.e., signed), we declare these variables as unsigned, so
- they can be reliably used as array indices. */
- register unsigned char c, c1;
-
- /* A random tempory spot in PATTERN. */
- const char *p1;
-
- /* Points to the end of the buffer, where we should append. */
- register unsigned char *b;
-
- /* Keeps track of unclosed groups. */
- compile_stack_type compile_stack;
-
- /* Points to the current (ending) position in the pattern. */
- const char *p = pattern;
- const char *pend = pattern + size;
-
- /* How to translate the characters in the pattern. */
- char *translate = bufp->translate;
-
- /* Address of the count-byte of the most recently inserted `exactn'
- command. This makes it possible to tell if a new exact-match
- character can be added to that command or if the character requires
- a new `exactn' command. */
- unsigned char *pending_exact = 0;
-
- /* Address of start of the most recently finished expression.
- This tells, e.g., postfix * where to find the start of its
- operand. Reset at the beginning of groups and alternatives. */
- unsigned char *laststart = 0;
-
- /* Address of beginning of regexp, or inside of last group. */
- unsigned char *begalt;
-
- /* Place in the uncompiled pattern (i.e., the {) to
- which to go back if the interval is invalid. */
- const char *beg_interval;
-
- /* Address of the place where a forward jump should go to the end of
- the containing expression. Each alternative of an `or' -- except the
- last -- ends with a forward jump of this sort. */
- unsigned char *fixup_alt_jump = 0;
-
- /* Counts open-groups as they are encountered. Remembered for the
- matching close-group on the compile stack, so the same register
- number is put in the stop_memory as the start_memory. */
- regnum_t regnum = 0;
-
-#ifdef DEBUG
- DEBUG_PRINT1 ("\nCompiling pattern: ");
- if (debug)
- {
- unsigned debug_count;
-
- for (debug_count = 0; debug_count < size; debug_count++)
- printchar (pattern[debug_count]);
- putchar ('\n');
- }
-#endif /* DEBUG */
-
- /* Initialize the compile stack. */
- compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
- if (compile_stack.stack == NULL)
- return REG_ESPACE;
-
- compile_stack.size = INIT_COMPILE_STACK_SIZE;
- compile_stack.avail = 0;
-
- /* Initialize the pattern buffer. */
- bufp->syntax = syntax;
- bufp->fastmap_accurate = 0;
- bufp->not_bol = bufp->not_eol = 0;
-
- /* Set `used' to zero, so that if we return an error, the pattern
- printer (for debugging) will think there's no pattern. We reset it
- at the end. */
- bufp->used = 0;
-
- /* Always count groups, whether or not bufp->no_sub is set. */
- bufp->re_nsub = 0;
-
-#if !defined (emacs) && !defined (SYNTAX_TABLE)
- /* Initialize the syntax table. */
- init_syntax_once ();
-#endif
-
- if (bufp->allocated == 0)
- {
- if (bufp->buffer)
- { /* If zero allocated, but buffer is non-null, try to realloc
- enough space. This loses if buffer's address is bogus, but
- that is the user's responsibility. */
- RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char);
- }
- else
- { /* Caller did not allocate a buffer. Do it for them. */
- bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char);
- }
- if (!bufp->buffer) return REG_ESPACE;
-
- bufp->allocated = INIT_BUF_SIZE;
- }
-
- begalt = b = bufp->buffer;
-
- /* Loop through the uncompiled pattern until we're at the end. */
- while (p != pend)
- {
- PATFETCH (c);
-
- switch (c)
- {
- case '^':
- {
- if ( /* If at start of pattern, it's an operator. */
- p == pattern + 1
- /* If context independent, it's an operator. */
- || syntax & RE_CONTEXT_INDEP_ANCHORS
- /* Otherwise, depends on what's come before. */
- || at_begline_loc_p (pattern, p, syntax))
- BUF_PUSH (begline);
- else
- goto normal_char;
- }
- break;
-
-
- case '$':
- {
- if ( /* If at end of pattern, it's an operator. */
- p == pend
- /* If context independent, it's an operator. */
- || syntax & RE_CONTEXT_INDEP_ANCHORS
- /* Otherwise, depends on what's next. */
- || at_endline_loc_p (p, pend, syntax))
- BUF_PUSH (endline);
- else
- goto normal_char;
- }
- break;
-
-
- case '+':
- case '?':
- if ((syntax & RE_BK_PLUS_QM)
- || (syntax & RE_LIMITED_OPS))
- goto normal_char;
- handle_plus:
- case '*':
- /* If there is no previous pattern... */
- if (!laststart)
- {
- if (syntax & RE_CONTEXT_INVALID_OPS)
- return REG_BADRPT;
- else if (!(syntax & RE_CONTEXT_INDEP_OPS))
- goto normal_char;
- }
-
- {
- /* Are we optimizing this jump? */
- boolean keep_string_p = false;
-
- /* 1 means zero (many) matches is allowed. */
- char zero_times_ok = 0, many_times_ok = 0;
-
- /* If there is a sequence of repetition chars, collapse it
- down to just one (the right one). We can't combine
- interval operators with these because of, e.g., `a{2}*',
- which should only match an even number of `a's. */
-
- for (;;)
- {
- zero_times_ok |= c != '+';
- many_times_ok |= c != '?';
-
- if (p == pend)
- break;
-
- PATFETCH (c);
-
- if (c == '*'
- || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
- ;
-
- else if (syntax & RE_BK_PLUS_QM && c == '\\')
- {
- if (p == pend) return REG_EESCAPE;
-
- PATFETCH (c1);
- if (!(c1 == '+' || c1 == '?'))
- {
- PATUNFETCH;
- PATUNFETCH;
- break;
- }
-
- c = c1;
- }
- else
- {
- PATUNFETCH;
- break;
- }
-
- /* If we get here, we found another repeat character. */
- }
-
- /* Star, etc. applied to an empty pattern is equivalent
- to an empty pattern. */
- if (!laststart)
- break;
-
- /* Now we know whether or not zero matches is allowed
- and also whether or not two or more matches is allowed. */
- if (many_times_ok)
- { /* More than one repetition is allowed, so put in at the
- end a backward relative jump from `b' to before the next
- jump we're going to put in below (which jumps from
- laststart to after this jump).
-
- But if we are at the `*' in the exact sequence `.*\n',
- insert an unconditional jump backwards to the .,
- instead of the beginning of the loop. This way we only
- push a failure point once, instead of every time
- through the loop. */
- assert (p - 1 > pattern);
-
- /* Allocate the space for the jump. */
- GET_BUFFER_SPACE (3);
-
- /* We know we are not at the first character of the pattern,
- because laststart was nonzero. And we've already
- incremented `p', by the way, to be the character after
- the `*'. Do we have to do something analogous here
- for null bytes, because of RE_DOT_NOT_NULL? */
- if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
- && zero_times_ok
- && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
- && !(syntax & RE_DOT_NEWLINE))
- { /* We have .*\n. */
- STORE_JUMP (jump, b, laststart);
- keep_string_p = true;
- }
- else
- /* Anything else. */
- STORE_JUMP (maybe_pop_jump, b, laststart - 3);
-
- /* We've added more stuff to the buffer. */
- b += 3;
- }
-
- /* On failure, jump from laststart to b + 3, which will be the
- end of the buffer after this jump is inserted. */
- GET_BUFFER_SPACE (3);
- INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
- : on_failure_jump,
- laststart, b + 3);
- pending_exact = 0;
- b += 3;
-
- if (!zero_times_ok)
- {
- /* At least one repetition is required, so insert a
- `dummy_failure_jump' before the initial
- `on_failure_jump' instruction of the loop. This
- effects a skip over that instruction the first time
- we hit that loop. */
- GET_BUFFER_SPACE (3);
- INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6);
- b += 3;
- }
- }
- break;
-
-
- case '.':
- laststart = b;
- BUF_PUSH (anychar);
- break;
-
-
- case '[':
- {
- boolean had_char_class = false;
-
- if (p == pend) return REG_EBRACK;
-
- /* Ensure that we have enough space to push a charset: the
- opcode, the length count, and the bitset; 34 bytes in all. */
- GET_BUFFER_SPACE (34);
-
- laststart = b;
-
- /* We test `*p == '^' twice, instead of using an if
- statement, so we only need one BUF_PUSH. */
- BUF_PUSH (*p == '^' ? charset_not : charset);
- if (*p == '^')
- p++;
-
- /* Remember the first position in the bracket expression. */
- p1 = p;
-
- /* Push the number of bytes in the bitmap. */
- BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
-
- /* Clear the whole map. */
- bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
-
- /* charset_not matches newline according to a syntax bit. */
- if ((re_opcode_t) b[-2] == charset_not
- && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
- SET_LIST_BIT ('\n');
-
- /* Read in characters and ranges, setting map bits. */
- for (;;)
- {
- if (p == pend) return REG_EBRACK;
-
- PATFETCH (c);
-
- /* \ might escape characters inside [...] and [^...]. */
- if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
- {
- if (p == pend) return REG_EESCAPE;
-
- PATFETCH (c1);
- SET_LIST_BIT (c1);
- continue;
- }
-
- /* Could be the end of the bracket expression. If it's
- not (i.e., when the bracket expression is `[]' so
- far), the ']' character bit gets set way below. */
- if (c == ']' && p != p1 + 1)
- break;
-
- /* Look ahead to see if it's a range when the last thing
- was a character class. */
- if (had_char_class && c == '-' && *p != ']')
- return REG_ERANGE;
-
- /* Look ahead to see if it's a range when the last thing
- was a character: if this is a hyphen not at the
- beginning or the end of a list, then it's the range
- operator. */
- if (c == '-'
- && !(p - 2 >= pattern && p[-2] == '[')
- && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
- && *p != ']')
- {
- reg_errcode_t ret
- = compile_range (&p, pend, translate, syntax, b);
- if (ret != REG_NOERROR) return ret;
- }
-
- else if (p[0] == '-' && p[1] != ']')
- { /* This handles ranges made up of characters only. */
- reg_errcode_t ret;
-
- /* Move past the `-'. */
- PATFETCH (c1);
-
- ret = compile_range (&p, pend, translate, syntax, b);
- if (ret != REG_NOERROR) return ret;
- }
-
- /* See if we're at the beginning of a possible character
- class. */
-
- else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
- { /* Leave room for the null. */
- char str[CHAR_CLASS_MAX_LENGTH + 1];
-
- PATFETCH (c);
- c1 = 0;
-
- /* If pattern is `[[:'. */
- if (p == pend) return REG_EBRACK;
-
- for (;;)
- {
- PATFETCH (c);
- if (c == ':' || c == ']' || p == pend
- || c1 == CHAR_CLASS_MAX_LENGTH)
- break;
- str[c1++] = c;
- }
- str[c1] = '\0';
-
- /* If isn't a word bracketed by `[:' and:`]':
- undo the ending character, the letters, and leave
- the leading `:' and `[' (but set bits for them). */
- if (c == ':' && *p == ']')
- {
- int ch;
- boolean is_alnum = STREQ (str, "alnum");
- boolean is_alpha = STREQ (str, "alpha");
- boolean is_blank = STREQ (str, "blank");
- boolean is_cntrl = STREQ (str, "cntrl");
- boolean is_digit = STREQ (str, "digit");
- boolean is_graph = STREQ (str, "graph");
- boolean is_lower = STREQ (str, "lower");
- boolean is_print = STREQ (str, "print");
- boolean is_punct = STREQ (str, "punct");
- boolean is_space = STREQ (str, "space");
- boolean is_upper = STREQ (str, "upper");
- boolean is_xdigit = STREQ (str, "xdigit");
-
- if (!IS_CHAR_CLASS (str)) return REG_ECTYPE;
-
- /* Throw away the ] at the end of the character
- class. */
- PATFETCH (c);
-
- if (p == pend) return REG_EBRACK;
-
- for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
- {
- if ( (is_alnum && ISALNUM (ch))
- || (is_alpha && ISALPHA (ch))
- || (is_blank && ISBLANK (ch))
- || (is_cntrl && ISCNTRL (ch))
- || (is_digit && ISDIGIT (ch))
- || (is_graph && ISGRAPH (ch))
- || (is_lower && ISLOWER (ch))
- || (is_print && ISPRINT (ch))
- || (is_punct && ISPUNCT (ch))
- || (is_space && ISSPACE (ch))
- || (is_upper && ISUPPER (ch))
- || (is_xdigit && ISXDIGIT (ch)))
- SET_LIST_BIT (ch);
- }
- had_char_class = true;
- }
- else
- {
- c1++;
- while (c1--)
- PATUNFETCH;
- SET_LIST_BIT ('[');
- SET_LIST_BIT (':');
- had_char_class = false;
- }
- }
- else
- {
- had_char_class = false;
- SET_LIST_BIT (c);
- }
- }
-
- /* Discard any (non)matching list bytes that are all 0 at the
- end of the map. Decrease the map-length byte too. */
- while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
- b[-1]--;
- b += b[-1];
- }
- break;
-
-
- case '(':
- if (syntax & RE_NO_BK_PARENS)
- goto handle_open;
- else
- goto normal_char;
-
-
- case ')':
- if (syntax & RE_NO_BK_PARENS)
- goto handle_close;
- else
- goto normal_char;
-
-
- case '\n':
- if (syntax & RE_NEWLINE_ALT)
- goto handle_alt;
- else
- goto normal_char;
-
-
- case '|':
- if (syntax & RE_NO_BK_VBAR)
- goto handle_alt;
- else
- goto normal_char;
-
-
- case '{':
- if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
- goto handle_interval;
- else
- goto normal_char;
-
-
- case '\\':
- if (p == pend) return REG_EESCAPE;
-
- /* Do not translate the character after the \, so that we can
- distinguish, e.g., \B from \b, even if we normally would
- translate, e.g., B to b. */
- PATFETCH_RAW (c);
-
- switch (c)
- {
- case '(':
- if (syntax & RE_NO_BK_PARENS)
- goto normal_backslash;
-
- handle_open:
- bufp->re_nsub++;
- regnum++;
-
- if (COMPILE_STACK_FULL)
- {
- RETALLOC (compile_stack.stack, compile_stack.size << 1,
- compile_stack_elt_t);
- if (compile_stack.stack == NULL) return REG_ESPACE;
-
- compile_stack.size <<= 1;
- }
-
- /* These are the values to restore when we hit end of this
- group. They are all relative offsets, so that if the
- whole pattern moves because of realloc, they will still
- be valid. */
- COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer;
- COMPILE_STACK_TOP.fixup_alt_jump
- = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
- COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;
- COMPILE_STACK_TOP.regnum = regnum;
-
- /* We will eventually replace the 0 with the number of
- groups inner to this one. But do not push a
- start_memory for groups beyond the last one we can
- represent in the compiled pattern. */
- if (regnum <= MAX_REGNUM)
- {
- COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2;
- BUF_PUSH_3 (start_memory, regnum, 0);
- }
-
- compile_stack.avail++;
-
- fixup_alt_jump = 0;
- laststart = 0;
- begalt = b;
- /* If we've reached MAX_REGNUM groups, then this open
- won't actually generate any code, so we'll have to
- clear pending_exact explicitly. */
- pending_exact = 0;
- break;
-
-
- case ')':
- if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
-
- if (COMPILE_STACK_EMPTY)
- if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
- goto normal_backslash;
- else
- return REG_ERPAREN;
-
- handle_close:
- if (fixup_alt_jump)
- { /* Push a dummy failure point at the end of the
- alternative for a possible future
- `pop_failure_jump' to pop. See comments at
- `push_dummy_failure' in `re_match_2'. */
- BUF_PUSH (push_dummy_failure);
-
- /* We allocated space for this jump when we assigned
- to `fixup_alt_jump', in the `handle_alt' case below. */
- STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
- }
-
- /* See similar code for backslashed left paren above. */
- if (COMPILE_STACK_EMPTY)
- if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
- goto normal_char;
- else
- return REG_ERPAREN;
-
- /* Since we just checked for an empty stack above, this
- ``can't happen''. */
- assert (compile_stack.avail != 0);
- {
- /* We don't just want to restore into `regnum', because
- later groups should continue to be numbered higher,
- as in `(ab)c(de)' -- the second group is #2. */
- regnum_t this_group_regnum;
-
- compile_stack.avail--;
- begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;
- fixup_alt_jump
- = COMPILE_STACK_TOP.fixup_alt_jump
- ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1
- : 0;
- laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;
- this_group_regnum = COMPILE_STACK_TOP.regnum;
- /* If we've reached MAX_REGNUM groups, then this open
- won't actually generate any code, so we'll have to
- clear pending_exact explicitly. */
- pending_exact = 0;
-
- /* We're at the end of the group, so now we know how many
- groups were inside this one. */
- if (this_group_regnum <= MAX_REGNUM)
- {
- unsigned char *inner_group_loc
- = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset;
-
- *inner_group_loc = regnum - this_group_regnum;
- BUF_PUSH_3 (stop_memory, this_group_regnum,
- regnum - this_group_regnum);
- }
- }
- break;
-
-
- case '|': /* `\|'. */
- if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
- goto normal_backslash;
- handle_alt:
- if (syntax & RE_LIMITED_OPS)
- goto normal_char;
-
- /* Insert before the previous alternative a jump which
- jumps to this alternative if the former fails. */
- GET_BUFFER_SPACE (3);
- INSERT_JUMP (on_failure_jump, begalt, b + 6);
- pending_exact = 0;
- b += 3;
-
- /* The alternative before this one has a jump after it
- which gets executed if it gets matched. Adjust that
- jump so it will jump to this alternative's analogous
- jump (put in below, which in turn will jump to the next
- (if any) alternative's such jump, etc.). The last such
- jump jumps to the correct final destination. A picture:
- _____ _____
- | | | |
- | v | v
- a | b | c
-
- If we are at `b', then fixup_alt_jump right now points to a
- three-byte space after `a'. We'll put in the jump, set
- fixup_alt_jump to right after `b', and leave behind three
- bytes which we'll fill in when we get to after `c'. */
-
- if (fixup_alt_jump)
- STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
-
- /* Mark and leave space for a jump after this alternative,
- to be filled in later either by next alternative or
- when know we're at the end of a series of alternatives. */
- fixup_alt_jump = b;
- GET_BUFFER_SPACE (3);
- b += 3;
-
- laststart = 0;
- begalt = b;
- break;
-
-
- case '{':
- /* If \{ is a literal. */
- if (!(syntax & RE_INTERVALS)
- /* If we're at `\{' and it's not the open-interval
- operator. */
- || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
- || (p - 2 == pattern && p == pend))
- goto normal_backslash;
-
- handle_interval:
- {
- /* If got here, then the syntax allows intervals. */
-
- /* At least (most) this many matches must be made. */
- int lower_bound = -1, upper_bound = -1;
-
- beg_interval = p - 1;
-
- if (p == pend)
- {
- if (syntax & RE_NO_BK_BRACES)
- goto unfetch_interval;
- else
- return REG_EBRACE;
- }
-
- GET_UNSIGNED_NUMBER (lower_bound);
-
- if (c == ',')
- {
- GET_UNSIGNED_NUMBER (upper_bound);
- if (upper_bound < 0) upper_bound = RE_DUP_MAX;
- }
- else
- /* Interval such as `{1}' => match exactly once. */
- upper_bound = lower_bound;
-
- if (lower_bound < 0 || upper_bound > RE_DUP_MAX
- || lower_bound > upper_bound)
- {
- if (syntax & RE_NO_BK_BRACES)
- goto unfetch_interval;
- else
- return REG_BADBR;
- }
-
- if (!(syntax & RE_NO_BK_BRACES))
- {
- if (c != '\\') return REG_EBRACE;
-
- PATFETCH (c);
- }
-
- if (c != '}')
- {
- if (syntax & RE_NO_BK_BRACES)
- goto unfetch_interval;
- else
- return REG_BADBR;
- }
-
- /* We just parsed a valid interval. */
-
- /* If it's invalid to have no preceding re. */
- if (!laststart)
- {
- if (syntax & RE_CONTEXT_INVALID_OPS)
- return REG_BADRPT;
- else if (syntax & RE_CONTEXT_INDEP_OPS)
- laststart = b;
- else
- goto unfetch_interval;
- }
-
- /* If the upper bound is zero, don't want to succeed at
- all; jump from `laststart' to `b + 3', which will be
- the end of the buffer after we insert the jump. */
- if (upper_bound == 0)
- {
- GET_BUFFER_SPACE (3);
- INSERT_JUMP (jump, laststart, b + 3);
- b += 3;
- }
-
- /* Otherwise, we have a nontrivial interval. When
- we're all done, the pattern will look like:
- set_number_at <jump count> <upper bound>
- set_number_at <succeed_n count> <lower bound>
- succeed_n <after jump addr> <succed_n count>
- <body of loop>
- jump_n <succeed_n addr> <jump count>
- (The upper bound and `jump_n' are omitted if
- `upper_bound' is 1, though.) */
- else
- { /* If the upper bound is > 1, we need to insert
- more at the end of the loop. */
- unsigned nbytes = 10 + (upper_bound > 1) * 10;
-
- GET_BUFFER_SPACE (nbytes);
-
- /* Initialize lower bound of the `succeed_n', even
- though it will be set during matching by its
- attendant `set_number_at' (inserted next),
- because `re_compile_fastmap' needs to know.
- Jump to the `jump_n' we might insert below. */
- INSERT_JUMP2 (succeed_n, laststart,
- b + 5 + (upper_bound > 1) * 5,
- lower_bound);
- b += 5;
-
- /* Code to initialize the lower bound. Insert
- before the `succeed_n'. The `5' is the last two
- bytes of this `set_number_at', plus 3 bytes of
- the following `succeed_n'. */
- insert_op2 (set_number_at, laststart, 5, lower_bound, b);
- b += 5;
-
- if (upper_bound > 1)
- { /* More than one repetition is allowed, so
- append a backward jump to the `succeed_n'
- that starts this interval.
-
- When we've reached this during matching,
- we'll have matched the interval once, so
- jump back only `upper_bound - 1' times. */
- STORE_JUMP2 (jump_n, b, laststart + 5,
- upper_bound - 1);
- b += 5;
-
- /* The location we want to set is the second
- parameter of the `jump_n'; that is `b-2' as
- an absolute address. `laststart' will be
- the `set_number_at' we're about to insert;
- `laststart+3' the number to set, the source
- for the relative address. But we are
- inserting into the middle of the pattern --
- so everything is getting moved up by 5.
- Conclusion: (b - 2) - (laststart + 3) + 5,
- i.e., b - laststart.
-
- We insert this at the beginning of the loop
- so that if we fail during matching, we'll
- reinitialize the bounds. */
- insert_op2 (set_number_at, laststart, b - laststart,
- upper_bound - 1, b);
- b += 5;
- }
- }
- pending_exact = 0;
- beg_interval = NULL;
- }
- break;
-
- unfetch_interval:
- /* If an invalid interval, match the characters as literals. */
- assert (beg_interval);
- p = beg_interval;
- beg_interval = NULL;
-
- /* normal_char and normal_backslash need `c'. */
- PATFETCH (c);
-
- if (!(syntax & RE_NO_BK_BRACES))
- {
- if (p > pattern && p[-1] == '\\')
- goto normal_backslash;
- }
- goto normal_char;
-
-#ifdef emacs
- /* There is no way to specify the before_dot and after_dot
- operators. rms says this is ok. --karl */
- case '=':
- BUF_PUSH (at_dot);
- break;
-
- case 's':
- laststart = b;
- PATFETCH (c);
- BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
- break;
-
- case 'S':
- laststart = b;
- PATFETCH (c);
- BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
- break;
-#endif /* emacs */
-
-
- case 'w':
- laststart = b;
- BUF_PUSH (wordchar);
- break;
-
-
- case 'W':
- laststart = b;
- BUF_PUSH (notwordchar);
- break;
-
-
- case '<':
- BUF_PUSH (wordbeg);
- break;
-
- case '>':
- BUF_PUSH (wordend);
- break;
-
- case 'b':
- BUF_PUSH (wordbound);
- break;
-
- case 'B':
- BUF_PUSH (notwordbound);
- break;
-
- case '`':
- BUF_PUSH (begbuf);
- break;
-
- case '\'':
- BUF_PUSH (endbuf);
- break;
-
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- if (syntax & RE_NO_BK_REFS)
- goto normal_char;
-
- c1 = c - '0';
-
- if (c1 > regnum)
- return REG_ESUBREG;
-
- /* Can't back reference to a subexpression if inside of it. */
- if (group_in_compile_stack (compile_stack, c1))
- goto normal_char;
-
- laststart = b;
- BUF_PUSH_2 (duplicate, c1);
- break;
-
-
- case '+':
- case '?':
- if (syntax & RE_BK_PLUS_QM)
- goto handle_plus;
- else
- goto normal_backslash;
-
- default:
- normal_backslash:
- /* You might think it would be useful for \ to mean
- not to translate; but if we don't translate it
- it will never match anything. */
- c = TRANSLATE (c);
- goto normal_char;
- }
- break;
-
-
- default:
- /* Expects the character in `c'. */
- normal_char:
- /* If no exactn currently being built. */
- if (!pending_exact
-
- /* If last exactn not at current position. */
- || pending_exact + *pending_exact + 1 != b
-
- /* We have only one byte following the exactn for the count. */
- || *pending_exact == (1 << BYTEWIDTH) - 1
-
- /* If followed by a repetition operator. */
- || *p == '*' || *p == '^'
- || ((syntax & RE_BK_PLUS_QM)
- ? *p == '\\' && (p[1] == '+' || p[1] == '?')
- : (*p == '+' || *p == '?'))
- || ((syntax & RE_INTERVALS)
- && ((syntax & RE_NO_BK_BRACES)
- ? *p == '{'
- : (p[0] == '\\' && p[1] == '{'))))
- {
- /* Start building a new exactn. */
-
- laststart = b;
-
- BUF_PUSH_2 (exactn, 0);
- pending_exact = b - 1;
- }
-
- BUF_PUSH (c);
- (*pending_exact)++;
- break;
- } /* switch (c) */
- } /* while p != pend */
-
-
- /* Through the pattern now. */
-
- if (fixup_alt_jump)
- STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
-
- if (!COMPILE_STACK_EMPTY)
- return REG_EPAREN;
-
- free (compile_stack.stack);
-
- /* We have succeeded; set the length of the buffer. */
- bufp->used = b - bufp->buffer;
-
-#ifdef DEBUG
- if (debug)
- {
- DEBUG_PRINT1 ("\nCompiled pattern: ");
- print_compiled_pattern (bufp);
- }
-#endif /* DEBUG */
-
- return REG_NOERROR;
-} /* regex_compile */
-
-/* Subroutines for `regex_compile'. */
-
-/* Store OP at LOC followed by two-byte integer parameter ARG. */
-
-static void
-store_op1 (op, loc, arg)
- re_opcode_t op;
- unsigned char *loc;
- int arg;
-{
- *loc = (unsigned char) op;
- STORE_NUMBER (loc + 1, arg);
-}
-
-
-/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */
-
-static void
-store_op2 (op, loc, arg1, arg2)
- re_opcode_t op;
- unsigned char *loc;
- int arg1, arg2;
-{
- *loc = (unsigned char) op;
- STORE_NUMBER (loc + 1, arg1);
- STORE_NUMBER (loc + 3, arg2);
-}
-
-
-/* Copy the bytes from LOC to END to open up three bytes of space at LOC
- for OP followed by two-byte integer parameter ARG. */
-
-static void
-insert_op1 (op, loc, arg, end)
- re_opcode_t op;
- unsigned char *loc;
- int arg;
- unsigned char *end;
-{
- register unsigned char *pfrom = end;
- register unsigned char *pto = end + 3;
-
- while (pfrom != loc)
- *--pto = *--pfrom;
-
- store_op1 (op, loc, arg);
-}
-
-
-/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */
-
-static void
-insert_op2 (op, loc, arg1, arg2, end)
- re_opcode_t op;
- unsigned char *loc;
- int arg1, arg2;
- unsigned char *end;
-{
- register unsigned char *pfrom = end;
- register unsigned char *pto = end + 5;
-
- while (pfrom != loc)
- *--pto = *--pfrom;
-
- store_op2 (op, loc, arg1, arg2);
-}
-
-
-/* P points to just after a ^ in PATTERN. Return true if that ^ comes
- after an alternative or a begin-subexpression. We assume there is at
- least one character before the ^. */
-
-static boolean
-at_begline_loc_p (pattern, p, syntax)
- const char *pattern, *p;
- reg_syntax_t syntax;
-{
- const char *prev = p - 2;
- boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
-
- return
- /* After a subexpression? */
- (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
- /* After an alternative? */
- || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
-}
-
-
-/* The dual of at_begline_loc_p. This one is for $. We assume there is
- at least one character after the $, i.e., `P < PEND'. */
-
-static boolean
-at_endline_loc_p (p, pend, syntax)
- const char *p, *pend;
- int syntax;
-{
- const char *next = p;
- boolean next_backslash = *next == '\\';
- const char *next_next = p + 1 < pend ? p + 1 : NULL;
-
- return
- /* Before a subexpression? */
- (syntax & RE_NO_BK_PARENS ? *next == ')'
- : next_backslash && next_next && *next_next == ')')
- /* Before an alternative? */
- || (syntax & RE_NO_BK_VBAR ? *next == '|'
- : next_backslash && next_next && *next_next == '|');
-}
-
-
-/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
- false if it's not. */
-
-static boolean
-group_in_compile_stack (compile_stack, regnum)
- compile_stack_type compile_stack;
- regnum_t regnum;
-{
- int this_element;
-
- for (this_element = compile_stack.avail - 1;
- this_element >= 0;
- this_element--)
- if (compile_stack.stack[this_element].regnum == regnum)
- return true;
-
- return false;
-}
-
-
-/* Read the ending character of a range (in a bracket expression) from the
- uncompiled pattern *P_PTR (which ends at PEND). We assume the
- starting character is in `P[-2]'. (`P[-1]' is the character `-'.)
- Then we set the translation of all bits between the starting and
- ending characters (inclusive) in the compiled pattern B.
-
- Return an error code.
-
- We use these short variable names so we can use the same macros as
- `regex_compile' itself. */
-
-static reg_errcode_t
-compile_range (p_ptr, pend, translate, syntax, b)
- const char **p_ptr, *pend;
- char *translate;
- reg_syntax_t syntax;
- unsigned char *b;
-{
- unsigned this_char;
-
- const char *p = *p_ptr;
- int range_start, range_end;
-
- if (p == pend)
- return REG_ERANGE;
-
- /* Even though the pattern is a signed `char *', we need to fetch
- with unsigned char *'s; if the high bit of the pattern character
- is set, the range endpoints will be negative if we fetch using a
- signed char *.
-
- We also want to fetch the endpoints without translating them; the
- appropriate translation is done in the bit-setting loop below. */
- range_start = ((unsigned char *) p)[-2];
- range_end = ((unsigned char *) p)[0];
-
- /* Have to increment the pointer into the pattern string, so the
- caller isn't still at the ending character. */
- (*p_ptr)++;
-
- /* If the start is after the end, the range is empty. */
- if (range_start > range_end)
- return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
-
- /* Here we see why `this_char' has to be larger than an `unsigned
- char' -- the range is inclusive, so if `range_end' == 0xff
- (assuming 8-bit characters), we would otherwise go into an infinite
- loop, since all characters <= 0xff. */
- for (this_char = range_start; this_char <= range_end; this_char++)
- {
- SET_LIST_BIT (TRANSLATE (this_char));
- }
-
- return REG_NOERROR;
-}
-
-/* Failure stack declarations and macros; both re_compile_fastmap and
- re_match_2 use a failure stack. These have to be macros because of
- REGEX_ALLOCATE. */
-
-
-/* Number of failure points for which to initially allocate space
- when matching. If this number is exceeded, we allocate more
- space, so it is not a hard limit. */
-#ifndef INIT_FAILURE_ALLOC
-#define INIT_FAILURE_ALLOC 5
-#endif
-
-/* Roughly the maximum number of failure points on the stack. Would be
- exactly that if always used MAX_FAILURE_SPACE each time we failed.
- This is a variable only so users of regex can assign to it; we never
- change it ourselves. */
-int re_max_failures = 2000;
-
-typedef const unsigned char *fail_stack_elt_t;
-
-typedef struct
-{
- fail_stack_elt_t *stack;
- unsigned size;
- unsigned avail; /* Offset of next open position. */
-} fail_stack_type;
-
-#define FAIL_STACK_EMPTY() (fail_stack.avail == 0)
-#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
-#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size)
-#define FAIL_STACK_TOP() (fail_stack.stack[fail_stack.avail])
-
-
-/* Initialize `fail_stack'. Do `return -2' if the alloc fails. */
-
-#define INIT_FAIL_STACK() \
- do { \
- fail_stack.stack = (fail_stack_elt_t *) \
- REGEX_ALLOCATE (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \
- \
- if (fail_stack.stack == NULL) \
- return -2; \
- \
- fail_stack.size = INIT_FAILURE_ALLOC; \
- fail_stack.avail = 0; \
- } while (0)
-
-
-/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
-
- Return 1 if succeeds, and 0 if either ran out of memory
- allocating space for it or it was already too large.
-
- REGEX_REALLOCATE requires `destination' be declared. */
-
-#define DOUBLE_FAIL_STACK(fail_stack) \
- ((fail_stack).size > re_max_failures * MAX_FAILURE_ITEMS \
- ? 0 \
- : ((fail_stack).stack = (fail_stack_elt_t *) \
- REGEX_REALLOCATE ((fail_stack).stack, \
- (fail_stack).size * sizeof (fail_stack_elt_t), \
- ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \
- \
- (fail_stack).stack == NULL \
- ? 0 \
- : ((fail_stack).size <<= 1, \
- 1)))
-
-
-/* Push PATTERN_OP on FAIL_STACK.
-
- Return 1 if was able to do so and 0 if ran out of memory allocating
- space to do so. */
-#define PUSH_PATTERN_OP(pattern_op, fail_stack) \
- ((FAIL_STACK_FULL () \
- && !DOUBLE_FAIL_STACK (fail_stack)) \
- ? 0 \
- : ((fail_stack).stack[(fail_stack).avail++] = pattern_op, \
- 1))
-
-/* This pushes an item onto the failure stack. Must be a four-byte
- value. Assumes the variable `fail_stack'. Probably should only
- be called from within `PUSH_FAILURE_POINT'. */
-#define PUSH_FAILURE_ITEM(item) \
- fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) item
-
-/* The complement operation. Assumes `fail_stack' is nonempty. */
-#define POP_FAILURE_ITEM() fail_stack.stack[--fail_stack.avail]
-
-/* Used to omit pushing failure point id's when we're not debugging. */
-#ifdef DEBUG
-#define DEBUG_PUSH PUSH_FAILURE_ITEM
-#define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_ITEM ()
-#else
-#define DEBUG_PUSH(item)
-#define DEBUG_POP(item_addr)
-#endif
-
-
-/* Push the information about the state we will need
- if we ever fail back to it.
-
- Requires variables fail_stack, regstart, regend, reg_info, and
- num_regs be declared. DOUBLE_FAIL_STACK requires `destination' be
- declared.
-
- Does `return FAILURE_CODE' if runs out of memory. */
-
-#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \
- do { \
- char *destination; \
- /* Must be int, so when we don't save any registers, the arithmetic \
- of 0 + -1 isn't done as unsigned. */ \
- int this_reg; \
- \
- DEBUG_STATEMENT (failure_id++); \
- DEBUG_STATEMENT (nfailure_points_pushed++); \
- DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
- DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\
- DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
- \
- DEBUG_PRINT2 (" slots needed: %d\n", NUM_FAILURE_ITEMS); \
- DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \
- \
- /* Ensure we have enough space allocated for what we will push. */ \
- while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \
- { \
- if (!DOUBLE_FAIL_STACK (fail_stack)) \
- return failure_code; \
- \
- DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \
- (fail_stack).size); \
- DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
- } \
- \
- /* Push the info, starting with the registers. */ \
- DEBUG_PRINT1 ("\n"); \
- \
- for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
- this_reg++) \
- { \
- DEBUG_PRINT2 (" Pushing reg: %d\n", this_reg); \
- DEBUG_STATEMENT (num_regs_pushed++); \
- \
- DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
- PUSH_FAILURE_ITEM (regstart[this_reg]); \
- \
- DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
- PUSH_FAILURE_ITEM (regend[this_reg]); \
- \
- DEBUG_PRINT2 (" info: 0x%x\n ", reg_info[this_reg]); \
- DEBUG_PRINT2 (" match_null=%d", \
- REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \
- DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \
- DEBUG_PRINT2 (" matched_something=%d", \
- MATCHED_SOMETHING (reg_info[this_reg])); \
- DEBUG_PRINT2 (" ever_matched=%d", \
- EVER_MATCHED_SOMETHING (reg_info[this_reg])); \
- DEBUG_PRINT1 ("\n"); \
- PUSH_FAILURE_ITEM (reg_info[this_reg].word); \
- } \
- \
- DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\
- PUSH_FAILURE_ITEM (lowest_active_reg); \
- \
- DEBUG_PRINT2 (" Pushing high active reg: %d\n", highest_active_reg);\
- PUSH_FAILURE_ITEM (highest_active_reg); \
- \
- DEBUG_PRINT2 (" Pushing pattern 0x%x: ", pattern_place); \
- DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \
- PUSH_FAILURE_ITEM (pattern_place); \
- \
- DEBUG_PRINT2 (" Pushing string 0x%x: `", string_place); \
- DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \
- size2); \
- DEBUG_PRINT1 ("'\n"); \
- PUSH_FAILURE_ITEM (string_place); \
- \
- DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \
- DEBUG_PUSH (failure_id); \
- } while (0)
-
-/* This is the number of items that are pushed and popped on the stack
- for each register. */
-#define NUM_REG_ITEMS 3
-
-/* Individual items aside from the registers. */
-#ifdef DEBUG
-#define NUM_NONREG_ITEMS 5 /* Includes failure point id. */
-#else
-#define NUM_NONREG_ITEMS 4
-#endif
-
-/* We push at most this many items on the stack. */
-#define MAX_FAILURE_ITEMS ((num_regs - 1) * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
-
-/* We actually push this many items. */
-#define NUM_FAILURE_ITEMS \
- ((highest_active_reg - lowest_active_reg + 1) * NUM_REG_ITEMS \
- + NUM_NONREG_ITEMS)
-
-/* How many items can still be added to the stack without overflowing it. */
-#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
-
-
-/* Pops what PUSH_FAIL_STACK pushes.
-
- We restore into the parameters, all of which should be lvalues:
- STR -- the saved data position.
- PAT -- the saved pattern position.
- LOW_REG, HIGH_REG -- the highest and lowest active registers.
- REGSTART, REGEND -- arrays of string positions.
- REG_INFO -- array of information about each subexpression.
-
- Also assumes the variables `fail_stack' and (if debugging), `bufp',
- `pend', `string1', `size1', `string2', and `size2'. */
-
-#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
-{ \
- DEBUG_STATEMENT (fail_stack_elt_t failure_id;) \
- int this_reg; \
- const unsigned char *string_temp; \
- \
- assert (!FAIL_STACK_EMPTY ()); \
- \
- /* Remove failure points and point to how many regs pushed. */ \
- DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
- DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
- DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
- \
- assert (fail_stack.avail >= NUM_NONREG_ITEMS); \
- \
- DEBUG_POP (&failure_id); \
- DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \
- \
- /* If the saved string location is NULL, it came from an \
- on_failure_keep_string_jump opcode, and we want to throw away the \
- saved NULL, thus retaining our current position in the string. */ \
- string_temp = POP_FAILURE_ITEM (); \
- if (string_temp != NULL) \
- str = (const char *) string_temp; \
- \
- DEBUG_PRINT2 (" Popping string 0x%x: `", str); \
- DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
- DEBUG_PRINT1 ("'\n"); \
- \
- pat = (unsigned char *) POP_FAILURE_ITEM (); \
- DEBUG_PRINT2 (" Popping pattern 0x%x: ", pat); \
- DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
- \
- /* Restore register info. */ \
- high_reg = (unsigned) POP_FAILURE_ITEM (); \
- DEBUG_PRINT2 (" Popping high active reg: %d\n", high_reg); \
- \
- low_reg = (unsigned) POP_FAILURE_ITEM (); \
- DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \
- \
- for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \
- { \
- DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \
- \
- reg_info[this_reg].word = POP_FAILURE_ITEM (); \
- DEBUG_PRINT2 (" info: 0x%x\n", reg_info[this_reg]); \
- \
- regend[this_reg] = (const char *) POP_FAILURE_ITEM (); \
- DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
- \
- regstart[this_reg] = (const char *) POP_FAILURE_ITEM (); \
- DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
- } \
- \
- DEBUG_STATEMENT (nfailure_points_popped++); \
-} /* POP_FAILURE_POINT */
-
-/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
- BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible
- characters can start a string that matches the pattern. This fastmap
- is used by re_search to skip quickly over impossible starting points.
-
- The caller must supply the address of a (1 << BYTEWIDTH)-byte data
- area as BUFP->fastmap.
-
- We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
- the pattern buffer.
-
- Returns 0 if we succeed, -2 if an internal error. */
-
-int
-re_compile_fastmap (bufp)
- struct re_pattern_buffer *bufp;
-{
- int j, k;
- fail_stack_type fail_stack;
-#ifndef REGEX_MALLOC
- char *destination;
-#endif
- /* We don't push any register information onto the failure stack. */
- unsigned num_regs = 0;
-
- register char *fastmap = bufp->fastmap;
- unsigned char *pattern = bufp->buffer;
- unsigned long size = bufp->used;
- const unsigned char *p = pattern;
- register unsigned char *pend = pattern + size;
-
- /* Assume that each path through the pattern can be null until
- proven otherwise. We set this false at the bottom of switch
- statement, to which we get only if a particular path doesn't
- match the empty string. */
- boolean path_can_be_null = true;
-
- /* We aren't doing a `succeed_n' to begin with. */
- boolean succeed_n_p = false;
-
- assert (fastmap != NULL && p != NULL);
-
- INIT_FAIL_STACK ();
- bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */
- bufp->fastmap_accurate = 1; /* It will be when we're done. */
- bufp->can_be_null = 0;
-
- while (p != pend || !FAIL_STACK_EMPTY ())
- {
- if (p == pend)
- {
- bufp->can_be_null |= path_can_be_null;
-
- /* Reset for next path. */
- path_can_be_null = true;
-
- p = fail_stack.stack[--fail_stack.avail];
- }
-
- /* We should never be about to go beyond the end of the pattern. */
- assert (p < pend);
-
-#ifdef SWITCH_ENUM_BUG
- switch ((int) ((re_opcode_t) *p++))
-#else
- switch ((re_opcode_t) *p++)
-#endif
- {
-
- /* I guess the idea here is to simply not bother with a fastmap
- if a backreference is used, since it's too hard to figure out
- the fastmap for the corresponding group. Setting
- `can_be_null' stops `re_search_2' from using the fastmap, so
- that is all we do. */
- case duplicate:
- bufp->can_be_null = 1;
- return 0;
-
-
- /* Following are the cases which match a character. These end
- with `break'. */
-
- case exactn:
- fastmap[p[1]] = 1;
- break;
-
-
- case charset:
- for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
- if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
- fastmap[j] = 1;
- break;
-
-
- case charset_not:
- /* Chars beyond end of map must be allowed. */
- for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
- fastmap[j] = 1;
-
- for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
- if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
- fastmap[j] = 1;
- break;
-
-
- case wordchar:
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (SYNTAX (j) == Sword)
- fastmap[j] = 1;
- break;
-
-
- case notwordchar:
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (SYNTAX (j) != Sword)
- fastmap[j] = 1;
- break;
-
-
- case anychar:
- /* `.' matches anything ... */
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- fastmap[j] = 1;
-
- /* ... except perhaps newline. */
- if (!(bufp->syntax & RE_DOT_NEWLINE))
- fastmap['\n'] = 0;
-
- /* Return if we have already set `can_be_null'; if we have,
- then the fastmap is irrelevant. Something's wrong here. */
- else if (bufp->can_be_null)
- return 0;
-
- /* Otherwise, have to check alternative paths. */
- break;
-
-
-#ifdef emacs
- case syntaxspec:
- k = *p++;
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (SYNTAX (j) == (enum syntaxcode) k)
- fastmap[j] = 1;
- break;
-
-
- case notsyntaxspec:
- k = *p++;
- for (j = 0; j < (1 << BYTEWIDTH); j++)
- if (SYNTAX (j) != (enum syntaxcode) k)
- fastmap[j] = 1;
- break;
-
-
- /* All cases after this match the empty string. These end with
- `continue'. */
-
-
- case before_dot:
- case at_dot:
- case after_dot:
- continue;
-#endif /* not emacs */
-
-
- case no_op:
- case begline:
- case endline:
- case begbuf:
- case endbuf:
- case wordbound:
- case notwordbound:
- case wordbeg:
- case wordend:
- case push_dummy_failure:
- continue;
-
-
- case jump_n:
- case pop_failure_jump:
- case maybe_pop_jump:
- case jump:
- case jump_past_alt:
- case dummy_failure_jump:
- EXTRACT_NUMBER_AND_INCR (j, p);
- p += j;
- if (j > 0)
- continue;
-
- /* Jump backward implies we just went through the body of a
- loop and matched nothing. Opcode jumped to should be
- `on_failure_jump' or `succeed_n'. Just treat it like an
- ordinary jump. For a * loop, it has pushed its failure
- point already; if so, discard that as redundant. */
- if ((re_opcode_t) *p != on_failure_jump
- && (re_opcode_t) *p != succeed_n)
- continue;
-
- p++;
- EXTRACT_NUMBER_AND_INCR (j, p);
- p += j;
-
- /* If what's on the stack is where we are now, pop it. */
- if (!FAIL_STACK_EMPTY ()
- && fail_stack.stack[fail_stack.avail - 1] == p)
- fail_stack.avail--;
-
- continue;
-
-
- case on_failure_jump:
- case on_failure_keep_string_jump:
- handle_on_failure_jump:
- EXTRACT_NUMBER_AND_INCR (j, p);
-
- /* For some patterns, e.g., `(a?)?', `p+j' here points to the
- end of the pattern. We don't want to push such a point,
- since when we restore it above, entering the switch will
- increment `p' past the end of the pattern. We don't need
- to push such a point since we obviously won't find any more
- fastmap entries beyond `pend'. Such a pattern can match
- the null string, though. */
- if (p + j < pend)
- {
- if (!PUSH_PATTERN_OP (p + j, fail_stack))
- return -2;
- }
- else
- bufp->can_be_null = 1;
-
- if (succeed_n_p)
- {
- EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
- succeed_n_p = false;
- }
-
- continue;
-
-
- case succeed_n:
- /* Get to the number of times to succeed. */
- p += 2;
-
- /* Increment p past the n for when k != 0. */
- EXTRACT_NUMBER_AND_INCR (k, p);
- if (k == 0)
- {
- p -= 4;
- succeed_n_p = true; /* Spaghetti code alert. */
- goto handle_on_failure_jump;
- }
- continue;
-
-
- case set_number_at:
- p += 4;
- continue;
-
-
- case start_memory:
- case stop_memory:
- p += 2;
- continue;
-
-
- default:
- abort (); /* We have listed all the cases. */
- } /* switch *p++ */
-
- /* Getting here means we have found the possible starting
- characters for one path of the pattern -- and that the empty
- string does not match. We need not follow this path further.
- Instead, look at the next alternative (remembered on the
- stack), or quit if no more. The test at the top of the loop
- does these things. */
- path_can_be_null = false;
- p = pend;
- } /* while p */
-
- /* Set `can_be_null' for the last path (also the first path, if the
- pattern is empty). */
- bufp->can_be_null |= path_can_be_null;
- return 0;
-} /* re_compile_fastmap */
-
-/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
- ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use
- this memory for recording register information. STARTS and ENDS
- must be allocated using the malloc library routine, and must each
- be at least NUM_REGS * sizeof (regoff_t) bytes long.
-
- If NUM_REGS == 0, then subsequent matches should allocate their own
- register data.
-
- Unless this function is called, the first search or match using
- PATTERN_BUFFER will allocate its own register data, without
- freeing the old data. */
-
-void
-re_set_registers (bufp, regs, num_regs, starts, ends)
- struct re_pattern_buffer *bufp;
- struct re_registers *regs;
- unsigned num_regs;
- regoff_t *starts, *ends;
-{
- if (num_regs)
- {
- bufp->regs_allocated = REGS_REALLOCATE;
- regs->num_regs = num_regs;
- regs->start = starts;
- regs->end = ends;
- }
- else
- {
- bufp->regs_allocated = REGS_UNALLOCATED;
- regs->num_regs = 0;
- regs->start = regs->end = (regoff_t) 0;
- }
-}
-
-/* Searching routines. */
-
-/* Like re_search_2, below, but only one string is specified, and
- doesn't let you say where to stop matching. */
-
-int
-re_search (bufp, string, size, startpos, range, regs)
- struct re_pattern_buffer *bufp;
- const char *string;
- int size, startpos, range;
- struct re_registers *regs;
-{
- return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
- regs, size);
-}
-
-
-/* Using the compiled pattern in BUFP->buffer, first tries to match the
- virtual concatenation of STRING1 and STRING2, starting first at index
- STARTPOS, then at STARTPOS + 1, and so on.
-
- STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
-
- RANGE is how far to scan while trying to match. RANGE = 0 means try
- only at STARTPOS; in general, the last start tried is STARTPOS +
- RANGE.
-
- In REGS, return the indices of the virtual concatenation of STRING1
- and STRING2 that matched the entire BUFP->buffer and its contained
- subexpressions.
-
- Do not consider matching one past the index STOP in the virtual
- concatenation of STRING1 and STRING2.
-
- We return either the position in the strings at which the match was
- found, -1 if no match, or -2 if error (such as failure
- stack overflow). */
-
-int
-re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
- struct re_pattern_buffer *bufp;
- const char *string1, *string2;
- int size1, size2;
- int startpos;
- int range;
- struct re_registers *regs;
- int stop;
-{
- int val;
- register char *fastmap = bufp->fastmap;
- register char *translate = bufp->translate;
- int total_size = size1 + size2;
- int endpos = startpos + range;
-
- /* Check for out-of-range STARTPOS. */
- if (startpos < 0 || startpos > total_size)
- return -1;
-
- /* Fix up RANGE if it might eventually take us outside
- the virtual concatenation of STRING1 and STRING2. */
- if (endpos < -1)
- range = -1 - startpos;
- else if (endpos > total_size)
- range = total_size - startpos;
-
- /* If the search isn't to be a backwards one, don't waste time in a
- search for a pattern that must be anchored. */
- if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0)
- {
- if (startpos > 0)
- return -1;
- else
- range = 1;
- }
-
- /* Update the fastmap now if not correct already. */
- if (fastmap && !bufp->fastmap_accurate)
- if (re_compile_fastmap (bufp) == -2)
- return -2;
-
- /* Loop through the string, looking for a place to start matching. */
- for (;;)
- {
- /* If a fastmap is supplied, skip quickly over characters that
- cannot be the start of a match. If the pattern can match the
- null string, however, we don't need to skip characters; we want
- the first null string. */
- if (fastmap && startpos < total_size && !bufp->can_be_null)
- {
- if (range > 0) /* Searching forwards. */
- {
- register const char *d;
- register int lim = 0;
- int irange = range;
-
- if (startpos < size1 && startpos + range >= size1)
- lim = range - (size1 - startpos);
-
- d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
-
- /* Written out as an if-else to avoid testing `translate'
- inside the loop. */
- if (translate)
- while (range > lim
- && !fastmap[(unsigned char)
- translate[(unsigned char) *d++]])
- range--;
- else
- while (range > lim && !fastmap[(unsigned char) *d++])
- range--;
-
- startpos += irange - range;
- }
- else /* Searching backwards. */
- {
- register char c = (size1 == 0 || startpos >= size1
- ? string2[startpos - size1]
- : string1[startpos]);
-
- if (!fastmap[(unsigned char) TRANSLATE (c)])
- goto advance;
- }
- }
-
- /* If can't match the null string, and that's all we have left, fail. */
- if (range >= 0 && startpos == total_size && fastmap
- && !bufp->can_be_null)
- return -1;
-
- val = re_match_2 (bufp, string1, size1, string2, size2,
- startpos, regs, stop);
- if (val >= 0)
- return startpos;
-
- if (val == -2)
- return -2;
-
- advance:
- if (!range)
- break;
- else if (range > 0)
- {
- range--;
- startpos++;
- }
- else
- {
- range++;
- startpos--;
- }
- }
- return -1;
-} /* re_search_2 */
-
-/* Declarations and macros for re_match_2. */
-
-static int bcmp_translate ();
-static boolean alt_match_null_string_p (),
- common_op_match_null_string_p (),
- group_match_null_string_p ();
-
-/* Structure for per-register (a.k.a. per-group) information.
- This must not be longer than one word, because we push this value
- onto the failure stack. Other register information, such as the
- starting and ending positions (which are addresses), and the list of
- inner groups (which is a bits list) are maintained in separate
- variables.
-
- We are making a (strictly speaking) nonportable assumption here: that
- the compiler will pack our bit fields into something that fits into
- the type of `word', i.e., is something that fits into one item on the
- failure stack. */
-typedef union
-{
- fail_stack_elt_t word;
- struct
- {
- /* This field is one if this group can match the empty string,
- zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
-#define MATCH_NULL_UNSET_VALUE 3
- unsigned match_null_string_p : 2;
- unsigned is_active : 1;
- unsigned matched_something : 1;
- unsigned ever_matched_something : 1;
- } bits;
-} register_info_type;
-
-#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
-#define IS_ACTIVE(R) ((R).bits.is_active)
-#define MATCHED_SOMETHING(R) ((R).bits.matched_something)
-#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
-
-
-/* Call this when have matched a real character; it sets `matched' flags
- for the subexpressions which we are currently inside. Also records
- that those subexprs have matched. */
-#define SET_REGS_MATCHED() \
- do \
- { \
- unsigned r; \
- for (r = lowest_active_reg; r <= highest_active_reg; r++) \
- { \
- MATCHED_SOMETHING (reg_info[r]) \
- = EVER_MATCHED_SOMETHING (reg_info[r]) \
- = 1; \
- } \
- } \
- while (0)
-
-
-/* This converts PTR, a pointer into one of the search strings `string1'
- and `string2' into an offset from the beginning of that string. */
-#define POINTER_TO_OFFSET(ptr) \
- (FIRST_STRING_P (ptr) ? (ptr) - string1 : (ptr) - string2 + size1)
-
-/* Registers are set to a sentinel when they haven't yet matched. */
-#define REG_UNSET_VALUE ((char *) -1)
-#define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
-
-
-/* Macros for dealing with the split strings in re_match_2. */
-
-#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
-
-/* Call before fetching a character with *d. This switches over to
- string2 if necessary. */
-#define PREFETCH() \
- while (d == dend) \
- { \
- /* End of string2 => fail. */ \
- if (dend == end_match_2) \
- goto fail; \
- /* End of string1 => advance to string2. */ \
- d = string2; \
- dend = end_match_2; \
- }
-
-
-/* Test if at very beginning or at very end of the virtual concatenation
- of `string1' and `string2'. If only one string, it's `string2'. */
-#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
-#define AT_STRINGS_END(d) ((d) == end2)
-
-
-/* Test if D points to a character which is word-constituent. We have
- two special cases to check for: if past the end of string1, look at
- the first character in string2; and if before the beginning of
- string2, look at the last character in string1. */
-#define WORDCHAR_P(d) \
- (SYNTAX ((d) == end1 ? *string2 \
- : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
- == Sword)
-
-/* Test if the character before D and the one at D differ with respect
- to being word-constituent. */
-#define AT_WORD_BOUNDARY(d) \
- (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \
- || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
-
-
-/* Free everything we malloc. */
-#ifdef REGEX_MALLOC
-#define FREE_VAR(var) if (var) free (var); var = NULL
-#define FREE_VARIABLES() \
- do { \
- FREE_VAR (fail_stack.stack); \
- FREE_VAR (regstart); \
- FREE_VAR (regend); \
- FREE_VAR (old_regstart); \
- FREE_VAR (old_regend); \
- FREE_VAR (best_regstart); \
- FREE_VAR (best_regend); \
- FREE_VAR (reg_info); \
- FREE_VAR (reg_dummy); \
- FREE_VAR (reg_info_dummy); \
- } while (0)
-#else /* not REGEX_MALLOC */
-/* Some MIPS systems (at least) want this to free alloca'd storage. */
-#define FREE_VARIABLES() alloca (0)
-#endif /* not REGEX_MALLOC */
-
-
-/* These values must meet several constraints. They must not be valid
- register values; since we have a limit of 255 registers (because
- we use only one byte in the pattern for the register number), we can
- use numbers larger than 255. They must differ by 1, because of
- NUM_FAILURE_ITEMS above. And the value for the lowest register must
- be larger than the value for the highest register, so we do not try
- to actually save any registers when none are active. */
-#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
-#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
-
-/* Matching routines. */
-
-#ifndef emacs /* Emacs never uses this. */
-/* re_match is like re_match_2 except it takes only a single string. */
-
-int
-re_match (bufp, string, size, pos, regs)
- struct re_pattern_buffer *bufp;
- const char *string;
- int size, pos;
- struct re_registers *regs;
- {
- return re_match_2 (bufp, NULL, 0, string, size, pos, regs, size);
-}
-#endif /* not emacs */
-
-
-/* re_match_2 matches the compiled pattern in BUFP against the
- the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
- and SIZE2, respectively). We start matching at POS, and stop
- matching at STOP.
-
- If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
- store offsets for the substring each group matched in REGS. See the
- documentation for exactly how many groups we fill.
-
- We return -1 if no match, -2 if an internal error (such as the
- failure stack overflowing). Otherwise, we return the length of the
- matched substring. */
-
-int
-re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
- struct re_pattern_buffer *bufp;
- const char *string1, *string2;
- int size1, size2;
- int pos;
- struct re_registers *regs;
- int stop;
-{
- /* General temporaries. */
- int mcnt;
- unsigned char *p1;
-
- /* Just past the end of the corresponding string. */
- const char *end1, *end2;
-
- /* Pointers into string1 and string2, just past the last characters in
- each to consider matching. */
- const char *end_match_1, *end_match_2;
-
- /* Where we are in the data, and the end of the current string. */
- const char *d, *dend;
-
- /* Where we are in the pattern, and the end of the pattern. */
- unsigned char *p = bufp->buffer;
- register unsigned char *pend = p + bufp->used;
-
- /* We use this to map every character in the string. */
- char *translate = bufp->translate;
-
- /* Failure point stack. Each place that can handle a failure further
- down the line pushes a failure point on this stack. It consists of
- restart, regend, and reg_info for all registers corresponding to
- the subexpressions we're currently inside, plus the number of such
- registers, and, finally, two char *'s. The first char * is where
- to resume scanning the pattern; the second one is where to resume
- scanning the strings. If the latter is zero, the failure point is
- a ``dummy''; if a failure happens and the failure point is a dummy,
- it gets discarded and the next next one is tried. */
- fail_stack_type fail_stack;
-#ifdef DEBUG
- static unsigned failure_id = 0;
- unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
-#endif
-
- /* We fill all the registers internally, independent of what we
- return, for use in backreferences. The number here includes
- an element for register zero. */
- unsigned num_regs = bufp->re_nsub + 1;
-
- /* The currently active registers. */
- unsigned lowest_active_reg = NO_LOWEST_ACTIVE_REG;
- unsigned highest_active_reg = NO_HIGHEST_ACTIVE_REG;
-
- /* Information on the contents of registers. These are pointers into
- the input strings; they record just what was matched (on this
- attempt) by a subexpression part of the pattern, that is, the
- regnum-th regstart pointer points to where in the pattern we began
- matching and the regnum-th regend points to right after where we
- stopped matching the regnum-th subexpression. (The zeroth register
- keeps track of what the whole pattern matches.) */
- const char **regstart, **regend;
-
- /* If a group that's operated upon by a repetition operator fails to
- match anything, then the register for its start will need to be
- restored because it will have been set to wherever in the string we
- are when we last see its open-group operator. Similarly for a
- register's end. */
- const char **old_regstart, **old_regend;
-
- /* The is_active field of reg_info helps us keep track of which (possibly
- nested) subexpressions we are currently in. The matched_something
- field of reg_info[reg_num] helps us tell whether or not we have
- matched any of the pattern so far this time through the reg_num-th
- subexpression. These two fields get reset each time through any
- loop their register is in. */
- register_info_type *reg_info;
-
- /* The following record the register info as found in the above
- variables when we find a match better than any we've seen before.
- This happens as we backtrack through the failure points, which in
- turn happens only if we have not yet matched the entire string. */
- unsigned best_regs_set = false;
- const char **best_regstart, **best_regend;
-
- /* Logically, this is `best_regend[0]'. But we don't want to have to
- allocate space for that if we're not allocating space for anything
- else (see below). Also, we never need info about register 0 for
- any of the other register vectors, and it seems rather a kludge to
- treat `best_regend' differently than the rest. So we keep track of
- the end of the best match so far in a separate variable. We
- initialize this to NULL so that when we backtrack the first time
- and need to test it, it's not garbage. */
- const char *match_end = NULL;
-
- /* Used when we pop values we don't care about. */
- const char **reg_dummy;
- register_info_type *reg_info_dummy;
-
-#ifdef DEBUG
- /* Counts the total number of registers pushed. */
- unsigned num_regs_pushed = 0;
-#endif
-
- DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
-
- INIT_FAIL_STACK ();
-
- /* Do not bother to initialize all the register variables if there are
- no groups in the pattern, as it takes a fair amount of time. If
- there are groups, we include space for register 0 (the whole
- pattern), even though we never use it, since it simplifies the
- array indexing. We should fix this. */
- if (bufp->re_nsub)
- {
- regstart = REGEX_TALLOC (num_regs, const char *);
- regend = REGEX_TALLOC (num_regs, const char *);
- old_regstart = REGEX_TALLOC (num_regs, const char *);
- old_regend = REGEX_TALLOC (num_regs, const char *);
- best_regstart = REGEX_TALLOC (num_regs, const char *);
- best_regend = REGEX_TALLOC (num_regs, const char *);
- reg_info = REGEX_TALLOC (num_regs, register_info_type);
- reg_dummy = REGEX_TALLOC (num_regs, const char *);
- reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type);
-
- if (!(regstart && regend && old_regstart && old_regend && reg_info
- && best_regstart && best_regend && reg_dummy && reg_info_dummy))
- {
- FREE_VARIABLES ();
- return -2;
- }
- }
-#ifdef REGEX_MALLOC
- else
- {
- /* We must initialize all our variables to NULL, so that
- `FREE_VARIABLES' doesn't try to free them. */
- regstart = regend = old_regstart = old_regend = best_regstart
- = best_regend = reg_dummy = NULL;
- reg_info = reg_info_dummy = (register_info_type *) NULL;
- }
-#endif /* REGEX_MALLOC */
-
- /* The starting position is bogus. */
- if (pos < 0 || pos > size1 + size2)
- {
- FREE_VARIABLES ();
- return -1;
- }
-
- /* Initialize subexpression text positions to -1 to mark ones that no
- start_memory/stop_memory has been seen for. Also initialize the
- register information struct. */
- for (mcnt = 1; mcnt < num_regs; mcnt++)
- {
- regstart[mcnt] = regend[mcnt]
- = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
-
- REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
- IS_ACTIVE (reg_info[mcnt]) = 0;
- MATCHED_SOMETHING (reg_info[mcnt]) = 0;
- EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
- }
-
- /* We move `string1' into `string2' if the latter's empty -- but not if
- `string1' is null. */
- if (size2 == 0 && string1 != NULL)
- {
- string2 = string1;
- size2 = size1;
- string1 = 0;
- size1 = 0;
- }
- end1 = string1 + size1;
- end2 = string2 + size2;
-
- /* Compute where to stop matching, within the two strings. */
- if (stop <= size1)
- {
- end_match_1 = string1 + stop;
- end_match_2 = string2;
- }
- else
- {
- end_match_1 = end1;
- end_match_2 = string2 + stop - size1;
- }
-
- /* `p' scans through the pattern as `d' scans through the data.
- `dend' is the end of the input string that `d' points within. `d'
- is advanced into the following input string whenever necessary, but
- this happens before fetching; therefore, at the beginning of the
- loop, `d' can be pointing at the end of a string, but it cannot
- equal `string2'. */
- if (size1 > 0 && pos <= size1)
- {
- d = string1 + pos;
- dend = end_match_1;
- }
- else
- {
- d = string2 + pos - size1;
- dend = end_match_2;
- }
-
- DEBUG_PRINT1 ("The compiled pattern is: ");
- DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
- DEBUG_PRINT1 ("The string to match is: `");
- DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
- DEBUG_PRINT1 ("'\n");
-
- /* This loops over pattern commands. It exits by returning from the
- function if the match is complete, or it drops through if the match
- fails at this starting point in the input data. */
- for (;;)
- {
- DEBUG_PRINT2 ("\n0x%x: ", p);
-
- if (p == pend)
- { /* End of pattern means we might have succeeded. */
- DEBUG_PRINT1 ("end of pattern ... ");
-
- /* If we haven't matched the entire string, and we want the
- longest match, try backtracking. */
- if (d != end_match_2)
- {
- DEBUG_PRINT1 ("backtracking.\n");
-
- if (!FAIL_STACK_EMPTY ())
- { /* More failure points to try. */
- boolean same_str_p = (FIRST_STRING_P (match_end)
- == MATCHING_IN_FIRST_STRING);
-
- /* If exceeds best match so far, save it. */
- if (!best_regs_set
- || (same_str_p && d > match_end)
- || (!same_str_p && !MATCHING_IN_FIRST_STRING))
- {
- best_regs_set = true;
- match_end = d;
-
- DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
-
- for (mcnt = 1; mcnt < num_regs; mcnt++)
- {
- best_regstart[mcnt] = regstart[mcnt];
- best_regend[mcnt] = regend[mcnt];
- }
- }
- goto fail;
- }
-
- /* If no failure points, don't restore garbage. */
- else if (best_regs_set)
- {
- restore_best_regs:
- /* Restore best match. It may happen that `dend ==
- end_match_1' while the restored d is in string2.
- For example, the pattern `x.*y.*z' against the
- strings `x-' and `y-z-', if the two strings are
- not consecutive in memory. */
- DEBUG_PRINT1 ("Restoring best registers.\n");
-
- d = match_end;
- dend = ((d >= string1 && d <= end1)
- ? end_match_1 : end_match_2);
-
- for (mcnt = 1; mcnt < num_regs; mcnt++)
- {
- regstart[mcnt] = best_regstart[mcnt];
- regend[mcnt] = best_regend[mcnt];
- }
- }
- } /* d != end_match_2 */
-
- DEBUG_PRINT1 ("Accepting match.\n");
-
- /* If caller wants register contents data back, do it. */
- if (regs && !bufp->no_sub)
- {
- /* Have the register data arrays been allocated? */
- if (bufp->regs_allocated == REGS_UNALLOCATED)
- { /* No. So allocate them with malloc. We need one
- extra element beyond `num_regs' for the `-1' marker
- GNU code uses. */
- regs->num_regs = MAX (RE_NREGS, num_regs + 1);
- regs->start = TALLOC (regs->num_regs, regoff_t);
- regs->end = TALLOC (regs->num_regs, regoff_t);
- if (regs->start == NULL || regs->end == NULL)
- return -2;
- bufp->regs_allocated = REGS_REALLOCATE;
- }
- else if (bufp->regs_allocated == REGS_REALLOCATE)
- { /* Yes. If we need more elements than were already
- allocated, reallocate them. If we need fewer, just
- leave it alone. */
- if (regs->num_regs < num_regs + 1)
- {
- regs->num_regs = num_regs + 1;
- RETALLOC (regs->start, regs->num_regs, regoff_t);
- RETALLOC (regs->end, regs->num_regs, regoff_t);
- if (regs->start == NULL || regs->end == NULL)
- return -2;
- }
- }
- else
- assert (bufp->regs_allocated == REGS_FIXED);
-
- /* Convert the pointer data in `regstart' and `regend' to
- indices. Register zero has to be set differently,
- since we haven't kept track of any info for it. */
- if (regs->num_regs > 0)
- {
- regs->start[0] = pos;
- regs->end[0] = (MATCHING_IN_FIRST_STRING ? d - string1
- : d - string2 + size1);
- }
-
- /* Go through the first `min (num_regs, regs->num_regs)'
- registers, since that is all we initialized. */
- for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++)
- {
- if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
- regs->start[mcnt] = regs->end[mcnt] = -1;
- else
- {
- regs->start[mcnt] = POINTER_TO_OFFSET (regstart[mcnt]);
- regs->end[mcnt] = POINTER_TO_OFFSET (regend[mcnt]);
- }
- }
-
- /* If the regs structure we return has more elements than
- were in the pattern, set the extra elements to -1. If
- we (re)allocated the registers, this is the case,
- because we always allocate enough to have at least one
- -1 at the end. */
- for (mcnt = num_regs; mcnt < regs->num_regs; mcnt++)
- regs->start[mcnt] = regs->end[mcnt] = -1;
- } /* regs && !bufp->no_sub */
-
- FREE_VARIABLES ();
- DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
- nfailure_points_pushed, nfailure_points_popped,
- nfailure_points_pushed - nfailure_points_popped);
- DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
-
- mcnt = d - pos - (MATCHING_IN_FIRST_STRING
- ? string1
- : string2 - size1);
-
- DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
-
- return mcnt;
- }
-
- /* Otherwise match next pattern command. */
-#ifdef SWITCH_ENUM_BUG
- switch ((int) ((re_opcode_t) *p++))
-#else
- switch ((re_opcode_t) *p++)
-#endif
- {
- /* Ignore these. Used to ignore the n of succeed_n's which
- currently have n == 0. */
- case no_op:
- DEBUG_PRINT1 ("EXECUTING no_op.\n");
- break;
-
-
- /* Match the next n pattern characters exactly. The following
- byte in the pattern defines n, and the n bytes after that
- are the characters to match. */
- case exactn:
- mcnt = *p++;
- DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
-
- /* This is written out as an if-else so we don't waste time
- testing `translate' inside the loop. */
- if (translate)
- {
- do
- {
- PREFETCH ();
- if (translate[(unsigned char) *d++] != (char) *p++)
- goto fail;
- }
- while (--mcnt);
- }
- else
- {
- do
- {
- PREFETCH ();
- if (*d++ != (char) *p++) goto fail;
- }
- while (--mcnt);
- }
- SET_REGS_MATCHED ();
- break;
-
-
- /* Match any character except possibly a newline or a null. */
- case anychar:
- DEBUG_PRINT1 ("EXECUTING anychar.\n");
-
- PREFETCH ();
-
- if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
- || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
- goto fail;
-
- SET_REGS_MATCHED ();
- DEBUG_PRINT2 (" Matched `%d'.\n", *d);
- d++;
- break;
-
-
- case charset:
- case charset_not:
- {
- register unsigned char c;
- boolean not = (re_opcode_t) *(p - 1) == charset_not;
-
- DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : "");
-
- PREFETCH ();
- c = TRANSLATE (*d); /* The character to match. */
-
- /* Cast to `unsigned' instead of `unsigned char' in case the
- bit list is a full 32 bytes long. */
- if (c < (unsigned) (*p * BYTEWIDTH)
- && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
- not = !not;
-
- p += 1 + *p;
-
- if (!not) goto fail;
-
- SET_REGS_MATCHED ();
- d++;
- break;
- }
-
-
- /* The beginning of a group is represented by start_memory.
- The arguments are the register number in the next byte, and the
- number of groups inner to this one in the next. The text
- matched within the group is recorded (in the internal
- registers data structure) under the register number. */
- case start_memory:
- DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]);
-
- /* Find out if this group can match the empty string. */
- p1 = p; /* To send to group_match_null_string_p. */
-
- if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
- REG_MATCH_NULL_STRING_P (reg_info[*p])
- = group_match_null_string_p (&p1, pend, reg_info);
-
- /* Save the position in the string where we were the last time
- we were at this open-group operator in case the group is
- operated upon by a repetition operator, e.g., with `(a*)*b'
- against `ab'; then we want to ignore where we are now in
- the string in case this attempt to match fails. */
- old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
- ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
- : regstart[*p];
- DEBUG_PRINT2 (" old_regstart: %d\n",
- POINTER_TO_OFFSET (old_regstart[*p]));
-
- regstart[*p] = d;
- DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
-
- IS_ACTIVE (reg_info[*p]) = 1;
- MATCHED_SOMETHING (reg_info[*p]) = 0;
-
- /* This is the new highest active register. */
- highest_active_reg = *p;
-
- /* If nothing was active before, this is the new lowest active
- register. */
- if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
- lowest_active_reg = *p;
-
- /* Move past the register number and inner group count. */
- p += 2;
- break;
-
-
- /* The stop_memory opcode represents the end of a group. Its
- arguments are the same as start_memory's: the register
- number, and the number of inner groups. */
- case stop_memory:
- DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]);
-
- /* We need to save the string position the last time we were at
- this close-group operator in case the group is operated
- upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
- against `aba'; then we want to ignore where we are now in
- the string in case this attempt to match fails. */
- old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
- ? REG_UNSET (regend[*p]) ? d : regend[*p]
- : regend[*p];
- DEBUG_PRINT2 (" old_regend: %d\n",
- POINTER_TO_OFFSET (old_regend[*p]));
-
- regend[*p] = d;
- DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
-
- /* This register isn't active anymore. */
- IS_ACTIVE (reg_info[*p]) = 0;
-
- /* If this was the only register active, nothing is active
- anymore. */
- if (lowest_active_reg == highest_active_reg)
- {
- lowest_active_reg = NO_LOWEST_ACTIVE_REG;
- highest_active_reg = NO_HIGHEST_ACTIVE_REG;
- }
- else
- { /* We must scan for the new highest active register, since
- it isn't necessarily one less than now: consider
- (a(b)c(d(e)f)g). When group 3 ends, after the f), the
- new highest active register is 1. */
- unsigned char r = *p - 1;
- while (r > 0 && !IS_ACTIVE (reg_info[r]))
- r--;
-
- /* If we end up at register zero, that means that we saved
- the registers as the result of an `on_failure_jump', not
- a `start_memory', and we jumped to past the innermost
- `stop_memory'. For example, in ((.)*) we save
- registers 1 and 2 as a result of the *, but when we pop
- back to the second ), we are at the stop_memory 1.
- Thus, nothing is active. */
- if (r == 0)
- {
- lowest_active_reg = NO_LOWEST_ACTIVE_REG;
- highest_active_reg = NO_HIGHEST_ACTIVE_REG;
- }
- else
- highest_active_reg = r;
- }
-
- /* If just failed to match something this time around with a
- group that's operated on by a repetition operator, try to
- force exit from the ``loop'', and restore the register
- information for this group that we had before trying this
- last match. */
- if ((!MATCHED_SOMETHING (reg_info[*p])
- || (re_opcode_t) p[-3] == start_memory)
- && (p + 2) < pend)
- {
- boolean is_a_jump_n = false;
-
- p1 = p + 2;
- mcnt = 0;
- switch ((re_opcode_t) *p1++)
- {
- case jump_n:
- is_a_jump_n = true;
- case pop_failure_jump:
- case maybe_pop_jump:
- case jump:
- case dummy_failure_jump:
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- if (is_a_jump_n)
- p1 += 2;
- break;
-
- default:
- /* do nothing */ ;
- }
- p1 += mcnt;
-
- /* If the next operation is a jump backwards in the pattern
- to an on_failure_jump right before the start_memory
- corresponding to this stop_memory, exit from the loop
- by forcing a failure after pushing on the stack the
- on_failure_jump's jump in the pattern, and d. */
- if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
- && (re_opcode_t) p1[3] == start_memory && p1[4] == *p)
- {
- /* If this group ever matched anything, then restore
- what its registers were before trying this last
- failed match, e.g., with `(a*)*b' against `ab' for
- regstart[1], and, e.g., with `((a*)*(b*)*)*'
- against `aba' for regend[3].
-
- Also restore the registers for inner groups for,
- e.g., `((a*)(b*))*' against `aba' (register 3 would
- otherwise get trashed). */
-
- if (EVER_MATCHED_SOMETHING (reg_info[*p]))
- {
- unsigned r;
-
- EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
-
- /* Restore this and inner groups' (if any) registers. */
- for (r = *p; r < *p + *(p + 1); r++)
- {
- regstart[r] = old_regstart[r];
-
- /* xx why this test? */
- if ((int) old_regend[r] >= (int) regstart[r])
- regend[r] = old_regend[r];
- }
- }
- p1++;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
-
- goto fail;
- }
- }
-
- /* Move past the register number and the inner group count. */
- p += 2;
- break;
-
-
- /* \<digit> has been turned into a `duplicate' command which is
- followed by the numeric value of <digit> as the register number. */
- case duplicate:
- {
- register const char *d2, *dend2;
- int regno = *p++; /* Get which register to match against. */
- DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
-
- /* Can't back reference a group which we've never matched. */
- if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
- goto fail;
-
- /* Where in input to try to start matching. */
- d2 = regstart[regno];
-
- /* Where to stop matching; if both the place to start and
- the place to stop matching are in the same string, then
- set to the place to stop, otherwise, for now have to use
- the end of the first string. */
-
- dend2 = ((FIRST_STRING_P (regstart[regno])
- == FIRST_STRING_P (regend[regno]))
- ? regend[regno] : end_match_1);
- for (;;)
- {
- /* If necessary, advance to next segment in register
- contents. */
- while (d2 == dend2)
- {
- if (dend2 == end_match_2) break;
- if (dend2 == regend[regno]) break;
-
- /* End of string1 => advance to string2. */
- d2 = string2;
- dend2 = regend[regno];
- }
- /* At end of register contents => success */
- if (d2 == dend2) break;
-
- /* If necessary, advance to next segment in data. */
- PREFETCH ();
-
- /* How many characters left in this segment to match. */
- mcnt = dend - d;
-
- /* Want how many consecutive characters we can match in
- one shot, so, if necessary, adjust the count. */
- if (mcnt > dend2 - d2)
- mcnt = dend2 - d2;
-
- /* Compare that many; failure if mismatch, else move
- past them. */
- if (translate
- ? bcmp_translate (d, d2, mcnt, translate)
- : bcmp (d, d2, mcnt))
- goto fail;
- d += mcnt, d2 += mcnt;
- }
- }
- break;
-
-
- /* begline matches the empty string at the beginning of the string
- (unless `not_bol' is set in `bufp'), and, if
- `newline_anchor' is set, after newlines. */
- case begline:
- DEBUG_PRINT1 ("EXECUTING begline.\n");
-
- if (AT_STRINGS_BEG (d))
- {
- if (!bufp->not_bol) break;
- }
- else if (d[-1] == '\n' && bufp->newline_anchor)
- {
- break;
- }
- /* In all other cases, we fail. */
- goto fail;
-
-
- /* endline is the dual of begline. */
- case endline:
- DEBUG_PRINT1 ("EXECUTING endline.\n");
-
- if (AT_STRINGS_END (d))
- {
- if (!bufp->not_eol) break;
- }
-
- /* We have to ``prefetch'' the next character. */
- else if ((d == end1 ? *string2 : *d) == '\n'
- && bufp->newline_anchor)
- {
- break;
- }
- goto fail;
-
-
- /* Match at the very beginning of the data. */
- case begbuf:
- DEBUG_PRINT1 ("EXECUTING begbuf.\n");
- if (AT_STRINGS_BEG (d))
- break;
- goto fail;
-
-
- /* Match at the very end of the data. */
- case endbuf:
- DEBUG_PRINT1 ("EXECUTING endbuf.\n");
- if (AT_STRINGS_END (d))
- break;
- goto fail;
-
-
- /* on_failure_keep_string_jump is used to optimize `.*\n'. It
- pushes NULL as the value for the string on the stack. Then
- `pop_failure_point' will keep the current value for the
- string, instead of restoring it. To see why, consider
- matching `foo\nbar' against `.*\n'. The .* matches the foo;
- then the . fails against the \n. But the next thing we want
- to do is match the \n against the \n; if we restored the
- string value, we would be back at the foo.
-
- Because this is used only in specific cases, we don't need to
- check all the things that `on_failure_jump' does, to make
- sure the right things get saved on the stack. Hence we don't
- share its code. The only reason to push anything on the
- stack at all is that otherwise we would have to change
- `anychar's code to do something besides goto fail in this
- case; that seems worse than this. */
- case on_failure_keep_string_jump:
- DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
-
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
-
- PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
- break;
-
-
- /* Uses of on_failure_jump:
-
- Each alternative starts with an on_failure_jump that points
- to the beginning of the next alternative. Each alternative
- except the last ends with a jump that in effect jumps past
- the rest of the alternatives. (They really jump to the
- ending jump of the following alternative, because tensioning
- these jumps is a hassle.)
-
- Repeats start with an on_failure_jump that points past both
- the repetition text and either the following jump or
- pop_failure_jump back to this on_failure_jump. */
- case on_failure_jump:
- on_failure:
- DEBUG_PRINT1 ("EXECUTING on_failure_jump");
-
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
-
- /* If this on_failure_jump comes right before a group (i.e.,
- the original * applied to a group), save the information
- for that group and all inner ones, so that if we fail back
- to this point, the group's information will be correct.
- For example, in \(a*\)*\1, we need the preceding group,
- and in \(\(a*\)b*\)\2, we need the inner group. */
-
- /* We can't use `p' to check ahead because we push
- a failure point to `p + mcnt' after we do this. */
- p1 = p;
-
- /* We need to skip no_op's before we look for the
- start_memory in case this on_failure_jump is happening as
- the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
- against aba. */
- while (p1 < pend && (re_opcode_t) *p1 == no_op)
- p1++;
-
- if (p1 < pend && (re_opcode_t) *p1 == start_memory)
- {
- /* We have a new highest active register now. This will
- get reset at the start_memory we are about to get to,
- but we will have saved all the registers relevant to
- this repetition op, as described above. */
- highest_active_reg = *(p1 + 1) + *(p1 + 2);
- if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
- lowest_active_reg = *(p1 + 1);
- }
-
- DEBUG_PRINT1 (":\n");
- PUSH_FAILURE_POINT (p + mcnt, d, -2);
- break;
-
-
- /* A smart repeat ends with `maybe_pop_jump'.
- We change it to either `pop_failure_jump' or `jump'. */
- case maybe_pop_jump:
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
- {
- register unsigned char *p2 = p;
-
- /* Compare the beginning of the repeat with what in the
- pattern follows its end. If we can establish that there
- is nothing that they would both match, i.e., that we
- would have to backtrack because of (as in, e.g., `a*a')
- then we can change to pop_failure_jump, because we'll
- never have to backtrack.
-
- This is not true in the case of alternatives: in
- `(a|ab)*' we do need to backtrack to the `ab' alternative
- (e.g., if the string was `ab'). But instead of trying to
- detect that here, the alternative has put on a dummy
- failure point which is what we will end up popping. */
-
- /* Skip over open/close-group commands. */
- while (p2 + 2 < pend
- && ((re_opcode_t) *p2 == stop_memory
- || (re_opcode_t) *p2 == start_memory))
- p2 += 3; /* Skip over args, too. */
-
- /* If we're at the end of the pattern, we can change. */
- if (p2 == pend)
- {
- /* Consider what happens when matching ":\(.*\)"
- against ":/". I don't really understand this code
- yet. */
- p[-3] = (unsigned char) pop_failure_jump;
- DEBUG_PRINT1
- (" End of pattern: change to `pop_failure_jump'.\n");
- }
-
- else if ((re_opcode_t) *p2 == exactn
- || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
- {
- register unsigned char c
- = *p2 == (unsigned char) endline ? '\n' : p2[2];
- p1 = p + mcnt;
-
- /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
- to the `maybe_finalize_jump' of this case. Examine what
- follows. */
- if ((re_opcode_t) p1[3] == exactn && p1[5] != c)
- {
- p[-3] = (unsigned char) pop_failure_jump;
- DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
- c, p1[5]);
- }
-
- else if ((re_opcode_t) p1[3] == charset
- || (re_opcode_t) p1[3] == charset_not)
- {
- int not = (re_opcode_t) p1[3] == charset_not;
-
- if (c < (unsigned char) (p1[4] * BYTEWIDTH)
- && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
- not = !not;
-
- /* `not' is equal to 1 if c would match, which means
- that we can't change to pop_failure_jump. */
- if (!not)
- {
- p[-3] = (unsigned char) pop_failure_jump;
- DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
- }
- }
- }
- }
- p -= 2; /* Point at relative address again. */
- if ((re_opcode_t) p[-1] != pop_failure_jump)
- {
- p[-1] = (unsigned char) jump;
- DEBUG_PRINT1 (" Match => jump.\n");
- goto unconditional_jump;
- }
- /* Note fall through. */
-
-
- /* The end of a simple repeat has a pop_failure_jump back to
- its matching on_failure_jump, where the latter will push a
- failure point. The pop_failure_jump takes off failure
- points put on by this pop_failure_jump's matching
- on_failure_jump; we got through the pattern to here from the
- matching on_failure_jump, so didn't fail. */
- case pop_failure_jump:
- {
- /* We need to pass separate storage for the lowest and
- highest registers, even though we don't care about the
- actual values. Otherwise, we will restore only one
- register from the stack, since lowest will == highest in
- `pop_failure_point'. */
- unsigned dummy_low_reg, dummy_high_reg;
- unsigned char *pdummy;
- const char *sdummy;
-
- DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
- POP_FAILURE_POINT (sdummy, pdummy,
- dummy_low_reg, dummy_high_reg,
- reg_dummy, reg_dummy, reg_info_dummy);
- }
- /* Note fall through. */
-
-
- /* Unconditionally jump (without popping any failure points). */
- case jump:
- unconditional_jump:
- EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
- DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
- p += mcnt; /* Do the jump. */
- DEBUG_PRINT2 ("(to 0x%x).\n", p);
- break;
-
-
- /* We need this opcode so we can detect where alternatives end
- in `group_match_null_string_p' et al. */
- case jump_past_alt:
- DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
- goto unconditional_jump;
-
-
- /* Normally, the on_failure_jump pushes a failure point, which
- then gets popped at pop_failure_jump. We will end up at
- pop_failure_jump, also, and with a pattern of, say, `a+', we
- are skipping over the on_failure_jump, so we have to push
- something meaningless for pop_failure_jump to pop. */
- case dummy_failure_jump:
- DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
- /* It doesn't matter what we push for the string here. What
- the code at `fail' tests is the value for the pattern. */
- PUSH_FAILURE_POINT (0, 0, -2);
- goto unconditional_jump;
-
-
- /* At the end of an alternative, we need to push a dummy failure
- point in case we are followed by a `pop_failure_jump', because
- we don't want the failure point for the alternative to be
- popped. For example, matching `(a|ab)*' against `aab'
- requires that we match the `ab' alternative. */
- case push_dummy_failure:
- DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
- /* See comments just above at `dummy_failure_jump' about the
- two zeroes. */
- PUSH_FAILURE_POINT (0, 0, -2);
- break;
-
- /* Have to succeed matching what follows at least n times.
- After that, handle like `on_failure_jump'. */
- case succeed_n:
- EXTRACT_NUMBER (mcnt, p + 2);
- DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
-
- assert (mcnt >= 0);
- /* Originally, this is how many times we HAVE to succeed. */
- if (mcnt > 0)
- {
- mcnt--;
- p += 2;
- STORE_NUMBER_AND_INCR (p, mcnt);
- DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p, mcnt);
- }
- else if (mcnt == 0)
- {
- DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2);
- p[2] = (unsigned char) no_op;
- p[3] = (unsigned char) no_op;
- goto on_failure;
- }
- break;
-
- case jump_n:
- EXTRACT_NUMBER (mcnt, p + 2);
- DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
-
- /* Originally, this is how many times we CAN jump. */
- if (mcnt)
- {
- mcnt--;
- STORE_NUMBER (p + 2, mcnt);
- goto unconditional_jump;
- }
- /* If don't have to jump any more, skip over the rest of command. */
- else
- p += 4;
- break;
-
- case set_number_at:
- {
- DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
-
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- p1 = p + mcnt;
- EXTRACT_NUMBER_AND_INCR (mcnt, p);
- DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt);
- STORE_NUMBER (p1, mcnt);
- break;
- }
-
- case wordbound:
- DEBUG_PRINT1 ("EXECUTING wordbound.\n");
- if (AT_WORD_BOUNDARY (d))
- break;
- goto fail;
-
- case notwordbound:
- DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
- if (AT_WORD_BOUNDARY (d))
- goto fail;
- break;
-
- case wordbeg:
- DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
- if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
- break;
- goto fail;
-
- case wordend:
- DEBUG_PRINT1 ("EXECUTING wordend.\n");
- if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
- && (!WORDCHAR_P (d) || AT_STRINGS_END (d)))
- break;
- goto fail;
-
-#ifdef emacs
-#ifdef emacs19
- case before_dot:
- DEBUG_PRINT1 ("EXECUTING before_dot.\n");
- if (PTR_CHAR_POS ((unsigned char *) d) >= point)
- goto fail;
- break;
-
- case at_dot:
- DEBUG_PRINT1 ("EXECUTING at_dot.\n");
- if (PTR_CHAR_POS ((unsigned char *) d) != point)
- goto fail;
- break;
-
- case after_dot:
- DEBUG_PRINT1 ("EXECUTING after_dot.\n");
- if (PTR_CHAR_POS ((unsigned char *) d) <= point)
- goto fail;
- break;
-#else /* not emacs19 */
- case at_dot:
- DEBUG_PRINT1 ("EXECUTING at_dot.\n");
- if (PTR_CHAR_POS ((unsigned char *) d) + 1 != point)
- goto fail;
- break;
-#endif /* not emacs19 */
-
- case syntaxspec:
- DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
- mcnt = *p++;
- goto matchsyntax;
-
- case wordchar:
- DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
- mcnt = (int) Sword;
- matchsyntax:
- PREFETCH ();
- if (SYNTAX (*d++) != (enum syntaxcode) mcnt)
- goto fail;
- SET_REGS_MATCHED ();
- break;
-
- case notsyntaxspec:
- DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
- mcnt = *p++;
- goto matchnotsyntax;
-
- case notwordchar:
- DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
- mcnt = (int) Sword;
- matchnotsyntax:
- PREFETCH ();
- if (SYNTAX (*d++) == (enum syntaxcode) mcnt)
- goto fail;
- SET_REGS_MATCHED ();
- break;
-
-#else /* not emacs */
- case wordchar:
- DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
- PREFETCH ();
- if (!WORDCHAR_P (d))
- goto fail;
- SET_REGS_MATCHED ();
- d++;
- break;
-
- case notwordchar:
- DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
- PREFETCH ();
- if (WORDCHAR_P (d))
- goto fail;
- SET_REGS_MATCHED ();
- d++;
- break;
-#endif /* not emacs */
-
- default:
- abort ();
- }
- continue; /* Successfully executed one pattern command; keep going. */
-
-
- /* We goto here if a matching operation fails. */
- fail:
- if (!FAIL_STACK_EMPTY ())
- { /* A restart point is known. Restore to that state. */
- DEBUG_PRINT1 ("\nFAIL:\n");
- POP_FAILURE_POINT (d, p,
- lowest_active_reg, highest_active_reg,
- regstart, regend, reg_info);
-
- /* If this failure point is a dummy, try the next one. */
- if (!p)
- goto fail;
-
- /* If we failed to the end of the pattern, don't examine *p. */
- assert (p <= pend);
- if (p < pend)
- {
- boolean is_a_jump_n = false;
-
- /* If failed to a backwards jump that's part of a repetition
- loop, need to pop this failure point and use the next one. */
- switch ((re_opcode_t) *p)
- {
- case jump_n:
- is_a_jump_n = true;
- case maybe_pop_jump:
- case pop_failure_jump:
- case jump:
- p1 = p + 1;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- p1 += mcnt;
-
- if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
- || (!is_a_jump_n
- && (re_opcode_t) *p1 == on_failure_jump))
- goto fail;
- break;
- default:
- /* do nothing */ ;
- }
- }
-
- if (d >= string1 && d <= end1)
- dend = end_match_1;
- }
- else
- break; /* Matching at this starting point really fails. */
- } /* for (;;) */
-
- if (best_regs_set)
- goto restore_best_regs;
-
- FREE_VARIABLES ();
-
- return -1; /* Failure to match. */
-} /* re_match_2 */
-
-/* Subroutine definitions for re_match_2. */
-
-
-/* We are passed P pointing to a register number after a start_memory.
-
- Return true if the pattern up to the corresponding stop_memory can
- match the empty string, and false otherwise.
-
- If we find the matching stop_memory, sets P to point to one past its number.
- Otherwise, sets P to an undefined byte less than or equal to END.
-
- We don't handle duplicates properly (yet). */
-
-static boolean
-group_match_null_string_p (p, end, reg_info)
- unsigned char **p, *end;
- register_info_type *reg_info;
-{
- int mcnt;
- /* Point to after the args to the start_memory. */
- unsigned char *p1 = *p + 2;
-
- while (p1 < end)
- {
- /* Skip over opcodes that can match nothing, and return true or
- false, as appropriate, when we get to one that can't, or to the
- matching stop_memory. */
-
- switch ((re_opcode_t) *p1)
- {
- /* Could be either a loop or a series of alternatives. */
- case on_failure_jump:
- p1++;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
-
- /* If the next operation is not a jump backwards in the
- pattern. */
-
- if (mcnt >= 0)
- {
- /* Go through the on_failure_jumps of the alternatives,
- seeing if any of the alternatives cannot match nothing.
- The last alternative starts with only a jump,
- whereas the rest start with on_failure_jump and end
- with a jump, e.g., here is the pattern for `a|b|c':
-
- /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
- /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
- /exactn/1/c
-
- So, we have to first go through the first (n-1)
- alternatives and then deal with the last one separately. */
-
-
- /* Deal with the first (n-1) alternatives, which start
- with an on_failure_jump (see above) that jumps to right
- past a jump_past_alt. */
-
- while ((re_opcode_t) p1[mcnt-3] == jump_past_alt)
- {
- /* `mcnt' holds how many bytes long the alternative
- is, including the ending `jump_past_alt' and
- its number. */
-
- if (!alt_match_null_string_p (p1, p1 + mcnt - 3,
- reg_info))
- return false;
-
- /* Move to right after this alternative, including the
- jump_past_alt. */
- p1 += mcnt;
-
- /* Break if it's the beginning of an n-th alternative
- that doesn't begin with an on_failure_jump. */
- if ((re_opcode_t) *p1 != on_failure_jump)
- break;
-
- /* Still have to check that it's not an n-th
- alternative that starts with an on_failure_jump. */
- p1++;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- if ((re_opcode_t) p1[mcnt-3] != jump_past_alt)
- {
- /* Get to the beginning of the n-th alternative. */
- p1 -= 3;
- break;
- }
- }
-
- /* Deal with the last alternative: go back and get number
- of the `jump_past_alt' just before it. `mcnt' contains
- the length of the alternative. */
- EXTRACT_NUMBER (mcnt, p1 - 2);
-
- if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info))
- return false;
-
- p1 += mcnt; /* Get past the n-th alternative. */
- } /* if mcnt > 0 */
- break;
-
-
- case stop_memory:
- assert (p1[1] == **p);
- *p = p1 + 2;
- return true;
-
-
- default:
- if (!common_op_match_null_string_p (&p1, end, reg_info))
- return false;
- }
- } /* while p1 < end */
-
- return false;
-} /* group_match_null_string_p */
-
-
-/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
- It expects P to be the first byte of a single alternative and END one
- byte past the last. The alternative can contain groups. */
-
-static boolean
-alt_match_null_string_p (p, end, reg_info)
- unsigned char *p, *end;
- register_info_type *reg_info;
-{
- int mcnt;
- unsigned char *p1 = p;
-
- while (p1 < end)
- {
- /* Skip over opcodes that can match nothing, and break when we get
- to one that can't. */
-
- switch ((re_opcode_t) *p1)
- {
- /* It's a loop. */
- case on_failure_jump:
- p1++;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- p1 += mcnt;
- break;
-
- default:
- if (!common_op_match_null_string_p (&p1, end, reg_info))
- return false;
- }
- } /* while p1 < end */
-
- return true;
-} /* alt_match_null_string_p */
-
-
-/* Deals with the ops common to group_match_null_string_p and
- alt_match_null_string_p.
-
- Sets P to one after the op and its arguments, if any. */
-
-static boolean
-common_op_match_null_string_p (p, end, reg_info)
- unsigned char **p, *end;
- register_info_type *reg_info;
-{
- int mcnt;
- boolean ret;
- int reg_no;
- unsigned char *p1 = *p;
-
- switch ((re_opcode_t) *p1++)
- {
- case no_op:
- case begline:
- case endline:
- case begbuf:
- case endbuf:
- case wordbeg:
- case wordend:
- case wordbound:
- case notwordbound:
-#ifdef emacs
- case before_dot:
- case at_dot:
- case after_dot:
-#endif
- break;
-
- case start_memory:
- reg_no = *p1;
- assert (reg_no > 0 && reg_no <= MAX_REGNUM);
- ret = group_match_null_string_p (&p1, end, reg_info);
-
- /* Have to set this here in case we're checking a group which
- contains a group and a back reference to it. */
-
- if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
- REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
-
- if (!ret)
- return false;
- break;
-
- /* If this is an optimized succeed_n for zero times, make the jump. */
- case jump:
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- if (mcnt >= 0)
- p1 += mcnt;
- else
- return false;
- break;
-
- case succeed_n:
- /* Get to the number of times to succeed. */
- p1 += 2;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
-
- if (mcnt == 0)
- {
- p1 -= 4;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- p1 += mcnt;
- }
- else
- return false;
- break;
-
- case duplicate:
- if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
- return false;
- break;
-
- case set_number_at:
- p1 += 4;
-
- default:
- /* All other opcodes mean we cannot match the empty string. */
- return false;
- }
-
- *p = p1;
- return true;
-} /* common_op_match_null_string_p */
-
-
-/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
- bytes; nonzero otherwise. */
-
-static int
-bcmp_translate (s1, s2, len, translate)
- unsigned char *s1, *s2;
- register int len;
- char *translate;
-{
- register unsigned char *p1 = s1, *p2 = s2;
- while (len)
- {
- if (translate[*p1++] != translate[*p2++]) return 1;
- len--;
- }
- return 0;
-}
-
-/* Entry points for GNU code. */
-
-/* re_compile_pattern is the GNU regular expression compiler: it
- compiles PATTERN (of length SIZE) and puts the result in BUFP.
- Returns 0 if the pattern was valid, otherwise an error string.
-
- Assumes the `allocated' (and perhaps `buffer') and `translate' fields
- are set in BUFP on entry.
-
- We call regex_compile to do the actual compilation. */
-
-const char *
-re_compile_pattern (pattern, length, bufp)
- const char *pattern;
- int length;
- struct re_pattern_buffer *bufp;
-{
- reg_errcode_t ret;
-
- /* GNU code is written to assume at least RE_NREGS registers will be set
- (and at least one extra will be -1). */
- bufp->regs_allocated = REGS_UNALLOCATED;
-
- /* And GNU code determines whether or not to get register information
- by passing null for the REGS argument to re_match, etc., not by
- setting no_sub. */
- bufp->no_sub = 0;
-
- /* Match anchors at newline. */
- bufp->newline_anchor = 1;
-
- ret = regex_compile (pattern, length, re_syntax_options, bufp);
-
- return re_error_msg[(int) ret];
-}
-
-/* Entry points compatible with 4.2 BSD regex library. We don't define
- them if this is an Emacs or POSIX compilation. */
-
-#if !defined (emacs) && !defined (_POSIX_SOURCE)
-
-/* BSD has one and only one pattern buffer. */
-static struct re_pattern_buffer re_comp_buf;
-
-char *
-re_comp (s)
- const char *s;
-{
- reg_errcode_t ret;
-
- if (!s)
- {
- if (!re_comp_buf.buffer)
- return "No previous regular expression";
- return 0;
- }
-
- if (!re_comp_buf.buffer)
- {
- re_comp_buf.buffer = (unsigned char *) malloc (200);
- if (re_comp_buf.buffer == NULL)
- return "Memory exhausted";
- re_comp_buf.allocated = 200;
-
- re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
- if (re_comp_buf.fastmap == NULL)
- return "Memory exhausted";
- }
-
- /* Since `re_exec' always passes NULL for the `regs' argument, we
- don't need to initialize the pattern buffer fields which affect it. */
-
- /* Match anchors at newlines. */
- re_comp_buf.newline_anchor = 1;
-
- ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
-
- /* Yes, we're discarding `const' here. */
- return (char *) re_error_msg[(int) ret];
-}
-
-
-int
-re_exec (s)
- const char *s;
-{
- const int len = strlen (s);
- return
- 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
-}
-#endif /* not emacs and not _POSIX_SOURCE */
-
-/* POSIX.2 functions. Don't define these for Emacs. */
-
-#ifndef emacs
-
-/* regcomp takes a regular expression as a string and compiles it.
-
- PREG is a regex_t *. We do not expect any fields to be initialized,
- since POSIX says we shouldn't. Thus, we set
-
- `buffer' to the compiled pattern;
- `used' to the length of the compiled pattern;
- `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
- REG_EXTENDED bit in CFLAGS is set; otherwise, to
- RE_SYNTAX_POSIX_BASIC;
- `newline_anchor' to REG_NEWLINE being set in CFLAGS;
- `fastmap' and `fastmap_accurate' to zero;
- `re_nsub' to the number of subexpressions in PATTERN.
-
- PATTERN is the address of the pattern string.
-
- CFLAGS is a series of bits which affect compilation.
-
- If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
- use POSIX basic syntax.
-
- If REG_NEWLINE is set, then . and [^...] don't match newline.
- Also, regexec will try a match beginning after every newline.
-
- If REG_ICASE is set, then we considers upper- and lowercase
- versions of letters to be equivalent when matching.
-
- If REG_NOSUB is set, then when PREG is passed to regexec, that
- routine will report only success or failure, and nothing about the
- registers.
-
- It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for
- the return codes and their meanings.) */
-
-int
-regcomp (preg, pattern, cflags)
- regex_t *preg;
- const char *pattern;
- int cflags;
-{
- reg_errcode_t ret;
- unsigned syntax
- = (cflags & REG_EXTENDED) ?
- RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
-
- /* regex_compile will allocate the space for the compiled pattern. */
- preg->buffer = 0;
- preg->allocated = 0;
-
- /* Don't bother to use a fastmap when searching. This simplifies the
- REG_NEWLINE case: if we used a fastmap, we'd have to put all the
- characters after newlines into the fastmap. This way, we just try
- every character. */
- preg->fastmap = 0;
-
- if (cflags & REG_ICASE)
- {
- unsigned i;
-
- preg->translate = (char *) malloc (CHAR_SET_SIZE);
- if (preg->translate == NULL)
- return (int) REG_ESPACE;
-
- /* Map uppercase characters to corresponding lowercase ones. */
- for (i = 0; i < CHAR_SET_SIZE; i++)
- preg->translate[i] = ISUPPER (i) ? tolower (i) : i;
- }
- else
- preg->translate = NULL;
-
- /* If REG_NEWLINE is set, newlines are treated differently. */
- if (cflags & REG_NEWLINE)
- { /* REG_NEWLINE implies neither . nor [^...] match newline. */
- syntax &= ~RE_DOT_NEWLINE;
- syntax |= RE_HAT_LISTS_NOT_NEWLINE;
- /* It also changes the matching behavior. */
- preg->newline_anchor = 1;
- }
- else
- preg->newline_anchor = 0;
-
- preg->no_sub = !!(cflags & REG_NOSUB);
-
- /* POSIX says a null character in the pattern terminates it, so we
- can use strlen here in compiling the pattern. */
- ret = regex_compile (pattern, strlen (pattern), syntax, preg);
-
- /* POSIX doesn't distinguish between an unmatched open-group and an
- unmatched close-group: both are REG_EPAREN. */
- if (ret == REG_ERPAREN) ret = REG_EPAREN;
-
- return (int) ret;
-}
-
-
-/* regexec searches for a given pattern, specified by PREG, in the
- string STRING.
-
- If NMATCH is zero or REG_NOSUB was set in the cflags argument to
- `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at
- least NMATCH elements, and we set them to the offsets of the
- corresponding matched substrings.
-
- EFLAGS specifies `execution flags' which affect matching: if
- REG_NOTBOL is set, then ^ does not match at the beginning of the
- string; if REG_NOTEOL is set, then $ does not match at the end.
-
- We return 0 if we find a match and REG_NOMATCH if not. */
-
-int
-regexec (preg, string, nmatch, pmatch, eflags)
- const regex_t *preg;
- const char *string;
- size_t nmatch;
- regmatch_t pmatch[];
- int eflags;
-{
- int ret;
- struct re_registers regs;
- regex_t private_preg;
- int len = strlen (string);
- boolean want_reg_info = !preg->no_sub && nmatch > 0;
-
- private_preg = *preg;
-
- private_preg.not_bol = !!(eflags & REG_NOTBOL);
- private_preg.not_eol = !!(eflags & REG_NOTEOL);
-
- /* The user has told us exactly how many registers to return
- information about, via `nmatch'. We have to pass that on to the
- matching routines. */
- private_preg.regs_allocated = REGS_FIXED;
-
- if (want_reg_info)
- {
- regs.num_regs = nmatch;
- regs.start = TALLOC (nmatch, regoff_t);
- regs.end = TALLOC (nmatch, regoff_t);
- if (regs.start == NULL || regs.end == NULL)
- return (int) REG_NOMATCH;
- }
-
- /* Perform the searching operation. */
- ret = re_search (&private_preg, string, len,
- /* start: */ 0, /* range: */ len,
- want_reg_info ? &regs : (struct re_registers *) 0);
-
- /* Copy the register information to the POSIX structure. */
- if (want_reg_info)
- {
- if (ret >= 0)
- {
- unsigned r;
-
- for (r = 0; r < nmatch; r++)
- {
- pmatch[r].rm_so = regs.start[r];
- pmatch[r].rm_eo = regs.end[r];
- }
- }
-
- /* If we needed the temporary register info, free the space now. */
- free (regs.start);
- free (regs.end);
- }
-
- /* We want zero return to mean success, unlike `re_search'. */
- return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
-}
-
-
-/* Returns a message corresponding to an error code, ERRCODE, returned
- from either regcomp or regexec. We don't use PREG here. */
-
-size_t
-regerror (errcode, preg, errbuf, errbuf_size)
- int errcode;
- const regex_t *preg;
- char *errbuf;
- size_t errbuf_size;
-{
- const char *msg;
- size_t msg_size;
-
- if (errcode < 0
- || errcode >= (sizeof (re_error_msg) / sizeof (re_error_msg[0])))
- /* Only error codes returned by the rest of the code should be passed
- to this routine. If we are given anything else, or if other regex
- code generates an invalid error code, then the program has a bug.
- Dump core so we can fix it. */
- abort ();
-
- msg = re_error_msg[errcode];
-
- /* POSIX doesn't require that we do anything in this case, but why
- not be nice. */
- if (! msg)
- msg = "Success";
-
- msg_size = strlen (msg) + 1; /* Includes the null. */
-
- if (errbuf_size != 0)
- {
- if (msg_size > errbuf_size)
- {
- strncpy (errbuf, msg, errbuf_size - 1);
- errbuf[errbuf_size - 1] = 0;
- }
- else
- strcpy (errbuf, msg);
- }
-
- return msg_size;
-}
-
-
-/* Free dynamically allocated space used by PREG. */
-
-void
-regfree (preg)
- regex_t *preg;
-{
- if (preg->buffer != NULL)
- free (preg->buffer);
- preg->buffer = NULL;
-
- preg->allocated = 0;
- preg->used = 0;
-
- if (preg->fastmap != NULL)
- free (preg->fastmap);
- preg->fastmap = NULL;
- preg->fastmap_accurate = 0;
-
- if (preg->translate != NULL)
- free (preg->translate);
- preg->translate = NULL;
-}
-
-#endif /* not emacs */
-
-/*
-Local variables:
-make-backup-files: t
-version-control: t
-trim-versions-without-asking: nil
-End:
-*/
+/* Extended regular expression matching and search library,
+ version 0.12.
+ (Implements POSIX draft P10003.2/D11.2, except for
+ internationalization features.)
+
+ Copyright (C) 1993 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* AIX requires this to be the first thing in the file. */
+#if defined (_AIX) && !defined (REGEX_MALLOC)
+ #pragma alloca
+#endif
+
+#define _GNU_SOURCE
+
+/* We need this for `regex.h', and perhaps for the Emacs include files. */
+#include <sys/types.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* The `emacs' switch turns on certain matching commands
+ that make sense only in Emacs. */
+#ifdef emacs
+
+#include "lisp.h"
+#include "buffer.h"
+#include "syntax.h"
+
+/* Emacs uses `NULL' as a predicate. */
+#undef NULL
+
+#else /* not emacs */
+
+/* We used to test for `BSTRING' here, but only GCC and Emacs define
+ `BSTRING', as far as I know, and neither of them use this code. */
+#if HAVE_STRING_H || STDC_HEADERS
+#include <string.h>
+#ifndef bcmp
+#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
+#endif
+#ifndef bcopy
+#define bcopy(s, d, n) memcpy ((d), (s), (n))
+#endif
+#ifndef bzero
+#define bzero(s, n) memset ((s), 0, (n))
+#endif
+#else
+#include <strings.h>
+#endif
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+char *malloc ();
+char *realloc ();
+#endif
+
+
+/* Define the syntax stuff for \<, \>, etc. */
+
+/* This must be nonzero for the wordchar and notwordchar pattern
+ commands in re_match_2. */
+#ifndef Sword
+#define Sword 1
+#endif
+
+#ifdef SYNTAX_TABLE
+
+extern char *re_syntax_table;
+
+#else /* not SYNTAX_TABLE */
+
+/* How many characters in the character set. */
+#define CHAR_SET_SIZE 256
+
+static char re_syntax_table[CHAR_SET_SIZE];
+
+static void
+init_syntax_once ()
+{
+ register int c;
+ static int done = 0;
+
+ if (done)
+ return;
+
+ bzero (re_syntax_table, sizeof re_syntax_table);
+
+ for (c = 'a'; c <= 'z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = 'A'; c <= 'Z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = '0'; c <= '9'; c++)
+ re_syntax_table[c] = Sword;
+
+ re_syntax_table['_'] = Sword;
+
+ done = 1;
+}
+
+#endif /* not SYNTAX_TABLE */
+
+#define SYNTAX(c) re_syntax_table[c]
+
+#endif /* not emacs */
+
+/* Get the interface, including the syntax bits. */
+#include "regex.h"
+
+/* isalpha etc. are used for the character classes. */
+#include <ctype.h>
+
+#ifndef isascii
+#define isascii(c) 1
+#endif
+
+#ifdef isblank
+#define ISBLANK(c) (isascii (c) && isblank (c))
+#else
+#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+#endif
+#ifdef isgraph
+#define ISGRAPH(c) (isascii (c) && isgraph (c))
+#else
+#define ISGRAPH(c) (isascii (c) && isprint (c) && !isspace (c))
+#endif
+
+#define ISPRINT(c) (isascii (c) && isprint (c))
+#define ISDIGIT(c) (isascii (c) && isdigit (c))
+#define ISALNUM(c) (isascii (c) && isalnum (c))
+#define ISALPHA(c) (isascii (c) && isalpha (c))
+#define ISCNTRL(c) (isascii (c) && iscntrl (c))
+#define ISLOWER(c) (isascii (c) && islower (c))
+#define ISPUNCT(c) (isascii (c) && ispunct (c))
+#define ISSPACE(c) (isascii (c) && isspace (c))
+#define ISUPPER(c) (isascii (c) && isupper (c))
+#define ISXDIGIT(c) (isascii (c) && isxdigit (c))
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* We remove any previous definition of `SIGN_EXTEND_CHAR',
+ since ours (we hope) works properly with all combinations of
+ machines, compilers, `char' and `unsigned char' argument types.
+ (Per Bothner suggested the basic approach.) */
+#undef SIGN_EXTEND_CHAR
+#if __STDC__
+#define SIGN_EXTEND_CHAR(c) ((signed char) (c))
+#else /* not __STDC__ */
+/* As in Harbison and Steele. */
+#define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
+#endif
+
+/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we
+ use `alloca' instead of `malloc'. This is because using malloc in
+ re_search* or re_match* could cause memory leaks when C-g is used in
+ Emacs; also, malloc is slower and causes storage fragmentation. On
+ the other hand, malloc is more portable, and easier to debug.
+
+ Because we sometimes use alloca, some routines have to be macros,
+ not functions -- `alloca'-allocated space disappears at the end of the
+ function it is called in. */
+
+#ifdef REGEX_MALLOC
+
+#define REGEX_ALLOCATE malloc
+#define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
+
+#else /* not REGEX_MALLOC */
+
+/* Emacs already defines alloca, sometimes. */
+#ifndef alloca
+
+/* Make alloca work the best possible way. */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not __GNUC__ */
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#else /* not __GNUC__ or HAVE_ALLOCA_H */
+#ifndef _AIX /* Already did AIX, up at the top. */
+char *alloca ();
+#endif /* not _AIX */
+#endif /* not HAVE_ALLOCA_H */
+#endif /* not __GNUC__ */
+
+#endif /* not alloca */
+
+#define REGEX_ALLOCATE alloca
+
+/* Assumes a `char *destination' variable. */
+#define REGEX_REALLOCATE(source, osize, nsize) \
+ (destination = (char *) alloca (nsize), \
+ bcopy (source, destination, osize), \
+ destination)
+
+#endif /* not REGEX_MALLOC */
+
+
+/* True if `size1' is non-NULL and PTR is pointing anywhere inside
+ `string1' or just past its end. This works if PTR is NULL, which is
+ a good thing. */
+#define FIRST_STRING_P(ptr) \
+ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
+
+/* (Re)Allocate N items of type T using malloc, or fail. */
+#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
+#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
+#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
+
+#define BYTEWIDTH 8 /* In bits. */
+
+#define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+typedef char boolean;
+#define false 0
+#define true 1
+
+/* These are the command codes that appear in compiled regular
+ expressions. Some opcodes are followed by argument bytes. A
+ command code can specify any interpretation whatsoever for its
+ arguments. Zero bytes may appear in the compiled regular expression.
+
+ The value of `exactn' is needed in search.c (search_buffer) in Emacs.
+ So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of
+ `exactn' we use here must also be 1. */
+
+typedef enum
+{
+ no_op = 0,
+
+ /* Followed by one byte giving n, then by n literal bytes. */
+ exactn = 1,
+
+ /* Matches any (more or less) character. */
+ anychar,
+
+ /* Matches any one char belonging to specified set. First
+ following byte is number of bitmap bytes. Then come bytes
+ for a bitmap saying which chars are in. Bits in each byte
+ are ordered low-bit-first. A character is in the set if its
+ bit is 1. A character too large to have a bit in the map is
+ automatically not in the set. */
+ charset,
+
+ /* Same parameters as charset, but match any character that is
+ not one of those specified. */
+ charset_not,
+
+ /* Start remembering the text that is matched, for storing in a
+ register. Followed by one byte with the register number, in
+ the range 0 to one less than the pattern buffer's re_nsub
+ field. Then followed by one byte with the number of groups
+ inner to this one. (This last has to be part of the
+ start_memory only because we need it in the on_failure_jump
+ of re_match_2.) */
+ start_memory,
+
+ /* Stop remembering the text that is matched and store it in a
+ memory register. Followed by one byte with the register
+ number, in the range 0 to one less than `re_nsub' in the
+ pattern buffer, and one byte with the number of inner groups,
+ just like `start_memory'. (We need the number of inner
+ groups here because we don't have any easy way of finding the
+ corresponding start_memory when we're at a stop_memory.) */
+ stop_memory,
+
+ /* Match a duplicate of something remembered. Followed by one
+ byte containing the register number. */
+ duplicate,
+
+ /* Fail unless at beginning of line. */
+ begline,
+
+ /* Fail unless at end of line. */
+ endline,
+
+ /* Succeeds if at beginning of buffer (if emacs) or at beginning
+ of string to be matched (if not). */
+ begbuf,
+
+ /* Analogously, for end of buffer/string. */
+ endbuf,
+
+ /* Followed by two byte relative address to which to jump. */
+ jump,
+
+ /* Same as jump, but marks the end of an alternative. */
+ jump_past_alt,
+
+ /* Followed by two-byte relative address of place to resume at
+ in case of failure. */
+ on_failure_jump,
+
+ /* Like on_failure_jump, but pushes a placeholder instead of the
+ current string position when executed. */
+ on_failure_keep_string_jump,
+
+ /* Throw away latest failure point and then jump to following
+ two-byte relative address. */
+ pop_failure_jump,
+
+ /* Change to pop_failure_jump if know won't have to backtrack to
+ match; otherwise change to jump. This is used to jump
+ back to the beginning of a repeat. If what follows this jump
+ clearly won't match what the repeat does, such that we can be
+ sure that there is no use backtracking out of repetitions
+ already matched, then we change it to a pop_failure_jump.
+ Followed by two-byte address. */
+ maybe_pop_jump,
+
+ /* Jump to following two-byte address, and push a dummy failure
+ point. This failure point will be thrown away if an attempt
+ is made to use it for a failure. A `+' construct makes this
+ before the first repeat. Also used as an intermediary kind
+ of jump when compiling an alternative. */
+ dummy_failure_jump,
+
+ /* Push a dummy failure point and continue. Used at the end of
+ alternatives. */
+ push_dummy_failure,
+
+ /* Followed by two-byte relative address and two-byte number n.
+ After matching N times, jump to the address upon failure. */
+ succeed_n,
+
+ /* Followed by two-byte relative address, and two-byte number n.
+ Jump to the address N times, then fail. */
+ jump_n,
+
+ /* Set the following two-byte relative address to the
+ subsequent two-byte number. The address *includes* the two
+ bytes of number. */
+ set_number_at,
+
+ wordchar, /* Matches any word-constituent character. */
+ notwordchar, /* Matches any char that is not a word-constituent. */
+
+ wordbeg, /* Succeeds if at word beginning. */
+ wordend, /* Succeeds if at word end. */
+
+ wordbound, /* Succeeds if at a word boundary. */
+ notwordbound /* Succeeds if not at a word boundary. */
+
+#ifdef emacs
+ ,before_dot, /* Succeeds if before point. */
+ at_dot, /* Succeeds if at point. */
+ after_dot, /* Succeeds if after point. */
+
+ /* Matches any character whose syntax is specified. Followed by
+ a byte which contains a syntax code, e.g., Sword. */
+ syntaxspec,
+
+ /* Matches any character whose syntax is not that specified. */
+ notsyntaxspec
+#endif /* emacs */
+} re_opcode_t;
+
+/* Common operations on the compiled pattern. */
+
+/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
+
+#define STORE_NUMBER(destination, number) \
+ do { \
+ (destination)[0] = (number) & 0377; \
+ (destination)[1] = (number) >> 8; \
+ } while (0)
+
+/* Same as STORE_NUMBER, except increment DESTINATION to
+ the byte after where the number is stored. Therefore, DESTINATION
+ must be an lvalue. */
+
+#define STORE_NUMBER_AND_INCR(destination, number) \
+ do { \
+ STORE_NUMBER (destination, number); \
+ (destination) += 2; \
+ } while (0)
+
+/* Put into DESTINATION a number stored in two contiguous bytes starting
+ at SOURCE. */
+
+#define EXTRACT_NUMBER(destination, source) \
+ do { \
+ (destination) = *(source) & 0377; \
+ (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \
+ } while (0)
+
+#ifdef DEBUG
+static void
+extract_number (dest, source)
+ int *dest;
+ unsigned char *source;
+{
+ int temp = SIGN_EXTEND_CHAR (*(source + 1));
+ *dest = *source & 0377;
+ *dest += temp << 8;
+}
+
+#ifndef EXTRACT_MACROS /* To debug the macros. */
+#undef EXTRACT_NUMBER
+#define EXTRACT_NUMBER(dest, src) extract_number (&dest, src)
+#endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+
+/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
+ SOURCE must be an lvalue. */
+
+#define EXTRACT_NUMBER_AND_INCR(destination, source) \
+ do { \
+ EXTRACT_NUMBER (destination, source); \
+ (source) += 2; \
+ } while (0)
+
+#ifdef DEBUG
+static void
+extract_number_and_incr (destination, source)
+ int *destination;
+ unsigned char **source;
+{
+ extract_number (destination, *source);
+ *source += 2;
+}
+
+#ifndef EXTRACT_MACROS
+#undef EXTRACT_NUMBER_AND_INCR
+#define EXTRACT_NUMBER_AND_INCR(dest, src) \
+ extract_number_and_incr (&dest, &src)
+#endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+
+/* If DEBUG is defined, Regex prints many voluminous messages about what
+ it is doing (if the variable `debug' is nonzero). If linked with the
+ main program in `iregex.c', you can enter patterns and strings
+ interactively. And if linked with the main program in `main.c' and
+ the other test files, you can run the already-written tests. */
+
+#ifdef DEBUG
+
+/* We use standard I/O for debugging. */
+#include <stdio.h>
+
+/* It is useful to test things that ``must'' be true when debugging. */
+#include <assert.h>
+
+static int debug = 0;
+
+#define DEBUG_STATEMENT(e) e
+#define DEBUG_PRINT1(x) if (debug) printf (x)
+#define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
+#define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
+#define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
+#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
+ if (debug) print_partial_compiled_pattern (s, e)
+#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
+ if (debug) print_double_string (w, s1, sz1, s2, sz2)
+
+
+extern void printchar ();
+
+/* Print the fastmap in human-readable form. */
+
+void
+print_fastmap (fastmap)
+ char *fastmap;
+{
+ unsigned was_a_range = 0;
+ unsigned i = 0;
+
+ while (i < (1 << BYTEWIDTH))
+ {
+ if (fastmap[i++])
+ {
+ was_a_range = 0;
+ printchar (i - 1);
+ while (i < (1 << BYTEWIDTH) && fastmap[i])
+ {
+ was_a_range = 1;
+ i++;
+ }
+ if (was_a_range)
+ {
+ printf ("-");
+ printchar (i - 1);
+ }
+ }
+ }
+ putchar ('\n');
+}
+
+
+/* Print a compiled pattern string in human-readable form, starting at
+ the START pointer into it and ending just before the pointer END. */
+
+void
+print_partial_compiled_pattern (start, end)
+ unsigned char *start;
+ unsigned char *end;
+{
+ int mcnt, mcnt2;
+ unsigned char *p = start;
+ unsigned char *pend = end;
+
+ if (start == NULL)
+ {
+ printf ("(null)\n");
+ return;
+ }
+
+ /* Loop over pattern commands. */
+ while (p < pend)
+ {
+ switch ((re_opcode_t) *p++)
+ {
+ case no_op:
+ printf ("/no_op");
+ break;
+
+ case exactn:
+ mcnt = *p++;
+ printf ("/exactn/%d", mcnt);
+ do
+ {
+ putchar ('/');
+ printchar (*p++);
+ }
+ while (--mcnt);
+ break;
+
+ case start_memory:
+ mcnt = *p++;
+ printf ("/start_memory/%d/%d", mcnt, *p++);
+ break;
+
+ case stop_memory:
+ mcnt = *p++;
+ printf ("/stop_memory/%d/%d", mcnt, *p++);
+ break;
+
+ case duplicate:
+ printf ("/duplicate/%d", *p++);
+ break;
+
+ case anychar:
+ printf ("/anychar");
+ break;
+
+ case charset:
+ case charset_not:
+ {
+ register int c;
+
+ printf ("/charset%s",
+ (re_opcode_t) *(p - 1) == charset_not ? "_not" : "");
+
+ assert (p + *p < pend);
+
+ for (c = 0; c < *p; c++)
+ {
+ unsigned bit;
+ unsigned char map_byte = p[1 + c];
+
+ putchar ('/');
+
+ for (bit = 0; bit < BYTEWIDTH; bit++)
+ if (map_byte & (1 << bit))
+ printchar (c * BYTEWIDTH + bit);
+ }
+ p += 1 + *p;
+ break;
+ }
+
+ case begline:
+ printf ("/begline");
+ break;
+
+ case endline:
+ printf ("/endline");
+ break;
+
+ case on_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_jump/0/%d", mcnt);
+ break;
+
+ case on_failure_keep_string_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_keep_string_jump/0/%d", mcnt);
+ break;
+
+ case dummy_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/dummy_failure_jump/0/%d", mcnt);
+ break;
+
+ case push_dummy_failure:
+ printf ("/push_dummy_failure");
+ break;
+
+ case maybe_pop_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/maybe_pop_jump/0/%d", mcnt);
+ break;
+
+ case pop_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/pop_failure_jump/0/%d", mcnt);
+ break;
+
+ case jump_past_alt:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/jump_past_alt/0/%d", mcnt);
+ break;
+
+ case jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/jump/0/%d", mcnt);
+ break;
+
+ case succeed_n:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/succeed_n/0/%d/0/%d", mcnt, mcnt2);
+ break;
+
+ case jump_n:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/jump_n/0/%d/0/%d", mcnt, mcnt2);
+ break;
+
+ case set_number_at:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/set_number_at/0/%d/0/%d", mcnt, mcnt2);
+ break;
+
+ case wordbound:
+ printf ("/wordbound");
+ break;
+
+ case notwordbound:
+ printf ("/notwordbound");
+ break;
+
+ case wordbeg:
+ printf ("/wordbeg");
+ break;
+
+ case wordend:
+ printf ("/wordend");
+
+#ifdef emacs
+ case before_dot:
+ printf ("/before_dot");
+ break;
+
+ case at_dot:
+ printf ("/at_dot");
+ break;
+
+ case after_dot:
+ printf ("/after_dot");
+ break;
+
+ case syntaxspec:
+ printf ("/syntaxspec");
+ mcnt = *p++;
+ printf ("/%d", mcnt);
+ break;
+
+ case notsyntaxspec:
+ printf ("/notsyntaxspec");
+ mcnt = *p++;
+ printf ("/%d", mcnt);
+ break;
+#endif /* emacs */
+
+ case wordchar:
+ printf ("/wordchar");
+ break;
+
+ case notwordchar:
+ printf ("/notwordchar");
+ break;
+
+ case begbuf:
+ printf ("/begbuf");
+ break;
+
+ case endbuf:
+ printf ("/endbuf");
+ break;
+
+ default:
+ printf ("?%d", *(p-1));
+ }
+ }
+ printf ("/\n");
+}
+
+
+void
+print_compiled_pattern (bufp)
+ struct re_pattern_buffer *bufp;
+{
+ unsigned char *buffer = bufp->buffer;
+
+ print_partial_compiled_pattern (buffer, buffer + bufp->used);
+ printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated);
+
+ if (bufp->fastmap_accurate && bufp->fastmap)
+ {
+ printf ("fastmap: ");
+ print_fastmap (bufp->fastmap);
+ }
+
+ printf ("re_nsub: %d\t", bufp->re_nsub);
+ printf ("regs_alloc: %d\t", bufp->regs_allocated);
+ printf ("can_be_null: %d\t", bufp->can_be_null);
+ printf ("newline_anchor: %d\n", bufp->newline_anchor);
+ printf ("no_sub: %d\t", bufp->no_sub);
+ printf ("not_bol: %d\t", bufp->not_bol);
+ printf ("not_eol: %d\t", bufp->not_eol);
+ printf ("syntax: %d\n", bufp->syntax);
+ /* Perhaps we should print the translate table? */
+}
+
+
+void
+print_double_string (where, string1, size1, string2, size2)
+ const char *where;
+ const char *string1;
+ const char *string2;
+ int size1;
+ int size2;
+{
+ unsigned this_char;
+
+ if (where == NULL)
+ printf ("(null)");
+ else
+ {
+ if (FIRST_STRING_P (where))
+ {
+ for (this_char = where - string1; this_char < size1; this_char++)
+ printchar (string1[this_char]);
+
+ where = string2;
+ }
+
+ for (this_char = where - string2; this_char < size2; this_char++)
+ printchar (string2[this_char]);
+ }
+}
+
+#else /* not DEBUG */
+
+#undef assert
+#define assert(e)
+
+#define DEBUG_STATEMENT(e)
+#define DEBUG_PRINT1(x)
+#define DEBUG_PRINT2(x1, x2)
+#define DEBUG_PRINT3(x1, x2, x3)
+#define DEBUG_PRINT4(x1, x2, x3, x4)
+#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
+#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
+
+#endif /* not DEBUG */
+
+/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
+ also be assigned to arbitrarily: each pattern buffer stores its own
+ syntax, so it can be changed between regex compilations. */
+reg_syntax_t re_syntax_options = RE_SYNTAX_EMACS;
+
+
+/* Specify the precise syntax of regexps for compilation. This provides
+ for compatibility for various utilities which historically have
+ different, incompatible syntaxes.
+
+ The argument SYNTAX is a bit mask comprised of the various bits
+ defined in regex.h. We return the old syntax. */
+
+reg_syntax_t
+re_set_syntax (syntax)
+ reg_syntax_t syntax;
+{
+ reg_syntax_t ret = re_syntax_options;
+
+ re_syntax_options = syntax;
+ return ret;
+}
+
+/* This table gives an error message for each of the error codes listed
+ in regex.h. Obviously the order here has to be same as there. */
+
+static const char *re_error_msg[] =
+ { NULL, /* REG_NOERROR */
+ "No match", /* REG_NOMATCH */
+ "Invalid regular expression", /* REG_BADPAT */
+ "Invalid collation character", /* REG_ECOLLATE */
+ "Invalid character class name", /* REG_ECTYPE */
+ "Trailing backslash", /* REG_EESCAPE */
+ "Invalid back reference", /* REG_ESUBREG */
+ "Unmatched [ or [^", /* REG_EBRACK */
+ "Unmatched ( or \\(", /* REG_EPAREN */
+ "Unmatched \\{", /* REG_EBRACE */
+ "Invalid content of \\{\\}", /* REG_BADBR */
+ "Invalid range end", /* REG_ERANGE */
+ "Memory exhausted", /* REG_ESPACE */
+ "Invalid preceding regular expression", /* REG_BADRPT */
+ "Premature end of regular expression", /* REG_EEND */
+ "Regular expression too big", /* REG_ESIZE */
+ "Unmatched ) or \\)", /* REG_ERPAREN */
+ };
+
+/* Subroutine declarations and macros for regex_compile. */
+
+static void store_op1 (), store_op2 ();
+static void insert_op1 (), insert_op2 ();
+static boolean at_begline_loc_p (), at_endline_loc_p ();
+static boolean group_in_compile_stack ();
+static reg_errcode_t compile_range ();
+
+/* Fetch the next character in the uncompiled pattern---translating it
+ if necessary. Also cast from a signed character in the constant
+ string passed to us by the user to an unsigned char that we can use
+ as an array index (in, e.g., `translate'). */
+#define PATFETCH(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ if (translate) c = translate[c]; \
+ } while (0)
+
+/* Fetch the next character in the uncompiled pattern, with no
+ translation. */
+#define PATFETCH_RAW(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ } while (0)
+
+/* Go backwards one character in the pattern. */
+#define PATUNFETCH p--
+
+
+/* If `translate' is non-null, return translate[D], else just D. We
+ cast the subscript to translate because some data is declared as
+ `char *', to avoid warnings when a string constant is passed. But
+ when we use a character as a subscript we must make it unsigned. */
+#define TRANSLATE(d) (translate ? translate[(unsigned char) (d)] : (d))
+
+
+/* Macros for outputting the compiled pattern into `buffer'. */
+
+/* If the buffer isn't allocated when it comes in, use this. */
+#define INIT_BUF_SIZE 32
+
+/* Make sure we have at least N more bytes of space in buffer. */
+#define GET_BUFFER_SPACE(n) \
+ while (b - bufp->buffer + (n) > bufp->allocated) \
+ EXTEND_BUFFER ()
+
+/* Make sure we have one more byte of buffer space and then add C to it. */
+#define BUF_PUSH(c) \
+ do { \
+ GET_BUFFER_SPACE (1); \
+ *b++ = (unsigned char) (c); \
+ } while (0)
+
+
+/* Ensure we have two more bytes of buffer space and then append C1 and C2. */
+#define BUF_PUSH_2(c1, c2) \
+ do { \
+ GET_BUFFER_SPACE (2); \
+ *b++ = (unsigned char) (c1); \
+ *b++ = (unsigned char) (c2); \
+ } while (0)
+
+
+/* As with BUF_PUSH_2, except for three bytes. */
+#define BUF_PUSH_3(c1, c2, c3) \
+ do { \
+ GET_BUFFER_SPACE (3); \
+ *b++ = (unsigned char) (c1); \
+ *b++ = (unsigned char) (c2); \
+ *b++ = (unsigned char) (c3); \
+ } while (0)
+
+
+/* Store a jump with opcode OP at LOC to location TO. We store a
+ relative address offset by the three bytes the jump itself occupies. */
+#define STORE_JUMP(op, loc, to) \
+ store_op1 (op, loc, (to) - (loc) - 3)
+
+/* Likewise, for a two-argument jump. */
+#define STORE_JUMP2(op, loc, to, arg) \
+ store_op2 (op, loc, (to) - (loc) - 3, arg)
+
+/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */
+#define INSERT_JUMP(op, loc, to) \
+ insert_op1 (op, loc, (to) - (loc) - 3, b)
+
+/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */
+#define INSERT_JUMP2(op, loc, to, arg) \
+ insert_op2 (op, loc, (to) - (loc) - 3, arg, b)
+
+
+/* This is not an arbitrary limit: the arguments which represent offsets
+ into the pattern are two bytes long. So if 2^16 bytes turns out to
+ be too small, many things would have to change. */
+#define MAX_BUF_SIZE (1L << 16)
+
+
+/* Extend the buffer by twice its current size via realloc and
+ reset the pointers that pointed into the old block to point to the
+ correct places in the new one. If extending the buffer results in it
+ being larger than MAX_BUF_SIZE, then flag memory exhausted. */
+#define EXTEND_BUFFER() \
+ do { \
+ unsigned char *old_buffer = bufp->buffer; \
+ if (bufp->allocated == MAX_BUF_SIZE) \
+ return REG_ESIZE; \
+ bufp->allocated <<= 1; \
+ if (bufp->allocated > MAX_BUF_SIZE) \
+ bufp->allocated = MAX_BUF_SIZE; \
+ bufp->buffer = (unsigned char *) realloc (bufp->buffer, bufp->allocated);\
+ if (bufp->buffer == NULL) \
+ return REG_ESPACE; \
+ /* If the buffer moved, move all the pointers into it. */ \
+ if (old_buffer != bufp->buffer) \
+ { \
+ b = (b - old_buffer) + bufp->buffer; \
+ begalt = (begalt - old_buffer) + bufp->buffer; \
+ if (fixup_alt_jump) \
+ fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\
+ if (laststart) \
+ laststart = (laststart - old_buffer) + bufp->buffer; \
+ if (pending_exact) \
+ pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
+ } \
+ } while (0)
+
+
+/* Since we have one byte reserved for the register number argument to
+ {start,stop}_memory, the maximum number of groups we can report
+ things about is what fits in that byte. */
+#define MAX_REGNUM 255
+
+/* But patterns can have more than `MAX_REGNUM' registers. We just
+ ignore the excess. */
+typedef unsigned regnum_t;
+
+
+/* Macros for the compile stack. */
+
+/* Since offsets can go either forwards or backwards, this type needs to
+ be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */
+typedef int pattern_offset_t;
+
+typedef struct
+{
+ pattern_offset_t begalt_offset;
+ pattern_offset_t fixup_alt_jump;
+ pattern_offset_t inner_group_offset;
+ pattern_offset_t laststart_offset;
+ regnum_t regnum;
+} compile_stack_elt_t;
+
+
+typedef struct
+{
+ compile_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} compile_stack_type;
+
+
+#define INIT_COMPILE_STACK_SIZE 32
+
+#define COMPILE_STACK_EMPTY (compile_stack.avail == 0)
+#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size)
+
+/* The next available element. */
+#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
+
+
+/* Set the bit for character C in a list. */
+#define SET_LIST_BIT(c) \
+ (b[((unsigned char) (c)) / BYTEWIDTH] \
+ |= 1 << (((unsigned char) c) % BYTEWIDTH))
+
+
+/* Get the next unsigned number in the uncompiled pattern. */
+#define GET_UNSIGNED_NUMBER(num) \
+ { if (p != pend) \
+ { \
+ PATFETCH (c); \
+ while (ISDIGIT (c)) \
+ { \
+ if (num < 0) \
+ num = 0; \
+ num = num * 10 + c - '0'; \
+ if (p == pend) \
+ break; \
+ PATFETCH (c); \
+ } \
+ } \
+ }
+
+#define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
+
+#define IS_CHAR_CLASS(string) \
+ (STREQ (string, "alpha") || STREQ (string, "upper") \
+ || STREQ (string, "lower") || STREQ (string, "digit") \
+ || STREQ (string, "alnum") || STREQ (string, "xdigit") \
+ || STREQ (string, "space") || STREQ (string, "print") \
+ || STREQ (string, "punct") || STREQ (string, "graph") \
+ || STREQ (string, "cntrl") || STREQ (string, "blank"))
+
+/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
+ Returns one of error codes defined in `regex.h', or zero for success.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate'
+ fields are set in BUFP on entry.
+
+ If it succeeds, results are put in BUFP (if it returns an error, the
+ contents of BUFP are undefined):
+ `buffer' is the compiled pattern;
+ `syntax' is set to SYNTAX;
+ `used' is set to the length of the compiled pattern;
+ `fastmap_accurate' is zero;
+ `re_nsub' is the number of subexpressions in PATTERN;
+ `not_bol' and `not_eol' are zero;
+
+ The `fastmap' and `newline_anchor' fields are neither
+ examined nor set. */
+
+static reg_errcode_t
+regex_compile (pattern, size, syntax, bufp)
+ const char *pattern;
+ int size;
+ reg_syntax_t syntax;
+ struct re_pattern_buffer *bufp;
+{
+ /* We fetch characters from PATTERN here. Even though PATTERN is
+ `char *' (i.e., signed), we declare these variables as unsigned, so
+ they can be reliably used as array indices. */
+ register unsigned char c, c1;
+
+ /* A random tempory spot in PATTERN. */
+ const char *p1;
+
+ /* Points to the end of the buffer, where we should append. */
+ register unsigned char *b;
+
+ /* Keeps track of unclosed groups. */
+ compile_stack_type compile_stack;
+
+ /* Points to the current (ending) position in the pattern. */
+ const char *p = pattern;
+ const char *pend = pattern + size;
+
+ /* How to translate the characters in the pattern. */
+ char *translate = bufp->translate;
+
+ /* Address of the count-byte of the most recently inserted `exactn'
+ command. This makes it possible to tell if a new exact-match
+ character can be added to that command or if the character requires
+ a new `exactn' command. */
+ unsigned char *pending_exact = 0;
+
+ /* Address of start of the most recently finished expression.
+ This tells, e.g., postfix * where to find the start of its
+ operand. Reset at the beginning of groups and alternatives. */
+ unsigned char *laststart = 0;
+
+ /* Address of beginning of regexp, or inside of last group. */
+ unsigned char *begalt;
+
+ /* Place in the uncompiled pattern (i.e., the {) to
+ which to go back if the interval is invalid. */
+ const char *beg_interval;
+
+ /* Address of the place where a forward jump should go to the end of
+ the containing expression. Each alternative of an `or' -- except the
+ last -- ends with a forward jump of this sort. */
+ unsigned char *fixup_alt_jump = 0;
+
+ /* Counts open-groups as they are encountered. Remembered for the
+ matching close-group on the compile stack, so the same register
+ number is put in the stop_memory as the start_memory. */
+ regnum_t regnum = 0;
+
+#ifdef DEBUG
+ DEBUG_PRINT1 ("\nCompiling pattern: ");
+ if (debug)
+ {
+ unsigned debug_count;
+
+ for (debug_count = 0; debug_count < size; debug_count++)
+ printchar (pattern[debug_count]);
+ putchar ('\n');
+ }
+#endif /* DEBUG */
+
+ /* Initialize the compile stack. */
+ compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
+ if (compile_stack.stack == NULL)
+ return REG_ESPACE;
+
+ compile_stack.size = INIT_COMPILE_STACK_SIZE;
+ compile_stack.avail = 0;
+
+ /* Initialize the pattern buffer. */
+ bufp->syntax = syntax;
+ bufp->fastmap_accurate = 0;
+ bufp->not_bol = bufp->not_eol = 0;
+
+ /* Set `used' to zero, so that if we return an error, the pattern
+ printer (for debugging) will think there's no pattern. We reset it
+ at the end. */
+ bufp->used = 0;
+
+ /* Always count groups, whether or not bufp->no_sub is set. */
+ bufp->re_nsub = 0;
+
+#if !defined (emacs) && !defined (SYNTAX_TABLE)
+ /* Initialize the syntax table. */
+ init_syntax_once ();
+#endif
+
+ if (bufp->allocated == 0)
+ {
+ if (bufp->buffer)
+ { /* If zero allocated, but buffer is non-null, try to realloc
+ enough space. This loses if buffer's address is bogus, but
+ that is the user's responsibility. */
+ RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char);
+ }
+ else
+ { /* Caller did not allocate a buffer. Do it for them. */
+ bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char);
+ }
+ if (!bufp->buffer) return REG_ESPACE;
+
+ bufp->allocated = INIT_BUF_SIZE;
+ }
+
+ begalt = b = bufp->buffer;
+
+ /* Loop through the uncompiled pattern until we're at the end. */
+ while (p != pend)
+ {
+ PATFETCH (c);
+
+ switch (c)
+ {
+ case '^':
+ {
+ if ( /* If at start of pattern, it's an operator. */
+ p == pattern + 1
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's come before. */
+ || at_begline_loc_p (pattern, p, syntax))
+ BUF_PUSH (begline);
+ else
+ goto normal_char;
+ }
+ break;
+
+
+ case '$':
+ {
+ if ( /* If at end of pattern, it's an operator. */
+ p == pend
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's next. */
+ || at_endline_loc_p (p, pend, syntax))
+ BUF_PUSH (endline);
+ else
+ goto normal_char;
+ }
+ break;
+
+
+ case '+':
+ case '?':
+ if ((syntax & RE_BK_PLUS_QM)
+ || (syntax & RE_LIMITED_OPS))
+ goto normal_char;
+ handle_plus:
+ case '*':
+ /* If there is no previous pattern... */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ return REG_BADRPT;
+ else if (!(syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ }
+
+ {
+ /* Are we optimizing this jump? */
+ boolean keep_string_p = false;
+
+ /* 1 means zero (many) matches is allowed. */
+ char zero_times_ok = 0, many_times_ok = 0;
+
+ /* If there is a sequence of repetition chars, collapse it
+ down to just one (the right one). We can't combine
+ interval operators with these because of, e.g., `a{2}*',
+ which should only match an even number of `a's. */
+
+ for (;;)
+ {
+ zero_times_ok |= c != '+';
+ many_times_ok |= c != '?';
+
+ if (p == pend)
+ break;
+
+ PATFETCH (c);
+
+ if (c == '*'
+ || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
+ ;
+
+ else if (syntax & RE_BK_PLUS_QM && c == '\\')
+ {
+ if (p == pend) return REG_EESCAPE;
+
+ PATFETCH (c1);
+ if (!(c1 == '+' || c1 == '?'))
+ {
+ PATUNFETCH;
+ PATUNFETCH;
+ break;
+ }
+
+ c = c1;
+ }
+ else
+ {
+ PATUNFETCH;
+ break;
+ }
+
+ /* If we get here, we found another repeat character. */
+ }
+
+ /* Star, etc. applied to an empty pattern is equivalent
+ to an empty pattern. */
+ if (!laststart)
+ break;
+
+ /* Now we know whether or not zero matches is allowed
+ and also whether or not two or more matches is allowed. */
+ if (many_times_ok)
+ { /* More than one repetition is allowed, so put in at the
+ end a backward relative jump from `b' to before the next
+ jump we're going to put in below (which jumps from
+ laststart to after this jump).
+
+ But if we are at the `*' in the exact sequence `.*\n',
+ insert an unconditional jump backwards to the .,
+ instead of the beginning of the loop. This way we only
+ push a failure point once, instead of every time
+ through the loop. */
+ assert (p - 1 > pattern);
+
+ /* Allocate the space for the jump. */
+ GET_BUFFER_SPACE (3);
+
+ /* We know we are not at the first character of the pattern,
+ because laststart was nonzero. And we've already
+ incremented `p', by the way, to be the character after
+ the `*'. Do we have to do something analogous here
+ for null bytes, because of RE_DOT_NOT_NULL? */
+ if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
+ && zero_times_ok
+ && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
+ && !(syntax & RE_DOT_NEWLINE))
+ { /* We have .*\n. */
+ STORE_JUMP (jump, b, laststart);
+ keep_string_p = true;
+ }
+ else
+ /* Anything else. */
+ STORE_JUMP (maybe_pop_jump, b, laststart - 3);
+
+ /* We've added more stuff to the buffer. */
+ b += 3;
+ }
+
+ /* On failure, jump from laststart to b + 3, which will be the
+ end of the buffer after this jump is inserted. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
+ : on_failure_jump,
+ laststart, b + 3);
+ pending_exact = 0;
+ b += 3;
+
+ if (!zero_times_ok)
+ {
+ /* At least one repetition is required, so insert a
+ `dummy_failure_jump' before the initial
+ `on_failure_jump' instruction of the loop. This
+ effects a skip over that instruction the first time
+ we hit that loop. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6);
+ b += 3;
+ }
+ }
+ break;
+
+
+ case '.':
+ laststart = b;
+ BUF_PUSH (anychar);
+ break;
+
+
+ case '[':
+ {
+ boolean had_char_class = false;
+
+ if (p == pend) return REG_EBRACK;
+
+ /* Ensure that we have enough space to push a charset: the
+ opcode, the length count, and the bitset; 34 bytes in all. */
+ GET_BUFFER_SPACE (34);
+
+ laststart = b;
+
+ /* We test `*p == '^' twice, instead of using an if
+ statement, so we only need one BUF_PUSH. */
+ BUF_PUSH (*p == '^' ? charset_not : charset);
+ if (*p == '^')
+ p++;
+
+ /* Remember the first position in the bracket expression. */
+ p1 = p;
+
+ /* Push the number of bytes in the bitmap. */
+ BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
+
+ /* Clear the whole map. */
+ bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
+
+ /* charset_not matches newline according to a syntax bit. */
+ if ((re_opcode_t) b[-2] == charset_not
+ && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
+ SET_LIST_BIT ('\n');
+
+ /* Read in characters and ranges, setting map bits. */
+ for (;;)
+ {
+ if (p == pend) return REG_EBRACK;
+
+ PATFETCH (c);
+
+ /* \ might escape characters inside [...] and [^...]. */
+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
+ {
+ if (p == pend) return REG_EESCAPE;
+
+ PATFETCH (c1);
+ SET_LIST_BIT (c1);
+ continue;
+ }
+
+ /* Could be the end of the bracket expression. If it's
+ not (i.e., when the bracket expression is `[]' so
+ far), the ']' character bit gets set way below. */
+ if (c == ']' && p != p1 + 1)
+ break;
+
+ /* Look ahead to see if it's a range when the last thing
+ was a character class. */
+ if (had_char_class && c == '-' && *p != ']')
+ return REG_ERANGE;
+
+ /* Look ahead to see if it's a range when the last thing
+ was a character: if this is a hyphen not at the
+ beginning or the end of a list, then it's the range
+ operator. */
+ if (c == '-'
+ && !(p - 2 >= pattern && p[-2] == '[')
+ && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
+ && *p != ']')
+ {
+ reg_errcode_t ret
+ = compile_range (&p, pend, translate, syntax, b);
+ if (ret != REG_NOERROR) return ret;
+ }
+
+ else if (p[0] == '-' && p[1] != ']')
+ { /* This handles ranges made up of characters only. */
+ reg_errcode_t ret;
+
+ /* Move past the `-'. */
+ PATFETCH (c1);
+
+ ret = compile_range (&p, pend, translate, syntax, b);
+ if (ret != REG_NOERROR) return ret;
+ }
+
+ /* See if we're at the beginning of a possible character
+ class. */
+
+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
+ { /* Leave room for the null. */
+ char str[CHAR_CLASS_MAX_LENGTH + 1];
+
+ PATFETCH (c);
+ c1 = 0;
+
+ /* If pattern is `[[:'. */
+ if (p == pend) return REG_EBRACK;
+
+ for (;;)
+ {
+ PATFETCH (c);
+ if (c == ':' || c == ']' || p == pend
+ || c1 == CHAR_CLASS_MAX_LENGTH)
+ break;
+ str[c1++] = c;
+ }
+ str[c1] = '\0';
+
+ /* If isn't a word bracketed by `[:' and:`]':
+ undo the ending character, the letters, and leave
+ the leading `:' and `[' (but set bits for them). */
+ if (c == ':' && *p == ']')
+ {
+ int ch;
+ boolean is_alnum = STREQ (str, "alnum");
+ boolean is_alpha = STREQ (str, "alpha");
+ boolean is_blank = STREQ (str, "blank");
+ boolean is_cntrl = STREQ (str, "cntrl");
+ boolean is_digit = STREQ (str, "digit");
+ boolean is_graph = STREQ (str, "graph");
+ boolean is_lower = STREQ (str, "lower");
+ boolean is_print = STREQ (str, "print");
+ boolean is_punct = STREQ (str, "punct");
+ boolean is_space = STREQ (str, "space");
+ boolean is_upper = STREQ (str, "upper");
+ boolean is_xdigit = STREQ (str, "xdigit");
+
+ if (!IS_CHAR_CLASS (str)) return REG_ECTYPE;
+
+ /* Throw away the ] at the end of the character
+ class. */
+ PATFETCH (c);
+
+ if (p == pend) return REG_EBRACK;
+
+ for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
+ {
+ if ( (is_alnum && ISALNUM (ch))
+ || (is_alpha && ISALPHA (ch))
+ || (is_blank && ISBLANK (ch))
+ || (is_cntrl && ISCNTRL (ch))
+ || (is_digit && ISDIGIT (ch))
+ || (is_graph && ISGRAPH (ch))
+ || (is_lower && ISLOWER (ch))
+ || (is_print && ISPRINT (ch))
+ || (is_punct && ISPUNCT (ch))
+ || (is_space && ISSPACE (ch))
+ || (is_upper && ISUPPER (ch))
+ || (is_xdigit && ISXDIGIT (ch)))
+ SET_LIST_BIT (ch);
+ }
+ had_char_class = true;
+ }
+ else
+ {
+ c1++;
+ while (c1--)
+ PATUNFETCH;
+ SET_LIST_BIT ('[');
+ SET_LIST_BIT (':');
+ had_char_class = false;
+ }
+ }
+ else
+ {
+ had_char_class = false;
+ SET_LIST_BIT (c);
+ }
+ }
+
+ /* Discard any (non)matching list bytes that are all 0 at the
+ end of the map. Decrease the map-length byte too. */
+ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
+ b[-1]--;
+ b += b[-1];
+ }
+ break;
+
+
+ case '(':
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_open;
+ else
+ goto normal_char;
+
+
+ case ')':
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_close;
+ else
+ goto normal_char;
+
+
+ case '\n':
+ if (syntax & RE_NEWLINE_ALT)
+ goto handle_alt;
+ else
+ goto normal_char;
+
+
+ case '|':
+ if (syntax & RE_NO_BK_VBAR)
+ goto handle_alt;
+ else
+ goto normal_char;
+
+
+ case '{':
+ if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
+ goto handle_interval;
+ else
+ goto normal_char;
+
+
+ case '\\':
+ if (p == pend) return REG_EESCAPE;
+
+ /* Do not translate the character after the \, so that we can
+ distinguish, e.g., \B from \b, even if we normally would
+ translate, e.g., B to b. */
+ PATFETCH_RAW (c);
+
+ switch (c)
+ {
+ case '(':
+ if (syntax & RE_NO_BK_PARENS)
+ goto normal_backslash;
+
+ handle_open:
+ bufp->re_nsub++;
+ regnum++;
+
+ if (COMPILE_STACK_FULL)
+ {
+ RETALLOC (compile_stack.stack, compile_stack.size << 1,
+ compile_stack_elt_t);
+ if (compile_stack.stack == NULL) return REG_ESPACE;
+
+ compile_stack.size <<= 1;
+ }
+
+ /* These are the values to restore when we hit end of this
+ group. They are all relative offsets, so that if the
+ whole pattern moves because of realloc, they will still
+ be valid. */
+ COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer;
+ COMPILE_STACK_TOP.fixup_alt_jump
+ = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
+ COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;
+ COMPILE_STACK_TOP.regnum = regnum;
+
+ /* We will eventually replace the 0 with the number of
+ groups inner to this one. But do not push a
+ start_memory for groups beyond the last one we can
+ represent in the compiled pattern. */
+ if (regnum <= MAX_REGNUM)
+ {
+ COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2;
+ BUF_PUSH_3 (start_memory, regnum, 0);
+ }
+
+ compile_stack.avail++;
+
+ fixup_alt_jump = 0;
+ laststart = 0;
+ begalt = b;
+ /* If we've reached MAX_REGNUM groups, then this open
+ won't actually generate any code, so we'll have to
+ clear pending_exact explicitly. */
+ pending_exact = 0;
+ break;
+
+
+ case ')':
+ if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
+
+ if (COMPILE_STACK_EMPTY)
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_backslash;
+ else
+ return REG_ERPAREN;
+
+ handle_close:
+ if (fixup_alt_jump)
+ { /* Push a dummy failure point at the end of the
+ alternative for a possible future
+ `pop_failure_jump' to pop. See comments at
+ `push_dummy_failure' in `re_match_2'. */
+ BUF_PUSH (push_dummy_failure);
+
+ /* We allocated space for this jump when we assigned
+ to `fixup_alt_jump', in the `handle_alt' case below. */
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
+ }
+
+ /* See similar code for backslashed left paren above. */
+ if (COMPILE_STACK_EMPTY)
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_char;
+ else
+ return REG_ERPAREN;
+
+ /* Since we just checked for an empty stack above, this
+ ``can't happen''. */
+ assert (compile_stack.avail != 0);
+ {
+ /* We don't just want to restore into `regnum', because
+ later groups should continue to be numbered higher,
+ as in `(ab)c(de)' -- the second group is #2. */
+ regnum_t this_group_regnum;
+
+ compile_stack.avail--;
+ begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;
+ fixup_alt_jump
+ = COMPILE_STACK_TOP.fixup_alt_jump
+ ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1
+ : 0;
+ laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;
+ this_group_regnum = COMPILE_STACK_TOP.regnum;
+ /* If we've reached MAX_REGNUM groups, then this open
+ won't actually generate any code, so we'll have to
+ clear pending_exact explicitly. */
+ pending_exact = 0;
+
+ /* We're at the end of the group, so now we know how many
+ groups were inside this one. */
+ if (this_group_regnum <= MAX_REGNUM)
+ {
+ unsigned char *inner_group_loc
+ = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset;
+
+ *inner_group_loc = regnum - this_group_regnum;
+ BUF_PUSH_3 (stop_memory, this_group_regnum,
+ regnum - this_group_regnum);
+ }
+ }
+ break;
+
+
+ case '|': /* `\|'. */
+ if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
+ goto normal_backslash;
+ handle_alt:
+ if (syntax & RE_LIMITED_OPS)
+ goto normal_char;
+
+ /* Insert before the previous alternative a jump which
+ jumps to this alternative if the former fails. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (on_failure_jump, begalt, b + 6);
+ pending_exact = 0;
+ b += 3;
+
+ /* The alternative before this one has a jump after it
+ which gets executed if it gets matched. Adjust that
+ jump so it will jump to this alternative's analogous
+ jump (put in below, which in turn will jump to the next
+ (if any) alternative's such jump, etc.). The last such
+ jump jumps to the correct final destination. A picture:
+ _____ _____
+ | | | |
+ | v | v
+ a | b | c
+
+ If we are at `b', then fixup_alt_jump right now points to a
+ three-byte space after `a'. We'll put in the jump, set
+ fixup_alt_jump to right after `b', and leave behind three
+ bytes which we'll fill in when we get to after `c'. */
+
+ if (fixup_alt_jump)
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+ /* Mark and leave space for a jump after this alternative,
+ to be filled in later either by next alternative or
+ when know we're at the end of a series of alternatives. */
+ fixup_alt_jump = b;
+ GET_BUFFER_SPACE (3);
+ b += 3;
+
+ laststart = 0;
+ begalt = b;
+ break;
+
+
+ case '{':
+ /* If \{ is a literal. */
+ if (!(syntax & RE_INTERVALS)
+ /* If we're at `\{' and it's not the open-interval
+ operator. */
+ || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+ || (p - 2 == pattern && p == pend))
+ goto normal_backslash;
+
+ handle_interval:
+ {
+ /* If got here, then the syntax allows intervals. */
+
+ /* At least (most) this many matches must be made. */
+ int lower_bound = -1, upper_bound = -1;
+
+ beg_interval = p - 1;
+
+ if (p == pend)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ return REG_EBRACE;
+ }
+
+ GET_UNSIGNED_NUMBER (lower_bound);
+
+ if (c == ',')
+ {
+ GET_UNSIGNED_NUMBER (upper_bound);
+ if (upper_bound < 0) upper_bound = RE_DUP_MAX;
+ }
+ else
+ /* Interval such as `{1}' => match exactly once. */
+ upper_bound = lower_bound;
+
+ if (lower_bound < 0 || upper_bound > RE_DUP_MAX
+ || lower_bound > upper_bound)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ return REG_BADBR;
+ }
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (c != '\\') return REG_EBRACE;
+
+ PATFETCH (c);
+ }
+
+ if (c != '}')
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ return REG_BADBR;
+ }
+
+ /* We just parsed a valid interval. */
+
+ /* If it's invalid to have no preceding re. */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ return REG_BADRPT;
+ else if (syntax & RE_CONTEXT_INDEP_OPS)
+ laststart = b;
+ else
+ goto unfetch_interval;
+ }
+
+ /* If the upper bound is zero, don't want to succeed at
+ all; jump from `laststart' to `b + 3', which will be
+ the end of the buffer after we insert the jump. */
+ if (upper_bound == 0)
+ {
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (jump, laststart, b + 3);
+ b += 3;
+ }
+
+ /* Otherwise, we have a nontrivial interval. When
+ we're all done, the pattern will look like:
+ set_number_at <jump count> <upper bound>
+ set_number_at <succeed_n count> <lower bound>
+ succeed_n <after jump addr> <succed_n count>
+ <body of loop>
+ jump_n <succeed_n addr> <jump count>
+ (The upper bound and `jump_n' are omitted if
+ `upper_bound' is 1, though.) */
+ else
+ { /* If the upper bound is > 1, we need to insert
+ more at the end of the loop. */
+ unsigned nbytes = 10 + (upper_bound > 1) * 10;
+
+ GET_BUFFER_SPACE (nbytes);
+
+ /* Initialize lower bound of the `succeed_n', even
+ though it will be set during matching by its
+ attendant `set_number_at' (inserted next),
+ because `re_compile_fastmap' needs to know.
+ Jump to the `jump_n' we might insert below. */
+ INSERT_JUMP2 (succeed_n, laststart,
+ b + 5 + (upper_bound > 1) * 5,
+ lower_bound);
+ b += 5;
+
+ /* Code to initialize the lower bound. Insert
+ before the `succeed_n'. The `5' is the last two
+ bytes of this `set_number_at', plus 3 bytes of
+ the following `succeed_n'. */
+ insert_op2 (set_number_at, laststart, 5, lower_bound, b);
+ b += 5;
+
+ if (upper_bound > 1)
+ { /* More than one repetition is allowed, so
+ append a backward jump to the `succeed_n'
+ that starts this interval.
+
+ When we've reached this during matching,
+ we'll have matched the interval once, so
+ jump back only `upper_bound - 1' times. */
+ STORE_JUMP2 (jump_n, b, laststart + 5,
+ upper_bound - 1);
+ b += 5;
+
+ /* The location we want to set is the second
+ parameter of the `jump_n'; that is `b-2' as
+ an absolute address. `laststart' will be
+ the `set_number_at' we're about to insert;
+ `laststart+3' the number to set, the source
+ for the relative address. But we are
+ inserting into the middle of the pattern --
+ so everything is getting moved up by 5.
+ Conclusion: (b - 2) - (laststart + 3) + 5,
+ i.e., b - laststart.
+
+ We insert this at the beginning of the loop
+ so that if we fail during matching, we'll
+ reinitialize the bounds. */
+ insert_op2 (set_number_at, laststart, b - laststart,
+ upper_bound - 1, b);
+ b += 5;
+ }
+ }
+ pending_exact = 0;
+ beg_interval = NULL;
+ }
+ break;
+
+ unfetch_interval:
+ /* If an invalid interval, match the characters as literals. */
+ assert (beg_interval);
+ p = beg_interval;
+ beg_interval = NULL;
+
+ /* normal_char and normal_backslash need `c'. */
+ PATFETCH (c);
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (p > pattern && p[-1] == '\\')
+ goto normal_backslash;
+ }
+ goto normal_char;
+
+#ifdef emacs
+ /* There is no way to specify the before_dot and after_dot
+ operators. rms says this is ok. --karl */
+ case '=':
+ BUF_PUSH (at_dot);
+ break;
+
+ case 's':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
+ break;
+
+ case 'S':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
+ break;
+#endif /* emacs */
+
+
+ case 'w':
+ laststart = b;
+ BUF_PUSH (wordchar);
+ break;
+
+
+ case 'W':
+ laststart = b;
+ BUF_PUSH (notwordchar);
+ break;
+
+
+ case '<':
+ BUF_PUSH (wordbeg);
+ break;
+
+ case '>':
+ BUF_PUSH (wordend);
+ break;
+
+ case 'b':
+ BUF_PUSH (wordbound);
+ break;
+
+ case 'B':
+ BUF_PUSH (notwordbound);
+ break;
+
+ case '`':
+ BUF_PUSH (begbuf);
+ break;
+
+ case '\'':
+ BUF_PUSH (endbuf);
+ break;
+
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ if (syntax & RE_NO_BK_REFS)
+ goto normal_char;
+
+ c1 = c - '0';
+
+ if (c1 > regnum)
+ return REG_ESUBREG;
+
+ /* Can't back reference to a subexpression if inside of it. */
+ if (group_in_compile_stack (compile_stack, c1))
+ goto normal_char;
+
+ laststart = b;
+ BUF_PUSH_2 (duplicate, c1);
+ break;
+
+
+ case '+':
+ case '?':
+ if (syntax & RE_BK_PLUS_QM)
+ goto handle_plus;
+ else
+ goto normal_backslash;
+
+ default:
+ normal_backslash:
+ /* You might think it would be useful for \ to mean
+ not to translate; but if we don't translate it
+ it will never match anything. */
+ c = TRANSLATE (c);
+ goto normal_char;
+ }
+ break;
+
+
+ default:
+ /* Expects the character in `c'. */
+ normal_char:
+ /* If no exactn currently being built. */
+ if (!pending_exact
+
+ /* If last exactn not at current position. */
+ || pending_exact + *pending_exact + 1 != b
+
+ /* We have only one byte following the exactn for the count. */
+ || *pending_exact == (1 << BYTEWIDTH) - 1
+
+ /* If followed by a repetition operator. */
+ || *p == '*' || *p == '^'
+ || ((syntax & RE_BK_PLUS_QM)
+ ? *p == '\\' && (p[1] == '+' || p[1] == '?')
+ : (*p == '+' || *p == '?'))
+ || ((syntax & RE_INTERVALS)
+ && ((syntax & RE_NO_BK_BRACES)
+ ? *p == '{'
+ : (p[0] == '\\' && p[1] == '{'))))
+ {
+ /* Start building a new exactn. */
+
+ laststart = b;
+
+ BUF_PUSH_2 (exactn, 0);
+ pending_exact = b - 1;
+ }
+
+ BUF_PUSH (c);
+ (*pending_exact)++;
+ break;
+ } /* switch (c) */
+ } /* while p != pend */
+
+
+ /* Through the pattern now. */
+
+ if (fixup_alt_jump)
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+ if (!COMPILE_STACK_EMPTY)
+ return REG_EPAREN;
+
+ free (compile_stack.stack);
+
+ /* We have succeeded; set the length of the buffer. */
+ bufp->used = b - bufp->buffer;
+
+#ifdef DEBUG
+ if (debug)
+ {
+ DEBUG_PRINT1 ("\nCompiled pattern: ");
+ print_compiled_pattern (bufp);
+ }
+#endif /* DEBUG */
+
+ return REG_NOERROR;
+} /* regex_compile */
+
+/* Subroutines for `regex_compile'. */
+
+/* Store OP at LOC followed by two-byte integer parameter ARG. */
+
+static void
+store_op1 (op, loc, arg)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg;
+{
+ *loc = (unsigned char) op;
+ STORE_NUMBER (loc + 1, arg);
+}
+
+
+/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */
+
+static void
+store_op2 (op, loc, arg1, arg2)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg1, arg2;
+{
+ *loc = (unsigned char) op;
+ STORE_NUMBER (loc + 1, arg1);
+ STORE_NUMBER (loc + 3, arg2);
+}
+
+
+/* Copy the bytes from LOC to END to open up three bytes of space at LOC
+ for OP followed by two-byte integer parameter ARG. */
+
+static void
+insert_op1 (op, loc, arg, end)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg;
+ unsigned char *end;
+{
+ register unsigned char *pfrom = end;
+ register unsigned char *pto = end + 3;
+
+ while (pfrom != loc)
+ *--pto = *--pfrom;
+
+ store_op1 (op, loc, arg);
+}
+
+
+/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */
+
+static void
+insert_op2 (op, loc, arg1, arg2, end)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg1, arg2;
+ unsigned char *end;
+{
+ register unsigned char *pfrom = end;
+ register unsigned char *pto = end + 5;
+
+ while (pfrom != loc)
+ *--pto = *--pfrom;
+
+ store_op2 (op, loc, arg1, arg2);
+}
+
+
+/* P points to just after a ^ in PATTERN. Return true if that ^ comes
+ after an alternative or a begin-subexpression. We assume there is at
+ least one character before the ^. */
+
+static boolean
+at_begline_loc_p (pattern, p, syntax)
+ const char *pattern, *p;
+ reg_syntax_t syntax;
+{
+ const char *prev = p - 2;
+ boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
+
+ return
+ /* After a subexpression? */
+ (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
+ /* After an alternative? */
+ || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
+}
+
+
+/* The dual of at_begline_loc_p. This one is for $. We assume there is
+ at least one character after the $, i.e., `P < PEND'. */
+
+static boolean
+at_endline_loc_p (p, pend, syntax)
+ const char *p, *pend;
+ int syntax;
+{
+ const char *next = p;
+ boolean next_backslash = *next == '\\';
+ const char *next_next = p + 1 < pend ? p + 1 : NULL;
+
+ return
+ /* Before a subexpression? */
+ (syntax & RE_NO_BK_PARENS ? *next == ')'
+ : next_backslash && next_next && *next_next == ')')
+ /* Before an alternative? */
+ || (syntax & RE_NO_BK_VBAR ? *next == '|'
+ : next_backslash && next_next && *next_next == '|');
+}
+
+
+/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
+ false if it's not. */
+
+static boolean
+group_in_compile_stack (compile_stack, regnum)
+ compile_stack_type compile_stack;
+ regnum_t regnum;
+{
+ int this_element;
+
+ for (this_element = compile_stack.avail - 1;
+ this_element >= 0;
+ this_element--)
+ if (compile_stack.stack[this_element].regnum == regnum)
+ return true;
+
+ return false;
+}
+
+
+/* Read the ending character of a range (in a bracket expression) from the
+ uncompiled pattern *P_PTR (which ends at PEND). We assume the
+ starting character is in `P[-2]'. (`P[-1]' is the character `-'.)
+ Then we set the translation of all bits between the starting and
+ ending characters (inclusive) in the compiled pattern B.
+
+ Return an error code.
+
+ We use these short variable names so we can use the same macros as
+ `regex_compile' itself. */
+
+static reg_errcode_t
+compile_range (p_ptr, pend, translate, syntax, b)
+ const char **p_ptr, *pend;
+ char *translate;
+ reg_syntax_t syntax;
+ unsigned char *b;
+{
+ unsigned this_char;
+
+ const char *p = *p_ptr;
+ int range_start, range_end;
+
+ if (p == pend)
+ return REG_ERANGE;
+
+ /* Even though the pattern is a signed `char *', we need to fetch
+ with unsigned char *'s; if the high bit of the pattern character
+ is set, the range endpoints will be negative if we fetch using a
+ signed char *.
+
+ We also want to fetch the endpoints without translating them; the
+ appropriate translation is done in the bit-setting loop below. */
+ range_start = ((unsigned char *) p)[-2];
+ range_end = ((unsigned char *) p)[0];
+
+ /* Have to increment the pointer into the pattern string, so the
+ caller isn't still at the ending character. */
+ (*p_ptr)++;
+
+ /* If the start is after the end, the range is empty. */
+ if (range_start > range_end)
+ return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
+
+ /* Here we see why `this_char' has to be larger than an `unsigned
+ char' -- the range is inclusive, so if `range_end' == 0xff
+ (assuming 8-bit characters), we would otherwise go into an infinite
+ loop, since all characters <= 0xff. */
+ for (this_char = range_start; this_char <= range_end; this_char++)
+ {
+ SET_LIST_BIT (TRANSLATE (this_char));
+ }
+
+ return REG_NOERROR;
+}
+
+/* Failure stack declarations and macros; both re_compile_fastmap and
+ re_match_2 use a failure stack. These have to be macros because of
+ REGEX_ALLOCATE. */
+
+
+/* Number of failure points for which to initially allocate space
+ when matching. If this number is exceeded, we allocate more
+ space, so it is not a hard limit. */
+#ifndef INIT_FAILURE_ALLOC
+#define INIT_FAILURE_ALLOC 5
+#endif
+
+/* Roughly the maximum number of failure points on the stack. Would be
+ exactly that if always used MAX_FAILURE_SPACE each time we failed.
+ This is a variable only so users of regex can assign to it; we never
+ change it ourselves. */
+int re_max_failures = 2000;
+
+typedef const unsigned char *fail_stack_elt_t;
+
+typedef struct
+{
+ fail_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} fail_stack_type;
+
+#define FAIL_STACK_EMPTY() (fail_stack.avail == 0)
+#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
+#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size)
+#define FAIL_STACK_TOP() (fail_stack.stack[fail_stack.avail])
+
+
+/* Initialize `fail_stack'. Do `return -2' if the alloc fails. */
+
+#define INIT_FAIL_STACK() \
+ do { \
+ fail_stack.stack = (fail_stack_elt_t *) \
+ REGEX_ALLOCATE (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \
+ \
+ if (fail_stack.stack == NULL) \
+ return -2; \
+ \
+ fail_stack.size = INIT_FAILURE_ALLOC; \
+ fail_stack.avail = 0; \
+ } while (0)
+
+
+/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
+
+ Return 1 if succeeds, and 0 if either ran out of memory
+ allocating space for it or it was already too large.
+
+ REGEX_REALLOCATE requires `destination' be declared. */
+
+#define DOUBLE_FAIL_STACK(fail_stack) \
+ ((fail_stack).size > re_max_failures * MAX_FAILURE_ITEMS \
+ ? 0 \
+ : ((fail_stack).stack = (fail_stack_elt_t *) \
+ REGEX_REALLOCATE ((fail_stack).stack, \
+ (fail_stack).size * sizeof (fail_stack_elt_t), \
+ ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \
+ \
+ (fail_stack).stack == NULL \
+ ? 0 \
+ : ((fail_stack).size <<= 1, \
+ 1)))
+
+
+/* Push PATTERN_OP on FAIL_STACK.
+
+ Return 1 if was able to do so and 0 if ran out of memory allocating
+ space to do so. */
+#define PUSH_PATTERN_OP(pattern_op, fail_stack) \
+ ((FAIL_STACK_FULL () \
+ && !DOUBLE_FAIL_STACK (fail_stack)) \
+ ? 0 \
+ : ((fail_stack).stack[(fail_stack).avail++] = pattern_op, \
+ 1))
+
+/* This pushes an item onto the failure stack. Must be a four-byte
+ value. Assumes the variable `fail_stack'. Probably should only
+ be called from within `PUSH_FAILURE_POINT'. */
+#define PUSH_FAILURE_ITEM(item) \
+ fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) item
+
+/* The complement operation. Assumes `fail_stack' is nonempty. */
+#define POP_FAILURE_ITEM() fail_stack.stack[--fail_stack.avail]
+
+/* Used to omit pushing failure point id's when we're not debugging. */
+#ifdef DEBUG
+#define DEBUG_PUSH PUSH_FAILURE_ITEM
+#define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_ITEM ()
+#else
+#define DEBUG_PUSH(item)
+#define DEBUG_POP(item_addr)
+#endif
+
+
+/* Push the information about the state we will need
+ if we ever fail back to it.
+
+ Requires variables fail_stack, regstart, regend, reg_info, and
+ num_regs be declared. DOUBLE_FAIL_STACK requires `destination' be
+ declared.
+
+ Does `return FAILURE_CODE' if runs out of memory. */
+
+#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \
+ do { \
+ char *destination; \
+ /* Must be int, so when we don't save any registers, the arithmetic \
+ of 0 + -1 isn't done as unsigned. */ \
+ int this_reg; \
+ \
+ DEBUG_STATEMENT (failure_id++); \
+ DEBUG_STATEMENT (nfailure_points_pushed++); \
+ DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
+ DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\
+ DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
+ \
+ DEBUG_PRINT2 (" slots needed: %d\n", NUM_FAILURE_ITEMS); \
+ DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \
+ \
+ /* Ensure we have enough space allocated for what we will push. */ \
+ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \
+ { \
+ if (!DOUBLE_FAIL_STACK (fail_stack)) \
+ return failure_code; \
+ \
+ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \
+ (fail_stack).size); \
+ DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
+ } \
+ \
+ /* Push the info, starting with the registers. */ \
+ DEBUG_PRINT1 ("\n"); \
+ \
+ for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
+ this_reg++) \
+ { \
+ DEBUG_PRINT2 (" Pushing reg: %d\n", this_reg); \
+ DEBUG_STATEMENT (num_regs_pushed++); \
+ \
+ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
+ PUSH_FAILURE_ITEM (regstart[this_reg]); \
+ \
+ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
+ PUSH_FAILURE_ITEM (regend[this_reg]); \
+ \
+ DEBUG_PRINT2 (" info: 0x%x\n ", reg_info[this_reg]); \
+ DEBUG_PRINT2 (" match_null=%d", \
+ REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" matched_something=%d", \
+ MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" ever_matched=%d", \
+ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT1 ("\n"); \
+ PUSH_FAILURE_ITEM (reg_info[this_reg].word); \
+ } \
+ \
+ DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\
+ PUSH_FAILURE_ITEM (lowest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing high active reg: %d\n", highest_active_reg);\
+ PUSH_FAILURE_ITEM (highest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing pattern 0x%x: ", pattern_place); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \
+ PUSH_FAILURE_ITEM (pattern_place); \
+ \
+ DEBUG_PRINT2 (" Pushing string 0x%x: `", string_place); \
+ DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \
+ size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ PUSH_FAILURE_ITEM (string_place); \
+ \
+ DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \
+ DEBUG_PUSH (failure_id); \
+ } while (0)
+
+/* This is the number of items that are pushed and popped on the stack
+ for each register. */
+#define NUM_REG_ITEMS 3
+
+/* Individual items aside from the registers. */
+#ifdef DEBUG
+#define NUM_NONREG_ITEMS 5 /* Includes failure point id. */
+#else
+#define NUM_NONREG_ITEMS 4
+#endif
+
+/* We push at most this many items on the stack. */
+#define MAX_FAILURE_ITEMS ((num_regs - 1) * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
+
+/* We actually push this many items. */
+#define NUM_FAILURE_ITEMS \
+ ((highest_active_reg - lowest_active_reg + 1) * NUM_REG_ITEMS \
+ + NUM_NONREG_ITEMS)
+
+/* How many items can still be added to the stack without overflowing it. */
+#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
+
+
+/* Pops what PUSH_FAIL_STACK pushes.
+
+ We restore into the parameters, all of which should be lvalues:
+ STR -- the saved data position.
+ PAT -- the saved pattern position.
+ LOW_REG, HIGH_REG -- the highest and lowest active registers.
+ REGSTART, REGEND -- arrays of string positions.
+ REG_INFO -- array of information about each subexpression.
+
+ Also assumes the variables `fail_stack' and (if debugging), `bufp',
+ `pend', `string1', `size1', `string2', and `size2'. */
+
+#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
+{ \
+ DEBUG_STATEMENT (fail_stack_elt_t failure_id;) \
+ int this_reg; \
+ const unsigned char *string_temp; \
+ \
+ assert (!FAIL_STACK_EMPTY ()); \
+ \
+ /* Remove failure points and point to how many regs pushed. */ \
+ DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
+ DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
+ DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
+ \
+ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \
+ \
+ DEBUG_POP (&failure_id); \
+ DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \
+ \
+ /* If the saved string location is NULL, it came from an \
+ on_failure_keep_string_jump opcode, and we want to throw away the \
+ saved NULL, thus retaining our current position in the string. */ \
+ string_temp = POP_FAILURE_ITEM (); \
+ if (string_temp != NULL) \
+ str = (const char *) string_temp; \
+ \
+ DEBUG_PRINT2 (" Popping string 0x%x: `", str); \
+ DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ \
+ pat = (unsigned char *) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" Popping pattern 0x%x: ", pat); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
+ \
+ /* Restore register info. */ \
+ high_reg = (unsigned) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" Popping high active reg: %d\n", high_reg); \
+ \
+ low_reg = (unsigned) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \
+ \
+ for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \
+ { \
+ DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \
+ \
+ reg_info[this_reg].word = POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" info: 0x%x\n", reg_info[this_reg]); \
+ \
+ regend[this_reg] = (const char *) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
+ \
+ regstart[this_reg] = (const char *) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
+ } \
+ \
+ DEBUG_STATEMENT (nfailure_points_popped++); \
+} /* POP_FAILURE_POINT */
+
+/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
+ BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible
+ characters can start a string that matches the pattern. This fastmap
+ is used by re_search to skip quickly over impossible starting points.
+
+ The caller must supply the address of a (1 << BYTEWIDTH)-byte data
+ area as BUFP->fastmap.
+
+ We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
+ the pattern buffer.
+
+ Returns 0 if we succeed, -2 if an internal error. */
+
+int
+re_compile_fastmap (bufp)
+ struct re_pattern_buffer *bufp;
+{
+ int j, k;
+ fail_stack_type fail_stack;
+#ifndef REGEX_MALLOC
+ char *destination;
+#endif
+ /* We don't push any register information onto the failure stack. */
+ unsigned num_regs = 0;
+
+ register char *fastmap = bufp->fastmap;
+ unsigned char *pattern = bufp->buffer;
+ unsigned long size = bufp->used;
+ const unsigned char *p = pattern;
+ register unsigned char *pend = pattern + size;
+
+ /* Assume that each path through the pattern can be null until
+ proven otherwise. We set this false at the bottom of switch
+ statement, to which we get only if a particular path doesn't
+ match the empty string. */
+ boolean path_can_be_null = true;
+
+ /* We aren't doing a `succeed_n' to begin with. */
+ boolean succeed_n_p = false;
+
+ assert (fastmap != NULL && p != NULL);
+
+ INIT_FAIL_STACK ();
+ bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */
+ bufp->fastmap_accurate = 1; /* It will be when we're done. */
+ bufp->can_be_null = 0;
+
+ while (p != pend || !FAIL_STACK_EMPTY ())
+ {
+ if (p == pend)
+ {
+ bufp->can_be_null |= path_can_be_null;
+
+ /* Reset for next path. */
+ path_can_be_null = true;
+
+ p = fail_stack.stack[--fail_stack.avail];
+ }
+
+ /* We should never be about to go beyond the end of the pattern. */
+ assert (p < pend);
+
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) ((re_opcode_t) *p++))
+#else
+ switch ((re_opcode_t) *p++)
+#endif
+ {
+
+ /* I guess the idea here is to simply not bother with a fastmap
+ if a backreference is used, since it's too hard to figure out
+ the fastmap for the corresponding group. Setting
+ `can_be_null' stops `re_search_2' from using the fastmap, so
+ that is all we do. */
+ case duplicate:
+ bufp->can_be_null = 1;
+ return 0;
+
+
+ /* Following are the cases which match a character. These end
+ with `break'. */
+
+ case exactn:
+ fastmap[p[1]] = 1;
+ break;
+
+
+ case charset:
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
+ fastmap[j] = 1;
+ break;
+
+
+ case charset_not:
+ /* Chars beyond end of map must be allowed. */
+ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
+ fastmap[j] = 1;
+
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
+ fastmap[j] = 1;
+ break;
+
+
+ case wordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == Sword)
+ fastmap[j] = 1;
+ break;
+
+
+ case notwordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != Sword)
+ fastmap[j] = 1;
+ break;
+
+
+ case anychar:
+ /* `.' matches anything ... */
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ fastmap[j] = 1;
+
+ /* ... except perhaps newline. */
+ if (!(bufp->syntax & RE_DOT_NEWLINE))
+ fastmap['\n'] = 0;
+
+ /* Return if we have already set `can_be_null'; if we have,
+ then the fastmap is irrelevant. Something's wrong here. */
+ else if (bufp->can_be_null)
+ return 0;
+
+ /* Otherwise, have to check alternative paths. */
+ break;
+
+
+#ifdef emacs
+ case syntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+
+
+ case notsyntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+
+
+ /* All cases after this match the empty string. These end with
+ `continue'. */
+
+
+ case before_dot:
+ case at_dot:
+ case after_dot:
+ continue;
+#endif /* not emacs */
+
+
+ case no_op:
+ case begline:
+ case endline:
+ case begbuf:
+ case endbuf:
+ case wordbound:
+ case notwordbound:
+ case wordbeg:
+ case wordend:
+ case push_dummy_failure:
+ continue;
+
+
+ case jump_n:
+ case pop_failure_jump:
+ case maybe_pop_jump:
+ case jump:
+ case jump_past_alt:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+ if (j > 0)
+ continue;
+
+ /* Jump backward implies we just went through the body of a
+ loop and matched nothing. Opcode jumped to should be
+ `on_failure_jump' or `succeed_n'. Just treat it like an
+ ordinary jump. For a * loop, it has pushed its failure
+ point already; if so, discard that as redundant. */
+ if ((re_opcode_t) *p != on_failure_jump
+ && (re_opcode_t) *p != succeed_n)
+ continue;
+
+ p++;
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+
+ /* If what's on the stack is where we are now, pop it. */
+ if (!FAIL_STACK_EMPTY ()
+ && fail_stack.stack[fail_stack.avail - 1] == p)
+ fail_stack.avail--;
+
+ continue;
+
+
+ case on_failure_jump:
+ case on_failure_keep_string_jump:
+ handle_on_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+
+ /* For some patterns, e.g., `(a?)?', `p+j' here points to the
+ end of the pattern. We don't want to push such a point,
+ since when we restore it above, entering the switch will
+ increment `p' past the end of the pattern. We don't need
+ to push such a point since we obviously won't find any more
+ fastmap entries beyond `pend'. Such a pattern can match
+ the null string, though. */
+ if (p + j < pend)
+ {
+ if (!PUSH_PATTERN_OP (p + j, fail_stack))
+ return -2;
+ }
+ else
+ bufp->can_be_null = 1;
+
+ if (succeed_n_p)
+ {
+ EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
+ succeed_n_p = false;
+ }
+
+ continue;
+
+
+ case succeed_n:
+ /* Get to the number of times to succeed. */
+ p += 2;
+
+ /* Increment p past the n for when k != 0. */
+ EXTRACT_NUMBER_AND_INCR (k, p);
+ if (k == 0)
+ {
+ p -= 4;
+ succeed_n_p = true; /* Spaghetti code alert. */
+ goto handle_on_failure_jump;
+ }
+ continue;
+
+
+ case set_number_at:
+ p += 4;
+ continue;
+
+
+ case start_memory:
+ case stop_memory:
+ p += 2;
+ continue;
+
+
+ default:
+ abort (); /* We have listed all the cases. */
+ } /* switch *p++ */
+
+ /* Getting here means we have found the possible starting
+ characters for one path of the pattern -- and that the empty
+ string does not match. We need not follow this path further.
+ Instead, look at the next alternative (remembered on the
+ stack), or quit if no more. The test at the top of the loop
+ does these things. */
+ path_can_be_null = false;
+ p = pend;
+ } /* while p */
+
+ /* Set `can_be_null' for the last path (also the first path, if the
+ pattern is empty). */
+ bufp->can_be_null |= path_can_be_null;
+ return 0;
+} /* re_compile_fastmap */
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use
+ this memory for recording register information. STARTS and ENDS
+ must be allocated using the malloc library routine, and must each
+ be at least NUM_REGS * sizeof (regoff_t) bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+
+void
+re_set_registers (bufp, regs, num_regs, starts, ends)
+ struct re_pattern_buffer *bufp;
+ struct re_registers *regs;
+ unsigned num_regs;
+ regoff_t *starts, *ends;
+{
+ if (num_regs)
+ {
+ bufp->regs_allocated = REGS_REALLOCATE;
+ regs->num_regs = num_regs;
+ regs->start = starts;
+ regs->end = ends;
+ }
+ else
+ {
+ bufp->regs_allocated = REGS_UNALLOCATED;
+ regs->num_regs = 0;
+ regs->start = regs->end = (regoff_t) 0;
+ }
+}
+
+/* Searching routines. */
+
+/* Like re_search_2, below, but only one string is specified, and
+ doesn't let you say where to stop matching. */
+
+int
+re_search (bufp, string, size, startpos, range, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int size, startpos, range;
+ struct re_registers *regs;
+{
+ return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
+ regs, size);
+}
+
+
+/* Using the compiled pattern in BUFP->buffer, first tries to match the
+ virtual concatenation of STRING1 and STRING2, starting first at index
+ STARTPOS, then at STARTPOS + 1, and so on.
+
+ STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
+
+ RANGE is how far to scan while trying to match. RANGE = 0 means try
+ only at STARTPOS; in general, the last start tried is STARTPOS +
+ RANGE.
+
+ In REGS, return the indices of the virtual concatenation of STRING1
+ and STRING2 that matched the entire BUFP->buffer and its contained
+ subexpressions.
+
+ Do not consider matching one past the index STOP in the virtual
+ concatenation of STRING1 and STRING2.
+
+ We return either the position in the strings at which the match was
+ found, -1 if no match, or -2 if error (such as failure
+ stack overflow). */
+
+int
+re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int startpos;
+ int range;
+ struct re_registers *regs;
+ int stop;
+{
+ int val;
+ register char *fastmap = bufp->fastmap;
+ register char *translate = bufp->translate;
+ int total_size = size1 + size2;
+ int endpos = startpos + range;
+
+ /* Check for out-of-range STARTPOS. */
+ if (startpos < 0 || startpos > total_size)
+ return -1;
+
+ /* Fix up RANGE if it might eventually take us outside
+ the virtual concatenation of STRING1 and STRING2. */
+ if (endpos < -1)
+ range = -1 - startpos;
+ else if (endpos > total_size)
+ range = total_size - startpos;
+
+ /* If the search isn't to be a backwards one, don't waste time in a
+ search for a pattern that must be anchored. */
+ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0)
+ {
+ if (startpos > 0)
+ return -1;
+ else
+ range = 1;
+ }
+
+ /* Update the fastmap now if not correct already. */
+ if (fastmap && !bufp->fastmap_accurate)
+ if (re_compile_fastmap (bufp) == -2)
+ return -2;
+
+ /* Loop through the string, looking for a place to start matching. */
+ for (;;)
+ {
+ /* If a fastmap is supplied, skip quickly over characters that
+ cannot be the start of a match. If the pattern can match the
+ null string, however, we don't need to skip characters; we want
+ the first null string. */
+ if (fastmap && startpos < total_size && !bufp->can_be_null)
+ {
+ if (range > 0) /* Searching forwards. */
+ {
+ register const char *d;
+ register int lim = 0;
+ int irange = range;
+
+ if (startpos < size1 && startpos + range >= size1)
+ lim = range - (size1 - startpos);
+
+ d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
+
+ /* Written out as an if-else to avoid testing `translate'
+ inside the loop. */
+ if (translate)
+ while (range > lim
+ && !fastmap[(unsigned char)
+ translate[(unsigned char) *d++]])
+ range--;
+ else
+ while (range > lim && !fastmap[(unsigned char) *d++])
+ range--;
+
+ startpos += irange - range;
+ }
+ else /* Searching backwards. */
+ {
+ register char c = (size1 == 0 || startpos >= size1
+ ? string2[startpos - size1]
+ : string1[startpos]);
+
+ if (!fastmap[(unsigned char) TRANSLATE (c)])
+ goto advance;
+ }
+ }
+
+ /* If can't match the null string, and that's all we have left, fail. */
+ if (range >= 0 && startpos == total_size && fastmap
+ && !bufp->can_be_null)
+ return -1;
+
+ val = re_match_2 (bufp, string1, size1, string2, size2,
+ startpos, regs, stop);
+ if (val >= 0)
+ return startpos;
+
+ if (val == -2)
+ return -2;
+
+ advance:
+ if (!range)
+ break;
+ else if (range > 0)
+ {
+ range--;
+ startpos++;
+ }
+ else
+ {
+ range++;
+ startpos--;
+ }
+ }
+ return -1;
+} /* re_search_2 */
+
+/* Declarations and macros for re_match_2. */
+
+static int bcmp_translate ();
+static boolean alt_match_null_string_p (),
+ common_op_match_null_string_p (),
+ group_match_null_string_p ();
+
+/* Structure for per-register (a.k.a. per-group) information.
+ This must not be longer than one word, because we push this value
+ onto the failure stack. Other register information, such as the
+ starting and ending positions (which are addresses), and the list of
+ inner groups (which is a bits list) are maintained in separate
+ variables.
+
+ We are making a (strictly speaking) nonportable assumption here: that
+ the compiler will pack our bit fields into something that fits into
+ the type of `word', i.e., is something that fits into one item on the
+ failure stack. */
+typedef union
+{
+ fail_stack_elt_t word;
+ struct
+ {
+ /* This field is one if this group can match the empty string,
+ zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
+#define MATCH_NULL_UNSET_VALUE 3
+ unsigned match_null_string_p : 2;
+ unsigned is_active : 1;
+ unsigned matched_something : 1;
+ unsigned ever_matched_something : 1;
+ } bits;
+} register_info_type;
+
+#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
+#define IS_ACTIVE(R) ((R).bits.is_active)
+#define MATCHED_SOMETHING(R) ((R).bits.matched_something)
+#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
+
+
+/* Call this when have matched a real character; it sets `matched' flags
+ for the subexpressions which we are currently inside. Also records
+ that those subexprs have matched. */
+#define SET_REGS_MATCHED() \
+ do \
+ { \
+ unsigned r; \
+ for (r = lowest_active_reg; r <= highest_active_reg; r++) \
+ { \
+ MATCHED_SOMETHING (reg_info[r]) \
+ = EVER_MATCHED_SOMETHING (reg_info[r]) \
+ = 1; \
+ } \
+ } \
+ while (0)
+
+
+/* This converts PTR, a pointer into one of the search strings `string1'
+ and `string2' into an offset from the beginning of that string. */
+#define POINTER_TO_OFFSET(ptr) \
+ (FIRST_STRING_P (ptr) ? (ptr) - string1 : (ptr) - string2 + size1)
+
+/* Registers are set to a sentinel when they haven't yet matched. */
+#define REG_UNSET_VALUE ((char *) -1)
+#define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
+
+
+/* Macros for dealing with the split strings in re_match_2. */
+
+#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
+
+/* Call before fetching a character with *d. This switches over to
+ string2 if necessary. */
+#define PREFETCH() \
+ while (d == dend) \
+ { \
+ /* End of string2 => fail. */ \
+ if (dend == end_match_2) \
+ goto fail; \
+ /* End of string1 => advance to string2. */ \
+ d = string2; \
+ dend = end_match_2; \
+ }
+
+
+/* Test if at very beginning or at very end of the virtual concatenation
+ of `string1' and `string2'. If only one string, it's `string2'. */
+#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
+#define AT_STRINGS_END(d) ((d) == end2)
+
+
+/* Test if D points to a character which is word-constituent. We have
+ two special cases to check for: if past the end of string1, look at
+ the first character in string2; and if before the beginning of
+ string2, look at the last character in string1. */
+#define WORDCHAR_P(d) \
+ (SYNTAX ((d) == end1 ? *string2 \
+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
+ == Sword)
+
+/* Test if the character before D and the one at D differ with respect
+ to being word-constituent. */
+#define AT_WORD_BOUNDARY(d) \
+ (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \
+ || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
+
+
+/* Free everything we malloc. */
+#ifdef REGEX_MALLOC
+#define FREE_VAR(var) if (var) free (var); var = NULL
+#define FREE_VARIABLES() \
+ do { \
+ FREE_VAR (fail_stack.stack); \
+ FREE_VAR (regstart); \
+ FREE_VAR (regend); \
+ FREE_VAR (old_regstart); \
+ FREE_VAR (old_regend); \
+ FREE_VAR (best_regstart); \
+ FREE_VAR (best_regend); \
+ FREE_VAR (reg_info); \
+ FREE_VAR (reg_dummy); \
+ FREE_VAR (reg_info_dummy); \
+ } while (0)
+#else /* not REGEX_MALLOC */
+/* Some MIPS systems (at least) want this to free alloca'd storage. */
+#define FREE_VARIABLES() alloca (0)
+#endif /* not REGEX_MALLOC */
+
+
+/* These values must meet several constraints. They must not be valid
+ register values; since we have a limit of 255 registers (because
+ we use only one byte in the pattern for the register number), we can
+ use numbers larger than 255. They must differ by 1, because of
+ NUM_FAILURE_ITEMS above. And the value for the lowest register must
+ be larger than the value for the highest register, so we do not try
+ to actually save any registers when none are active. */
+#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
+#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
+
+/* Matching routines. */
+
+#ifndef emacs /* Emacs never uses this. */
+/* re_match is like re_match_2 except it takes only a single string. */
+
+int
+re_match (bufp, string, size, pos, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int size, pos;
+ struct re_registers *regs;
+ {
+ return re_match_2 (bufp, NULL, 0, string, size, pos, regs, size);
+}
+#endif /* not emacs */
+
+
+/* re_match_2 matches the compiled pattern in BUFP against the
+ the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
+ and SIZE2, respectively). We start matching at POS, and stop
+ matching at STOP.
+
+ If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
+ store offsets for the substring each group matched in REGS. See the
+ documentation for exactly how many groups we fill.
+
+ We return -1 if no match, -2 if an internal error (such as the
+ failure stack overflowing). Otherwise, we return the length of the
+ matched substring. */
+
+int
+re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int pos;
+ struct re_registers *regs;
+ int stop;
+{
+ /* General temporaries. */
+ int mcnt;
+ unsigned char *p1;
+
+ /* Just past the end of the corresponding string. */
+ const char *end1, *end2;
+
+ /* Pointers into string1 and string2, just past the last characters in
+ each to consider matching. */
+ const char *end_match_1, *end_match_2;
+
+ /* Where we are in the data, and the end of the current string. */
+ const char *d, *dend;
+
+ /* Where we are in the pattern, and the end of the pattern. */
+ unsigned char *p = bufp->buffer;
+ register unsigned char *pend = p + bufp->used;
+
+ /* We use this to map every character in the string. */
+ char *translate = bufp->translate;
+
+ /* Failure point stack. Each place that can handle a failure further
+ down the line pushes a failure point on this stack. It consists of
+ restart, regend, and reg_info for all registers corresponding to
+ the subexpressions we're currently inside, plus the number of such
+ registers, and, finally, two char *'s. The first char * is where
+ to resume scanning the pattern; the second one is where to resume
+ scanning the strings. If the latter is zero, the failure point is
+ a ``dummy''; if a failure happens and the failure point is a dummy,
+ it gets discarded and the next next one is tried. */
+ fail_stack_type fail_stack;
+#ifdef DEBUG
+ static unsigned failure_id = 0;
+ unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
+#endif
+
+ /* We fill all the registers internally, independent of what we
+ return, for use in backreferences. The number here includes
+ an element for register zero. */
+ unsigned num_regs = bufp->re_nsub + 1;
+
+ /* The currently active registers. */
+ unsigned lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ unsigned highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+
+ /* Information on the contents of registers. These are pointers into
+ the input strings; they record just what was matched (on this
+ attempt) by a subexpression part of the pattern, that is, the
+ regnum-th regstart pointer points to where in the pattern we began
+ matching and the regnum-th regend points to right after where we
+ stopped matching the regnum-th subexpression. (The zeroth register
+ keeps track of what the whole pattern matches.) */
+ const char **regstart, **regend;
+
+ /* If a group that's operated upon by a repetition operator fails to
+ match anything, then the register for its start will need to be
+ restored because it will have been set to wherever in the string we
+ are when we last see its open-group operator. Similarly for a
+ register's end. */
+ const char **old_regstart, **old_regend;
+
+ /* The is_active field of reg_info helps us keep track of which (possibly
+ nested) subexpressions we are currently in. The matched_something
+ field of reg_info[reg_num] helps us tell whether or not we have
+ matched any of the pattern so far this time through the reg_num-th
+ subexpression. These two fields get reset each time through any
+ loop their register is in. */
+ register_info_type *reg_info;
+
+ /* The following record the register info as found in the above
+ variables when we find a match better than any we've seen before.
+ This happens as we backtrack through the failure points, which in
+ turn happens only if we have not yet matched the entire string. */
+ unsigned best_regs_set = false;
+ const char **best_regstart, **best_regend;
+
+ /* Logically, this is `best_regend[0]'. But we don't want to have to
+ allocate space for that if we're not allocating space for anything
+ else (see below). Also, we never need info about register 0 for
+ any of the other register vectors, and it seems rather a kludge to
+ treat `best_regend' differently than the rest. So we keep track of
+ the end of the best match so far in a separate variable. We
+ initialize this to NULL so that when we backtrack the first time
+ and need to test it, it's not garbage. */
+ const char *match_end = NULL;
+
+ /* Used when we pop values we don't care about. */
+ const char **reg_dummy;
+ register_info_type *reg_info_dummy;
+
+#ifdef DEBUG
+ /* Counts the total number of registers pushed. */
+ unsigned num_regs_pushed = 0;
+#endif
+
+ DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
+
+ INIT_FAIL_STACK ();
+
+ /* Do not bother to initialize all the register variables if there are
+ no groups in the pattern, as it takes a fair amount of time. If
+ there are groups, we include space for register 0 (the whole
+ pattern), even though we never use it, since it simplifies the
+ array indexing. We should fix this. */
+ if (bufp->re_nsub)
+ {
+ regstart = REGEX_TALLOC (num_regs, const char *);
+ regend = REGEX_TALLOC (num_regs, const char *);
+ old_regstart = REGEX_TALLOC (num_regs, const char *);
+ old_regend = REGEX_TALLOC (num_regs, const char *);
+ best_regstart = REGEX_TALLOC (num_regs, const char *);
+ best_regend = REGEX_TALLOC (num_regs, const char *);
+ reg_info = REGEX_TALLOC (num_regs, register_info_type);
+ reg_dummy = REGEX_TALLOC (num_regs, const char *);
+ reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type);
+
+ if (!(regstart && regend && old_regstart && old_regend && reg_info
+ && best_regstart && best_regend && reg_dummy && reg_info_dummy))
+ {
+ FREE_VARIABLES ();
+ return -2;
+ }
+ }
+#ifdef REGEX_MALLOC
+ else
+ {
+ /* We must initialize all our variables to NULL, so that
+ `FREE_VARIABLES' doesn't try to free them. */
+ regstart = regend = old_regstart = old_regend = best_regstart
+ = best_regend = reg_dummy = NULL;
+ reg_info = reg_info_dummy = (register_info_type *) NULL;
+ }
+#endif /* REGEX_MALLOC */
+
+ /* The starting position is bogus. */
+ if (pos < 0 || pos > size1 + size2)
+ {
+ FREE_VARIABLES ();
+ return -1;
+ }
+
+ /* Initialize subexpression text positions to -1 to mark ones that no
+ start_memory/stop_memory has been seen for. Also initialize the
+ register information struct. */
+ for (mcnt = 1; mcnt < num_regs; mcnt++)
+ {
+ regstart[mcnt] = regend[mcnt]
+ = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
+
+ REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
+ IS_ACTIVE (reg_info[mcnt]) = 0;
+ MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ }
+
+ /* We move `string1' into `string2' if the latter's empty -- but not if
+ `string1' is null. */
+ if (size2 == 0 && string1 != NULL)
+ {
+ string2 = string1;
+ size2 = size1;
+ string1 = 0;
+ size1 = 0;
+ }
+ end1 = string1 + size1;
+ end2 = string2 + size2;
+
+ /* Compute where to stop matching, within the two strings. */
+ if (stop <= size1)
+ {
+ end_match_1 = string1 + stop;
+ end_match_2 = string2;
+ }
+ else
+ {
+ end_match_1 = end1;
+ end_match_2 = string2 + stop - size1;
+ }
+
+ /* `p' scans through the pattern as `d' scans through the data.
+ `dend' is the end of the input string that `d' points within. `d'
+ is advanced into the following input string whenever necessary, but
+ this happens before fetching; therefore, at the beginning of the
+ loop, `d' can be pointing at the end of a string, but it cannot
+ equal `string2'. */
+ if (size1 > 0 && pos <= size1)
+ {
+ d = string1 + pos;
+ dend = end_match_1;
+ }
+ else
+ {
+ d = string2 + pos - size1;
+ dend = end_match_2;
+ }
+
+ DEBUG_PRINT1 ("The compiled pattern is: ");
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
+ DEBUG_PRINT1 ("The string to match is: `");
+ DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
+ DEBUG_PRINT1 ("'\n");
+
+ /* This loops over pattern commands. It exits by returning from the
+ function if the match is complete, or it drops through if the match
+ fails at this starting point in the input data. */
+ for (;;)
+ {
+ DEBUG_PRINT2 ("\n0x%x: ", p);
+
+ if (p == pend)
+ { /* End of pattern means we might have succeeded. */
+ DEBUG_PRINT1 ("end of pattern ... ");
+
+ /* If we haven't matched the entire string, and we want the
+ longest match, try backtracking. */
+ if (d != end_match_2)
+ {
+ DEBUG_PRINT1 ("backtracking.\n");
+
+ if (!FAIL_STACK_EMPTY ())
+ { /* More failure points to try. */
+ boolean same_str_p = (FIRST_STRING_P (match_end)
+ == MATCHING_IN_FIRST_STRING);
+
+ /* If exceeds best match so far, save it. */
+ if (!best_regs_set
+ || (same_str_p && d > match_end)
+ || (!same_str_p && !MATCHING_IN_FIRST_STRING))
+ {
+ best_regs_set = true;
+ match_end = d;
+
+ DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
+
+ for (mcnt = 1; mcnt < num_regs; mcnt++)
+ {
+ best_regstart[mcnt] = regstart[mcnt];
+ best_regend[mcnt] = regend[mcnt];
+ }
+ }
+ goto fail;
+ }
+
+ /* If no failure points, don't restore garbage. */
+ else if (best_regs_set)
+ {
+ restore_best_regs:
+ /* Restore best match. It may happen that `dend ==
+ end_match_1' while the restored d is in string2.
+ For example, the pattern `x.*y.*z' against the
+ strings `x-' and `y-z-', if the two strings are
+ not consecutive in memory. */
+ DEBUG_PRINT1 ("Restoring best registers.\n");
+
+ d = match_end;
+ dend = ((d >= string1 && d <= end1)
+ ? end_match_1 : end_match_2);
+
+ for (mcnt = 1; mcnt < num_regs; mcnt++)
+ {
+ regstart[mcnt] = best_regstart[mcnt];
+ regend[mcnt] = best_regend[mcnt];
+ }
+ }
+ } /* d != end_match_2 */
+
+ DEBUG_PRINT1 ("Accepting match.\n");
+
+ /* If caller wants register contents data back, do it. */
+ if (regs && !bufp->no_sub)
+ {
+ /* Have the register data arrays been allocated? */
+ if (bufp->regs_allocated == REGS_UNALLOCATED)
+ { /* No. So allocate them with malloc. We need one
+ extra element beyond `num_regs' for the `-1' marker
+ GNU code uses. */
+ regs->num_regs = MAX (RE_NREGS, num_regs + 1);
+ regs->start = TALLOC (regs->num_regs, regoff_t);
+ regs->end = TALLOC (regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ return -2;
+ bufp->regs_allocated = REGS_REALLOCATE;
+ }
+ else if (bufp->regs_allocated == REGS_REALLOCATE)
+ { /* Yes. If we need more elements than were already
+ allocated, reallocate them. If we need fewer, just
+ leave it alone. */
+ if (regs->num_regs < num_regs + 1)
+ {
+ regs->num_regs = num_regs + 1;
+ RETALLOC (regs->start, regs->num_regs, regoff_t);
+ RETALLOC (regs->end, regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ return -2;
+ }
+ }
+ else
+ assert (bufp->regs_allocated == REGS_FIXED);
+
+ /* Convert the pointer data in `regstart' and `regend' to
+ indices. Register zero has to be set differently,
+ since we haven't kept track of any info for it. */
+ if (regs->num_regs > 0)
+ {
+ regs->start[0] = pos;
+ regs->end[0] = (MATCHING_IN_FIRST_STRING ? d - string1
+ : d - string2 + size1);
+ }
+
+ /* Go through the first `min (num_regs, regs->num_regs)'
+ registers, since that is all we initialized. */
+ for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++)
+ {
+ if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+ else
+ {
+ regs->start[mcnt] = POINTER_TO_OFFSET (regstart[mcnt]);
+ regs->end[mcnt] = POINTER_TO_OFFSET (regend[mcnt]);
+ }
+ }
+
+ /* If the regs structure we return has more elements than
+ were in the pattern, set the extra elements to -1. If
+ we (re)allocated the registers, this is the case,
+ because we always allocate enough to have at least one
+ -1 at the end. */
+ for (mcnt = num_regs; mcnt < regs->num_regs; mcnt++)
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+ } /* regs && !bufp->no_sub */
+
+ FREE_VARIABLES ();
+ DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
+ nfailure_points_pushed, nfailure_points_popped,
+ nfailure_points_pushed - nfailure_points_popped);
+ DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
+
+ mcnt = d - pos - (MATCHING_IN_FIRST_STRING
+ ? string1
+ : string2 - size1);
+
+ DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
+
+ return mcnt;
+ }
+
+ /* Otherwise match next pattern command. */
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) ((re_opcode_t) *p++))
+#else
+ switch ((re_opcode_t) *p++)
+#endif
+ {
+ /* Ignore these. Used to ignore the n of succeed_n's which
+ currently have n == 0. */
+ case no_op:
+ DEBUG_PRINT1 ("EXECUTING no_op.\n");
+ break;
+
+
+ /* Match the next n pattern characters exactly. The following
+ byte in the pattern defines n, and the n bytes after that
+ are the characters to match. */
+ case exactn:
+ mcnt = *p++;
+ DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
+
+ /* This is written out as an if-else so we don't waste time
+ testing `translate' inside the loop. */
+ if (translate)
+ {
+ do
+ {
+ PREFETCH ();
+ if (translate[(unsigned char) *d++] != (char) *p++)
+ goto fail;
+ }
+ while (--mcnt);
+ }
+ else
+ {
+ do
+ {
+ PREFETCH ();
+ if (*d++ != (char) *p++) goto fail;
+ }
+ while (--mcnt);
+ }
+ SET_REGS_MATCHED ();
+ break;
+
+
+ /* Match any character except possibly a newline or a null. */
+ case anychar:
+ DEBUG_PRINT1 ("EXECUTING anychar.\n");
+
+ PREFETCH ();
+
+ if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
+ || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
+ goto fail;
+
+ SET_REGS_MATCHED ();
+ DEBUG_PRINT2 (" Matched `%d'.\n", *d);
+ d++;
+ break;
+
+
+ case charset:
+ case charset_not:
+ {
+ register unsigned char c;
+ boolean not = (re_opcode_t) *(p - 1) == charset_not;
+
+ DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : "");
+
+ PREFETCH ();
+ c = TRANSLATE (*d); /* The character to match. */
+
+ /* Cast to `unsigned' instead of `unsigned char' in case the
+ bit list is a full 32 bytes long. */
+ if (c < (unsigned) (*p * BYTEWIDTH)
+ && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+
+ p += 1 + *p;
+
+ if (!not) goto fail;
+
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+ }
+
+
+ /* The beginning of a group is represented by start_memory.
+ The arguments are the register number in the next byte, and the
+ number of groups inner to this one in the next. The text
+ matched within the group is recorded (in the internal
+ registers data structure) under the register number. */
+ case start_memory:
+ DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]);
+
+ /* Find out if this group can match the empty string. */
+ p1 = p; /* To send to group_match_null_string_p. */
+
+ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[*p])
+ = group_match_null_string_p (&p1, pend, reg_info);
+
+ /* Save the position in the string where we were the last time
+ we were at this open-group operator in case the group is
+ operated upon by a repetition operator, e.g., with `(a*)*b'
+ against `ab'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
+ : regstart[*p];
+ DEBUG_PRINT2 (" old_regstart: %d\n",
+ POINTER_TO_OFFSET (old_regstart[*p]));
+
+ regstart[*p] = d;
+ DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
+
+ IS_ACTIVE (reg_info[*p]) = 1;
+ MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* This is the new highest active register. */
+ highest_active_reg = *p;
+
+ /* If nothing was active before, this is the new lowest active
+ register. */
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *p;
+
+ /* Move past the register number and inner group count. */
+ p += 2;
+ break;
+
+
+ /* The stop_memory opcode represents the end of a group. Its
+ arguments are the same as start_memory's: the register
+ number, and the number of inner groups. */
+ case stop_memory:
+ DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]);
+
+ /* We need to save the string position the last time we were at
+ this close-group operator in case the group is operated
+ upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
+ against `aba'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regend[*p]) ? d : regend[*p]
+ : regend[*p];
+ DEBUG_PRINT2 (" old_regend: %d\n",
+ POINTER_TO_OFFSET (old_regend[*p]));
+
+ regend[*p] = d;
+ DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
+
+ /* This register isn't active anymore. */
+ IS_ACTIVE (reg_info[*p]) = 0;
+
+ /* If this was the only register active, nothing is active
+ anymore. */
+ if (lowest_active_reg == highest_active_reg)
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ { /* We must scan for the new highest active register, since
+ it isn't necessarily one less than now: consider
+ (a(b)c(d(e)f)g). When group 3 ends, after the f), the
+ new highest active register is 1. */
+ unsigned char r = *p - 1;
+ while (r > 0 && !IS_ACTIVE (reg_info[r]))
+ r--;
+
+ /* If we end up at register zero, that means that we saved
+ the registers as the result of an `on_failure_jump', not
+ a `start_memory', and we jumped to past the innermost
+ `stop_memory'. For example, in ((.)*) we save
+ registers 1 and 2 as a result of the *, but when we pop
+ back to the second ), we are at the stop_memory 1.
+ Thus, nothing is active. */
+ if (r == 0)
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ highest_active_reg = r;
+ }
+
+ /* If just failed to match something this time around with a
+ group that's operated on by a repetition operator, try to
+ force exit from the ``loop'', and restore the register
+ information for this group that we had before trying this
+ last match. */
+ if ((!MATCHED_SOMETHING (reg_info[*p])
+ || (re_opcode_t) p[-3] == start_memory)
+ && (p + 2) < pend)
+ {
+ boolean is_a_jump_n = false;
+
+ p1 = p + 2;
+ mcnt = 0;
+ switch ((re_opcode_t) *p1++)
+ {
+ case jump_n:
+ is_a_jump_n = true;
+ case pop_failure_jump:
+ case maybe_pop_jump:
+ case jump:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if (is_a_jump_n)
+ p1 += 2;
+ break;
+
+ default:
+ /* do nothing */ ;
+ }
+ p1 += mcnt;
+
+ /* If the next operation is a jump backwards in the pattern
+ to an on_failure_jump right before the start_memory
+ corresponding to this stop_memory, exit from the loop
+ by forcing a failure after pushing on the stack the
+ on_failure_jump's jump in the pattern, and d. */
+ if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
+ && (re_opcode_t) p1[3] == start_memory && p1[4] == *p)
+ {
+ /* If this group ever matched anything, then restore
+ what its registers were before trying this last
+ failed match, e.g., with `(a*)*b' against `ab' for
+ regstart[1], and, e.g., with `((a*)*(b*)*)*'
+ against `aba' for regend[3].
+
+ Also restore the registers for inner groups for,
+ e.g., `((a*)(b*))*' against `aba' (register 3 would
+ otherwise get trashed). */
+
+ if (EVER_MATCHED_SOMETHING (reg_info[*p]))
+ {
+ unsigned r;
+
+ EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* Restore this and inner groups' (if any) registers. */
+ for (r = *p; r < *p + *(p + 1); r++)
+ {
+ regstart[r] = old_regstart[r];
+
+ /* xx why this test? */
+ if ((int) old_regend[r] >= (int) regstart[r])
+ regend[r] = old_regend[r];
+ }
+ }
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
+
+ goto fail;
+ }
+ }
+
+ /* Move past the register number and the inner group count. */
+ p += 2;
+ break;
+
+
+ /* \<digit> has been turned into a `duplicate' command which is
+ followed by the numeric value of <digit> as the register number. */
+ case duplicate:
+ {
+ register const char *d2, *dend2;
+ int regno = *p++; /* Get which register to match against. */
+ DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
+
+ /* Can't back reference a group which we've never matched. */
+ if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
+ goto fail;
+
+ /* Where in input to try to start matching. */
+ d2 = regstart[regno];
+
+ /* Where to stop matching; if both the place to start and
+ the place to stop matching are in the same string, then
+ set to the place to stop, otherwise, for now have to use
+ the end of the first string. */
+
+ dend2 = ((FIRST_STRING_P (regstart[regno])
+ == FIRST_STRING_P (regend[regno]))
+ ? regend[regno] : end_match_1);
+ for (;;)
+ {
+ /* If necessary, advance to next segment in register
+ contents. */
+ while (d2 == dend2)
+ {
+ if (dend2 == end_match_2) break;
+ if (dend2 == regend[regno]) break;
+
+ /* End of string1 => advance to string2. */
+ d2 = string2;
+ dend2 = regend[regno];
+ }
+ /* At end of register contents => success */
+ if (d2 == dend2) break;
+
+ /* If necessary, advance to next segment in data. */
+ PREFETCH ();
+
+ /* How many characters left in this segment to match. */
+ mcnt = dend - d;
+
+ /* Want how many consecutive characters we can match in
+ one shot, so, if necessary, adjust the count. */
+ if (mcnt > dend2 - d2)
+ mcnt = dend2 - d2;
+
+ /* Compare that many; failure if mismatch, else move
+ past them. */
+ if (translate
+ ? bcmp_translate (d, d2, mcnt, translate)
+ : bcmp (d, d2, mcnt))
+ goto fail;
+ d += mcnt, d2 += mcnt;
+ }
+ }
+ break;
+
+
+ /* begline matches the empty string at the beginning of the string
+ (unless `not_bol' is set in `bufp'), and, if
+ `newline_anchor' is set, after newlines. */
+ case begline:
+ DEBUG_PRINT1 ("EXECUTING begline.\n");
+
+ if (AT_STRINGS_BEG (d))
+ {
+ if (!bufp->not_bol) break;
+ }
+ else if (d[-1] == '\n' && bufp->newline_anchor)
+ {
+ break;
+ }
+ /* In all other cases, we fail. */
+ goto fail;
+
+
+ /* endline is the dual of begline. */
+ case endline:
+ DEBUG_PRINT1 ("EXECUTING endline.\n");
+
+ if (AT_STRINGS_END (d))
+ {
+ if (!bufp->not_eol) break;
+ }
+
+ /* We have to ``prefetch'' the next character. */
+ else if ((d == end1 ? *string2 : *d) == '\n'
+ && bufp->newline_anchor)
+ {
+ break;
+ }
+ goto fail;
+
+
+ /* Match at the very beginning of the data. */
+ case begbuf:
+ DEBUG_PRINT1 ("EXECUTING begbuf.\n");
+ if (AT_STRINGS_BEG (d))
+ break;
+ goto fail;
+
+
+ /* Match at the very end of the data. */
+ case endbuf:
+ DEBUG_PRINT1 ("EXECUTING endbuf.\n");
+ if (AT_STRINGS_END (d))
+ break;
+ goto fail;
+
+
+ /* on_failure_keep_string_jump is used to optimize `.*\n'. It
+ pushes NULL as the value for the string on the stack. Then
+ `pop_failure_point' will keep the current value for the
+ string, instead of restoring it. To see why, consider
+ matching `foo\nbar' against `.*\n'. The .* matches the foo;
+ then the . fails against the \n. But the next thing we want
+ to do is match the \n against the \n; if we restored the
+ string value, we would be back at the foo.
+
+ Because this is used only in specific cases, we don't need to
+ check all the things that `on_failure_jump' does, to make
+ sure the right things get saved on the stack. Hence we don't
+ share its code. The only reason to push anything on the
+ stack at all is that otherwise we would have to change
+ `anychar's code to do something besides goto fail in this
+ case; that seems worse than this. */
+ case on_failure_keep_string_jump:
+ DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
+
+ PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
+ break;
+
+
+ /* Uses of on_failure_jump:
+
+ Each alternative starts with an on_failure_jump that points
+ to the beginning of the next alternative. Each alternative
+ except the last ends with a jump that in effect jumps past
+ the rest of the alternatives. (They really jump to the
+ ending jump of the following alternative, because tensioning
+ these jumps is a hassle.)
+
+ Repeats start with an on_failure_jump that points past both
+ the repetition text and either the following jump or
+ pop_failure_jump back to this on_failure_jump. */
+ case on_failure_jump:
+ on_failure:
+ DEBUG_PRINT1 ("EXECUTING on_failure_jump");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
+
+ /* If this on_failure_jump comes right before a group (i.e.,
+ the original * applied to a group), save the information
+ for that group and all inner ones, so that if we fail back
+ to this point, the group's information will be correct.
+ For example, in \(a*\)*\1, we need the preceding group,
+ and in \(\(a*\)b*\)\2, we need the inner group. */
+
+ /* We can't use `p' to check ahead because we push
+ a failure point to `p + mcnt' after we do this. */
+ p1 = p;
+
+ /* We need to skip no_op's before we look for the
+ start_memory in case this on_failure_jump is happening as
+ the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
+ against aba. */
+ while (p1 < pend && (re_opcode_t) *p1 == no_op)
+ p1++;
+
+ if (p1 < pend && (re_opcode_t) *p1 == start_memory)
+ {
+ /* We have a new highest active register now. This will
+ get reset at the start_memory we are about to get to,
+ but we will have saved all the registers relevant to
+ this repetition op, as described above. */
+ highest_active_reg = *(p1 + 1) + *(p1 + 2);
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *(p1 + 1);
+ }
+
+ DEBUG_PRINT1 (":\n");
+ PUSH_FAILURE_POINT (p + mcnt, d, -2);
+ break;
+
+
+ /* A smart repeat ends with `maybe_pop_jump'.
+ We change it to either `pop_failure_jump' or `jump'. */
+ case maybe_pop_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
+ {
+ register unsigned char *p2 = p;
+
+ /* Compare the beginning of the repeat with what in the
+ pattern follows its end. If we can establish that there
+ is nothing that they would both match, i.e., that we
+ would have to backtrack because of (as in, e.g., `a*a')
+ then we can change to pop_failure_jump, because we'll
+ never have to backtrack.
+
+ This is not true in the case of alternatives: in
+ `(a|ab)*' we do need to backtrack to the `ab' alternative
+ (e.g., if the string was `ab'). But instead of trying to
+ detect that here, the alternative has put on a dummy
+ failure point which is what we will end up popping. */
+
+ /* Skip over open/close-group commands. */
+ while (p2 + 2 < pend
+ && ((re_opcode_t) *p2 == stop_memory
+ || (re_opcode_t) *p2 == start_memory))
+ p2 += 3; /* Skip over args, too. */
+
+ /* If we're at the end of the pattern, we can change. */
+ if (p2 == pend)
+ {
+ /* Consider what happens when matching ":\(.*\)"
+ against ":/". I don't really understand this code
+ yet. */
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1
+ (" End of pattern: change to `pop_failure_jump'.\n");
+ }
+
+ else if ((re_opcode_t) *p2 == exactn
+ || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
+ {
+ register unsigned char c
+ = *p2 == (unsigned char) endline ? '\n' : p2[2];
+ p1 = p + mcnt;
+
+ /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
+ to the `maybe_finalize_jump' of this case. Examine what
+ follows. */
+ if ((re_opcode_t) p1[3] == exactn && p1[5] != c)
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
+ c, p1[5]);
+ }
+
+ else if ((re_opcode_t) p1[3] == charset
+ || (re_opcode_t) p1[3] == charset_not)
+ {
+ int not = (re_opcode_t) p1[3] == charset_not;
+
+ if (c < (unsigned char) (p1[4] * BYTEWIDTH)
+ && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+
+ /* `not' is equal to 1 if c would match, which means
+ that we can't change to pop_failure_jump. */
+ if (!not)
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ }
+ }
+ p -= 2; /* Point at relative address again. */
+ if ((re_opcode_t) p[-1] != pop_failure_jump)
+ {
+ p[-1] = (unsigned char) jump;
+ DEBUG_PRINT1 (" Match => jump.\n");
+ goto unconditional_jump;
+ }
+ /* Note fall through. */
+
+
+ /* The end of a simple repeat has a pop_failure_jump back to
+ its matching on_failure_jump, where the latter will push a
+ failure point. The pop_failure_jump takes off failure
+ points put on by this pop_failure_jump's matching
+ on_failure_jump; we got through the pattern to here from the
+ matching on_failure_jump, so didn't fail. */
+ case pop_failure_jump:
+ {
+ /* We need to pass separate storage for the lowest and
+ highest registers, even though we don't care about the
+ actual values. Otherwise, we will restore only one
+ register from the stack, since lowest will == highest in
+ `pop_failure_point'. */
+ unsigned dummy_low_reg, dummy_high_reg;
+ unsigned char *pdummy;
+ const char *sdummy;
+
+ DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
+ POP_FAILURE_POINT (sdummy, pdummy,
+ dummy_low_reg, dummy_high_reg,
+ reg_dummy, reg_dummy, reg_info_dummy);
+ }
+ /* Note fall through. */
+
+
+ /* Unconditionally jump (without popping any failure points). */
+ case jump:
+ unconditional_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
+ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
+ p += mcnt; /* Do the jump. */
+ DEBUG_PRINT2 ("(to 0x%x).\n", p);
+ break;
+
+
+ /* We need this opcode so we can detect where alternatives end
+ in `group_match_null_string_p' et al. */
+ case jump_past_alt:
+ DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
+ goto unconditional_jump;
+
+
+ /* Normally, the on_failure_jump pushes a failure point, which
+ then gets popped at pop_failure_jump. We will end up at
+ pop_failure_jump, also, and with a pattern of, say, `a+', we
+ are skipping over the on_failure_jump, so we have to push
+ something meaningless for pop_failure_jump to pop. */
+ case dummy_failure_jump:
+ DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
+ /* It doesn't matter what we push for the string here. What
+ the code at `fail' tests is the value for the pattern. */
+ PUSH_FAILURE_POINT (0, 0, -2);
+ goto unconditional_jump;
+
+
+ /* At the end of an alternative, we need to push a dummy failure
+ point in case we are followed by a `pop_failure_jump', because
+ we don't want the failure point for the alternative to be
+ popped. For example, matching `(a|ab)*' against `aab'
+ requires that we match the `ab' alternative. */
+ case push_dummy_failure:
+ DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
+ /* See comments just above at `dummy_failure_jump' about the
+ two zeroes. */
+ PUSH_FAILURE_POINT (0, 0, -2);
+ break;
+
+ /* Have to succeed matching what follows at least n times.
+ After that, handle like `on_failure_jump'. */
+ case succeed_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
+
+ assert (mcnt >= 0);
+ /* Originally, this is how many times we HAVE to succeed. */
+ if (mcnt > 0)
+ {
+ mcnt--;
+ p += 2;
+ STORE_NUMBER_AND_INCR (p, mcnt);
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p, mcnt);
+ }
+ else if (mcnt == 0)
+ {
+ DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2);
+ p[2] = (unsigned char) no_op;
+ p[3] = (unsigned char) no_op;
+ goto on_failure;
+ }
+ break;
+
+ case jump_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
+
+ /* Originally, this is how many times we CAN jump. */
+ if (mcnt)
+ {
+ mcnt--;
+ STORE_NUMBER (p + 2, mcnt);
+ goto unconditional_jump;
+ }
+ /* If don't have to jump any more, skip over the rest of command. */
+ else
+ p += 4;
+ break;
+
+ case set_number_at:
+ {
+ DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ p1 = p + mcnt;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt);
+ STORE_NUMBER (p1, mcnt);
+ break;
+ }
+
+ case wordbound:
+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
+ if (AT_WORD_BOUNDARY (d))
+ break;
+ goto fail;
+
+ case notwordbound:
+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
+ if (AT_WORD_BOUNDARY (d))
+ goto fail;
+ break;
+
+ case wordbeg:
+ DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
+ if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
+ break;
+ goto fail;
+
+ case wordend:
+ DEBUG_PRINT1 ("EXECUTING wordend.\n");
+ if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
+ && (!WORDCHAR_P (d) || AT_STRINGS_END (d)))
+ break;
+ goto fail;
+
+#ifdef emacs
+#ifdef emacs19
+ case before_dot:
+ DEBUG_PRINT1 ("EXECUTING before_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) >= point)
+ goto fail;
+ break;
+
+ case at_dot:
+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) != point)
+ goto fail;
+ break;
+
+ case after_dot:
+ DEBUG_PRINT1 ("EXECUTING after_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) <= point)
+ goto fail;
+ break;
+#else /* not emacs19 */
+ case at_dot:
+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) + 1 != point)
+ goto fail;
+ break;
+#endif /* not emacs19 */
+
+ case syntaxspec:
+ DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
+ mcnt = *p++;
+ goto matchsyntax;
+
+ case wordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
+ mcnt = (int) Sword;
+ matchsyntax:
+ PREFETCH ();
+ if (SYNTAX (*d++) != (enum syntaxcode) mcnt)
+ goto fail;
+ SET_REGS_MATCHED ();
+ break;
+
+ case notsyntaxspec:
+ DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
+ mcnt = *p++;
+ goto matchnotsyntax;
+
+ case notwordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
+ mcnt = (int) Sword;
+ matchnotsyntax:
+ PREFETCH ();
+ if (SYNTAX (*d++) == (enum syntaxcode) mcnt)
+ goto fail;
+ SET_REGS_MATCHED ();
+ break;
+
+#else /* not emacs */
+ case wordchar:
+ DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
+ PREFETCH ();
+ if (!WORDCHAR_P (d))
+ goto fail;
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+
+ case notwordchar:
+ DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
+ PREFETCH ();
+ if (WORDCHAR_P (d))
+ goto fail;
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+#endif /* not emacs */
+
+ default:
+ abort ();
+ }
+ continue; /* Successfully executed one pattern command; keep going. */
+
+
+ /* We goto here if a matching operation fails. */
+ fail:
+ if (!FAIL_STACK_EMPTY ())
+ { /* A restart point is known. Restore to that state. */
+ DEBUG_PRINT1 ("\nFAIL:\n");
+ POP_FAILURE_POINT (d, p,
+ lowest_active_reg, highest_active_reg,
+ regstart, regend, reg_info);
+
+ /* If this failure point is a dummy, try the next one. */
+ if (!p)
+ goto fail;
+
+ /* If we failed to the end of the pattern, don't examine *p. */
+ assert (p <= pend);
+ if (p < pend)
+ {
+ boolean is_a_jump_n = false;
+
+ /* If failed to a backwards jump that's part of a repetition
+ loop, need to pop this failure point and use the next one. */
+ switch ((re_opcode_t) *p)
+ {
+ case jump_n:
+ is_a_jump_n = true;
+ case maybe_pop_jump:
+ case pop_failure_jump:
+ case jump:
+ p1 = p + 1;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+
+ if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
+ || (!is_a_jump_n
+ && (re_opcode_t) *p1 == on_failure_jump))
+ goto fail;
+ break;
+ default:
+ /* do nothing */ ;
+ }
+ }
+
+ if (d >= string1 && d <= end1)
+ dend = end_match_1;
+ }
+ else
+ break; /* Matching at this starting point really fails. */
+ } /* for (;;) */
+
+ if (best_regs_set)
+ goto restore_best_regs;
+
+ FREE_VARIABLES ();
+
+ return -1; /* Failure to match. */
+} /* re_match_2 */
+
+/* Subroutine definitions for re_match_2. */
+
+
+/* We are passed P pointing to a register number after a start_memory.
+
+ Return true if the pattern up to the corresponding stop_memory can
+ match the empty string, and false otherwise.
+
+ If we find the matching stop_memory, sets P to point to one past its number.
+ Otherwise, sets P to an undefined byte less than or equal to END.
+
+ We don't handle duplicates properly (yet). */
+
+static boolean
+group_match_null_string_p (p, end, reg_info)
+ unsigned char **p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ /* Point to after the args to the start_memory. */
+ unsigned char *p1 = *p + 2;
+
+ while (p1 < end)
+ {
+ /* Skip over opcodes that can match nothing, and return true or
+ false, as appropriate, when we get to one that can't, or to the
+ matching stop_memory. */
+
+ switch ((re_opcode_t) *p1)
+ {
+ /* Could be either a loop or a series of alternatives. */
+ case on_failure_jump:
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+
+ /* If the next operation is not a jump backwards in the
+ pattern. */
+
+ if (mcnt >= 0)
+ {
+ /* Go through the on_failure_jumps of the alternatives,
+ seeing if any of the alternatives cannot match nothing.
+ The last alternative starts with only a jump,
+ whereas the rest start with on_failure_jump and end
+ with a jump, e.g., here is the pattern for `a|b|c':
+
+ /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
+ /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
+ /exactn/1/c
+
+ So, we have to first go through the first (n-1)
+ alternatives and then deal with the last one separately. */
+
+
+ /* Deal with the first (n-1) alternatives, which start
+ with an on_failure_jump (see above) that jumps to right
+ past a jump_past_alt. */
+
+ while ((re_opcode_t) p1[mcnt-3] == jump_past_alt)
+ {
+ /* `mcnt' holds how many bytes long the alternative
+ is, including the ending `jump_past_alt' and
+ its number. */
+
+ if (!alt_match_null_string_p (p1, p1 + mcnt - 3,
+ reg_info))
+ return false;
+
+ /* Move to right after this alternative, including the
+ jump_past_alt. */
+ p1 += mcnt;
+
+ /* Break if it's the beginning of an n-th alternative
+ that doesn't begin with an on_failure_jump. */
+ if ((re_opcode_t) *p1 != on_failure_jump)
+ break;
+
+ /* Still have to check that it's not an n-th
+ alternative that starts with an on_failure_jump. */
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if ((re_opcode_t) p1[mcnt-3] != jump_past_alt)
+ {
+ /* Get to the beginning of the n-th alternative. */
+ p1 -= 3;
+ break;
+ }
+ }
+
+ /* Deal with the last alternative: go back and get number
+ of the `jump_past_alt' just before it. `mcnt' contains
+ the length of the alternative. */
+ EXTRACT_NUMBER (mcnt, p1 - 2);
+
+ if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info))
+ return false;
+
+ p1 += mcnt; /* Get past the n-th alternative. */
+ } /* if mcnt > 0 */
+ break;
+
+
+ case stop_memory:
+ assert (p1[1] == **p);
+ *p = p1 + 2;
+ return true;
+
+
+ default:
+ if (!common_op_match_null_string_p (&p1, end, reg_info))
+ return false;
+ }
+ } /* while p1 < end */
+
+ return false;
+} /* group_match_null_string_p */
+
+
+/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
+ It expects P to be the first byte of a single alternative and END one
+ byte past the last. The alternative can contain groups. */
+
+static boolean
+alt_match_null_string_p (p, end, reg_info)
+ unsigned char *p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ unsigned char *p1 = p;
+
+ while (p1 < end)
+ {
+ /* Skip over opcodes that can match nothing, and break when we get
+ to one that can't. */
+
+ switch ((re_opcode_t) *p1)
+ {
+ /* It's a loop. */
+ case on_failure_jump:
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+ break;
+
+ default:
+ if (!common_op_match_null_string_p (&p1, end, reg_info))
+ return false;
+ }
+ } /* while p1 < end */
+
+ return true;
+} /* alt_match_null_string_p */
+
+
+/* Deals with the ops common to group_match_null_string_p and
+ alt_match_null_string_p.
+
+ Sets P to one after the op and its arguments, if any. */
+
+static boolean
+common_op_match_null_string_p (p, end, reg_info)
+ unsigned char **p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ boolean ret;
+ int reg_no;
+ unsigned char *p1 = *p;
+
+ switch ((re_opcode_t) *p1++)
+ {
+ case no_op:
+ case begline:
+ case endline:
+ case begbuf:
+ case endbuf:
+ case wordbeg:
+ case wordend:
+ case wordbound:
+ case notwordbound:
+#ifdef emacs
+ case before_dot:
+ case at_dot:
+ case after_dot:
+#endif
+ break;
+
+ case start_memory:
+ reg_no = *p1;
+ assert (reg_no > 0 && reg_no <= MAX_REGNUM);
+ ret = group_match_null_string_p (&p1, end, reg_info);
+
+ /* Have to set this here in case we're checking a group which
+ contains a group and a back reference to it. */
+
+ if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
+
+ if (!ret)
+ return false;
+ break;
+
+ /* If this is an optimized succeed_n for zero times, make the jump. */
+ case jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if (mcnt >= 0)
+ p1 += mcnt;
+ else
+ return false;
+ break;
+
+ case succeed_n:
+ /* Get to the number of times to succeed. */
+ p1 += 2;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+
+ if (mcnt == 0)
+ {
+ p1 -= 4;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+ }
+ else
+ return false;
+ break;
+
+ case duplicate:
+ if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
+ return false;
+ break;
+
+ case set_number_at:
+ p1 += 4;
+
+ default:
+ /* All other opcodes mean we cannot match the empty string. */
+ return false;
+ }
+
+ *p = p1;
+ return true;
+} /* common_op_match_null_string_p */
+
+
+/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
+ bytes; nonzero otherwise. */
+
+static int
+bcmp_translate (s1, s2, len, translate)
+ unsigned char *s1, *s2;
+ register int len;
+ char *translate;
+{
+ register unsigned char *p1 = s1, *p2 = s2;
+ while (len)
+ {
+ if (translate[*p1++] != translate[*p2++]) return 1;
+ len--;
+ }
+ return 0;
+}
+
+/* Entry points for GNU code. */
+
+/* re_compile_pattern is the GNU regular expression compiler: it
+ compiles PATTERN (of length SIZE) and puts the result in BUFP.
+ Returns 0 if the pattern was valid, otherwise an error string.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate' fields
+ are set in BUFP on entry.
+
+ We call regex_compile to do the actual compilation. */
+
+const char *
+re_compile_pattern (pattern, length, bufp)
+ const char *pattern;
+ int length;
+ struct re_pattern_buffer *bufp;
+{
+ reg_errcode_t ret;
+
+ /* GNU code is written to assume at least RE_NREGS registers will be set
+ (and at least one extra will be -1). */
+ bufp->regs_allocated = REGS_UNALLOCATED;
+
+ /* And GNU code determines whether or not to get register information
+ by passing null for the REGS argument to re_match, etc., not by
+ setting no_sub. */
+ bufp->no_sub = 0;
+
+ /* Match anchors at newline. */
+ bufp->newline_anchor = 1;
+
+ ret = regex_compile (pattern, length, re_syntax_options, bufp);
+
+ return re_error_msg[(int) ret];
+}
+
+/* Entry points compatible with 4.2 BSD regex library. We don't define
+ them if this is an Emacs or POSIX compilation. */
+
+#if !defined (emacs) && !defined (_POSIX_SOURCE)
+
+/* BSD has one and only one pattern buffer. */
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+re_comp (s)
+ const char *s;
+{
+ reg_errcode_t ret;
+
+ if (!s)
+ {
+ if (!re_comp_buf.buffer)
+ return "No previous regular expression";
+ return 0;
+ }
+
+ if (!re_comp_buf.buffer)
+ {
+ re_comp_buf.buffer = (unsigned char *) malloc (200);
+ if (re_comp_buf.buffer == NULL)
+ return "Memory exhausted";
+ re_comp_buf.allocated = 200;
+
+ re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
+ if (re_comp_buf.fastmap == NULL)
+ return "Memory exhausted";
+ }
+
+ /* Since `re_exec' always passes NULL for the `regs' argument, we
+ don't need to initialize the pattern buffer fields which affect it. */
+
+ /* Match anchors at newlines. */
+ re_comp_buf.newline_anchor = 1;
+
+ ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
+
+ /* Yes, we're discarding `const' here. */
+ return (char *) re_error_msg[(int) ret];
+}
+
+
+int
+re_exec (s)
+ const char *s;
+{
+ const int len = strlen (s);
+ return
+ 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
+}
+#endif /* not emacs and not _POSIX_SOURCE */
+
+/* POSIX.2 functions. Don't define these for Emacs. */
+
+#ifndef emacs
+
+/* regcomp takes a regular expression as a string and compiles it.
+
+ PREG is a regex_t *. We do not expect any fields to be initialized,
+ since POSIX says we shouldn't. Thus, we set
+
+ `buffer' to the compiled pattern;
+ `used' to the length of the compiled pattern;
+ `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
+ REG_EXTENDED bit in CFLAGS is set; otherwise, to
+ RE_SYNTAX_POSIX_BASIC;
+ `newline_anchor' to REG_NEWLINE being set in CFLAGS;
+ `fastmap' and `fastmap_accurate' to zero;
+ `re_nsub' to the number of subexpressions in PATTERN.
+
+ PATTERN is the address of the pattern string.
+
+ CFLAGS is a series of bits which affect compilation.
+
+ If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
+ use POSIX basic syntax.
+
+ If REG_NEWLINE is set, then . and [^...] don't match newline.
+ Also, regexec will try a match beginning after every newline.
+
+ If REG_ICASE is set, then we considers upper- and lowercase
+ versions of letters to be equivalent when matching.
+
+ If REG_NOSUB is set, then when PREG is passed to regexec, that
+ routine will report only success or failure, and nothing about the
+ registers.
+
+ It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for
+ the return codes and their meanings.) */
+
+int
+regcomp (preg, pattern, cflags)
+ regex_t *preg;
+ const char *pattern;
+ int cflags;
+{
+ reg_errcode_t ret;
+ unsigned syntax
+ = (cflags & REG_EXTENDED) ?
+ RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
+
+ /* regex_compile will allocate the space for the compiled pattern. */
+ preg->buffer = 0;
+ preg->allocated = 0;
+
+ /* Don't bother to use a fastmap when searching. This simplifies the
+ REG_NEWLINE case: if we used a fastmap, we'd have to put all the
+ characters after newlines into the fastmap. This way, we just try
+ every character. */
+ preg->fastmap = 0;
+
+ if (cflags & REG_ICASE)
+ {
+ unsigned i;
+
+ preg->translate = (char *) malloc (CHAR_SET_SIZE);
+ if (preg->translate == NULL)
+ return (int) REG_ESPACE;
+
+ /* Map uppercase characters to corresponding lowercase ones. */
+ for (i = 0; i < CHAR_SET_SIZE; i++)
+ preg->translate[i] = ISUPPER (i) ? tolower (i) : i;
+ }
+ else
+ preg->translate = NULL;
+
+ /* If REG_NEWLINE is set, newlines are treated differently. */
+ if (cflags & REG_NEWLINE)
+ { /* REG_NEWLINE implies neither . nor [^...] match newline. */
+ syntax &= ~RE_DOT_NEWLINE;
+ syntax |= RE_HAT_LISTS_NOT_NEWLINE;
+ /* It also changes the matching behavior. */
+ preg->newline_anchor = 1;
+ }
+ else
+ preg->newline_anchor = 0;
+
+ preg->no_sub = !!(cflags & REG_NOSUB);
+
+ /* POSIX says a null character in the pattern terminates it, so we
+ can use strlen here in compiling the pattern. */
+ ret = regex_compile (pattern, strlen (pattern), syntax, preg);
+
+ /* POSIX doesn't distinguish between an unmatched open-group and an
+ unmatched close-group: both are REG_EPAREN. */
+ if (ret == REG_ERPAREN) ret = REG_EPAREN;
+
+ return (int) ret;
+}
+
+
+/* regexec searches for a given pattern, specified by PREG, in the
+ string STRING.
+
+ If NMATCH is zero or REG_NOSUB was set in the cflags argument to
+ `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at
+ least NMATCH elements, and we set them to the offsets of the
+ corresponding matched substrings.
+
+ EFLAGS specifies `execution flags' which affect matching: if
+ REG_NOTBOL is set, then ^ does not match at the beginning of the
+ string; if REG_NOTEOL is set, then $ does not match at the end.
+
+ We return 0 if we find a match and REG_NOMATCH if not. */
+
+int
+regexec (preg, string, nmatch, pmatch, eflags)
+ const regex_t *preg;
+ const char *string;
+ size_t nmatch;
+ regmatch_t pmatch[];
+ int eflags;
+{
+ int ret;
+ struct re_registers regs;
+ regex_t private_preg;
+ int len = strlen (string);
+ boolean want_reg_info = !preg->no_sub && nmatch > 0;
+
+ private_preg = *preg;
+
+ private_preg.not_bol = !!(eflags & REG_NOTBOL);
+ private_preg.not_eol = !!(eflags & REG_NOTEOL);
+
+ /* The user has told us exactly how many registers to return
+ information about, via `nmatch'. We have to pass that on to the
+ matching routines. */
+ private_preg.regs_allocated = REGS_FIXED;
+
+ if (want_reg_info)
+ {
+ regs.num_regs = nmatch;
+ regs.start = TALLOC (nmatch, regoff_t);
+ regs.end = TALLOC (nmatch, regoff_t);
+ if (regs.start == NULL || regs.end == NULL)
+ return (int) REG_NOMATCH;
+ }
+
+ /* Perform the searching operation. */
+ ret = re_search (&private_preg, string, len,
+ /* start: */ 0, /* range: */ len,
+ want_reg_info ? &regs : (struct re_registers *) 0);
+
+ /* Copy the register information to the POSIX structure. */
+ if (want_reg_info)
+ {
+ if (ret >= 0)
+ {
+ unsigned r;
+
+ for (r = 0; r < nmatch; r++)
+ {
+ pmatch[r].rm_so = regs.start[r];
+ pmatch[r].rm_eo = regs.end[r];
+ }
+ }
+
+ /* If we needed the temporary register info, free the space now. */
+ free (regs.start);
+ free (regs.end);
+ }
+
+ /* We want zero return to mean success, unlike `re_search'. */
+ return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
+}
+
+
+/* Returns a message corresponding to an error code, ERRCODE, returned
+ from either regcomp or regexec. We don't use PREG here. */
+
+size_t
+regerror (errcode, preg, errbuf, errbuf_size)
+ int errcode;
+ const regex_t *preg;
+ char *errbuf;
+ size_t errbuf_size;
+{
+ const char *msg;
+ size_t msg_size;
+
+ if (errcode < 0
+ || errcode >= (sizeof (re_error_msg) / sizeof (re_error_msg[0])))
+ /* Only error codes returned by the rest of the code should be passed
+ to this routine. If we are given anything else, or if other regex
+ code generates an invalid error code, then the program has a bug.
+ Dump core so we can fix it. */
+ abort ();
+
+ msg = re_error_msg[errcode];
+
+ /* POSIX doesn't require that we do anything in this case, but why
+ not be nice. */
+ if (! msg)
+ msg = "Success";
+
+ msg_size = strlen (msg) + 1; /* Includes the null. */
+
+ if (errbuf_size != 0)
+ {
+ if (msg_size > errbuf_size)
+ {
+ strncpy (errbuf, msg, errbuf_size - 1);
+ errbuf[errbuf_size - 1] = 0;
+ }
+ else
+ strcpy (errbuf, msg);
+ }
+
+ return msg_size;
+}
+
+
+/* Free dynamically allocated space used by PREG. */
+
+void
+regfree (preg)
+ regex_t *preg;
+{
+ if (preg->buffer != NULL)
+ free (preg->buffer);
+ preg->buffer = NULL;
+
+ preg->allocated = 0;
+ preg->used = 0;
+
+ if (preg->fastmap != NULL)
+ free (preg->fastmap);
+ preg->fastmap = NULL;
+ preg->fastmap_accurate = 0;
+
+ if (preg->translate != NULL)
+ free (preg->translate);
+ preg->translate = NULL;
+}
+
+#endif /* not emacs */
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/MSVC/regex/regex.h b/MSVC/regex/regex.h
index 27a32ec..92e3344 100644
--- a/MSVC/regex/regex.h
+++ b/MSVC/regex/regex.h
@@ -1,498 +1,498 @@
-/* Definitions for data structures and routines for the regular
- expression library, version 0.12.
-
- Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifndef __REGEXP_LIBRARY_H__
-#define __REGEXP_LIBRARY_H__
-
-/* POSIX says that <sys/types.h> must be included (by the caller) before
- <regex.h>. */
-
-#ifdef VMS
-/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
- should be there. */
-#include <stddef.h>
-#endif
-
-
-/* The following bits are used to determine the regexp syntax we
- recognize. The set/not-set meanings are chosen so that Emacs syntax
- remains the value 0. The bits are given in alphabetical order, and
- the definitions shifted by one from the previous bit; thus, when we
- add or remove a bit, only one other definition need change. */
-typedef unsigned reg_syntax_t;
-
-/* If this bit is not set, then \ inside a bracket expression is literal.
- If set, then such a \ quotes the following character. */
-#define RE_BACKSLASH_ESCAPE_IN_LISTS (1)
-
-/* If this bit is not set, then + and ? are operators, and \+ and \? are
- literals.
- If set, then \+ and \? are operators and + and ? are literals. */
-#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
-
-/* If this bit is set, then character classes are supported. They are:
- [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
- [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
- If not set, then character classes are not supported. */
-#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
-
-/* If this bit is set, then ^ and $ are always anchors (outside bracket
- expressions, of course).
- If this bit is not set, then it depends:
- ^ is an anchor if it is at the beginning of a regular
- expression or after an open-group or an alternation operator;
- $ is an anchor if it is at the end of a regular expression, or
- before a close-group or an alternation operator.
-
- This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
- POSIX draft 11.2 says that * etc. in leading positions is undefined.
- We already implemented a previous draft which made those constructs
- invalid, though, so we haven't changed the code back. */
-#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
-
-/* If this bit is set, then special characters are always special
- regardless of where they are in the pattern.
- If this bit is not set, then special characters are special only in
- some contexts; otherwise they are ordinary. Specifically,
- * + ? and intervals are only special when not after the beginning,
- open-group, or alternation operator. */
-#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
-
-/* If this bit is set, then *, +, ?, and { cannot be first in an re or
- immediately after an alternation or begin-group operator. */
-#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
-
-/* If this bit is set, then . matches newline.
- If not set, then it doesn't. */
-#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
-
-/* If this bit is set, then . doesn't match NUL.
- If not set, then it does. */
-#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
-
-/* If this bit is set, nonmatching lists [^...] do not match newline.
- If not set, they do. */
-#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
-
-/* If this bit is set, either \{...\} or {...} defines an
- interval, depending on RE_NO_BK_BRACES.
- If not set, \{, \}, {, and } are literals. */
-#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
-
-/* If this bit is set, +, ? and | aren't recognized as operators.
- If not set, they are. */
-#define RE_LIMITED_OPS (RE_INTERVALS << 1)
-
-/* If this bit is set, newline is an alternation operator.
- If not set, newline is literal. */
-#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
-
-/* If this bit is set, then `{...}' defines an interval, and \{ and \}
- are literals.
- If not set, then `\{...\}' defines an interval. */
-#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
-
-/* If this bit is set, (...) defines a group, and \( and \) are literals.
- If not set, \(...\) defines a group, and ( and ) are literals. */
-#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
-
-/* If this bit is set, then \<digit> matches <digit>.
- If not set, then \<digit> is a back-reference. */
-#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
-
-/* If this bit is set, then | is an alternation operator, and \| is literal.
- If not set, then \| is an alternation operator, and | is literal. */
-#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
-
-/* If this bit is set, then an ending range point collating higher
- than the starting range point, as in [z-a], is invalid.
- If not set, then when ending range point collates higher than the
- starting range point, the range is ignored. */
-#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
-
-/* If this bit is set, then an unmatched ) is ordinary.
- If not set, then an unmatched ) is invalid. */
-#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
-
-/* This global variable defines the particular regexp syntax to use (for
- some interfaces). When a regexp is compiled, the syntax used is
- stored in the pattern buffer, so changing this does not affect
- already-compiled regexps. */
-extern reg_syntax_t re_syntax_options;
-
-/* Define combinations of the above bits for the standard possibilities.
- (The [[[ comments delimit what gets put into the Texinfo file, so
- don't delete them!) */
-/* [[[begin syntaxes]]] */
-#define RE_SYNTAX_EMACS 0
-
-#define RE_SYNTAX_AWK \
- (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
- | RE_NO_BK_PARENS | RE_NO_BK_REFS \
- | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
- | RE_UNMATCHED_RIGHT_PAREN_ORD)
-
-#define RE_SYNTAX_POSIX_AWK \
- (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS)
-
-#define RE_SYNTAX_GREP \
- (RE_BK_PLUS_QM | RE_CHAR_CLASSES \
- | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
- | RE_NEWLINE_ALT)
-
-#define RE_SYNTAX_EGREP \
- (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
- | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
- | RE_NEWLINE_ALT | RE_NO_BK_PARENS \
- | RE_NO_BK_VBAR)
-
-#define RE_SYNTAX_POSIX_EGREP \
- (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
-
-/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
-#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
-
-#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
-
-/* Syntax bits common to both basic and extended POSIX regex syntax. */
-#define _RE_SYNTAX_POSIX_COMMON \
- (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
- | RE_INTERVALS | RE_NO_EMPTY_RANGES)
-
-#define RE_SYNTAX_POSIX_BASIC \
- (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
-
-/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
- RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
- isn't minimal, since other operators, such as \`, aren't disabled. */
-#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
- (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
-
-#define RE_SYNTAX_POSIX_EXTENDED \
- (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
- | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
- | RE_NO_BK_PARENS | RE_NO_BK_VBAR \
- | RE_UNMATCHED_RIGHT_PAREN_ORD)
-
-/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
- replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
-#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
- (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
- | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
- | RE_NO_BK_PARENS | RE_NO_BK_REFS \
- | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
-/* [[[end syntaxes]]] */
-
-/* Maximum number of duplicates an interval can allow. Some systems
- (erroneously) define this in other header files, but we want our
- value, so remove any previous define. */
-#ifdef RE_DUP_MAX
-#undef RE_DUP_MAX
-#endif
-#define RE_DUP_MAX ((1 << 15) - 1)
-
-
-/* POSIX `cflags' bits (i.e., information for `regcomp'). */
-
-/* If this bit is set, then use extended regular expression syntax.
- If not set, then use basic regular expression syntax. */
-#define REG_EXTENDED 1
-
-/* If this bit is set, then ignore case when matching.
- If not set, then case is significant. */
-#define REG_ICASE (REG_EXTENDED << 1)
-
-/* If this bit is set, then anchors do not match at newline
- characters in the string.
- If not set, then anchors do match at newlines. */
-#define REG_NEWLINE (REG_ICASE << 1)
-
-/* If this bit is set, then report only success or fail in regexec.
- If not set, then returns differ between not matching and errors. */
-#define REG_NOSUB (REG_NEWLINE << 1)
-
-
-/* POSIX `eflags' bits (i.e., information for regexec). */
-
-/* If this bit is set, then the beginning-of-line operator doesn't match
- the beginning of the string (presumably because it's not the
- beginning of a line).
- If not set, then the beginning-of-line operator does match the
- beginning of the string. */
-#define REG_NOTBOL 1
-
-/* Like REG_NOTBOL, except for the end-of-line. */
-#define REG_NOTEOL (1 << 1)
-
-
-/* If any error codes are removed, changed, or added, update the
- `re_error_msg' table in regex.c. */
-typedef enum
-{
- REG_NOERROR = 0, /* Success. */
- REG_NOMATCH, /* Didn't find a match (for regexec). */
-
- /* POSIX regcomp return error codes. (In the order listed in the
- standard.) */
- REG_BADPAT, /* Invalid pattern. */
- REG_ECOLLATE, /* Not implemented. */
- REG_ECTYPE, /* Invalid character class name. */
- REG_EESCAPE, /* Trailing backslash. */
- REG_ESUBREG, /* Invalid back reference. */
- REG_EBRACK, /* Unmatched left bracket. */
- REG_EPAREN, /* Parenthesis imbalance. */
- REG_EBRACE, /* Unmatched \{. */
- REG_BADBR, /* Invalid contents of \{\}. */
- REG_ERANGE, /* Invalid range end. */
- REG_ESPACE, /* Ran out of memory. */
- REG_BADRPT, /* No preceding re for repetition op. */
-
- /* Error codes we've added. */
- REG_EEND, /* Premature end. */
- REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
- REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
-} reg_errcode_t;
-
-/* This data structure represents a compiled pattern. Before calling
- the pattern compiler, the fields `buffer', `allocated', `fastmap',
- `translate', and `no_sub' can be set. After the pattern has been
- compiled, the `re_nsub' field is available. All other fields are
- private to the regex routines. */
-
-struct re_pattern_buffer
-{
-/* [[[begin pattern_buffer]]] */
- /* Space that holds the compiled pattern. It is declared as
- `unsigned char *' because its elements are
- sometimes used as array indexes. */
- unsigned char *buffer;
-
- /* Number of bytes to which `buffer' points. */
- unsigned long allocated;
-
- /* Number of bytes actually used in `buffer'. */
- unsigned long used;
-
- /* Syntax setting with which the pattern was compiled. */
- reg_syntax_t syntax;
-
- /* Pointer to a fastmap, if any, otherwise zero. re_search uses
- the fastmap, if there is one, to skip over impossible
- starting points for matches. */
- char *fastmap;
-
- /* Either a translate table to apply to all characters before
- comparing them, or zero for no translation. The translation
- is applied to a pattern when it is compiled and to a string
- when it is matched. */
- char *translate;
-
- /* Number of subexpressions found by the compiler. */
- size_t re_nsub;
-
- /* Zero if this pattern cannot match the empty string, one else.
- Well, in truth it's used only in `re_search_2', to see
- whether or not we should use the fastmap, so we don't set
- this absolutely perfectly; see `re_compile_fastmap' (the
- `duplicate' case). */
- unsigned can_be_null : 1;
-
- /* If REGS_UNALLOCATED, allocate space in the `regs' structure
- for `max (RE_NREGS, re_nsub + 1)' groups.
- If REGS_REALLOCATE, reallocate space if necessary.
- If REGS_FIXED, use what's there. */
-#define REGS_UNALLOCATED 0
-#define REGS_REALLOCATE 1
-#define REGS_FIXED 2
- unsigned regs_allocated : 2;
-
- /* Set to zero when `regex_compile' compiles a pattern; set to one
- by `re_compile_fastmap' if it updates the fastmap. */
- unsigned fastmap_accurate : 1;
-
- /* If set, `re_match_2' does not return information about
- subexpressions. */
- unsigned no_sub : 1;
-
- /* If set, a beginning-of-line anchor doesn't match at the
- beginning of the string. */
- unsigned not_bol : 1;
-
- /* Similarly for an end-of-line anchor. */
- unsigned not_eol : 1;
-
- /* If true, an anchor at a newline matches. */
- unsigned newline_anchor : 1;
-
-/* [[[end pattern_buffer]]] */
-};
-
-typedef struct re_pattern_buffer regex_t;
-
-
-/* search.c (search_buffer) in Emacs needs this one opcode value. It is
- defined both in `regex.c' and here. */
-#define RE_EXACTN_VALUE 1
-
-/* Type for byte offsets within the string. POSIX mandates this. */
-typedef int regoff_t;
-
-
-/* This is the structure we store register match data in. See
- regex.texinfo for a full description of what registers match. */
-struct re_registers
-{
- unsigned num_regs;
- regoff_t *start;
- regoff_t *end;
-};
-
-
-/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
- `re_match_2' returns information about at least this many registers
- the first time a `regs' structure is passed. */
-#ifndef RE_NREGS
-#define RE_NREGS 30
-#endif
-
-
-/* POSIX specification for registers. Aside from the different names than
- `re_registers', POSIX uses an array of structures, instead of a
- structure of arrays. */
-typedef struct
-{
- regoff_t rm_so; /* Byte offset from string's start to substring's start. */
- regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
-} regmatch_t;
-
-/* Declarations for routines. */
-
-/* To avoid duplicating every routine declaration -- once with a
- prototype (if we are ANSI), and once without (if we aren't) -- we
- use the following macro to declare argument types. This
- unfortunately clutters up the declarations a bit, but I think it's
- worth it. */
-
-#if __STDC__
-
-#define _RE_ARGS(args) args
-
-#else /* not __STDC__ */
-
-#define _RE_ARGS(args) ()
-
-#endif /* not __STDC__ */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Sets the current default syntax to SYNTAX, and return the old syntax.
- You can also simply assign to the `re_syntax_options' variable. */
-extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
-
-/* Compile the regular expression PATTERN, with length LENGTH
- and syntax given by the global `re_syntax_options', into the buffer
- BUFFER. Return NULL if successful, and an error string if not. */
-extern const char *re_compile_pattern
- _RE_ARGS ((const char *pattern, int length,
- struct re_pattern_buffer *buffer));
-
-
-/* Compile a fastmap for the compiled pattern in BUFFER; used to
- accelerate searches. Return 0 if successful and -2 if was an
- internal error. */
-extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
-
-
-/* Search in the string STRING (with length LENGTH) for the pattern
- compiled into BUFFER. Start searching at position START, for RANGE
- characters. Return the starting position of the match, -1 for no
- match, or -2 for an internal error. Also return register
- information in REGS (if REGS and BUFFER->no_sub are nonzero). */
-extern int re_search
- _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
- int length, int start, int range, struct re_registers *regs));
-
-
-/* Like `re_search', but search in the concatenation of STRING1 and
- STRING2. Also, stop searching at index START + STOP. */
-extern int re_search_2
- _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
- int length1, const char *string2, int length2,
- int start, int range, struct re_registers *regs, int stop));
-
-
-/* Like `re_search', but return how many characters in STRING the regexp
- in BUFFER matched, starting at position START. */
-extern int re_match
- _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
- int length, int start, struct re_registers *regs));
-
-
-/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
-extern int re_match_2
- _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
- int length1, const char *string2, int length2,
- int start, struct re_registers *regs, int stop));
-
-
-/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
- ENDS. Subsequent matches using BUFFER and REGS will use this memory
- for recording register information. STARTS and ENDS must be
- allocated with malloc, and must each be at least `NUM_REGS * sizeof
- (regoff_t)' bytes long.
-
- If NUM_REGS == 0, then subsequent matches should allocate their own
- register data.
-
- Unless this function is called, the first search or match using
- PATTERN_BUFFER will allocate its own register data, without
- freeing the old data. */
-extern void re_set_registers
- _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
- unsigned num_regs, regoff_t *starts, regoff_t *ends));
-
-/* 4.2 bsd compatibility. */
-extern char *re_comp _RE_ARGS ((const char *));
-extern int re_exec _RE_ARGS ((const char *));
-
-/* POSIX compatibility. */
-extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));
-extern int regexec
- _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch,
- regmatch_t pmatch[], int eflags));
-extern size_t regerror
- _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf,
- size_t errbuf_size));
-extern void regfree _RE_ARGS ((regex_t *preg));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not __REGEXP_LIBRARY_H__ */
-
-/*
-Local variables:
-make-backup-files: t
-version-control: t
-trim-versions-without-asking: nil
-End:
-*/
+/* Definitions for data structures and routines for the regular
+ expression library, version 0.12.
+
+ Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef __REGEXP_LIBRARY_H__
+#define __REGEXP_LIBRARY_H__
+
+/* POSIX says that <sys/types.h> must be included (by the caller) before
+ <regex.h>. */
+
+#ifdef VMS
+/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
+ should be there. */
+#include <stddef.h>
+#endif
+
+
+/* The following bits are used to determine the regexp syntax we
+ recognize. The set/not-set meanings are chosen so that Emacs syntax
+ remains the value 0. The bits are given in alphabetical order, and
+ the definitions shifted by one from the previous bit; thus, when we
+ add or remove a bit, only one other definition need change. */
+typedef unsigned reg_syntax_t;
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+ If set, then such a \ quotes the following character. */
+#define RE_BACKSLASH_ESCAPE_IN_LISTS (1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+ literals.
+ If set, then \+ and \? are operators and + and ? are literals. */
+#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported. They are:
+ [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
+ [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+ If not set, then character classes are not supported. */
+#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+ expressions, of course).
+ If this bit is not set, then it depends:
+ ^ is an anchor if it is at the beginning of a regular
+ expression or after an open-group or an alternation operator;
+ $ is an anchor if it is at the end of a regular expression, or
+ before a close-group or an alternation operator.
+
+ This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+ POSIX draft 11.2 says that * etc. in leading positions is undefined.
+ We already implemented a previous draft which made those constructs
+ invalid, though, so we haven't changed the code back. */
+#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+ regardless of where they are in the pattern.
+ If this bit is not set, then special characters are special only in
+ some contexts; otherwise they are ordinary. Specifically,
+ * + ? and intervals are only special when not after the beginning,
+ open-group, or alternation operator. */
+#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+ immediately after an alternation or begin-group operator. */
+#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+ If not set, then it doesn't. */
+#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+ If not set, then it does. */
+#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+ If not set, they do. */
+#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+ interval, depending on RE_NO_BK_BRACES.
+ If not set, \{, \}, {, and } are literals. */
+#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+ If not set, they are. */
+#define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+ If not set, newline is literal. */
+#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+ are literals.
+ If not set, then `\{...\}' defines an interval. */
+#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+ If not set, \(...\) defines a group, and ( and ) are literals. */
+#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+ If not set, then \<digit> is a back-reference. */
+#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+ If not set, then \| is an alternation operator, and | is literal. */
+#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+ than the starting range point, as in [z-a], is invalid.
+ If not set, then when ending range point collates higher than the
+ starting range point, the range is ignored. */
+#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+ If not set, then an unmatched ) is invalid. */
+#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* This global variable defines the particular regexp syntax to use (for
+ some interfaces). When a regexp is compiled, the syntax used is
+ stored in the pattern buffer, so changing this does not affect
+ already-compiled regexps. */
+extern reg_syntax_t re_syntax_options;
+
+/* Define combinations of the above bits for the standard possibilities.
+ (The [[[ comments delimit what gets put into the Texinfo file, so
+ don't delete them!) */
+/* [[[begin syntaxes]]] */
+#define RE_SYNTAX_EMACS 0
+
+#define RE_SYNTAX_AWK \
+ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+#define RE_SYNTAX_POSIX_AWK \
+ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS)
+
+#define RE_SYNTAX_GREP \
+ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \
+ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
+ | RE_NEWLINE_ALT)
+
+#define RE_SYNTAX_EGREP \
+ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
+ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \
+ | RE_NO_BK_VBAR)
+
+#define RE_SYNTAX_POSIX_EGREP \
+ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
+#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax. */
+#define _RE_SYNTAX_POSIX_COMMON \
+ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
+ | RE_INTERVALS | RE_NO_EMPTY_RANGES)
+
+#define RE_SYNTAX_POSIX_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+ RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
+ isn't minimal, since other operators, such as \`, aren't disabled. */
+#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+#define RE_SYNTAX_POSIX_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
+ replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
+#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+
+/* Maximum number of duplicates an interval can allow. Some systems
+ (erroneously) define this in other header files, but we want our
+ value, so remove any previous define. */
+#ifdef RE_DUP_MAX
+#undef RE_DUP_MAX
+#endif
+#define RE_DUP_MAX ((1 << 15) - 1)
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp'). */
+
+/* If this bit is set, then use extended regular expression syntax.
+ If not set, then use basic regular expression syntax. */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+ If not set, then case is significant. */
+#define REG_ICASE (REG_EXTENDED << 1)
+
+/* If this bit is set, then anchors do not match at newline
+ characters in the string.
+ If not set, then anchors do match at newlines. */
+#define REG_NEWLINE (REG_ICASE << 1)
+
+/* If this bit is set, then report only success or fail in regexec.
+ If not set, then returns differ between not matching and errors. */
+#define REG_NOSUB (REG_NEWLINE << 1)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec). */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+ the beginning of the string (presumably because it's not the
+ beginning of a line).
+ If not set, then the beginning-of-line operator does match the
+ beginning of the string. */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line. */
+#define REG_NOTEOL (1 << 1)
+
+
+/* If any error codes are removed, changed, or added, update the
+ `re_error_msg' table in regex.c. */
+typedef enum
+{
+ REG_NOERROR = 0, /* Success. */
+ REG_NOMATCH, /* Didn't find a match (for regexec). */
+
+ /* POSIX regcomp return error codes. (In the order listed in the
+ standard.) */
+ REG_BADPAT, /* Invalid pattern. */
+ REG_ECOLLATE, /* Not implemented. */
+ REG_ECTYPE, /* Invalid character class name. */
+ REG_EESCAPE, /* Trailing backslash. */
+ REG_ESUBREG, /* Invalid back reference. */
+ REG_EBRACK, /* Unmatched left bracket. */
+ REG_EPAREN, /* Parenthesis imbalance. */
+ REG_EBRACE, /* Unmatched \{. */
+ REG_BADBR, /* Invalid contents of \{\}. */
+ REG_ERANGE, /* Invalid range end. */
+ REG_ESPACE, /* Ran out of memory. */
+ REG_BADRPT, /* No preceding re for repetition op. */
+
+ /* Error codes we've added. */
+ REG_EEND, /* Premature end. */
+ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
+ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
+} reg_errcode_t;
+
+/* This data structure represents a compiled pattern. Before calling
+ the pattern compiler, the fields `buffer', `allocated', `fastmap',
+ `translate', and `no_sub' can be set. After the pattern has been
+ compiled, the `re_nsub' field is available. All other fields are
+ private to the regex routines. */
+
+struct re_pattern_buffer
+{
+/* [[[begin pattern_buffer]]] */
+ /* Space that holds the compiled pattern. It is declared as
+ `unsigned char *' because its elements are
+ sometimes used as array indexes. */
+ unsigned char *buffer;
+
+ /* Number of bytes to which `buffer' points. */
+ unsigned long allocated;
+
+ /* Number of bytes actually used in `buffer'. */
+ unsigned long used;
+
+ /* Syntax setting with which the pattern was compiled. */
+ reg_syntax_t syntax;
+
+ /* Pointer to a fastmap, if any, otherwise zero. re_search uses
+ the fastmap, if there is one, to skip over impossible
+ starting points for matches. */
+ char *fastmap;
+
+ /* Either a translate table to apply to all characters before
+ comparing them, or zero for no translation. The translation
+ is applied to a pattern when it is compiled and to a string
+ when it is matched. */
+ char *translate;
+
+ /* Number of subexpressions found by the compiler. */
+ size_t re_nsub;
+
+ /* Zero if this pattern cannot match the empty string, one else.
+ Well, in truth it's used only in `re_search_2', to see
+ whether or not we should use the fastmap, so we don't set
+ this absolutely perfectly; see `re_compile_fastmap' (the
+ `duplicate' case). */
+ unsigned can_be_null : 1;
+
+ /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+ for `max (RE_NREGS, re_nsub + 1)' groups.
+ If REGS_REALLOCATE, reallocate space if necessary.
+ If REGS_FIXED, use what's there. */
+#define REGS_UNALLOCATED 0
+#define REGS_REALLOCATE 1
+#define REGS_FIXED 2
+ unsigned regs_allocated : 2;
+
+ /* Set to zero when `regex_compile' compiles a pattern; set to one
+ by `re_compile_fastmap' if it updates the fastmap. */
+ unsigned fastmap_accurate : 1;
+
+ /* If set, `re_match_2' does not return information about
+ subexpressions. */
+ unsigned no_sub : 1;
+
+ /* If set, a beginning-of-line anchor doesn't match at the
+ beginning of the string. */
+ unsigned not_bol : 1;
+
+ /* Similarly for an end-of-line anchor. */
+ unsigned not_eol : 1;
+
+ /* If true, an anchor at a newline matches. */
+ unsigned newline_anchor : 1;
+
+/* [[[end pattern_buffer]]] */
+};
+
+typedef struct re_pattern_buffer regex_t;
+
+
+/* search.c (search_buffer) in Emacs needs this one opcode value. It is
+ defined both in `regex.c' and here. */
+#define RE_EXACTN_VALUE 1
+
+/* Type for byte offsets within the string. POSIX mandates this. */
+typedef int regoff_t;
+
+
+/* This is the structure we store register match data in. See
+ regex.texinfo for a full description of what registers match. */
+struct re_registers
+{
+ unsigned num_regs;
+ regoff_t *start;
+ regoff_t *end;
+};
+
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+ `re_match_2' returns information about at least this many registers
+ the first time a `regs' structure is passed. */
+#ifndef RE_NREGS
+#define RE_NREGS 30
+#endif
+
+
+/* POSIX specification for registers. Aside from the different names than
+ `re_registers', POSIX uses an array of structures, instead of a
+ structure of arrays. */
+typedef struct
+{
+ regoff_t rm_so; /* Byte offset from string's start to substring's start. */
+ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
+} regmatch_t;
+
+/* Declarations for routines. */
+
+/* To avoid duplicating every routine declaration -- once with a
+ prototype (if we are ANSI), and once without (if we aren't) -- we
+ use the following macro to declare argument types. This
+ unfortunately clutters up the declarations a bit, but I think it's
+ worth it. */
+
+#if __STDC__
+
+#define _RE_ARGS(args) args
+
+#else /* not __STDC__ */
+
+#define _RE_ARGS(args) ()
+
+#endif /* not __STDC__ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+ You can also simply assign to the `re_syntax_options' variable. */
+extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
+
+/* Compile the regular expression PATTERN, with length LENGTH
+ and syntax given by the global `re_syntax_options', into the buffer
+ BUFFER. Return NULL if successful, and an error string if not. */
+extern const char *re_compile_pattern
+ _RE_ARGS ((const char *pattern, int length,
+ struct re_pattern_buffer *buffer));
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+ accelerate searches. Return 0 if successful and -2 if was an
+ internal error. */
+extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+ compiled into BUFFER. Start searching at position START, for RANGE
+ characters. Return the starting position of the match, -1 for no
+ match, or -2 for an internal error. Also return register
+ information in REGS (if REGS and BUFFER->no_sub are nonzero). */
+extern int re_search
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, int range, struct re_registers *regs));
+
+
+/* Like `re_search', but search in the concatenation of STRING1 and
+ STRING2. Also, stop searching at index START + STOP. */
+extern int re_search_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, int range, struct re_registers *regs, int stop));
+
+
+/* Like `re_search', but return how many characters in STRING the regexp
+ in BUFFER matched, starting at position START. */
+extern int re_match
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, struct re_registers *regs));
+
+
+/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
+extern int re_match_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, struct re_registers *regs, int stop));
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using BUFFER and REGS will use this memory
+ for recording register information. STARTS and ENDS must be
+ allocated with malloc, and must each be at least `NUM_REGS * sizeof
+ (regoff_t)' bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+extern void re_set_registers
+ _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
+ unsigned num_regs, regoff_t *starts, regoff_t *ends));
+
+/* 4.2 bsd compatibility. */
+extern char *re_comp _RE_ARGS ((const char *));
+extern int re_exec _RE_ARGS ((const char *));
+
+/* POSIX compatibility. */
+extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));
+extern int regexec
+ _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch,
+ regmatch_t pmatch[], int eflags));
+extern size_t regerror
+ _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf,
+ size_t errbuf_size));
+extern void regfree _RE_ARGS ((regex_t *preg));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not __REGEXP_LIBRARY_H__ */
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/include/Action.h b/include/Action.h
index 542a6b6..2a4c75a 100644
--- a/include/Action.h
+++ b/include/Action.h
@@ -1,32 +1,32 @@
-#ifndef __ACTION_H__
-#define __ACTION_H__
-
-#include <Task.h>
-#include <Handle.h>
-#include <Variables.h>
-#include <Exceptions.h>
-
-class Action : public Base {
- public:
- Action(const String & = "");
- virtual ~Action();
- Action * Look4URL(const String &);
- virtual Task * Do(Variables *, Variables *, Handle *) = 0;
- virtual void SendHead(Handle *);
- virtual void SendFoot(Handle *);
- virtual void ShowButton(Handle *, const String & = " Ok ", const String & = "start");
- virtual String GetTitle(void) = 0;
- String GetURL(void);
- void CleanUp(void);
-
- protected:
- void Accessed(void);
-
- private:
- static Action * start;
- Action * next, * prev;
- String URL;
- bool hastoclean, accessed;
-};
-
-#endif
+#ifndef __ACTION_H__
+#define __ACTION_H__
+
+#include <Task.h>
+#include <Handle.h>
+#include <Variables.h>
+#include <Exceptions.h>
+
+class Action : public Base {
+ public:
+ Action(const String & = "");
+ virtual ~Action();
+ Action * Look4URL(const String &);
+ virtual Task * Do(Variables *, Variables *, Handle *) = 0;
+ virtual void SendHead(Handle *);
+ virtual void SendFoot(Handle *);
+ virtual void ShowButton(Handle *, const String & = " Ok ", const String & = "start");
+ virtual String GetTitle(void) = 0;
+ String GetURL(void);
+ void CleanUp(void);
+
+ protected:
+ void Accessed(void);
+
+ private:
+ static Action * start;
+ Action * next, * prev;
+ String URL;
+ bool hastoclean, accessed;
+};
+
+#endif
diff --git a/include/BLua.h b/include/BLua.h
index 52918ee..e2fc852 100644
--- a/include/BLua.h
+++ b/include/BLua.h
@@ -1,376 +1,376 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: BLua.h,v 1.18 2004-11-27 21:01:20 pixel Exp $ */
-
-#ifndef __BLUA_H__
-#define __BLUA_H__
-
-struct lua_State;
-
-extern "C" {
- void do_lua_lock(lua_State *);
- void do_lua_unlock(lua_State *);
-}
-
-#define lua_lock(L) do_lua_lock(L)
-#define lua_unlock(L) do_lua_unlock(L)
-
-#include <lua.h>
-#include <map>
-#include <Exceptions.h>
-#include <Handle.h>
-
-class Lua : public Base {
- public:
- Lua();
- Lua(const Lua &) throw (GeneralException);
- virtual ~Lua();
- void open_base();
- void open_table();
- void open_io();
- void open_string();
- void open_math();
- void open_debug();
- void open_dir();
- void declarefunc(const String &, lua_CFunction, int = LUA_GLOBALSINDEX);
- void call(const String &, int = LUA_GLOBALSINDEX, int = 0, int = 0);
- void call(int = 0, int = 0);
- void push();
- void push(lua_Number);
- void push(const String &);
- void push(bool);
- void push(char *, int size = -1);
- void push(void *);
- void push(lua_CFunction, int = 0);
- void pop(int = 1);
- void newtable();
- void * newuser(size_t);
- void settable(int = -3, bool raw = false);
- void gettable(int = -2, bool raw = false);
- void setvar();
- int gettop();
- void error(const String &);
- int type(int = -1);
- bool isnil(int = -1);
- bool isboolean(int = -1);
- bool isnumber(int = -1);
- bool isstring(int = -1);
- bool istable(int = -1);
- bool isfunction(int = -1);
- bool iscfunction(int = -1);
- bool isuserdata(int = -1);
- bool islightuserdata(int = -1);
- bool toboolean(int = -1);
- lua_Number tonumber(int = -1);
- String tostring(int = -1);
- lua_CFunction tocfunction(int = -1);
- void * touserdata(int = -1);
- Lua * tothread(int = -1);
- void load(Handle *, bool docall = true) throw (GeneralException);
- void dump(Handle *, bool strip = true);
- Lua * thread();
- int yield(int nargs = 0);
- int resume(int nresults = 0);
- static Lua * find(lua_State *) throw (GeneralException);
- void showerror();
- int getmetatable(int = -1);
- int setmetatable(int = -2);
- int sethook(lua_Hook func, int mask, int count);
-
- void do_break();
-
- virtual void lock() {}
- virtual void unlock() {}
- private:
- Lua(lua_State *);
- lua_State * L;
- static std::map<lua_State *, Lua *> lualist;
-};
-
-class LuaObject : public Base {
- public:
- LuaObject() : wantdestruct(false), pushed(false) {}
- virtual void push(Lua *) throw (GeneralException);
- static void * getme(Lua *, int = 1);
- void pushdestruct(Lua *) throw (GeneralException);
- protected:
- virtual void pushmembers(Lua *) = 0;
- void pushme(Lua *, void *, bool = true);
- static void pushit(Lua *, const String &, lua_CFunction);
- static void pushmeta(Lua *, const String &, lua_CFunction);
- bool wantdestruct, pushed;
-};
-
-class LuaException : public GeneralException {
- public:
- LuaException(String);
- protected:
- LuaException();
-};
-
-enum Lua_types_t {
- LUA_OBJECT = 0x01,
- LUA_TABLE = 0x02,
- LUA_BOOLEAN = 0x04,
- LUA_NUMBER = 0x08,
- LUA_STRING = 0x10,
- LUA_FUNCTION = 0x20,
- LUA_NIL = 0x40,
- LUA_ANY = 0x7f,
-};
-
-#define MAX_TYPE 7
-
-#define MAXARGS 32
-
-struct lua_functypes_t {
- int number;
- char * name;
- int minargs, maxargs;
- int argtypes[MAXARGS];
-};
-
-#define DECLARE_METHOD(classname, enumvar) static int method_##enumvar(lua_State * L) { \
- return LuaHelpers<classname>::method_multiplex( \
- enumvar, \
- L, \
- sLua_##classname::classname##_proceed, \
- 0, \
- classname##_methods, \
- true); \
- }
-
-#define DECLARE_FUNCTION(classname, enumvar) static int function_##enumvar(lua_State * L) { \
- return LuaHelpers<classname>::method_multiplex( \
- enumvar, \
- L, \
- 0, \
- sLua_##classname::classname##_proceed_statics, \
- classname##_functions, \
- false); \
- }
-
-#define PUSH_METHOD(classname, enumvar) pushit( \
- L, \
- classname##_methods[enumvar].name, \
- sLua_##classname::method_##enumvar)
-
-#define PUSH_METAMETHOD(classname, enumvar) pushmeta( \
- L, \
- String("__") + classname##_methods[enumvar].name, \
- sLua_##classname::method_##enumvar)
-
-#define PUSH_FUNCTION(classname, enumvar) L->declarefunc( \
- classname##_functions[enumvar].name, \
- sLua_##classname::function_##enumvar)
-
-
-#define CHECK_METHODS(classname) { \
- int i = 0; \
- while (classname##_methods[i].number != -1) { \
- if (i != classname##_methods[i].number) { \
- throw GeneralException("Datas of " #classname "_methods inconsistants!"); \
- } \
- i++; \
- } \
-}
-
-#define CHECK_FUNCTIONS(classname) { \
- int i = 0; \
- while (classname##_functions[i].number != -1) { \
- if (i != classname##_functions[i].number) { \
- throw GeneralException("Datas of " #classname "_functions inconsistants!"); \
- } \
- i++; \
- } \
-}
-
-#include <typeinfo>
-
-template <class T>
-class LuaHelpers : public Base {
- public:
- static int method_multiplex(int caller, lua_State * _L, int (*proceed)(Lua * L, int n, T * obj, int caller), int (*proceed_static)(Lua * L, int n, int caller), lua_functypes_t * tab, bool method) {
- Lua * L = Lua::find(_L);
- int add = method ? 1 : 0;
- int n = L->gettop() - add;
- T * obj = 0;
- int i, j, mask;
- bool invalid = false, arg_valid;
-
- if (method)
- obj = (T *) LuaObject::getme(L);
-
- if ((n < tab[caller].minargs) || (n > tab[caller].maxargs)) {
- invalid = true;
- } else {
- for (i = 0; i < tab[caller].maxargs && !invalid; i++) {
- if (n >= (i + 1)) {
- arg_valid = false;
- for (j = 0; j < MAX_TYPE && !arg_valid; j++) {
- mask = 1 << j;
- if (tab[caller].argtypes[i] & mask) {
- switch(mask) {
- case LUA_OBJECT:
- if (L->istable(i + 1 + add)) {
- L->push("__obj");
- L->gettable(i + 1 + add);
- arg_valid = L->isuserdata();
- L->pop();
- } else {
- arg_valid = L->isnil(i + 1 + add);
- }
- break;
- case LUA_TABLE:
- arg_valid = L->istable(i + 1 + add);
- break;
- case LUA_BOOLEAN:
- arg_valid = L->isboolean(i + 1 + add);
- break;
- case LUA_NUMBER:
- arg_valid = L->isnumber(i + 1 + add);
- break;
- case LUA_STRING:
- arg_valid = L->isstring(i + 1 + add);
- break;
- case LUA_FUNCTION:
- arg_valid = L->isfunction(i + 1 + add);
- break;
- case LUA_NIL:
- arg_valid = L->isnil(i + 1 + add);
- break;
- }
- }
- }
- invalid = !arg_valid;
- }
- }
- }
-
- if (invalid) {
- if (method) {
- L->error(String("Invalid arguments to method `") + typeid(T).name() + "::" + tab[caller].name + "'");
- } else {
- L->error(String("Invalid arguments to function `") + typeid(T).name() + "::" + tab[caller].name + "'");
- }
- }
-
- if (method) {
- return proceed(L, n, obj, caller);
- } else {
- return proceed_static(L, n, caller);
- }
- }
-};
-
-
- /*******************************\
-|** Let's have a sample of use **|
- \*******************************/
-
-#ifdef THIS_IS_A_SAMPLE_WHICH_DOES_NOT_COMPILE
-Luacdfile::Luacdfile(cdfile * h) : LuaHandle(h) { }
-
-enum cdfile_methods_t {
- CDFILE_XXX = 0,
- CDFILE_YYY
-};
-
-enum cdfile_functions_t {
- CDFILE_NEWCDFILE = 0,
-};
-
-struct lua_functypes_t cdutils_methods[] = {
- { CDFILE_XXX, "xxx", 1, 1, {LUA_OBJECT} },
- { CDFILE_YYY, "yyy", 0, 2, {LUA_NUMBER, LUA_NUMBER} },
- { -1, 0, 0, 0, 0 }
-};
-
-struct lua_functypes_t cdfile_functions[] = {
- { CDFILE_NEWCDFILE, "cdfile", 1, 4, {LUA_OBJECT, LUA_ANY, LUA_NUMBER, LUA_NUMBER} },
- { -1, 0, 0, 0, 0 }
-};
-
-class sLua_cdfile : public Base {
- public:
- static int newcdfile(lua_State * L);
- DECLARE_METHOD(cdfile, CDFILE_XXX);
- DECLARE_METHOD(cdfile, CDFILE_YYY);
- DECLARE_FUNCTION(cdfile, CDFILE_NEWCDFILE);
- private:
- static int cdfile_proceed(Lua * L, int n, cdfile * obj, int caller);
- static int cdfile_proceed_statics(Lua * L, int n, int caller);
-};
-
-void Luacdfile::pushmembers(Lua * L) {
- {
- LuaHandle::pushmembers(L);
- or
- pushme(L, SomeObject);
- }
- PUSH_METHOD(cdfile, CDFILE_XXX);
- PUSH_METHOD(cdfile, CDFILE_YYY);
-}
-
-void Luacdfile::pushstatics(Lua * L) {
- CHECK_METHODS(cdfile);
- CHECK_FUNCTIONS(cdfile);
-
- PUSH_FUNCTION(cdfile, CDFILE_NEWCDFILE);
-}
-
-int sLua_cdfile::cdfile_proceed(Lua * L, int n, cdfile * cdfile, int caller) {
- int r = 0;
- SomeObj * obj;
- int arg1 = DEFAULT1, arg2 = DEFAULT2;
-
- switch(caller) {
- case CDFILE_XXX:
- obj = (SomeObj *) LuaObject::getme(L, 2);
- cdfile->xxx(obj);
- break;
- case CDFILE_YYY:
- if (n >= 1)
- arg1 = L->tonumber(2);
- if (n >= 2)
- arg2 = L->tonumber(3);
- L->push((lua_Number) cdfile->yyy(arg1, arg2));
- r = 1;
- break;
- }
-
- return r;
-}
-
-int sLua_cdfile::cdfile_proceed_statics(Lua * L, int n, int caller) {
- int r = 0;
-
- switch(caller) {
- case CDFILE_NEWCDFILE:
- /****TODO****/
- break;
- }
-
- return r;
-}
-
-#endif
-
-#endif
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: BLua.h,v 1.19 2004-11-27 21:46:02 pixel Exp $ */
+
+#ifndef __BLUA_H__
+#define __BLUA_H__
+
+struct lua_State;
+
+extern "C" {
+ void do_lua_lock(lua_State *);
+ void do_lua_unlock(lua_State *);
+}
+
+#define lua_lock(L) do_lua_lock(L)
+#define lua_unlock(L) do_lua_unlock(L)
+
+#include <lua.h>
+#include <map>
+#include <Exceptions.h>
+#include <Handle.h>
+
+class Lua : public Base {
+ public:
+ Lua();
+ Lua(const Lua &) throw (GeneralException);
+ virtual ~Lua();
+ void open_base();
+ void open_table();
+ void open_io();
+ void open_string();
+ void open_math();
+ void open_debug();
+ void open_dir();
+ void declarefunc(const String &, lua_CFunction, int = LUA_GLOBALSINDEX);
+ void call(const String &, int = LUA_GLOBALSINDEX, int = 0, int = 0);
+ void call(int = 0, int = 0);
+ void push();
+ void push(lua_Number);
+ void push(const String &);
+ void push(bool);
+ void push(char *, int size = -1);
+ void push(void *);
+ void push(lua_CFunction, int = 0);
+ void pop(int = 1);
+ void newtable();
+ void * newuser(size_t);
+ void settable(int = -3, bool raw = false);
+ void gettable(int = -2, bool raw = false);
+ void setvar();
+ int gettop();
+ void error(const String &);
+ int type(int = -1);
+ bool isnil(int = -1);
+ bool isboolean(int = -1);
+ bool isnumber(int = -1);
+ bool isstring(int = -1);
+ bool istable(int = -1);
+ bool isfunction(int = -1);
+ bool iscfunction(int = -1);
+ bool isuserdata(int = -1);
+ bool islightuserdata(int = -1);
+ bool toboolean(int = -1);
+ lua_Number tonumber(int = -1);
+ String tostring(int = -1);
+ lua_CFunction tocfunction(int = -1);
+ void * touserdata(int = -1);
+ Lua * tothread(int = -1);
+ void load(Handle *, bool docall = true) throw (GeneralException);
+ void dump(Handle *, bool strip = true);
+ Lua * thread();
+ int yield(int nargs = 0);
+ int resume(int nresults = 0);
+ static Lua * find(lua_State *) throw (GeneralException);
+ void showerror();
+ int getmetatable(int = -1);
+ int setmetatable(int = -2);
+ int sethook(lua_Hook func, int mask, int count);
+
+ void do_break();
+
+ virtual void lock() {}
+ virtual void unlock() {}
+ private:
+ Lua(lua_State *);
+ lua_State * L;
+ static std::map<lua_State *, Lua *> lualist;
+};
+
+class LuaObject : public Base {
+ public:
+ LuaObject() : wantdestruct(false), pushed(false) {}
+ virtual void push(Lua *) throw (GeneralException);
+ static void * getme(Lua *, int = 1);
+ void pushdestruct(Lua *) throw (GeneralException);
+ protected:
+ virtual void pushmembers(Lua *) = 0;
+ void pushme(Lua *, void *, bool = true);
+ static void pushit(Lua *, const String &, lua_CFunction);
+ static void pushmeta(Lua *, const String &, lua_CFunction);
+ bool wantdestruct, pushed;
+};
+
+class LuaException : public GeneralException {
+ public:
+ LuaException(String);
+ protected:
+ LuaException();
+};
+
+enum Lua_types_t {
+ LUA_OBJECT = 0x01,
+ LUA_TABLE = 0x02,
+ LUA_BOOLEAN = 0x04,
+ LUA_NUMBER = 0x08,
+ LUA_STRING = 0x10,
+ LUA_FUNCTION = 0x20,
+ LUA_NIL = 0x40,
+ LUA_ANY = 0x7f,
+};
+
+#define MAX_TYPE 7
+
+#define MAXARGS 32
+
+struct lua_functypes_t {
+ int number;
+ char * name;
+ int minargs, maxargs;
+ int argtypes[MAXARGS];
+};
+
+#define DECLARE_METHOD(classname, enumvar) static int method_##enumvar(lua_State * L) { \
+ return LuaHelpers<classname>::method_multiplex( \
+ enumvar, \
+ L, \
+ sLua_##classname::classname##_proceed, \
+ 0, \
+ classname##_methods, \
+ true); \
+ }
+
+#define DECLARE_FUNCTION(classname, enumvar) static int function_##enumvar(lua_State * L) { \
+ return LuaHelpers<classname>::method_multiplex( \
+ enumvar, \
+ L, \
+ 0, \
+ sLua_##classname::classname##_proceed_statics, \
+ classname##_functions, \
+ false); \
+ }
+
+#define PUSH_METHOD(classname, enumvar) pushit( \
+ L, \
+ classname##_methods[enumvar].name, \
+ sLua_##classname::method_##enumvar)
+
+#define PUSH_METAMETHOD(classname, enumvar) pushmeta( \
+ L, \
+ String("__") + classname##_methods[enumvar].name, \
+ sLua_##classname::method_##enumvar)
+
+#define PUSH_FUNCTION(classname, enumvar) L->declarefunc( \
+ classname##_functions[enumvar].name, \
+ sLua_##classname::function_##enumvar)
+
+
+#define CHECK_METHODS(classname) { \
+ int i = 0; \
+ while (classname##_methods[i].number != -1) { \
+ if (i != classname##_methods[i].number) { \
+ throw GeneralException("Datas of " #classname "_methods inconsistants!"); \
+ } \
+ i++; \
+ } \
+}
+
+#define CHECK_FUNCTIONS(classname) { \
+ int i = 0; \
+ while (classname##_functions[i].number != -1) { \
+ if (i != classname##_functions[i].number) { \
+ throw GeneralException("Datas of " #classname "_functions inconsistants!"); \
+ } \
+ i++; \
+ } \
+}
+
+#include <typeinfo>
+
+template <class T>
+class LuaHelpers : public Base {
+ public:
+ static int method_multiplex(int caller, lua_State * _L, int (*proceed)(Lua * L, int n, T * obj, int caller), int (*proceed_static)(Lua * L, int n, int caller), lua_functypes_t * tab, bool method) {
+ Lua * L = Lua::find(_L);
+ int add = method ? 1 : 0;
+ int n = L->gettop() - add;
+ T * obj = 0;
+ int i, j, mask;
+ bool invalid = false, arg_valid;
+
+ if (method)
+ obj = (T *) LuaObject::getme(L);
+
+ if ((n < tab[caller].minargs) || (n > tab[caller].maxargs)) {
+ invalid = true;
+ } else {
+ for (i = 0; i < tab[caller].maxargs && !invalid; i++) {
+ if (n >= (i + 1)) {
+ arg_valid = false;
+ for (j = 0; j < MAX_TYPE && !arg_valid; j++) {
+ mask = 1 << j;
+ if (tab[caller].argtypes[i] & mask) {
+ switch(mask) {
+ case LUA_OBJECT:
+ if (L->istable(i + 1 + add)) {
+ L->push("__obj");
+ L->gettable(i + 1 + add);
+ arg_valid = L->isuserdata();
+ L->pop();
+ } else {
+ arg_valid = L->isnil(i + 1 + add);
+ }
+ break;
+ case LUA_TABLE:
+ arg_valid = L->istable(i + 1 + add);
+ break;
+ case LUA_BOOLEAN:
+ arg_valid = L->isboolean(i + 1 + add);
+ break;
+ case LUA_NUMBER:
+ arg_valid = L->isnumber(i + 1 + add);
+ break;
+ case LUA_STRING:
+ arg_valid = L->isstring(i + 1 + add);
+ break;
+ case LUA_FUNCTION:
+ arg_valid = L->isfunction(i + 1 + add);
+ break;
+ case LUA_NIL:
+ arg_valid = L->isnil(i + 1 + add);
+ break;
+ }
+ }
+ }
+ invalid = !arg_valid;
+ }
+ }
+ }
+
+ if (invalid) {
+ if (method) {
+ L->error(String("Invalid arguments to method `") + typeid(T).name() + "::" + tab[caller].name + "'");
+ } else {
+ L->error(String("Invalid arguments to function `") + typeid(T).name() + "::" + tab[caller].name + "'");
+ }
+ }
+
+ if (method) {
+ return proceed(L, n, obj, caller);
+ } else {
+ return proceed_static(L, n, caller);
+ }
+ }
+};
+
+
+ /*******************************\
+|** Let's have a sample of use **|
+ \*******************************/
+
+#ifdef THIS_IS_A_SAMPLE_WHICH_DOES_NOT_COMPILE
+Luacdfile::Luacdfile(cdfile * h) : LuaHandle(h) { }
+
+enum cdfile_methods_t {
+ CDFILE_XXX = 0,
+ CDFILE_YYY
+};
+
+enum cdfile_functions_t {
+ CDFILE_NEWCDFILE = 0,
+};
+
+struct lua_functypes_t cdutils_methods[] = {
+ { CDFILE_XXX, "xxx", 1, 1, {LUA_OBJECT} },
+ { CDFILE_YYY, "yyy", 0, 2, {LUA_NUMBER, LUA_NUMBER} },
+ { -1, 0, 0, 0, 0 }
+};
+
+struct lua_functypes_t cdfile_functions[] = {
+ { CDFILE_NEWCDFILE, "cdfile", 1, 4, {LUA_OBJECT, LUA_ANY, LUA_NUMBER, LUA_NUMBER} },
+ { -1, 0, 0, 0, 0 }
+};
+
+class sLua_cdfile : public Base {
+ public:
+ static int newcdfile(lua_State * L);
+ DECLARE_METHOD(cdfile, CDFILE_XXX);
+ DECLARE_METHOD(cdfile, CDFILE_YYY);
+ DECLARE_FUNCTION(cdfile, CDFILE_NEWCDFILE);
+ private:
+ static int cdfile_proceed(Lua * L, int n, cdfile * obj, int caller);
+ static int cdfile_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luacdfile::pushmembers(Lua * L) {
+ {
+ LuaHandle::pushmembers(L);
+ or
+ pushme(L, SomeObject);
+ }
+ PUSH_METHOD(cdfile, CDFILE_XXX);
+ PUSH_METHOD(cdfile, CDFILE_YYY);
+}
+
+void Luacdfile::pushstatics(Lua * L) {
+ CHECK_METHODS(cdfile);
+ CHECK_FUNCTIONS(cdfile);
+
+ PUSH_FUNCTION(cdfile, CDFILE_NEWCDFILE);
+}
+
+int sLua_cdfile::cdfile_proceed(Lua * L, int n, cdfile * cdfile, int caller) {
+ int r = 0;
+ SomeObj * obj;
+ int arg1 = DEFAULT1, arg2 = DEFAULT2;
+
+ switch(caller) {
+ case CDFILE_XXX:
+ obj = (SomeObj *) LuaObject::getme(L, 2);
+ cdfile->xxx(obj);
+ break;
+ case CDFILE_YYY:
+ if (n >= 1)
+ arg1 = L->tonumber(2);
+ if (n >= 2)
+ arg2 = L->tonumber(3);
+ L->push((lua_Number) cdfile->yyy(arg1, arg2));
+ r = 1;
+ break;
+ }
+
+ return r;
+}
+
+int sLua_cdfile::cdfile_proceed_statics(Lua * L, int n, int caller) {
+ int r = 0;
+
+ switch(caller) {
+ case CDFILE_NEWCDFILE:
+ /****TODO****/
+ break;
+ }
+
+ return r;
+}
+
+#endif
+
+#endif
diff --git a/include/BString.h b/include/BString.h
index 13dd33b..2809822 100644
--- a/include/BString.h
+++ b/include/BString.h
@@ -1,101 +1,101 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: BString.h,v 1.11 2004-11-27 21:43:48 pixel Exp $ */
-
-#ifndef __STRING_H__
-#define __STRING_H__
-
-#include <string.h>
-#include <stdarg.h>
-#include <iostream>
-#include <string>
-#include <Exceptions.h>
-#include <generic.h>
-
-struct ugly_string {
- const char * p;
-};
-
-class String : public Base {
- public:
- String(const String &);
- String(const char * = "");
- String(char);
- String(int);
- String(unsigned int);
- String(int64);
- String(Uint64);
- String(double);
- ~String();
- const char * set(const char *, va_list);
- const char * set(const char *, ...);
- const char * set(const ugly_string &, ...);
- int scanf(const char *, ...) const;
- int scanf(const ugly_string &, ...) const;
- const char * to_charp(size_t = 0, ssize_t = -1) const;
- String extract(size_t = 0, ssize_t = -1) const;
- char * strdup(size_t = 0, ssize_t = -1) const;
- int to_int() const;
- double to_double() const;
- String to_sqldate() const;
- String to_sqltime() const;
- String from_sqldate() const;
- String from_sqltime() const;
- double datedif(const String &) const;
- bool is_date() const;
- bool is_number() const;
- bool is_float() const;
- bool is_time() const;
- size_t strlen() const;
- ssize_t strchr(char, size_t = 0) const;
- ssize_t strrchr(char) const;
- ssize_t strstr(const String &) const;
- int strchrcnt(char) const;
- String ltrim() const;
- String rtrim() const;
- String trim() const;
- String & operator=(const String &);
- String operator+(const String &) const;
- String & operator+=(const String &);
- bool operator!=(const String &) const;
- bool operator==(const String &) const;
- bool operator<=(const String &) const;
- bool operator>=(const String &) const;
- bool operator<(const String &) const;
- bool operator>(const String &) const;
- char operator[](size_t i) const;
- char & operator[](size_t i);
- operator ugly_string() const;
- String & toupper();
- String & tolower();
-
- private:
- String(int hs, char *);
- static char t[];
- char * str;
- size_t siz;
-};
-
-std::ostream & operator<<(std::ostream &, const String &);
-std::istream & operator>>(std::istream &, String &);
-
-String operator+(const char *, const String &);
-
-#endif
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: BString.h,v 1.12 2004-11-27 21:46:02 pixel Exp $ */
+
+#ifndef __STRING_H__
+#define __STRING_H__
+
+#include <string.h>
+#include <stdarg.h>
+#include <iostream>
+#include <string>
+#include <Exceptions.h>
+#include <generic.h>
+
+struct ugly_string {
+ const char * p;
+};
+
+class String : public Base {
+ public:
+ String(const String &);
+ String(const char * = "");
+ String(char);
+ String(int);
+ String(unsigned int);
+ String(int64);
+ String(Uint64);
+ String(double);
+ ~String();
+ const char * set(const char *, va_list);
+ const char * set(const char *, ...);
+ const char * set(const ugly_string &, ...);
+ int scanf(const char *, ...) const;
+ int scanf(const ugly_string &, ...) const;
+ const char * to_charp(size_t = 0, ssize_t = -1) const;
+ String extract(size_t = 0, ssize_t = -1) const;
+ char * strdup(size_t = 0, ssize_t = -1) const;
+ int to_int() const;
+ double to_double() const;
+ String to_sqldate() const;
+ String to_sqltime() const;
+ String from_sqldate() const;
+ String from_sqltime() const;
+ double datedif(const String &) const;
+ bool is_date() const;
+ bool is_number() const;
+ bool is_float() const;
+ bool is_time() const;
+ size_t strlen() const;
+ ssize_t strchr(char, size_t = 0) const;
+ ssize_t strrchr(char) const;
+ ssize_t strstr(const String &) const;
+ int strchrcnt(char) const;
+ String ltrim() const;
+ String rtrim() const;
+ String trim() const;
+ String & operator=(const String &);
+ String operator+(const String &) const;
+ String & operator+=(const String &);
+ bool operator!=(const String &) const;
+ bool operator==(const String &) const;
+ bool operator<=(const String &) const;
+ bool operator>=(const String &) const;
+ bool operator<(const String &) const;
+ bool operator>(const String &) const;
+ char operator[](size_t i) const;
+ char & operator[](size_t i);
+ operator ugly_string() const;
+ String & toupper();
+ String & tolower();
+
+ private:
+ String(int hs, char *);
+ static char t[];
+ char * str;
+ size_t siz;
+};
+
+std::ostream & operator<<(std::ostream &, const String &);
+std::istream & operator>>(std::istream &, String &);
+
+String operator+(const char *, const String &);
+
+#endif
diff --git a/include/Buffer.h b/include/Buffer.h
index 41e8da3..dceac94 100644
--- a/include/Buffer.h
+++ b/include/Buffer.h
@@ -1,61 +1,61 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: Buffer.h,v 1.18 2004-11-27 21:43:48 pixel Exp $ */
-
-#ifndef __BUFFER_H__
-#define __BUFFER_H__
-
-#include <zlib.h>
-#include <Exceptions.h>
-#include <Handle.h>
-
-#ifndef realloc_threshold
-#define realloc_threshold 256
-#endif
-
-class Buffer : public Handle {
- public:
- Buffer(bool seekable = false);
- Buffer(const Buffer &);
- virtual ~Buffer();
- virtual ssize_t write(const void *buf, size_t count) throw(GeneralException);
- virtual ssize_t read(void *buf, size_t count) throw (GeneralException);
- virtual bool CanRead() const;
- virtual bool CanWrite() const;
- virtual String GetName() const;
- virtual Buffer operator=(const Buffer &);
- virtual bool CanWatch() const;
- virtual ssize_t GetSize() const;
- virtual bool CanSeek() const;
- virtual off_t seek(off_t, int = SEEK_SET) throw (GeneralException);
- virtual off_t tell() const;
- Byte operator[](size_t) const;
- Byte & operator[](size_t);
- off_t wseek(off_t, int = SEEK_SET) throw (GeneralException);
- off_t wtell() const;
- void reset();
-
- private:
- Byte * buffer, zero;
- size_t realsiz, bufsiz, ptr, wptr;
- bool seekable;
-};
-
-#endif
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: Buffer.h,v 1.19 2004-11-27 21:46:02 pixel Exp $ */
+
+#ifndef __BUFFER_H__
+#define __BUFFER_H__
+
+#include <zlib.h>
+#include <Exceptions.h>
+#include <Handle.h>
+
+#ifndef realloc_threshold
+#define realloc_threshold 256
+#endif
+
+class Buffer : public Handle {
+ public:
+ Buffer(bool seekable = false);
+ Buffer(const Buffer &);
+ virtual ~Buffer();
+ virtual ssize_t write(const void *buf, size_t count) throw(GeneralException);
+ virtual ssize_t read(void *buf, size_t count) throw (GeneralException);
+ virtual bool CanRead() const;
+ virtual bool CanWrite() const;
+ virtual String GetName() const;
+ virtual Buffer operator=(const Buffer &);
+ virtual bool CanWatch() const;
+ virtual ssize_t GetSize() const;
+ virtual bool CanSeek() const;
+ virtual off_t seek(off_t, int = SEEK_SET) throw (GeneralException);
+ virtual off_t tell() const;
+ Byte operator[](size_t) const;
+ Byte & operator[](size_t);
+ off_t wseek(off_t, int = SEEK_SET) throw (GeneralException);
+ off_t wtell() const;
+ void reset();
+
+ private:
+ Byte * buffer, zero;
+ size_t realsiz, bufsiz, ptr, wptr;
+ bool seekable;
+};
+
+#endif
diff --git a/include/Color.h b/include/Color.h
index d4807ed..5b2ec06 100644
--- a/include/Color.h
+++ b/include/Color.h
@@ -1,320 +1,320 @@
-#ifndef __COLOR_H__
-#define __COLOR_H__
-
-struct Color {
- Color() : R(255), G(255), B(255), A(255) { }
- Color(unsigned char aR, unsigned char aG, unsigned char aB, unsigned char aA = 255) :
- R(aR), G(aG), B(aB), A(aA) { }
- Color(const Color & c) : R(c.R), G(c.G), B(c.B), A(c.A) { }
- bool operator==(const Color & c) const {
- return (R == c.R) && (G == c.G) && (B == c.B) && (A == c.A);
- }
- unsigned char R, G, B, A;
-};
-
-/*
-
-From http://www.spacetoday.org/BoilerRoom/Colors.html :
-
-F0F8FF aliceblue
-FAEBD7 antiquewhite
-00FFFF aqua
-7FFFD4 aquamarine
-F0FFFF azure
-F5F5DC beige
-FFE4C4 bisque
-000000 black
-FFEBCD blanchedalmond
-0000FF blue
-8A2BE2 blueviolet
-A52A2A brown
-DEB887 burlywood
-5F9EA0 cadetblue
-7FFF00 chartreuse
-D2691E chocolate
-FF7F50 coral
-6495ED cornflowerblue
-FFF8DC cornsilk
-DC143C crimson
-00FFFF cyan
-00008B darkblue
-008B8B darkcyan
-B8860B darkgoldenrod
-A9A9A9 darkgray
-006400 darkgreen
-BDB76B darkkhaki
-8B008B darkmagenta
-556B2F darkolivegreen
-FF8C00 darkorange
-9932CC darkorchid
-8B0000 darkred
-E9967A darksalmon
-8FBC8F darkseagreen
-483D8B darkslateblue
-2F4F4F darkslategray
-00CED1 darkturquoise
-9400D3 darkviolet
-FF1493 deeppink
-00BFFF deepskyblue
-696969 dimgray
-1E90FF dodgerblue
-B22222 firebrick
-FFFAF0 floralwhite
-228B22 forestgreen
-FF00FF fuchsia
-DCDCDC gainsboro
-F8F8FF ghostwhite
-FFD700 gold
-DAA520 goldenrod
-808080 gray
-008000 green
-ADFF2F greenyellow
-F0FFF0 honeydew
-FF69B4 hotpink
-CD5C5C indianred
-4B0082 indigo
-FFFFF0 ivory
-F0E68C khaki
-E6E6FA lavender
-FFF0F5 lavenderblush
-7CFC00 lawngreen
-FFFACD lemonchiffon
-ADD8E6 lightblue
-F08080 lightcoral
-E0FFFF lightcyan
-FAFAD2 lightgoldenrodyellow
-90EE90 lightgreen
-D3D3D3 lightgrey
-FFB6C1 lightpink
-FFA07A lightsalmon
-20B2AA lightseagreen
-87CEFA lightskyblue
-778899 lightslategray
-B0C4DE lightsteelblue
-FFFFE0 lightyellow
-00FF00 lime
-32CD32 limegreen
-FAF0E6 linen
-FF00FF magenta
-800000 maroon
-66CDAA mediumaquamarine
-0000CD mediumblue
-BA55D3 mediumorchid
-9370DB mediumpurple
-3CB371 mediumseagreen
-7B68EE mediumslateblue
-00FA9A mediumspringgreen
-48D1CC mediumturquoise
-C71585 mediumvioletred
-191970 midnightblue
-F5FFFA mintcream
-FFE4E1 mistyrose
-FFE4B5 moccasin
-FFDEAD navajowhite
-000080 navy
-FDF5E6 oldlace
-808000 olive
-6B8E23 olivedrab
-FFA500 orange
-FF4500 orangered
-DA70D6 orchid
-EEE8AA palegoldenrod
-98FB98 palegreen
-AFEEEE paleturquoise
-DB7093 palevioletred
-FFEFD5 papayawhip
-FFDAB9 peachpuff
-CD853F peru
-FFC0CB pink
-DDA0DD plum
-B0E0E6 powderblue
-800080 purple
-FF0000 red
-BC8F8F rosybrown
-4169E1 royalblue
-8B4513 saddlebrown
-FA8072 salmon
-F4A460 sandybrown
-2E8B57 seagreen
-FFF5EE seashell
-A0522D sienna
-C0C0C0 silver
-87CEEB skyblue
-6A5ACD slateblue
-708090 slategray
-FFFAFA snow
-00FF7F springgreen
-4682B4 steelblue
-D2B48C tan
-008080 teal
-D8BFD8 thistle
-FF6347 tomato
-40E0D0 turquoise
-EE82EE violet
-F5DEB3 wheat
-FFFFFF white
-F5F5F5 whitesmoke
-FFFF00 yellow
-9ACD32 yellowgreen
-
-*/
-
-#define ALICEBLUE (Color(0xf0, 0xf8, 0xff))
-#define ANTIQUEWHITE (Color(0xfa, 0xeb, 0xd7))
-#define AQUA (Color(0x00, 0xff, 0xff))
-#define AQUAMARINE (Color(0x7f, 0xff, 0xd4))
-#define AZURE (Color(0xf0, 0xff, 0xff))
-#define BEIGE (Color(0xf5, 0xf5, 0xdc))
-#define BISQUE (Color(0xff, 0xe4, 0xc4))
-#define BLACK (Color(0x00, 0x00, 0x00))
-#define BLANCHEDALMOND (Color(0xff, 0xeb, 0xcd))
-#define BLUE (Color(0x00, 0x00, 0xff))
-#define BLUEVIOLET (Color(0x8a, 0x2b, 0xe2))
-#define BROWN (Color(0xa5, 0x2a, 0x2a))
-#define BURLYWOOD (Color(0xde, 0xb8, 0x87))
-#define CADETBLUE (Color(0x5f, 0x9e, 0xa0))
-#define CHARTREUSE (Color(0x7f, 0xff, 0x00))
-#define CHOCOLATE (Color(0xd2, 0x69, 0x1e))
-#define CORAL (Color(0xff, 0x7f, 0x50))
-#define CORNFLOWERBLUE (Color(0x64, 0x95, 0xed))
-#define CORNSILK (Color(0xff, 0xf8, 0xdc))
-#define CRIMSON (Color(0xdc, 0x14, 0x3c))
-#define CYAN (Color(0x00, 0xff, 0xff))
-#define DARKBLUE (Color(0x00, 0x00, 0x8b))
-#define DARKCYAN (Color(0x00, 0x8b, 0x8b))
-#define DARKGOLDENROD (Color(0xb8, 0x86, 0x0b))
-#define DARKGRAY (Color(0xa9, 0xa9, 0xa9))
-#define DARKGREEN (Color(0x00, 0x64, 0x00))
-#define DARKKHAKI (Color(0xbd, 0xb7, 0x6b))
-#define DARKMAGENTA (Color(0x8b, 0x00, 0x8b))
-#define DARKOLIVEGREEN (Color(0x55, 0x6b, 0x2f))
-#define DARKORANGE (Color(0xff, 0x8c, 0x00))
-#define DARKORCHID (Color(0x99, 0x32, 0xcc))
-#define DARKRED (Color(0x8b, 0x00, 0x00))
-#define DARKSALMON (Color(0xe9, 0x96, 0x7a))
-#define DARKSEAGREEN (Color(0x8f, 0xbc, 0x8f))
-#define DARKSLATEBLUE (Color(0x48, 0x3d, 0x8b))
-#define DARKSLATEGRAY (Color(0x2f, 0x4f, 0x4f))
-#define DARKTURQUOISE (Color(0x00, 0xce, 0xd1))
-#define DARKVIOLET (Color(0x94, 0x00, 0xd3))
-#define DEEPPINK (Color(0xff, 0x14, 0x93))
-#define DEEPSKYBLUE (Color(0x00, 0xbf, 0xff))
-#define DIMGRAY (Color(0x69, 0x69, 0x69))
-#define DODGERBLUE (Color(0x1e, 0x90, 0xff))
-#define FIREBRICK (Color(0xb2, 0x22, 0x22))
-#define FLORALWHITE (Color(0xff, 0xfa, 0xf0))
-#define FORESTGREEN (Color(0x22, 0x8b, 0x22))
-#define FUCHSIA (Color(0xff, 0x00, 0xff))
-#define GAINSBORO (Color(0xdc, 0xdc, 0xdc))
-#define GHOSTWHITE (Color(0xf8, 0xf8, 0xff))
-#define GOLD (Color(0xff, 0xd7, 0x00))
-#define GOLDENROD (Color(0xda, 0xa5, 0x20))
-#define GRAY (Color(0x80, 0x80, 0x80))
-#define GREEN (Color(0x00, 0x80, 0x00))
-#define GREENYELLOW (Color(0xad, 0xff, 0x2f))
-#define HONEYDEW (Color(0xf0, 0xff, 0xf0))
-#define HOTPINK (Color(0xff, 0x69, 0xb4))
-#define INDIANRED (Color(0xcd, 0x5c, 0x5c))
-#define INDIGO (Color(0x4b, 0x00, 0x82))
-#define IVORY (Color(0xff, 0xff, 0xf0))
-#define KHAKI (Color(0xf0, 0xe6, 0x8c))
-#define LAVENDER (Color(0xe6, 0xe6, 0xfa))
-#define LAVENDERBLUSH (Color(0xff, 0xf0, 0xf5))
-#define LAWNGREEN (Color(0x7c, 0xfc, 0x00))
-#define LEMONCHIFFON (Color(0xff, 0xfa, 0xcd))
-#define LIGHTBLUE (Color(0xad, 0xd8, 0xe6))
-#define LIGHTCORAL (Color(0xf0, 0x80, 0x80))
-#define LIGHTCYAN (Color(0xe0, 0xff, 0xff))
-#define LIGHTGOLDENRODYELLOW (Color(0xfa, 0xfa, 0xd2))
-#define LIGHTGREEN (Color(0x90, 0xee, 0x90))
-#define LIGHTGREY (Color(0xd3, 0xd3, 0xd3))
-#define LIGHTPINK (Color(0xff, 0xb6, 0xc1))
-#define LIGHTSALMON (Color(0xff, 0xa0, 0x7a))
-#define LIGHTSEAGREEN (Color(0x20, 0xb2, 0xaa))
-#define LIGHTSKYBLUE (Color(0x87, 0xce, 0xfa))
-#define LIGHTSLATEGRAY (Color(0x77, 0x88, 0x99))
-#define LIGHTSTEELBLUE (Color(0xb0, 0xc4, 0xde))
-#define LIGHTYELLOW (Color(0xff, 0xff, 0xe0))
-#define LIME (Color(0x00, 0xff, 0x00))
-#define LIMEGREEN (Color(0x32, 0xcd, 0x32))
-#define LINEN (Color(0xfa, 0xf0, 0xe6))
-#define MAGENTA (Color(0xff, 0x00, 0xff))
-#define MAROON (Color(0x80, 0x00, 0x00))
-#define MEDIUMAQUAMARINE (Color(0x66, 0xcd, 0xaa))
-#define MEDIUMBLUE (Color(0x00, 0x00, 0xcd))
-#define MEDIUMORCHID (Color(0xba, 0x55, 0xd3))
-#define MEDIUMPURPLE (Color(0x93, 0x70, 0xdb))
-#define MEDIUMSEAGREEN (Color(0x3c, 0xb3, 0x71))
-#define MEDIUMSLATEBLUE (Color(0x7b, 0x68, 0xee))
-#define MEDIUMSPRINGGREEN (Color(0x00, 0xfa, 0x9a))
-#define MEDIUMTURQUOISE (Color(0x48, 0xd1, 0xcc))
-#define MEDIUMVIOLETRED (Color(0xc7, 0x15, 0x85))
-#define MIDNIGHTBLUE (Color(0x19, 0x19, 0x70))
-#define MINTCREAM (Color(0xf5, 0xff, 0xfa))
-#define MISTYROSE (Color(0xff, 0xe4, 0xe1))
-#define MOCCASIN (Color(0xff, 0xe4, 0xb5))
-#define NAVAJOWHITE (Color(0xff, 0xde, 0xad))
-#define NAVY (Color(0x00, 0x00, 0x80))
-#define OLDLACE (Color(0xfd, 0xf5, 0xe6))
-#define OLIVE (Color(0x80, 0x80, 0x00))
-#define OLIVEDRAB (Color(0x6b, 0x8e, 0x23))
-#define ORANGE (Color(0xff, 0xa5, 0x00))
-#define ORANGERED (Color(0xff, 0x45, 0x00))
-#define ORCHID (Color(0xda, 0x70, 0xd6))
-#define PALEGOLDENROD (Color(0xee, 0xe8, 0xaa))
-#define PALEGREEN (Color(0x98, 0xfb, 0x98))
-#define PALETURQUOISE (Color(0xaf, 0xee, 0xee))
-#define PALEVIOLETRED (Color(0xdb, 0x70, 0x93))
-#define PAPAYAWHIP (Color(0xff, 0xef, 0xd5))
-#define PEACHPUFF (Color(0xff, 0xda, 0xb9))
-#define PERU (Color(0xcd, 0x85, 0x3f))
-#define PINK (Color(0xff, 0xc0, 0xcb))
-#define PLUM (Color(0xdd, 0xa0, 0xdd))
-#define POWDERBLUE (Color(0xb0, 0xe0, 0xe6))
-#define PURPLE (Color(0x80, 0x00, 0x80))
-#define RED (Color(0xff, 0x00, 0x00))
-#define ROSYBROWN (Color(0xbc, 0x8f, 0x8f))
-#define ROYALBLUE (Color(0x41, 0x69, 0xe1))
-#define SADDLEBROWN (Color(0x8b, 0x45, 0x13))
-#define SALMON (Color(0xfa, 0x80, 0x72))
-#define SANDYBROWN (Color(0xf4, 0xa4, 0x60))
-#define SEAGREEN (Color(0x2e, 0x8b, 0x57))
-#define SEASHELL (Color(0xff, 0xf5, 0xee))
-#define SIENNA (Color(0xa0, 0x52, 0x2d))
-#define SILVER (Color(0xc0, 0xc0, 0xc0))
-#define SKYBLUE (Color(0x87, 0xce, 0xeb))
-#define SLATEBLUE (Color(0x6a, 0x5a, 0xcd))
-#define SLATEGRAY (Color(0x70, 0x80, 0x90))
-#define SNOW (Color(0xff, 0xfa, 0xfa))
-#define SPRINGGREEN (Color(0x00, 0xff, 0x7f))
-#define STEELBLUE (Color(0x46, 0x82, 0xb4))
-#define TAN (Color(0xd2, 0xb4, 0x8c))
-#define TEAL (Color(0x00, 0x80, 0x80))
-#define THISTLE (Color(0xd8, 0xbf, 0xd8))
-#define TOMATO (Color(0xff, 0x63, 0x47))
-#define TURQUOISE (Color(0x40, 0xe0, 0xd0))
-#define VIOLET (Color(0xee, 0x82, 0xee))
-#define WHEAT (Color(0xf5, 0xde, 0xb3))
-#define WHITE (Color(0xff, 0xff, 0xff))
-#define WHITESMOKE (Color(0xf5, 0xf5, 0xf5))
-#define YELLOW (Color(0xff, 0xff, 0x00))
-#define YELLOWGREEN (Color(0x9a, 0xcd, 0x32))
-
-#define DOS_BLACK (Color(0x00, 0x00, 0x00)) // Black
-#define DOS_BLUE (Color(0x00, 0x00, 0xaa)) // Blue
-#define DOS_GREEN (Color(0x00, 0xaa, 0x00)) // Green
-#define DOS_CYAN (Color(0x00, 0xaa, 0xaa)) // Cyan
-#define DOS_RED (Color(0xaa, 0x00, 0x00)) // Red
-#define DOS_MAGENTA (Color(0xaa, 0x00, 0xaa)) // Magenta
-#define DOS_BRAWN (Color(0xaa, 0x55, 0x00)) // Brawn
-#define DOS_WHITE (Color(0xaa, 0xaa, 0xaa)) // White
-#define DOS_GRAY (Color(0x55, 0x55, 0x55)) // Gray
-#define DOS_HIGH_BLUE (Color(0x55, 0x55, 0xff)) // High Blue
-#define DOS_HIGH_GREEN (Color(0x55, 0xff, 0x55)) // High Green
-#define DOS_HIGH_CYAN (Color(0x55, 0xff, 0xff)) // High Cyan
-#define DOS_HIGH_RED (Color(0xff, 0x55, 0x55)) // High Red
-#define DOS_HIGH_MAGENTA (Color(0xff, 0x55, 0xff)) // High Magenta
-#define DOS_YELLOW (Color(0xff, 0xff, 0x55)) // Yellow
-#define DOS_HIGH_WHITE (Color(0xff, 0xff, 0xff)) // High White
-
-#endif
+#ifndef __COLOR_H__
+#define __COLOR_H__
+
+struct Color {
+ Color() : R(255), G(255), B(255), A(255) { }
+ Color(unsigned char aR, unsigned char aG, unsigned char aB, unsigned char aA = 255) :
+ R(aR), G(aG), B(aB), A(aA) { }
+ Color(const Color & c) : R(c.R), G(c.G), B(c.B), A(c.A) { }
+ bool operator==(const Color & c) const {
+ return (R == c.R) && (G == c.G) && (B == c.B) && (A == c.A);
+ }
+ unsigned char R, G, B, A;
+};
+
+/*
+
+From http://www.spacetoday.org/BoilerRoom/Colors.html :
+
+F0F8FF aliceblue
+FAEBD7 antiquewhite
+00FFFF aqua
+7FFFD4 aquamarine
+F0FFFF azure
+F5F5DC beige
+FFE4C4 bisque
+000000 black
+FFEBCD blanchedalmond
+0000FF blue
+8A2BE2 blueviolet
+A52A2A brown
+DEB887 burlywood
+5F9EA0 cadetblue
+7FFF00 chartreuse
+D2691E chocolate
+FF7F50 coral
+6495ED cornflowerblue
+FFF8DC cornsilk
+DC143C crimson
+00FFFF cyan
+00008B darkblue
+008B8B darkcyan
+B8860B darkgoldenrod
+A9A9A9 darkgray
+006400 darkgreen
+BDB76B darkkhaki
+8B008B darkmagenta
+556B2F darkolivegreen
+FF8C00 darkorange
+9932CC darkorchid
+8B0000 darkred
+E9967A darksalmon
+8FBC8F darkseagreen
+483D8B darkslateblue
+2F4F4F darkslategray
+00CED1 darkturquoise
+9400D3 darkviolet
+FF1493 deeppink
+00BFFF deepskyblue
+696969 dimgray
+1E90FF dodgerblue
+B22222 firebrick
+FFFAF0 floralwhite
+228B22 forestgreen
+FF00FF fuchsia
+DCDCDC gainsboro
+F8F8FF ghostwhite
+FFD700 gold
+DAA520 goldenrod
+808080 gray
+008000 green
+ADFF2F greenyellow
+F0FFF0 honeydew
+FF69B4 hotpink
+CD5C5C indianred
+4B0082 indigo
+FFFFF0 ivory
+F0E68C khaki
+E6E6FA lavender
+FFF0F5 lavenderblush
+7CFC00 lawngreen
+FFFACD lemonchiffon
+ADD8E6 lightblue
+F08080 lightcoral
+E0FFFF lightcyan
+FAFAD2 lightgoldenrodyellow
+90EE90 lightgreen
+D3D3D3 lightgrey
+FFB6C1 lightpink
+FFA07A lightsalmon
+20B2AA lightseagreen
+87CEFA lightskyblue
+778899 lightslategray
+B0C4DE lightsteelblue
+FFFFE0 lightyellow
+00FF00 lime
+32CD32 limegreen
+FAF0E6 linen
+FF00FF magenta
+800000 maroon
+66CDAA mediumaquamarine
+0000CD mediumblue
+BA55D3 mediumorchid
+9370DB mediumpurple
+3CB371 mediumseagreen
+7B68EE mediumslateblue
+00FA9A mediumspringgreen
+48D1CC mediumturquoise
+C71585 mediumvioletred
+191970 midnightblue
+F5FFFA mintcream
+FFE4E1 mistyrose
+FFE4B5 moccasin
+FFDEAD navajowhite
+000080 navy
+FDF5E6 oldlace
+808000 olive
+6B8E23 olivedrab
+FFA500 orange
+FF4500 orangered
+DA70D6 orchid
+EEE8AA palegoldenrod
+98FB98 palegreen
+AFEEEE paleturquoise
+DB7093 palevioletred
+FFEFD5 papayawhip
+FFDAB9 peachpuff
+CD853F peru
+FFC0CB pink
+DDA0DD plum
+B0E0E6 powderblue
+800080 purple
+FF0000 red
+BC8F8F rosybrown
+4169E1 royalblue
+8B4513 saddlebrown
+FA8072 salmon
+F4A460 sandybrown
+2E8B57 seagreen
+FFF5EE seashell
+A0522D sienna
+C0C0C0 silver
+87CEEB skyblue
+6A5ACD slateblue
+708090 slategray
+FFFAFA snow
+00FF7F springgreen
+4682B4 steelblue
+D2B48C tan
+008080 teal
+D8BFD8 thistle
+FF6347 tomato
+40E0D0 turquoise
+EE82EE violet
+F5DEB3 wheat
+FFFFFF white
+F5F5F5 whitesmoke
+FFFF00 yellow
+9ACD32 yellowgreen
+
+*/
+
+#define ALICEBLUE (Color(0xf0, 0xf8, 0xff))
+#define ANTIQUEWHITE (Color(0xfa, 0xeb, 0xd7))
+#define AQUA (Color(0x00, 0xff, 0xff))
+#define AQUAMARINE (Color(0x7f, 0xff, 0xd4))
+#define AZURE (Color(0xf0, 0xff, 0xff))
+#define BEIGE (Color(0xf5, 0xf5, 0xdc))
+#define BISQUE (Color(0xff, 0xe4, 0xc4))
+#define BLACK (Color(0x00, 0x00, 0x00))
+#define BLANCHEDALMOND (Color(0xff, 0xeb, 0xcd))
+#define BLUE (Color(0x00, 0x00, 0xff))
+#define BLUEVIOLET (Color(0x8a, 0x2b, 0xe2))
+#define BROWN (Color(0xa5, 0x2a, 0x2a))
+#define BURLYWOOD (Color(0xde, 0xb8, 0x87))
+#define CADETBLUE (Color(0x5f, 0x9e, 0xa0))
+#define CHARTREUSE (Color(0x7f, 0xff, 0x00))
+#define CHOCOLATE (Color(0xd2, 0x69, 0x1e))
+#define CORAL (Color(0xff, 0x7f, 0x50))
+#define CORNFLOWERBLUE (Color(0x64, 0x95, 0xed))
+#define CORNSILK (Color(0xff, 0xf8, 0xdc))
+#define CRIMSON (Color(0xdc, 0x14, 0x3c))
+#define CYAN (Color(0x00, 0xff, 0xff))
+#define DARKBLUE (Color(0x00, 0x00, 0x8b))
+#define DARKCYAN (Color(0x00, 0x8b, 0x8b))
+#define DARKGOLDENROD (Color(0xb8, 0x86, 0x0b))
+#define DARKGRAY (Color(0xa9, 0xa9, 0xa9))
+#define DARKGREEN (Color(0x00, 0x64, 0x00))
+#define DARKKHAKI (Color(0xbd, 0xb7, 0x6b))
+#define DARKMAGENTA (Color(0x8b, 0x00, 0x8b))
+#define DARKOLIVEGREEN (Color(0x55, 0x6b, 0x2f))
+#define DARKORANGE (Color(0xff, 0x8c, 0x00))
+#define DARKORCHID (Color(0x99, 0x32, 0xcc))
+#define DARKRED (Color(0x8b, 0x00, 0x00))
+#define DARKSALMON (Color(0xe9, 0x96, 0x7a))
+#define DARKSEAGREEN (Color(0x8f, 0xbc, 0x8f))
+#define DARKSLATEBLUE (Color(0x48, 0x3d, 0x8b))
+#define DARKSLATEGRAY (Color(0x2f, 0x4f, 0x4f))
+#define DARKTURQUOISE (Color(0x00, 0xce, 0xd1))
+#define DARKVIOLET (Color(0x94, 0x00, 0xd3))
+#define DEEPPINK (Color(0xff, 0x14, 0x93))
+#define DEEPSKYBLUE (Color(0x00, 0xbf, 0xff))
+#define DIMGRAY (Color(0x69, 0x69, 0x69))
+#define DODGERBLUE (Color(0x1e, 0x90, 0xff))
+#define FIREBRICK (Color(0xb2, 0x22, 0x22))
+#define FLORALWHITE (Color(0xff, 0xfa, 0xf0))
+#define FORESTGREEN (Color(0x22, 0x8b, 0x22))
+#define FUCHSIA (Color(0xff, 0x00, 0xff))
+#define GAINSBORO (Color(0xdc, 0xdc, 0xdc))
+#define GHOSTWHITE (Color(0xf8, 0xf8, 0xff))
+#define GOLD (Color(0xff, 0xd7, 0x00))
+#define GOLDENROD (Color(0xda, 0xa5, 0x20))
+#define GRAY (Color(0x80, 0x80, 0x80))
+#define GREEN (Color(0x00, 0x80, 0x00))
+#define GREENYELLOW (Color(0xad, 0xff, 0x2f))
+#define HONEYDEW (Color(0xf0, 0xff, 0xf0))
+#define HOTPINK (Color(0xff, 0x69, 0xb4))
+#define INDIANRED (Color(0xcd, 0x5c, 0x5c))
+#define INDIGO (Color(0x4b, 0x00, 0x82))
+#define IVORY (Color(0xff, 0xff, 0xf0))
+#define KHAKI (Color(0xf0, 0xe6, 0x8c))
+#define LAVENDER (Color(0xe6, 0xe6, 0xfa))
+#define LAVENDERBLUSH (Color(0xff, 0xf0, 0xf5))
+#define LAWNGREEN (Color(0x7c, 0xfc, 0x00))
+#define LEMONCHIFFON (Color(0xff, 0xfa, 0xcd))
+#define LIGHTBLUE (Color(0xad, 0xd8, 0xe6))
+#define LIGHTCORAL (Color(0xf0, 0x80, 0x80))
+#define LIGHTCYAN (Color(0xe0, 0xff, 0xff))
+#define LIGHTGOLDENRODYELLOW (Color(0xfa, 0xfa, 0xd2))
+#define LIGHTGREEN (Color(0x90, 0xee, 0x90))
+#define LIGHTGREY (Color(0xd3, 0xd3, 0xd3))
+#define LIGHTPINK (Color(0xff, 0xb6, 0xc1))
+#define LIGHTSALMON (Color(0xff, 0xa0, 0x7a))
+#define LIGHTSEAGREEN (Color(0x20, 0xb2, 0xaa))
+#define LIGHTSKYBLUE (Color(0x87, 0xce, 0xfa))
+#define LIGHTSLATEGRAY (Color(0x77, 0x88, 0x99))
+#define LIGHTSTEELBLUE (Color(0xb0, 0xc4, 0xde))
+#define LIGHTYELLOW (Color(0xff, 0xff, 0xe0))
+#define LIME (Color(0x00, 0xff, 0x00))
+#define LIMEGREEN (Color(0x32, 0xcd, 0x32))
+#define LINEN (Color(0xfa, 0xf0, 0xe6))
+#define MAGENTA (Color(0xff, 0x00, 0xff))
+#define MAROON (Color(0x80, 0x00, 0x00))
+#define MEDIUMAQUAMARINE (Color(0x66, 0xcd, 0xaa))
+#define MEDIUMBLUE (Color(0x00, 0x00, 0xcd))
+#define MEDIUMORCHID (Color(0xba, 0x55, 0xd3))
+#define MEDIUMPURPLE (Color(0x93, 0x70, 0xdb))
+#define MEDIUMSEAGREEN (Color(0x3c, 0xb3, 0x71))
+#define MEDIUMSLATEBLUE (Color(0x7b, 0x68, 0xee))
+#define MEDIUMSPRINGGREEN (Color(0x00, 0xfa, 0x9a))
+#define MEDIUMTURQUOISE (Color(0x48, 0xd1, 0xcc))
+#define MEDIUMVIOLETRED (Color(0xc7, 0x15, 0x85))
+#define MIDNIGHTBLUE (Color(0x19, 0x19, 0x70))
+#define MINTCREAM (Color(0xf5, 0xff, 0xfa))
+#define MISTYROSE (Color(0xff, 0xe4, 0xe1))
+#define MOCCASIN (Color(0xff, 0xe4, 0xb5))
+#define NAVAJOWHITE (Color(0xff, 0xde, 0xad))
+#define NAVY (Color(0x00, 0x00, 0x80))
+#define OLDLACE (Color(0xfd, 0xf5, 0xe6))
+#define OLIVE (Color(0x80, 0x80, 0x00))
+#define OLIVEDRAB (Color(0x6b, 0x8e, 0x23))
+#define ORANGE (Color(0xff, 0xa5, 0x00))
+#define ORANGERED (Color(0xff, 0x45, 0x00))
+#define ORCHID (Color(0xda, 0x70, 0xd6))
+#define PALEGOLDENROD (Color(0xee, 0xe8, 0xaa))
+#define PALEGREEN (Color(0x98, 0xfb, 0x98))
+#define PALETURQUOISE (Color(0xaf, 0xee, 0xee))
+#define PALEVIOLETRED (Color(0xdb, 0x70, 0x93))
+#define PAPAYAWHIP (Color(0xff, 0xef, 0xd5))
+#define PEACHPUFF (Color(0xff, 0xda, 0xb9))
+#define PERU (Color(0xcd, 0x85, 0x3f))
+#define PINK (Color(0xff, 0xc0, 0xcb))
+#define PLUM (Color(0xdd, 0xa0, 0xdd))
+#define POWDERBLUE (Color(0xb0, 0xe0, 0xe6))
+#define PURPLE (Color(0x80, 0x00, 0x80))
+#define RED (Color(0xff, 0x00, 0x00))
+#define ROSYBROWN (Color(0xbc, 0x8f, 0x8f))
+#define ROYALBLUE (Color(0x41, 0x69, 0xe1))
+#define SADDLEBROWN (Color(0x8b, 0x45, 0x13))
+#define SALMON (Color(0xfa, 0x80, 0x72))
+#define SANDYBROWN (Color(0xf4, 0xa4, 0x60))
+#define SEAGREEN (Color(0x2e, 0x8b, 0x57))
+#define SEASHELL (Color(0xff, 0xf5, 0xee))
+#define SIENNA (Color(0xa0, 0x52, 0x2d))
+#define SILVER (Color(0xc0, 0xc0, 0xc0))
+#define SKYBLUE (Color(0x87, 0xce, 0xeb))
+#define SLATEBLUE (Color(0x6a, 0x5a, 0xcd))
+#define SLATEGRAY (Color(0x70, 0x80, 0x90))
+#define SNOW (Color(0xff, 0xfa, 0xfa))
+#define SPRINGGREEN (Color(0x00, 0xff, 0x7f))
+#define STEELBLUE (Color(0x46, 0x82, 0xb4))
+#define TAN (Color(0xd2, 0xb4, 0x8c))
+#define TEAL (Color(0x00, 0x80, 0x80))
+#define THISTLE (Color(0xd8, 0xbf, 0xd8))
+#define TOMATO (Color(0xff, 0x63, 0x47))
+#define TURQUOISE (Color(0x40, 0xe0, 0xd0))
+#define VIOLET (Color(0xee, 0x82, 0xee))
+#define WHEAT (Color(0xf5, 0xde, 0xb3))
+#define WHITE (Color(0xff, 0xff, 0xff))
+#define WHITESMOKE (Color(0xf5, 0xf5, 0xf5))
+#define YELLOW (Color(0xff, 0xff, 0x00))
+#define YELLOWGREEN (Color(0x9a, 0xcd, 0x32))
+
+#define DOS_BLACK (Color(0x00, 0x00, 0x00)) // Black
+#define DOS_BLUE (Color(0x00, 0x00, 0xaa)) // Blue
+#define DOS_GREEN (Color(0x00, 0xaa, 0x00)) // Green
+#define DOS_CYAN (Color(0x00, 0xaa, 0xaa)) // Cyan
+#define DOS_RED (Color(0xaa, 0x00, 0x00)) // Red
+#define DOS_MAGENTA (Color(0xaa, 0x00, 0xaa)) // Magenta
+#define DOS_BRAWN (Color(0xaa, 0x55, 0x00)) // Brawn
+#define DOS_WHITE (Color(0xaa, 0xaa, 0xaa)) // White
+#define DOS_GRAY (Color(0x55, 0x55, 0x55)) // Gray
+#define DOS_HIGH_BLUE (Color(0x55, 0x55, 0xff)) // High Blue
+#define DOS_HIGH_GREEN (Color(0x55, 0xff, 0x55)) // High Green
+#define DOS_HIGH_CYAN (Color(0x55, 0xff, 0xff)) // High Cyan
+#define DOS_HIGH_RED (Color(0xff, 0x55, 0x55)) // High Red
+#define DOS_HIGH_MAGENTA (Color(0xff, 0x55, 0xff)) // High Magenta
+#define DOS_YELLOW (Color(0xff, 0xff, 0x55)) // Yellow
+#define DOS_HIGH_WHITE (Color(0xff, 0xff, 0xff)) // High White
+
+#endif
diff --git a/include/ConfigFile.h b/include/ConfigFile.h
index 02e9bbe..11434bd 100644
--- a/include/ConfigFile.h
+++ b/include/ConfigFile.h
@@ -1,19 +1,19 @@
-#ifndef __CONFIGFILE_H__
-#define __CONFIGFILE_H__
-
-#include <Exceptions.h>
-#include <Handle.h>
-#include <map>
-
-typedef std::map<String, String> ConfigSectionContents;
-typedef std::map<String, ConfigSectionContents> ConfigSection;
-
-class ConfigFile : public Base {
- public:
- ConfigFile(Handle *) throw (GeneralException);
- ConfigSectionContents & operator[](String);
- private:
- ConfigSection c;
-};
-
-#endif
+#ifndef __CONFIGFILE_H__
+#define __CONFIGFILE_H__
+
+#include <Exceptions.h>
+#include <Handle.h>
+#include <map>
+
+typedef std::map<String, String> ConfigSectionContents;
+typedef std::map<String, ConfigSectionContents> ConfigSection;
+
+class ConfigFile : public Base {
+ public:
+ ConfigFile(Handle *) throw (GeneralException);
+ ConfigSectionContents & operator[](String);
+ private:
+ ConfigSection c;
+};
+
+#endif
diff --git a/include/Confirm.h b/include/Confirm.h
index 0fd9723..ef1dabc 100644
--- a/include/Confirm.h
+++ b/include/Confirm.h
@@ -1,20 +1,20 @@
-#ifndef __CONFIRM_H__
-#define __CONFIRM_H__
-
-#include <Action.h>
-#include <BString.h>
-#include <Exceptions.h>
-
-class Confirm : public Action {
- public:
- Confirm(const String & titre, const String & msg, const String & url, Action * yes, Action * no = 0);
- virtual ~Confirm() { }
- virtual String GetTitle();
- virtual Task * Do(Variables *, Variables *, Handle *);
-
- private:
- String tit, msg;
- Action * NYes, * NNo;
-};
-
-#endif
+#ifndef __CONFIRM_H__
+#define __CONFIRM_H__
+
+#include <Action.h>
+#include <BString.h>
+#include <Exceptions.h>
+
+class Confirm : public Action {
+ public:
+ Confirm(const String & titre, const String & msg, const String & url, Action * yes, Action * no = 0);
+ virtual ~Confirm() { }
+ virtual String GetTitle();
+ virtual Task * Do(Variables *, Variables *, Handle *);
+
+ private:
+ String tit, msg;
+ Action * NYes, * NNo;
+};
+
+#endif
diff --git a/include/CopyJob.h b/include/CopyJob.h
index bcc9afe..7284b24 100644
--- a/include/CopyJob.h
+++ b/include/CopyJob.h
@@ -1,26 +1,26 @@
-#ifndef __COPYJOB_H__
-#define __COPYJOB_H__
-
-#include <sys/time.h>
-#include <Task.h>
-#include <Handle.h>
-
-#define COPY_BUFSIZ 4096
-
-class CopyJob : public Task {
- public:
- CopyJob(Handle *, Handle *, ssize_t = -1, bool = false, bool = false, int = -1);
- virtual ~CopyJob();
- virtual int Do() throw (GeneralException);
- virtual String GetName();
-
- private:
- Handle * s, * d;
- bool ds, dd;
- ssize_t siz, cursiz;
- char buffer[COPY_BUFSIZ + 1];
- int r, w, tw, shape;
- struct timeval start;
-};
-
-#endif
+#ifndef __COPYJOB_H__
+#define __COPYJOB_H__
+
+#include <sys/time.h>
+#include <Task.h>
+#include <Handle.h>
+
+#define COPY_BUFSIZ 4096
+
+class CopyJob : public Task {
+ public:
+ CopyJob(Handle *, Handle *, ssize_t = -1, bool = false, bool = false, int = -1);
+ virtual ~CopyJob();
+ virtual int Do() throw (GeneralException);
+ virtual String GetName();
+
+ private:
+ Handle * s, * d;
+ bool ds, dd;
+ ssize_t siz, cursiz;
+ char buffer[COPY_BUFSIZ + 1];
+ int r, w, tw, shape;
+ struct timeval start;
+};
+
+#endif
diff --git a/include/Exceptions.h b/include/Exceptions.h
index 310dfb1..cf293c8 100644
--- a/include/Exceptions.h
+++ b/include/Exceptions.h
@@ -1,160 +1,160 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: Exceptions.h,v 1.37 2004-11-27 21:43:48 pixel Exp $ */
-
-#ifndef __EXCEPTIONS_H__
-#define __EXCEPTIONS_H__
-
-#include <stdio.h>
-#include <stddef.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <vector>
-#include <generic.h>
-
-#if !defined pid_t && !defined _SYS_TYPES_H
-typedef int pid_t;
-#endif
-
-#ifdef _MSC_VER
-#pragma warning (disable:4290)
-#endif
-
-class String;
-struct ugly_string;
-
-class Base {
- public:
- virtual ~Base() {};
- static char * strdup(const char * s);
- static void * malloc(ssize_t s);
- static void * realloc(void * p, size_t s);
- static void * calloc(size_t n, size_t s);
- void * operator new(size_t s);
- void * operator new(size_t s, void * p);
- void operator delete(void * p);
- template <class T>
- static void free(T *& p) {
- unsigned char * t = (unsigned char *) p;
- xfree(t);
- p = 0;
- }
- static int pipe(int * p, int flag = 0);
- static pid_t fork();
- static void exit(int);
- static void printm(int level, const ugly_string &, ...);
- static void printm(int level, const char *, ...);
- static void exception(const String &);
- static void pushcontext(const String &);
- static void popcontext(void);
- static void flushcontext(void);
- private:
- static std::vector<String> context;
-};
-
-class GeneralException : public Base {
- public:
- GeneralException(String);
- GeneralException(const GeneralException &);
- ~GeneralException();
- const char * GetMsg() const;
-
- protected:
- GeneralException();
- char * msg;
- static char t[BUFSIZ];
-};
-
-char * xstrdup(const char *);
-void * xmalloc(size_t) throw (GeneralException);
-void xfree(unsigned char *&);
-void * xrealloc(void *, size_t);
-int xpipe(int *, int = 0) throw (GeneralException);
-pid_t xfork() throw (GeneralException);
-void xexit(int) throw (GeneralException);
-void xexception(const String &) throw (GeneralException);
-
-class MemoryException : public GeneralException {
- public:
- MemoryException(ssize_t);
-};
-
-class TaskNotFound : public GeneralException {
- public:
- TaskNotFound();
-};
-
-enum op_t {
- IO_WRITE = 1,
- IO_READ
-};
-
-class IOGeneral : public GeneralException {
- public:
- IOGeneral(String);
- protected:
- IOGeneral();
-};
-
-class IOException : public IOGeneral {
- public:
- IOException(String, op_t, ssize_t);
-};
-
-class IOAgain : public IOGeneral {
- public:
- IOAgain();
-};
-
-class TaskSwitch : public GeneralException {
- public:
- TaskSwitch();
-};
-
-class Exit : public GeneralException {
- public:
- Exit(int);
- int GetCode();
- private:
- int code;
-};
-
-class printer_t : public Base {
- public:
- virtual bool printm(int, const char *, va_list) = 0;
-};
-
-extern printer_t * printer;
-
-class locker_t : public Base {
- public:
- virtual void lock() = 0;
- virtual void unlock() = 0;
-};
-
-extern locker_t * locker;
-
-#define LOCK if (locker) locker->lock()
-#define UNLOCK if (locker) locker->unlock();
-
-#include <BString.h>
-
-#endif
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: Exceptions.h,v 1.38 2004-11-27 21:46:02 pixel Exp $ */
+
+#ifndef __EXCEPTIONS_H__
+#define __EXCEPTIONS_H__
+
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <vector>
+#include <generic.h>
+
+#if !defined pid_t && !defined _SYS_TYPES_H
+typedef int pid_t;
+#endif
+
+#ifdef _MSC_VER
+#pragma warning (disable:4290)
+#endif
+
+class String;
+struct ugly_string;
+
+class Base {
+ public:
+ virtual ~Base() {};
+ static char * strdup(const char * s);
+ static void * malloc(ssize_t s);
+ static void * realloc(void * p, size_t s);
+ static void * calloc(size_t n, size_t s);
+ void * operator new(size_t s);
+ void * operator new(size_t s, void * p);
+ void operator delete(void * p);
+ template <class T>
+ static void free(T *& p) {
+ unsigned char * t = (unsigned char *) p;
+ xfree(t);
+ p = 0;
+ }
+ static int pipe(int * p, int flag = 0);
+ static pid_t fork();
+ static void exit(int);
+ static void printm(int level, const ugly_string &, ...);
+ static void printm(int level, const char *, ...);
+ static void exception(const String &);
+ static void pushcontext(const String &);
+ static void popcontext(void);
+ static void flushcontext(void);
+ private:
+ static std::vector<String> context;
+};
+
+class GeneralException : public Base {
+ public:
+ GeneralException(String);
+ GeneralException(const GeneralException &);
+ ~GeneralException();
+ const char * GetMsg() const;
+
+ protected:
+ GeneralException();
+ char * msg;
+ static char t[BUFSIZ];
+};
+
+char * xstrdup(const char *);
+void * xmalloc(size_t) throw (GeneralException);
+void xfree(unsigned char *&);
+void * xrealloc(void *, size_t);
+int xpipe(int *, int = 0) throw (GeneralException);
+pid_t xfork() throw (GeneralException);
+void xexit(int) throw (GeneralException);
+void xexception(const String &) throw (GeneralException);
+
+class MemoryException : public GeneralException {
+ public:
+ MemoryException(ssize_t);
+};
+
+class TaskNotFound : public GeneralException {
+ public:
+ TaskNotFound();
+};
+
+enum op_t {
+ IO_WRITE = 1,
+ IO_READ
+};
+
+class IOGeneral : public GeneralException {
+ public:
+ IOGeneral(String);
+ protected:
+ IOGeneral();
+};
+
+class IOException : public IOGeneral {
+ public:
+ IOException(String, op_t, ssize_t);
+};
+
+class IOAgain : public IOGeneral {
+ public:
+ IOAgain();
+};
+
+class TaskSwitch : public GeneralException {
+ public:
+ TaskSwitch();
+};
+
+class Exit : public GeneralException {
+ public:
+ Exit(int);
+ int GetCode();
+ private:
+ int code;
+};
+
+class printer_t : public Base {
+ public:
+ virtual bool printm(int, const char *, va_list) = 0;
+};
+
+extern printer_t * printer;
+
+class locker_t : public Base {
+ public:
+ virtual void lock() = 0;
+ virtual void unlock() = 0;
+};
+
+extern locker_t * locker;
+
+#define LOCK if (locker) locker->lock()
+#define UNLOCK if (locker) locker->unlock();
+
+#include <BString.h>
+
+#endif
diff --git a/include/Form.h b/include/Form.h
index 5dccb35..f0fa93f 100644
--- a/include/Form.h
+++ b/include/Form.h
@@ -1,23 +1,23 @@
-#ifndef __FORM_H__
-#define __FORM_H__
-
-#include <Action.h>
-#include <BString.h>
-#include <Exceptions.h>
-
-class Form : public Action {
- public:
- Form(const String & titre, const String & url, const String & inv,
- String * names, String * invs, String * defaults, String ** lists, String ** descs,
- int nb, Action * ok = 0);
- virtual ~Form() { }
- virtual String GetTitle();
- virtual Task * Do(Variables *, Variables *, Handle *);
-
- private:
- String tit, iv, * nms, * ivs, * defs, ** lsts, ** dscs;
- int n;
- Action * Next;
-};
-
-#endif
+#ifndef __FORM_H__
+#define __FORM_H__
+
+#include <Action.h>
+#include <BString.h>
+#include <Exceptions.h>
+
+class Form : public Action {
+ public:
+ Form(const String & titre, const String & url, const String & inv,
+ String * names, String * invs, String * defaults, String ** lists, String ** descs,
+ int nb, Action * ok = 0);
+ virtual ~Form() { }
+ virtual String GetTitle();
+ virtual Task * Do(Variables *, Variables *, Handle *);
+
+ private:
+ String tit, iv, * nms, * ivs, * defs, ** lsts, ** dscs;
+ int n;
+ Action * Next;
+};
+
+#endif
diff --git a/include/GMPString.h b/include/GMPString.h
index d1c7424..77364bf 100644
--- a/include/GMPString.h
+++ b/include/GMPString.h
@@ -1,18 +1,18 @@
-#ifndef __GMPSTRING_H__
-#define __GMPSTRING_H__
-#include <gmpxx.h>
-#include "BString.h"
-
-class GMPString : public Base {
- public:
- GMPString(const GMPString &);
- GMPString(const mpz_class &);
- GMPString(const mpq_class &);
- GMPString(const mpf_class &);
- ~GMPString();
- operator String() const;
- private:
- char * str;
-};
-
-#endif
+#ifndef __GMPSTRING_H__
+#define __GMPSTRING_H__
+#include <gmpxx.h>
+#include "BString.h"
+
+class GMPString : public Base {
+ public:
+ GMPString(const GMPString &);
+ GMPString(const mpz_class &);
+ GMPString(const mpq_class &);
+ GMPString(const mpf_class &);
+ ~GMPString();
+ operator String() const;
+ private:
+ char * str;
+};
+
+#endif
diff --git a/include/Handle.h b/include/Handle.h
index ee0f3f7..9b6f88d 100644
--- a/include/Handle.h
+++ b/include/Handle.h
@@ -1,92 +1,92 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: Handle.h,v 1.33 2004-11-27 21:43:48 pixel Exp $ */
-
-#ifndef __HANDLE_H__
-#define __HANDLE_H__
-
-#include <sys/types.h>
-#include <time.h>
-
-#include <zlib.h>
-#include <iostream>
-#include <BString.h>
-#include <Exceptions.h>
-
-class Handle : public Base {
- public:
- Handle(const Handle &);
- virtual ~Handle();
- virtual ssize_t read(void * buf, size_t count) throw (GeneralException);
- virtual ssize_t write(const void * buf, size_t count) throw (GeneralException);
- Uint8 readU8();
- Uint16 readU16();
- Uint32 readU32();
- void writeU8(Uint8);
- void writeU16(Uint16);
- void writeU32(Uint32);
- void copyto(Handle *, ssize_t = -1);
- void copyfrom(Handle *, ssize_t = -1);
- bool IsClosed(void) const;
- bool IsNonBlock(void) const;
- void SetNonBlock(void);
- virtual bool CanRead() const;
- virtual bool CanWrite() const;
- virtual bool CanSeek() const;
- virtual off_t seek(off_t, int = SEEK_SET) throw (GeneralException);
- virtual off_t tell() const;
- virtual String GetName() const;
- virtual ssize_t GetSize() const;
- virtual time_t GetModif() const;
- void close() throw (GeneralException);
- int GetHandle();
- void * GetHFile();
- virtual bool CanWatch() const;
- virtual int Dup() const throw (GeneralException);
- virtual void SetZ(int = 9) throw (GeneralException);
- virtual void Flush();
-
- void * mmap(off_t = 0, size_t = -1) throw (GeneralException);
- void munmap() throw (GeneralException);
- protected:
- Handle(int h);
- int GetHandle() const;
- off_t itell;
- void * hFile;
- private:
- ssize_t uwrite(const void *, size_t) throw (GeneralException);
- ssize_t uread(void *, size_t);
- int h;
- bool closed, nonblock;
- gzFile zfile;
- z_stream zstrm;
- int z, c;
- void * hMapObject;
- bool mapped;
- size_t maplength;
- void * mappedarea;
-};
-
-Handle & operator<<(Handle &, const String &);
-Handle & operator>>(Handle &, String &);
-
-void copy(Handle *, Handle *, ssize_t = -1);
-
-#endif
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: Handle.h,v 1.34 2004-11-27 21:46:02 pixel Exp $ */
+
+#ifndef __HANDLE_H__
+#define __HANDLE_H__
+
+#include <sys/types.h>
+#include <time.h>
+
+#include <zlib.h>
+#include <iostream>
+#include <BString.h>
+#include <Exceptions.h>
+
+class Handle : public Base {
+ public:
+ Handle(const Handle &);
+ virtual ~Handle();
+ virtual ssize_t read(void * buf, size_t count) throw (GeneralException);
+ virtual ssize_t write(const void * buf, size_t count) throw (GeneralException);
+ Uint8 readU8();
+ Uint16 readU16();
+ Uint32 readU32();
+ void writeU8(Uint8);
+ void writeU16(Uint16);
+ void writeU32(Uint32);
+ void copyto(Handle *, ssize_t = -1);
+ void copyfrom(Handle *, ssize_t = -1);
+ bool IsClosed(void) const;
+ bool IsNonBlock(void) const;
+ void SetNonBlock(void);
+ virtual bool CanRead() const;
+ virtual bool CanWrite() const;
+ virtual bool CanSeek() const;
+ virtual off_t seek(off_t, int = SEEK_SET) throw (GeneralException);
+ virtual off_t tell() const;
+ virtual String GetName() const;
+ virtual ssize_t GetSize() const;
+ virtual time_t GetModif() const;
+ void close() throw (GeneralException);
+ int GetHandle();
+ void * GetHFile();
+ virtual bool CanWatch() const;
+ virtual int Dup() const throw (GeneralException);
+ virtual void SetZ(int = 9) throw (GeneralException);
+ virtual void Flush();
+
+ void * mmap(off_t = 0, size_t = -1) throw (GeneralException);
+ void munmap() throw (GeneralException);
+ protected:
+ Handle(int h);
+ int GetHandle() const;
+ off_t itell;
+ void * hFile;
+ private:
+ ssize_t uwrite(const void *, size_t) throw (GeneralException);
+ ssize_t uread(void *, size_t);
+ int h;
+ bool closed, nonblock;
+ gzFile zfile;
+ z_stream zstrm;
+ int z, c;
+ void * hMapObject;
+ bool mapped;
+ size_t maplength;
+ void * mappedarea;
+};
+
+Handle & operator<<(Handle &, const String &);
+Handle & operator>>(Handle &, String &);
+
+void copy(Handle *, Handle *, ssize_t = -1);
+
+#endif
diff --git a/include/HttpServ.h b/include/HttpServ.h
index e704814..fc58246 100644
--- a/include/HttpServ.h
+++ b/include/HttpServ.h
@@ -1,30 +1,30 @@
-#ifndef __HTTPSERV_H__
-#define __HTTPSERV_H__
-
-#include <Socket.h>
-#include <BString.h>
-#include <Variables.h>
-#include <Action.h>
-#include <Task.h>
-#include <Exceptions.h>
-
-class HttpServ : public Task {
- public:
- HttpServ(Action *, int = 1500, const String & = String("GruiK Server v0.1")) throw (GeneralException);
- virtual ~HttpServ();
- void SetMenu(Action *);
- virtual String GetName();
-
- protected:
- virtual int Do() throw (GeneralException);
-
- private:
- Socket Listener;
- Action * p;
- String name;
- int localport;
-};
-
-extern String endhl, endnl;
-
-#endif
+#ifndef __HTTPSERV_H__
+#define __HTTPSERV_H__
+
+#include <Socket.h>
+#include <BString.h>
+#include <Variables.h>
+#include <Action.h>
+#include <Task.h>
+#include <Exceptions.h>
+
+class HttpServ : public Task {
+ public:
+ HttpServ(Action *, int = 1500, const String & = String("GruiK Server v0.1")) throw (GeneralException);
+ virtual ~HttpServ();
+ void SetMenu(Action *);
+ virtual String GetName();
+
+ protected:
+ virtual int Do() throw (GeneralException);
+
+ private:
+ Socket Listener;
+ Action * p;
+ String name;
+ int localport;
+};
+
+extern String endhl, endnl;
+
+#endif
diff --git a/include/IRC.h b/include/IRC.h
index 65a827c..6823b21 100644
--- a/include/IRC.h
+++ b/include/IRC.h
@@ -1,201 +1,201 @@
-#ifndef __IRC_H__
-#define __IRC_H__
-
-#include <Socket.h>
-#include <Exceptions.h>
-#include <BString.h>
-
-#define RPL_WELCOME 1
-#define RPL_YOURHOST 2
-#define RPL_CREATED 3
-#define RPL_MYINFO 4
-#define RPL_BOUNCE 5
-#define RPL_TRACELINK 200
-#define RPL_TRACECONNECTING 201
-#define RPL_TRACEHANDSHAKE 202
-#define RPL_TRACEUNKNOWN 203
-#define RPL_TRACEOPERATOR 204
-#define RPL_TRACEUSER 205
-#define RPL_TRACESERVER 206
-#define RPL_TRACESERVICE 207
-#define RPL_TRACENEWTYPE 208
-#define RPL_TRACECLASS 209
-#define RPL_TRACERECONNECT 210
-#define RPL_STATSLINKINFO 211
-#define RPL_STATSCOMMANDS 212
-#define RPL_STATSCLINE 213
-#define RPL_STATSILINE 215
-#define RPL_STATSQLINE 217
-#define RPL_ENDOFSTATS 219
-#define RPL_UMODEIS 221
-#define RPL_SERVICEINFO 231
-#define RPL_SERVICE 233
-#define RPL_SERVLIST 234
-#define RPL_SERVLISTEND 235
-#define RPL_STATSVLINE 240
-#define RPL_STATSUPTIME 242
-#define RPL_STATSOLINE 243
-#define RPL_STATSHLINE 244
-#define RPL_STATSPING 246
-#define RPL_STATSDLINE 250
-#define RPL_LUSERCLIENT 251
-#define RPL_LUSEROP 252
-#define RPL_LUSERUNKNOWN 253
-#define RPL_LUSERCHANNELS 254
-#define RPL_LUSERME 255
-#define RPL_ADMINME 256
-#define RPL_ADMINLOC1 257
-#define RPL_ADMINLOC2 258
-#define RPL_ADMINEMAIL 259
-#define RPL_TRACELOG 261
-#define RPL_TRACEEND 262
-#define RPL_TRYAGAIN 263
-#define RPL_NONE 300
-#define RPL_AWAY 301
-#define RPL_USERHOST 302
-#define RPL_ISON 303
-#define RPL_UNAWAY 305
-#define RPL_NOWAWAY 306
-#define RPL_WHOISUSER 311
-#define RPL_WHOISSERVER 312
-#define RPL_WHOISOPERATOR 313
-#define RPL_WHOWASUSER 314
-#define RPL_ENDOFWHO 315
-#define RPL_WHOISIDLE 317
-#define RPL_ENDOFWHOIS 318
-#define RPL_WHOISCHANNELS 319
-#define RPL_LISTSTART 321
-#define RPL_LIST 322
-#define RPL_LISTEND 323
-#define RPL_CHANNELMODEIS 324
-#define RPL_UNIQOPIS 325
-#define RPL_NOTOPIC 331
-#define RPL_TOPIC 332
-#define RPL_INVITING 341
-#define RPL_SUMMONING 342
-#define RPL_INVITELIST 346
-#define RPL_ENDOFINVITELIST 347
-#define RPL_EXCEPTLIST 348
-#define RPL_ENDOFEXCEPTLIST 349
-#define RPL_VERSION 351
-#define RPL_WHOREPLY 352
-#define RPL_NAMREPLY 353
-#define RPL_KILLDONE 361
-#define RPL_CLOSEEND 363
-#define RPL_LINKS 364
-#define RPL_ENDOFLINKS 365
-#define RPL_ENDOFNAMES 366
-#define RPL_BANLIST 367
-#define RPL_ENDOFBANLIST 368
-#define RPL_ENDOFWHOWAS 369
-#define RPL_INFO 371
-#define RPL_MOTD 372
-#define RPL_ENDOFINFO 374
-#define RPL_MOTDSTART 375
-#define RPL_ENDOFMOTD 376
-#define RPL_YOUREOPER 381
-#define RPL_REHASHING 382
-#define RPL_YOURESERVICE 383
-#define RPL_MYPORTIS 384
-#define RPL_TIME 391
-#define RPL_USERSSTART 392
-#define RPL_USERS 393
-#define RPL_ENDOFUSERS 394
-#define RPL_NOUSERS 395
-#define ERR_NOSUCHNICK 401
-#define ERR_NOSUCHSERVER 402
-#define ERR_NOSUCHCHANNEL 403
-#define ERR_CANNOTSENDTOCHAN 404
-#define ERR_TOOMANYCHANNELS 405
-#define ERR_WASNOSUCHNICK 406
-#define ERR_TOOMANYTARGETS 407
-#define ERR_NOSUCHSERVICE 408
-#define ERR_NOORIGIN 409
-#define ERR_NORECIPIENT 411
-#define ERR_NOTEXTTOSEND 412
-#define ERR_NOTOPLEVEL 413
-#define ERR_WILDTOPLEVEL 414
-#define ERR_BADMASK 415
-#define ERR_UNKNOWNCOMMAND 421
-#define ERR_NOMOTD 422
-#define ERR_NOADMININFO 423
-#define ERR_FILEERROR 424
-#define ERR_NONICKNAMEGIVEN 431
-#define ERR_ERRONEUSNICKNAME 432
-#define ERR_NICKNAMEINUSE 433
-#define ERR_NICKCOLLISION 436
-#define ERR_UNAVAILRESOURCE 437
-#define ERR_USERNOTINCHANNEL 441
-#define ERR_NOTONCHANNEL 442
-#define ERR_USERONCHANNEL 443
-#define ERR_NOLOGIN 444
-#define ERR_SUMMONDISABLED 445
-#define ERR_USERSDISABLED 446
-#define ERR_NOTREGISTERED 451
-#define ERR_NEEDMOREPARAMS 461
-#define ERR_ALREADYREGISTRED 462
-#define ERR_NOPERMFORHOST 463
-#define ERR_PASSWDMISMATCH 464
-#define ERR_YOUREBANNEDCREEP 465
-#define ERR_YOUWILLBEBANNED 466
-#define ERR_KEYSET 467
-#define ERR_CHANNELISFULL 471
-#define ERR_UNKNOWNMODE 472
-#define ERR_INVITEONLYCHAN 473
-#define ERR_BANNEDFROMCHAN 474
-#define ERR_BADCHANNELKEY 475
-#define ERR_BADCHANMASK 476
-#define ERR_NOCHANMODES 477
-#define ERR_BANLISTFULL 478
-#define ERR_NOPRIVILEGES 481
-#define ERR_CHANOPRIVSNEEDED 482
-#define ERR_CANTKILLSERVER 483
-#define ERR_RESTRICTED 484
-#define ERR_UNIQOPPRIVSNEEDED 485
-#define ERR_NOOPERHOST 491
-#define ERR_NOSERVICEHOST 492
-#define ERR_UMODEUNKNOWNFLAG 501
-#define ERR_USERSDONTMATCH 502
-
-typedef struct {
- char * msg;
- int code;
-} ircmsg_t;
-
-#define MSG_COUNT 151
-
-extern ircmsg_t ircmsgs[];
-
-class Channel : public Base {
- public:
- Channel(const String &, const String & = "");
- ~Channel();
-
- protected:
- Channel * GetNext();
- Channel * GetPrev();
- String GetName();
- String GetKey();
-
- private:
- String Name, Key;
- static Channel * start;
- Channel * next, * prev;
-};
-
-class IRC : public Base {
- public:
- IRC(const String & = "Nick", const String & = "irc.openprojects.net", const String & = "guest_user", const String & = "Irc Name", int Port = 6667);
- virtual ~IRC();
- bool Connect();
- void MainLoop();
-
- private:
- int Parse(const String &);
- String nick, server, user, name;
- int port;
- Socket sock;
- int loginsequence;
-};
-
-#endif
+#ifndef __IRC_H__
+#define __IRC_H__
+
+#include <Socket.h>
+#include <Exceptions.h>
+#include <BString.h>
+
+#define RPL_WELCOME 1
+#define RPL_YOURHOST 2
+#define RPL_CREATED 3
+#define RPL_MYINFO 4
+#define RPL_BOUNCE 5
+#define RPL_TRACELINK 200
+#define RPL_TRACECONNECTING 201
+#define RPL_TRACEHANDSHAKE 202
+#define RPL_TRACEUNKNOWN 203
+#define RPL_TRACEOPERATOR 204
+#define RPL_TRACEUSER 205
+#define RPL_TRACESERVER 206
+#define RPL_TRACESERVICE 207
+#define RPL_TRACENEWTYPE 208
+#define RPL_TRACECLASS 209
+#define RPL_TRACERECONNECT 210
+#define RPL_STATSLINKINFO 211
+#define RPL_STATSCOMMANDS 212
+#define RPL_STATSCLINE 213
+#define RPL_STATSILINE 215
+#define RPL_STATSQLINE 217
+#define RPL_ENDOFSTATS 219
+#define RPL_UMODEIS 221
+#define RPL_SERVICEINFO 231
+#define RPL_SERVICE 233
+#define RPL_SERVLIST 234
+#define RPL_SERVLISTEND 235
+#define RPL_STATSVLINE 240
+#define RPL_STATSUPTIME 242
+#define RPL_STATSOLINE 243
+#define RPL_STATSHLINE 244
+#define RPL_STATSPING 246
+#define RPL_STATSDLINE 250
+#define RPL_LUSERCLIENT 251
+#define RPL_LUSEROP 252
+#define RPL_LUSERUNKNOWN 253
+#define RPL_LUSERCHANNELS 254
+#define RPL_LUSERME 255
+#define RPL_ADMINME 256
+#define RPL_ADMINLOC1 257
+#define RPL_ADMINLOC2 258
+#define RPL_ADMINEMAIL 259
+#define RPL_TRACELOG 261
+#define RPL_TRACEEND 262
+#define RPL_TRYAGAIN 263
+#define RPL_NONE 300
+#define RPL_AWAY 301
+#define RPL_USERHOST 302
+#define RPL_ISON 303
+#define RPL_UNAWAY 305
+#define RPL_NOWAWAY 306
+#define RPL_WHOISUSER 311
+#define RPL_WHOISSERVER 312
+#define RPL_WHOISOPERATOR 313
+#define RPL_WHOWASUSER 314
+#define RPL_ENDOFWHO 315
+#define RPL_WHOISIDLE 317
+#define RPL_ENDOFWHOIS 318
+#define RPL_WHOISCHANNELS 319
+#define RPL_LISTSTART 321
+#define RPL_LIST 322
+#define RPL_LISTEND 323
+#define RPL_CHANNELMODEIS 324
+#define RPL_UNIQOPIS 325
+#define RPL_NOTOPIC 331
+#define RPL_TOPIC 332
+#define RPL_INVITING 341
+#define RPL_SUMMONING 342
+#define RPL_INVITELIST 346
+#define RPL_ENDOFINVITELIST 347
+#define RPL_EXCEPTLIST 348
+#define RPL_ENDOFEXCEPTLIST 349
+#define RPL_VERSION 351
+#define RPL_WHOREPLY 352
+#define RPL_NAMREPLY 353
+#define RPL_KILLDONE 361
+#define RPL_CLOSEEND 363
+#define RPL_LINKS 364
+#define RPL_ENDOFLINKS 365
+#define RPL_ENDOFNAMES 366
+#define RPL_BANLIST 367
+#define RPL_ENDOFBANLIST 368
+#define RPL_ENDOFWHOWAS 369
+#define RPL_INFO 371
+#define RPL_MOTD 372
+#define RPL_ENDOFINFO 374
+#define RPL_MOTDSTART 375
+#define RPL_ENDOFMOTD 376
+#define RPL_YOUREOPER 381
+#define RPL_REHASHING 382
+#define RPL_YOURESERVICE 383
+#define RPL_MYPORTIS 384
+#define RPL_TIME 391
+#define RPL_USERSSTART 392
+#define RPL_USERS 393
+#define RPL_ENDOFUSERS 394
+#define RPL_NOUSERS 395
+#define ERR_NOSUCHNICK 401
+#define ERR_NOSUCHSERVER 402
+#define ERR_NOSUCHCHANNEL 403
+#define ERR_CANNOTSENDTOCHAN 404
+#define ERR_TOOMANYCHANNELS 405
+#define ERR_WASNOSUCHNICK 406
+#define ERR_TOOMANYTARGETS 407
+#define ERR_NOSUCHSERVICE 408
+#define ERR_NOORIGIN 409
+#define ERR_NORECIPIENT 411
+#define ERR_NOTEXTTOSEND 412
+#define ERR_NOTOPLEVEL 413
+#define ERR_WILDTOPLEVEL 414
+#define ERR_BADMASK 415
+#define ERR_UNKNOWNCOMMAND 421
+#define ERR_NOMOTD 422
+#define ERR_NOADMININFO 423
+#define ERR_FILEERROR 424
+#define ERR_NONICKNAMEGIVEN 431
+#define ERR_ERRONEUSNICKNAME 432
+#define ERR_NICKNAMEINUSE 433
+#define ERR_NICKCOLLISION 436
+#define ERR_UNAVAILRESOURCE 437
+#define ERR_USERNOTINCHANNEL 441
+#define ERR_NOTONCHANNEL 442
+#define ERR_USERONCHANNEL 443
+#define ERR_NOLOGIN 444
+#define ERR_SUMMONDISABLED 445
+#define ERR_USERSDISABLED 446
+#define ERR_NOTREGISTERED 451
+#define ERR_NEEDMOREPARAMS 461
+#define ERR_ALREADYREGISTRED 462
+#define ERR_NOPERMFORHOST 463
+#define ERR_PASSWDMISMATCH 464
+#define ERR_YOUREBANNEDCREEP 465
+#define ERR_YOUWILLBEBANNED 466
+#define ERR_KEYSET 467
+#define ERR_CHANNELISFULL 471
+#define ERR_UNKNOWNMODE 472
+#define ERR_INVITEONLYCHAN 473
+#define ERR_BANNEDFROMCHAN 474
+#define ERR_BADCHANNELKEY 475
+#define ERR_BADCHANMASK 476
+#define ERR_NOCHANMODES 477
+#define ERR_BANLISTFULL 478
+#define ERR_NOPRIVILEGES 481
+#define ERR_CHANOPRIVSNEEDED 482
+#define ERR_CANTKILLSERVER 483
+#define ERR_RESTRICTED 484
+#define ERR_UNIQOPPRIVSNEEDED 485
+#define ERR_NOOPERHOST 491
+#define ERR_NOSERVICEHOST 492
+#define ERR_UMODEUNKNOWNFLAG 501
+#define ERR_USERSDONTMATCH 502
+
+typedef struct {
+ char * msg;
+ int code;
+} ircmsg_t;
+
+#define MSG_COUNT 151
+
+extern ircmsg_t ircmsgs[];
+
+class Channel : public Base {
+ public:
+ Channel(const String &, const String & = "");
+ ~Channel();
+
+ protected:
+ Channel * GetNext();
+ Channel * GetPrev();
+ String GetName();
+ String GetKey();
+
+ private:
+ String Name, Key;
+ static Channel * start;
+ Channel * next, * prev;
+};
+
+class IRC : public Base {
+ public:
+ IRC(const String & = "Nick", const String & = "irc.openprojects.net", const String & = "guest_user", const String & = "Irc Name", int Port = 6667);
+ virtual ~IRC();
+ bool Connect();
+ void MainLoop();
+
+ private:
+ int Parse(const String &);
+ String nick, server, user, name;
+ int port;
+ Socket sock;
+ int loginsequence;
+};
+
+#endif
diff --git a/include/Image.h b/include/Image.h
index 4a7d0ef..633ab55 100644
--- a/include/Image.h
+++ b/include/Image.h
@@ -1,53 +1,53 @@
-#ifndef __IMAGE_H__
-#define __IMAGE_H__
-
-#include <Buffer.h>
-#include <generic.h>
-#include <Color.h>
-
-enum {
- FORMAT_TGA_BASIC
-};
-
-class Image : public Buffer {
- public:
- Image(unsigned int, unsigned int);
- virtual ~Image();
- Color GetPixel(unsigned int, unsigned int) const;
- void SetPixel(unsigned int, unsigned int, Color);
- bool Prepare(unsigned int = FORMAT_TGA_BASIC);
- void Fill(Color = Color(0, 0, 0));
- virtual String GetName() const;
- virtual bool CanWrite() const;
-
- private:
- typedef unsigned char Byte;
- typedef unsigned short int Word;
- typedef unsigned long int DWord;
- struct TGAHeader {
- Byte IDLength;
- Byte ColorMapType;
- Byte ImageType;
- Word CM_FirstEntry;
- Word CM_Length;
- Byte CM_EntrySize;
- Word IS_XOrigin;
- Word IS_YOrigin;
- Word IS_Width;
- Word IS_Height;
- Byte IS_Depth;
- Byte IS_Descriptor;
- } PACKED;
-
- struct TGAFooter {
- DWord ExtOffset;
- DWord DevOffset;
- char Sig[18];
- } PACKED;
-
- unsigned int x, y;
- bool r;
- Color * img;
-};
-
-#endif
+#ifndef __IMAGE_H__
+#define __IMAGE_H__
+
+#include <Buffer.h>
+#include <generic.h>
+#include <Color.h>
+
+enum {
+ FORMAT_TGA_BASIC
+};
+
+class Image : public Buffer {
+ public:
+ Image(unsigned int, unsigned int);
+ virtual ~Image();
+ Color GetPixel(unsigned int, unsigned int) const;
+ void SetPixel(unsigned int, unsigned int, Color);
+ bool Prepare(unsigned int = FORMAT_TGA_BASIC);
+ void Fill(Color = Color(0, 0, 0));
+ virtual String GetName() const;
+ virtual bool CanWrite() const;
+
+ private:
+ typedef unsigned char Byte;
+ typedef unsigned short int Word;
+ typedef unsigned long int DWord;
+ struct TGAHeader {
+ Byte IDLength;
+ Byte ColorMapType;
+ Byte ImageType;
+ Word CM_FirstEntry;
+ Word CM_Length;
+ Byte CM_EntrySize;
+ Word IS_XOrigin;
+ Word IS_YOrigin;
+ Word IS_Width;
+ Word IS_Height;
+ Byte IS_Depth;
+ Byte IS_Descriptor;
+ } PACKED;
+
+ struct TGAFooter {
+ DWord ExtOffset;
+ DWord DevOffset;
+ char Sig[18];
+ } PACKED;
+
+ unsigned int x, y;
+ bool r;
+ Color * img;
+};
+
+#endif
diff --git a/include/InPipe.h b/include/InPipe.h
index b08b35c..2828da3 100644
--- a/include/InPipe.h
+++ b/include/InPipe.h
@@ -1,19 +1,19 @@
-#ifndef __INPIPE_H__
-#define __INPIPE_H__
-
-#include <Handle.h>
-
-class InPipe : public Handle {
- public:
- InPipe();
- InPipe(const InPipe &);
- virtual ~InPipe();
- void Hook();
- virtual bool CanWrite();
- virtual bool CanRead();
- virtual String GetName();
- private:
- int p[2], hooked;
-};
-
-#endif
+#ifndef __INPIPE_H__
+#define __INPIPE_H__
+
+#include <Handle.h>
+
+class InPipe : public Handle {
+ public:
+ InPipe();
+ InPipe(const InPipe &);
+ virtual ~InPipe();
+ void Hook();
+ virtual bool CanWrite();
+ virtual bool CanRead();
+ virtual String GetName();
+ private:
+ int p[2], hooked;
+};
+
+#endif
diff --git a/include/Input.h b/include/Input.h
index 20eaf4c..5a76e71 100644
--- a/include/Input.h
+++ b/include/Input.h
@@ -1,116 +1,116 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: Input.h,v 1.20 2004-11-27 21:43:48 pixel Exp $ */
-
-#ifndef __INPUT_H__
-#define __INPUT_H__
-
-#include <sys/types.h>
-#include <time.h>
-#include <BString.h>
-#include <Handle.h>
-
-enum ArchiveType {
- ARCHIVE_BUILTIN = 0,
- ARCHIVE_EXECUTABLE
-};
-
-class Input : public Handle {
- public:
- Input(const String & = "") throw (GeneralException);
- Input(const Input &);
- virtual ~Input() {}
- virtual bool CanWrite() const;
- virtual bool CanRead() const;
- virtual bool CanSeek() const;
- virtual off_t seek(off_t, int = SEEK_SET) throw (GeneralException);
- virtual String GetName() const;
- virtual ssize_t GetSize() const;
- virtual time_t GetModif() const;
- virtual void SetZ(int = 9) throw (GeneralException);
-
- struct openresults_t {
- String name;
- int type;
- size_t size;
- size_t ptr;
- };
-
- protected:
- String n;
- off_t size;
- time_t date_modif;
- openresults_t results;
- bool fromarchive;
-
- private:
- int wrapopen(const String &, openresults_t *);
-};
-
-class Stdin_t : public Input {
- public:
- Stdin_t();
- virtual ~Stdin_t() {}
- virtual bool CanSeek() const;
- virtual String GetName() const;
-};
-
-extern Stdin_t Stdin;
-
-class Archive : public Base {
- public:
- Archive(const String &, int = ARCHIVE_BUILTIN);
- Archive(Handle *, int = ARCHIVE_BUILTIN);
- virtual ~Archive();
- protected:
- static Archive * inarchive(const String &);
- Handle * GetHandle();
- int open(const String &, Input::openresults_t *);
- private:
- void create() throw (GeneralException);
- bool inarchivein(const String &);
- int openin(const String &, Input::openresults_t *) throw (GeneralException);
- class FileTree : public Base {
- public:
- FileTree(const String & = "", size_t = 0, int = 0, FileTree * = 0);
- virtual ~FileTree();
- int compute_ptrs(size_t = 0);
- FileTree * Father();
- FileTree * Child();
- FileTree * Next();
- FileTree * Prev();
- String name;
- int type;
- size_t size;
- size_t ptr;
- private:
- void touched();
- FileTree * next, * prev, * father, * child;
- } filetree;
- String name;
- Handle * archive;
- int type;
- Archive * next, * prev;
- static Archive * header;
-
- friend class Input;
-};
-
-#endif
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: Input.h,v 1.21 2004-11-27 21:46:02 pixel Exp $ */
+
+#ifndef __INPUT_H__
+#define __INPUT_H__
+
+#include <sys/types.h>
+#include <time.h>
+#include <BString.h>
+#include <Handle.h>
+
+enum ArchiveType {
+ ARCHIVE_BUILTIN = 0,
+ ARCHIVE_EXECUTABLE
+};
+
+class Input : public Handle {
+ public:
+ Input(const String & = "") throw (GeneralException);
+ Input(const Input &);
+ virtual ~Input() {}
+ virtual bool CanWrite() const;
+ virtual bool CanRead() const;
+ virtual bool CanSeek() const;
+ virtual off_t seek(off_t, int = SEEK_SET) throw (GeneralException);
+ virtual String GetName() const;
+ virtual ssize_t GetSize() const;
+ virtual time_t GetModif() const;
+ virtual void SetZ(int = 9) throw (GeneralException);
+
+ struct openresults_t {
+ String name;
+ int type;
+ size_t size;
+ size_t ptr;
+ };
+
+ protected:
+ String n;
+ off_t size;
+ time_t date_modif;
+ openresults_t results;
+ bool fromarchive;
+
+ private:
+ int wrapopen(const String &, openresults_t *);
+};
+
+class Stdin_t : public Input {
+ public:
+ Stdin_t();
+ virtual ~Stdin_t() {}
+ virtual bool CanSeek() const;
+ virtual String GetName() const;
+};
+
+extern Stdin_t Stdin;
+
+class Archive : public Base {
+ public:
+ Archive(const String &, int = ARCHIVE_BUILTIN);
+ Archive(Handle *, int = ARCHIVE_BUILTIN);
+ virtual ~Archive();
+ protected:
+ static Archive * inarchive(const String &);
+ Handle * GetHandle();
+ int open(const String &, Input::openresults_t *);
+ private:
+ void create() throw (GeneralException);
+ bool inarchivein(const String &);
+ int openin(const String &, Input::openresults_t *) throw (GeneralException);
+ class FileTree : public Base {
+ public:
+ FileTree(const String & = "", size_t = 0, int = 0, FileTree * = 0);
+ virtual ~FileTree();
+ int compute_ptrs(size_t = 0);
+ FileTree * Father();
+ FileTree * Child();
+ FileTree * Next();
+ FileTree * Prev();
+ String name;
+ int type;
+ size_t size;
+ size_t ptr;
+ private:
+ void touched();
+ FileTree * next, * prev, * father, * child;
+ } filetree;
+ String name;
+ Handle * archive;
+ int type;
+ Archive * next, * prev;
+ static Archive * header;
+
+ friend class Input;
+};
+
+#endif
diff --git a/include/LuaHandle.h b/include/LuaHandle.h
index 2ef61df..ed31593 100644
--- a/include/LuaHandle.h
+++ b/include/LuaHandle.h
@@ -1,81 +1,81 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: LuaHandle.h,v 1.7 2004-11-27 21:43:48 pixel Exp $ */
-
-#ifndef __LUAHANDLE_H__
-#define __LUAHANDLE_H__
-
-#include <Exceptions.h>
-#include <Input.h>
-#include <Output.h>
-#include <Buffer.h>
-#include <BLua.h>
-
-class LuaHandle : public LuaObject {
- public:
- LuaHandle(Handle *);
- protected:
- virtual void pushmembers(Lua *);
- Handle * h;
-};
-
-class LuaInput : public LuaHandle {
- public:
- static void pushconstruct(Lua *);
- LuaInput(Input *);
- protected:
- virtual void pushmembers(Lua *);
-};
-
-class LuaOutput : public LuaHandle {
- public:
- static void pushconstruct(Lua *);
- LuaOutput(Output *);
- protected:
- virtual void pushmembers(Lua *);
-};
-
-class LuaBuffer : public LuaHandle {
- public:
- static void pushconstruct(Lua *);
- LuaBuffer(Buffer *);
- protected:
- virtual void pushmembers(Lua *);
-};
-
-class HandleLua : public Handle {
- public:
- HandleLua();
- virtual ~HandleLua();
- virtual ssize_t read(void * buf, size_t count) throw (GeneralException);
- virtual ssize_t write(const void * buf, size_t count) throw (GeneralException);
- virtual bool CanRead() const;
- virtual bool CanWrite() const;
- virtual bool CanSeek() const;
- virtual off_t seek(off_t, int = SEEK_SET) throw (GeneralException);
- virtual off_t tell() const;
- virtual String GetName() const;
- virtual ssize_t GetSize() const;
- virtual time_t GetModif() const;
- virtual bool CanWatch() const;
- virtual void Flush();
-};
-
-#endif
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: LuaHandle.h,v 1.8 2004-11-27 21:46:03 pixel Exp $ */
+
+#ifndef __LUAHANDLE_H__
+#define __LUAHANDLE_H__
+
+#include <Exceptions.h>
+#include <Input.h>
+#include <Output.h>
+#include <Buffer.h>
+#include <BLua.h>
+
+class LuaHandle : public LuaObject {
+ public:
+ LuaHandle(Handle *);
+ protected:
+ virtual void pushmembers(Lua *);
+ Handle * h;
+};
+
+class LuaInput : public LuaHandle {
+ public:
+ static void pushconstruct(Lua *);
+ LuaInput(Input *);
+ protected:
+ virtual void pushmembers(Lua *);
+};
+
+class LuaOutput : public LuaHandle {
+ public:
+ static void pushconstruct(Lua *);
+ LuaOutput(Output *);
+ protected:
+ virtual void pushmembers(Lua *);
+};
+
+class LuaBuffer : public LuaHandle {
+ public:
+ static void pushconstruct(Lua *);
+ LuaBuffer(Buffer *);
+ protected:
+ virtual void pushmembers(Lua *);
+};
+
+class HandleLua : public Handle {
+ public:
+ HandleLua();
+ virtual ~HandleLua();
+ virtual ssize_t read(void * buf, size_t count) throw (GeneralException);
+ virtual ssize_t write(const void * buf, size_t count) throw (GeneralException);
+ virtual bool CanRead() const;
+ virtual bool CanWrite() const;
+ virtual bool CanSeek() const;
+ virtual off_t seek(off_t, int = SEEK_SET) throw (GeneralException);
+ virtual off_t tell() const;
+ virtual String GetName() const;
+ virtual ssize_t GetSize() const;
+ virtual time_t GetModif() const;
+ virtual bool CanWatch() const;
+ virtual void Flush();
+};
+
+#endif
diff --git a/include/Main.h b/include/Main.h
index f0db8ca..7d8da5e 100644
--- a/include/Main.h
+++ b/include/Main.h
@@ -1,60 +1,60 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: Main.h,v 1.15 2004-11-27 21:43:48 pixel Exp $ */
-
-#ifndef __MAIN_H__
-#define __MAIN_H__
-
-#include <Exceptions.h>
-#include <gettext.h>
-
-extern char ** environ;
-
-class Main : public Base {
- public:
- Main();
- virtual ~Main();
- virtual int startup() throw (GeneralException) = 0;
- static int truemain(Main *, int, char **, char **);
- protected:
- int argc;
- char ** argv;
- char ** enve;
- bool setted;
- private:
- void set_args(int, char **, char **);
-
-};
-
-#define CODE_BEGINS \
-class Appli; \
-Appli * Application; \
-class Appli : public Main {
-#define CODE_ENDS }; \
-int main(int argc, char ** argv) { \
- int r; \
- setlocale(LC_ALL, ""); \
- Application = new Appli(); \
- r = Main::truemain(Application, argc, argv, environ); \
- delete Application; \
- return r; \
- }
-
-#endif
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: Main.h,v 1.16 2004-11-27 21:46:03 pixel Exp $ */
+
+#ifndef __MAIN_H__
+#define __MAIN_H__
+
+#include <Exceptions.h>
+#include <gettext.h>
+
+extern char ** environ;
+
+class Main : public Base {
+ public:
+ Main();
+ virtual ~Main();
+ virtual int startup() throw (GeneralException) = 0;
+ static int truemain(Main *, int, char **, char **);
+ protected:
+ int argc;
+ char ** argv;
+ char ** enve;
+ bool setted;
+ private:
+ void set_args(int, char **, char **);
+
+};
+
+#define CODE_BEGINS \
+class Appli; \
+Appli * Application; \
+class Appli : public Main {
+#define CODE_ENDS }; \
+int main(int argc, char ** argv) { \
+ int r; \
+ setlocale(LC_ALL, ""); \
+ Application = new Appli(); \
+ r = Main::truemain(Application, argc, argv, environ); \
+ delete Application; \
+ return r; \
+ }
+
+#endif
diff --git a/include/Menu.h b/include/Menu.h
index 1caec66..91e1459 100644
--- a/include/Menu.h
+++ b/include/Menu.h
@@ -1,22 +1,22 @@
-#ifndef __MENU_H__
-#define __MENU_H__
-
-#include <Action.h>
-#include <BString.h>
-#include <Exceptions.h>
-
-class Menu : public Action {
- public:
- Menu(const String & titre, const String & url, String * labels, Action ** listac, int nb);
- virtual ~Menu() {}
- virtual String GetTitle();
- virtual Task * Do(Variables *, Variables *, Handle *);
-
- private:
- String tit;
- String * lt;
- Action ** la;
- int nba;
-};
-
-#endif
+#ifndef __MENU_H__
+#define __MENU_H__
+
+#include <Action.h>
+#include <BString.h>
+#include <Exceptions.h>
+
+class Menu : public Action {
+ public:
+ Menu(const String & titre, const String & url, String * labels, Action ** listac, int nb);
+ virtual ~Menu() {}
+ virtual String GetTitle();
+ virtual Task * Do(Variables *, Variables *, Handle *);
+
+ private:
+ String tit;
+ String * lt;
+ Action ** la;
+ int nba;
+};
+
+#endif
diff --git a/include/Message.h b/include/Message.h
index fd6c6e9..01c59da 100644
--- a/include/Message.h
+++ b/include/Message.h
@@ -1,20 +1,20 @@
-#ifndef __MESSAGE_H__
-#define __MESSAGE_H__
-
-#include <Action.h>
-#include <BString.h>
-#include <Exceptions.h>
-
-class Message : public Action {
- public:
- Message(const String & titre, const String & msg, const String & url, Action * ok = 0);
- virtual ~Message() { }
- virtual String GetTitle();
- virtual Task * Do(Variables *, Variables *, Handle *);
-
- private:
- String tit, msg;
- Action * Next;
-};
-
-#endif
+#ifndef __MESSAGE_H__
+#define __MESSAGE_H__
+
+#include <Action.h>
+#include <BString.h>
+#include <Exceptions.h>
+
+class Message : public Action {
+ public:
+ Message(const String & titre, const String & msg, const String & url, Action * ok = 0);
+ virtual ~Message() { }
+ virtual String GetTitle();
+ virtual Task * Do(Variables *, Variables *, Handle *);
+
+ private:
+ String tit, msg;
+ Action * Next;
+};
+
+#endif
diff --git a/include/OutPipe.h b/include/OutPipe.h
index 9d016da..467a89b 100644
--- a/include/OutPipe.h
+++ b/include/OutPipe.h
@@ -1,19 +1,19 @@
-#ifndef __OUTPIPE_H__
-#define __OUTPIPE_H__
-
-#include <Handle.h>
-
-class OutPipe : public Handle {
- public:
- OutPipe();
- OutPipe(const OutPipe &);
- virtual ~OutPipe();
- void Hook();
- virtual bool CanWrite();
- virtual bool CanRead();
- virtual String GetName();
- private:
- int p[2], hooked;
-};
-
-#endif
+#ifndef __OUTPIPE_H__
+#define __OUTPIPE_H__
+
+#include <Handle.h>
+
+class OutPipe : public Handle {
+ public:
+ OutPipe();
+ OutPipe(const OutPipe &);
+ virtual ~OutPipe();
+ void Hook();
+ virtual bool CanWrite();
+ virtual bool CanRead();
+ virtual String GetName();
+ private:
+ int p[2], hooked;
+};
+
+#endif
diff --git a/include/Output.h b/include/Output.h
index 17d12d8..3144b32 100644
--- a/include/Output.h
+++ b/include/Output.h
@@ -1,71 +1,71 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: Output.h,v 1.13 2004-11-27 21:43:48 pixel Exp $ */
-
-#ifndef __OUTPUT_H__
-#define __OUTPUT_H__
-
-#include <sys/types.h>
-#include <time.h>
-#include <BString.h>
-#include <Handle.h>
-
-class Output : public Handle {
- public:
- Output(String = "", int create = 1, int trunc = 1) throw (GeneralException);
- Output(const Output &);
- virtual ~Output() {}
- virtual bool CanWrite() const;
- virtual bool CanRead() const;
- virtual bool CanSeek() const;
- virtual off_t seek(off_t, int = SEEK_SET) throw (GeneralException);
- virtual String GetName() const;
-
- protected:
- String n;
- off_t size;
- time_t date_modif;
-
- private:
- int wrapopen(const String &, int, int);
-};
-
-class Stdout_t : public Output {
- public:
- Stdout_t();
- virtual ~Stdout_t() {}
- virtual bool CanSeek() const;
- virtual String GetName() const;
-};
-
-class Stderr_t : public Handle {
- public:
- Stderr_t();
- virtual ~Stderr_t() {}
- virtual bool CanWrite() const;
- virtual bool CanRead() const;
- virtual bool CanSeek() const;
- virtual String GetName() const;
-};
-
-extern Stdout_t Stdout;
-extern Stderr_t Stderr;
-
-#endif
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: Output.h,v 1.14 2004-11-27 21:46:03 pixel Exp $ */
+
+#ifndef __OUTPUT_H__
+#define __OUTPUT_H__
+
+#include <sys/types.h>
+#include <time.h>
+#include <BString.h>
+#include <Handle.h>
+
+class Output : public Handle {
+ public:
+ Output(String = "", int create = 1, int trunc = 1) throw (GeneralException);
+ Output(const Output &);
+ virtual ~Output() {}
+ virtual bool CanWrite() const;
+ virtual bool CanRead() const;
+ virtual bool CanSeek() const;
+ virtual off_t seek(off_t, int = SEEK_SET) throw (GeneralException);
+ virtual String GetName() const;
+
+ protected:
+ String n;
+ off_t size;
+ time_t date_modif;
+
+ private:
+ int wrapopen(const String &, int, int);
+};
+
+class Stdout_t : public Output {
+ public:
+ Stdout_t();
+ virtual ~Stdout_t() {}
+ virtual bool CanSeek() const;
+ virtual String GetName() const;
+};
+
+class Stderr_t : public Handle {
+ public:
+ Stderr_t();
+ virtual ~Stderr_t() {}
+ virtual bool CanWrite() const;
+ virtual bool CanRead() const;
+ virtual bool CanSeek() const;
+ virtual String GetName() const;
+};
+
+extern Stdout_t Stdout;
+extern Stderr_t Stderr;
+
+#endif
diff --git a/include/ReadJob.h b/include/ReadJob.h
index 95a373e..d861aff 100644
--- a/include/ReadJob.h
+++ b/include/ReadJob.h
@@ -1,20 +1,20 @@
-#ifndef __READJOB_H__
-#define __READJOB_H__
-
-#include <Task.h>
-#include <Handle.h>
-#include <Regex.h>
-
-class ReadJob : public Task {
- public:
- ReadJob(Handle *, Handle *, const Regex & = empty);
- virtual ~ReadJob();
- virtual int Do() throw (GeneralException);
- virtual String GetName();
-
- private:
- Handle * s, * d;
- const Regex * regex;
-};
-
-#endif
+#ifndef __READJOB_H__
+#define __READJOB_H__
+
+#include <Task.h>
+#include <Handle.h>
+#include <Regex.h>
+
+class ReadJob : public Task {
+ public:
+ ReadJob(Handle *, Handle *, const Regex & = empty);
+ virtual ~ReadJob();
+ virtual int Do() throw (GeneralException);
+ virtual String GetName();
+
+ private:
+ Handle * s, * d;
+ const Regex * regex;
+};
+
+#endif
diff --git a/include/Regex.h b/include/Regex.h
index daac59f..b076342 100644
--- a/include/Regex.h
+++ b/include/Regex.h
@@ -1,22 +1,22 @@
-#ifndef __REGEX_H__
-#define __REGEX_H__
-
-#include <Exceptions.h>
-#include <BString.h>
-#include <regex.h>
-
-class Regex : public Base {
- public:
- Regex(const String &, int = REG_EXTENDED, int = 0) throw (GeneralException);
- Regex(const Regex &);
- ~Regex();
- bool Match(const String &) const;
- private:
- regex_t preg;
- int cflags, eflags;
- char * pattern;
-};
-
-extern Regex empty, any;
-
-#endif
+#ifndef __REGEX_H__
+#define __REGEX_H__
+
+#include <Exceptions.h>
+#include <BString.h>
+#include <regex.h>
+
+class Regex : public Base {
+ public:
+ Regex(const String &, int = REG_EXTENDED, int = 0) throw (GeneralException);
+ Regex(const Regex &);
+ ~Regex();
+ bool Match(const String &) const;
+ private:
+ regex_t preg;
+ int cflags, eflags;
+ char * pattern;
+};
+
+extern Regex empty, any;
+
+#endif
diff --git a/include/SQL.h b/include/SQL.h
index 637ff90..4385a6d 100644
--- a/include/SQL.h
+++ b/include/SQL.h
@@ -1,25 +1,25 @@
-#ifndef __SQL_H__
-#define __SQL_H__
-
-#include <map>
-#include <mysql.h>
-#include <Exceptions.h>
-
-typedef std::map<String, String> AssocArray;
-
-class SQLConnection : public Base {
- public:
- SQLConnection(String host, String user, String passwd, String db, int port = 3306, String socket = "", unsigned long clags = 0) throw (GeneralException);
- ~SQLConnection();
- void query(String) throw (GeneralException);
- int numrows();
- int numfields();
- AssocArray fetchrow();
- private:
- MYSQL con;
- MYSQL_RES * res;
- int nr, nf;
- MYSQL_FIELD * fields;
-};
-
-#endif
+#ifndef __SQL_H__
+#define __SQL_H__
+
+#include <map>
+#include <mysql.h>
+#include <Exceptions.h>
+
+typedef std::map<String, String> AssocArray;
+
+class SQLConnection : public Base {
+ public:
+ SQLConnection(String host, String user, String passwd, String db, int port = 3306, String socket = "", unsigned long clags = 0) throw (GeneralException);
+ ~SQLConnection();
+ void query(String) throw (GeneralException);
+ int numrows();
+ int numfields();
+ AssocArray fetchrow();
+ private:
+ MYSQL con;
+ MYSQL_RES * res;
+ int nr, nf;
+ MYSQL_FIELD * fields;
+};
+
+#endif
diff --git a/include/Socket.h b/include/Socket.h
index 482a09f..245ed9e 100644
--- a/include/Socket.h
+++ b/include/Socket.h
@@ -1,33 +1,33 @@
-#ifndef __SOCKET_H__
-#define __SOCKET_H__
-
-#include <Handle.h>
-#include <BString.h>
-#include <Output.h>
-#include <Input.h>
-#include <Exceptions.h>
-
-class Socket : public Handle {
- public:
- Socket() throw (GeneralException);
- Socket(const Socket &);
- virtual ~Socket() {}
- bool SetLocal(const String &, int = 0);
- bool Connect(const String &, int);
- bool Listen();
- Socket Accept() throw (GeneralException);
- bool IsConnected();
- bool IsListening();
- virtual bool CanRead();
- virtual bool CanWrite();
- virtual String GetName();
- int GetPort();
- void CloseWrite();
- void CloseRead();
-
- private:
- Socket(int s);
- bool connected, listening, writeclosed, readclosed;
-};
-
-#endif
+#ifndef __SOCKET_H__
+#define __SOCKET_H__
+
+#include <Handle.h>
+#include <BString.h>
+#include <Output.h>
+#include <Input.h>
+#include <Exceptions.h>
+
+class Socket : public Handle {
+ public:
+ Socket() throw (GeneralException);
+ Socket(const Socket &);
+ virtual ~Socket() {}
+ bool SetLocal(const String &, int = 0);
+ bool Connect(const String &, int);
+ bool Listen();
+ Socket Accept() throw (GeneralException);
+ bool IsConnected();
+ bool IsListening();
+ virtual bool CanRead();
+ virtual bool CanWrite();
+ virtual String GetName();
+ int GetPort();
+ void CloseWrite();
+ void CloseRead();
+
+ private:
+ Socket(int s);
+ bool connected, listening, writeclosed, readclosed;
+};
+
+#endif
diff --git a/include/Table.h b/include/Table.h
index 00de842..c972fa3 100644
--- a/include/Table.h
+++ b/include/Table.h
@@ -1,21 +1,21 @@
-#ifndef __TABLE_H__
-#define __TABLE_H__
-
-#include <Action.h>
-#include <BString.h>
-#include <Exceptions.h>
-
-class Table : public Action {
- public:
- Table(const String & titre, const String & url, String * heads, String * cells, int nbcol, int nblgn, Action * ok = 0);
- virtual ~Table() { }
- virtual String GetTitle();
- virtual Task * Do(Variables *, Variables *, Handle *);
-
- private:
- String tit, * hds, * cls;
- int nc, nl;
- Action * Next;
-};
-
-#endif
+#ifndef __TABLE_H__
+#define __TABLE_H__
+
+#include <Action.h>
+#include <BString.h>
+#include <Exceptions.h>
+
+class Table : public Action {
+ public:
+ Table(const String & titre, const String & url, String * heads, String * cells, int nbcol, int nblgn, Action * ok = 0);
+ virtual ~Table() { }
+ virtual String GetTitle();
+ virtual Task * Do(Variables *, Variables *, Handle *);
+
+ private:
+ String tit, * hds, * cls;
+ int nc, nl;
+ Action * Next;
+};
+
+#endif
diff --git a/include/Task.h b/include/Task.h
index 384207a..9c966a3 100644
--- a/include/Task.h
+++ b/include/Task.h
@@ -1,55 +1,55 @@
-#ifndef __TASK_H__
-#define __TASK_H__
-
-#include <unistd.h>
-#include <sys/time.h>
-#include <vector>
-#include <Exceptions.h>
-#include <Handle.h>
-
-#define TASK_ON_HOLD 0
-#define TASK_DONE 1
-#define TASK_BURST 2
-
-#define W4_STICKY 1
-#define W4_READING 2
-#define W4_WRITING 4
-
-class Task : public Base {
- public:
- Task();
- virtual ~Task();
- virtual String GetName();
- int Run();
- int DryRun();
- int GetState();
- void Suspend(int = -1) throw (GeneralException);
- void WaitFor(Task *);
- void WaitFor(Handle *, int = 0);
- void WaitFor(pid_t);
- void WaitFor(timeval, int = 0);
- Task * WaitedBy();
- void SetBurst();
- void Stop();
- void Restart();
- bool IsStopped();
- void RemoveFromWatches();
-
- protected:
- virtual int Do() throw (GeneralException);
- int current;
-
- private:
- class wbta_t {
- public:
- wbta_t(Task * ata) : ta(ata) { }
- Task * ta;
- };
-
- int state;
- bool stopped;
- bool suspended;
- Task * wbta;
-};
-
-#endif
+#ifndef __TASK_H__
+#define __TASK_H__
+
+#include <unistd.h>
+#include <sys/time.h>
+#include <vector>
+#include <Exceptions.h>
+#include <Handle.h>
+
+#define TASK_ON_HOLD 0
+#define TASK_DONE 1
+#define TASK_BURST 2
+
+#define W4_STICKY 1
+#define W4_READING 2
+#define W4_WRITING 4
+
+class Task : public Base {
+ public:
+ Task();
+ virtual ~Task();
+ virtual String GetName();
+ int Run();
+ int DryRun();
+ int GetState();
+ void Suspend(int = -1) throw (GeneralException);
+ void WaitFor(Task *);
+ void WaitFor(Handle *, int = 0);
+ void WaitFor(pid_t);
+ void WaitFor(timeval, int = 0);
+ Task * WaitedBy();
+ void SetBurst();
+ void Stop();
+ void Restart();
+ bool IsStopped();
+ void RemoveFromWatches();
+
+ protected:
+ virtual int Do() throw (GeneralException);
+ int current;
+
+ private:
+ class wbta_t {
+ public:
+ wbta_t(Task * ata) : ta(ata) { }
+ Task * ta;
+ };
+
+ int state;
+ bool stopped;
+ bool suspended;
+ Task * wbta;
+};
+
+#endif
diff --git a/include/TaskMan.h b/include/TaskMan.h
index dec46a3..128339f 100644
--- a/include/TaskMan.h
+++ b/include/TaskMan.h
@@ -1,74 +1,74 @@
-#ifndef __TASKMAN_H__
-#define __TASKMAN_H__
-
-#include <signal.h>
-#include <Task.h>
-#include <vector>
-
-#define E_BURST 0
-#define E_HANDLE 1
-#define E_PROCESS 2
-#define E_TIMEOUT 3
-#define E_TASK 4
-
-class TaskMan : public Base {
- public:
- static void AddTask(Task *);
- static std::vector<Task *>::iterator FindTask(Task *) throw (GeneralException);
- static void RemoveFromWatches(Task *);
- static void Init() throw (GeneralException);
- static void MainLoop() throw (GeneralException);
- static void WaitFor(Handle *, Task *, int = 0);
- static void WaitFor(pid_t, Task *, int = 0);
- static void WaitFor(timeval, Task *, int = 0);
- static int GotChild(pid_t, int);
- static void Stop();
- static int Event();
- static Task * Etask();
- static Handle * Ehandle();
- static int Eprocess();
- static int Estatus();
-
- class w4ha_t {
- public:
- w4ha_t(Handle * aha, int aflags, Task * aT) : ha(aha), flags(aflags), dirthy(true), T(aT) { }
- Handle * ha;
- int flags;
- bool dirthy;
- Task * T;
- };
-
- class w4pr_t {
- public:
- w4pr_t(pid_t apr, Task * aT) : pr(apr), flag(0), status(0), T(aT) { }
- pid_t pr;
- int flag, status;
- Task * T;
- };
-
- class w4to_t {
- public:
- w4to_t(timeval ato, int aflags, Task * aT) : to(ato), flags(aflags), T(aT) { }
- timeval to;
- int flags;
- Task * T;
- };
- typedef std::vector<Task *> TaskList_t;
-
- private:
- static TaskList_t TaskList;
- static TaskList_t Zombies;
- static int number;
- static bool inited;
- static std::vector<w4ha_t> w4ha;
- static std::vector<w4pr_t> w4pr;
- static std::vector<w4to_t> w4to;
- static bool stopped;
- static int event;
- static Task * etask;
- static Handle * ehandle;
- static int eprocess, estatus;
- static sigset_t sigchildset;
-};
-
-#endif
+#ifndef __TASKMAN_H__
+#define __TASKMAN_H__
+
+#include <signal.h>
+#include <Task.h>
+#include <vector>
+
+#define E_BURST 0
+#define E_HANDLE 1
+#define E_PROCESS 2
+#define E_TIMEOUT 3
+#define E_TASK 4
+
+class TaskMan : public Base {
+ public:
+ static void AddTask(Task *);
+ static std::vector<Task *>::iterator FindTask(Task *) throw (GeneralException);
+ static void RemoveFromWatches(Task *);
+ static void Init() throw (GeneralException);
+ static void MainLoop() throw (GeneralException);
+ static void WaitFor(Handle *, Task *, int = 0);
+ static void WaitFor(pid_t, Task *, int = 0);
+ static void WaitFor(timeval, Task *, int = 0);
+ static int GotChild(pid_t, int);
+ static void Stop();
+ static int Event();
+ static Task * Etask();
+ static Handle * Ehandle();
+ static int Eprocess();
+ static int Estatus();
+
+ class w4ha_t {
+ public:
+ w4ha_t(Handle * aha, int aflags, Task * aT) : ha(aha), flags(aflags), dirthy(true), T(aT) { }
+ Handle * ha;
+ int flags;
+ bool dirthy;
+ Task * T;
+ };
+
+ class w4pr_t {
+ public:
+ w4pr_t(pid_t apr, Task * aT) : pr(apr), flag(0), status(0), T(aT) { }
+ pid_t pr;
+ int flag, status;
+ Task * T;
+ };
+
+ class w4to_t {
+ public:
+ w4to_t(timeval ato, int aflags, Task * aT) : to(ato), flags(aflags), T(aT) { }
+ timeval to;
+ int flags;
+ Task * T;
+ };
+ typedef std::vector<Task *> TaskList_t;
+
+ private:
+ static TaskList_t TaskList;
+ static TaskList_t Zombies;
+ static int number;
+ static bool inited;
+ static std::vector<w4ha_t> w4ha;
+ static std::vector<w4pr_t> w4pr;
+ static std::vector<w4to_t> w4to;
+ static bool stopped;
+ static int event;
+ static Task * etask;
+ static Handle * ehandle;
+ static int eprocess, estatus;
+ static sigset_t sigchildset;
+};
+
+#endif
diff --git a/include/Variables.h b/include/Variables.h
index 9fab80c..ac4ef58 100644
--- a/include/Variables.h
+++ b/include/Variables.h
@@ -1,28 +1,28 @@
-#ifndef __VARIABLES_H__
-#define __VARIABLES_H__
-
-#include <vector>
-#include <BString.h>
-#include <Handle.h>
-#include <Exceptions.h>
-
-class Variables : public Base {
- public:
- Variables(int = 0);
- Variables(const Variables &);
- ~Variables();
- void SetTo(int i, const String &);
- String operator[](const String &);
- String operator[](int i);
- void Dump(Handle *, const String & = "");
- int GetNb();
- void Add(const String &);
- void Del(int);
- void Del(const String &);
-
- private:
- std::vector<String> Vars;
- int nbvars;
-};
-
-#endif
+#ifndef __VARIABLES_H__
+#define __VARIABLES_H__
+
+#include <vector>
+#include <BString.h>
+#include <Handle.h>
+#include <Exceptions.h>
+
+class Variables : public Base {
+ public:
+ Variables(int = 0);
+ Variables(const Variables &);
+ ~Variables();
+ void SetTo(int i, const String &);
+ String operator[](const String &);
+ String operator[](int i);
+ void Dump(Handle *, const String & = "");
+ int GetNb();
+ void Add(const String &);
+ void Del(int);
+ void Del(const String &);
+
+ private:
+ std::vector<String> Vars;
+ int nbvars;
+};
+
+#endif
diff --git a/include/generic.h b/include/generic.h
index bdfb51c..fe9b529 100644
--- a/include/generic.h
+++ b/include/generic.h
@@ -1,194 +1,194 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: generic.h,v 1.30 2004-11-27 21:43:48 pixel Exp $ */
-
-#ifndef __GENERIC_H__
-#define __GENERIC_H__
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-
-#define M_BARE -1
-#define M_ERROR 0
-#define M_STATUS 1
-#define M_WARNING 2
-#define M_INFO 3
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-#ifndef bcopy
-#define bcopy(x,y,z) memcpy((y),(x),(z))
-#endif
-
-#if ! defined SDL_VERSIONNUM && ! defined Uint32
-typedef unsigned long int Uint32;
-#endif
-
-#ifndef int32
-typedef signed long int int32;
-#endif
-
-#ifndef Uint16
-typedef unsigned short int Uint16;
-#endif
-
-#ifndef int16
-typedef signed short int int16;
-#endif
-
-#ifndef Uint8
-typedef unsigned char Uint8;
-#endif
-
-#ifndef int8
-typedef signed char int8;
-#endif
-
-#ifndef Byte
-typedef Uint8 Byte;
-#endif
-
-#ifndef Word
-typedef Uint16 Word;
-#endif
-
-#ifndef DWord
-typedef Uint32 DWord;
-#endif
-
-#if !defined __ssize_t_defined && !defined _SSIZE_T && !defined ssize_t && !defined _BSD_SSIZE_T_DEFINED_
-typedef int32 ssize_t;
-#endif
-
-#if defined __linux__ || defined sun || defined __solaris__ || defined __CYGWIN32__ || defined __MINGW32__ || defined FORCE64 || defined __APPLE__
-typedef long long int64;
-typedef unsigned long long Uint64;
-#else
-#if defined _WIN32
-typedef _int64 int64;
-typedef unsigned _int64 Uint64;
-#else
-#error Unsupported platform (need 64 bits ints definition)
-#endif
-#endif
-
-#ifndef PACKED
-#if defined __linux__ || defined sun || defined __solaris__ || defined __CYGWIN32__ || defined __MINGW32__ || defined __APPLE__
-#define PACKED __attribute__((packed))
-#else // PACKED
-#define PACKED
-#endif
-#endif // !PACKED
-
-#ifndef PPACKED
-#if defined __linux__ || defined sun || defined __solaris__ || defined __CYGWIN32__ || defined __MINGW32__ || defined __APPLE__
-#define PPACKED
-#else // PPACKED
-#define PPACKED __declspec(align(1))
-#endif
-#endif // !PPACKED
-
-extern char verbosity;
-char ** split(char * s, char t);
-
-#ifdef _WIN32
-#define tolittle(x) x
-static Uint32 tobig(Uint32 x) {
- return (x >> 24) | ((x >> 8) & 0x0000ff00) | ((x << 8) & 0x00ff0000) | (x << 24);
-}
-#else
-#define tolittle(x) x
-static Uint32 tobig(Uint32 x) {
- return (x >> 24) | ((x >> 8) & 0x0000ff00) | ((x << 8) & 0x00ff0000) | (x << 24);
-}
-#endif
-
-#if defined __cplusplus
-
-#ifndef MAX
-template<class T>
-inline T MAX(T a, T b) {
- return a < b ? b : a;
-}
-#endif
-
-#ifndef MIN
-template<class T>
-inline T MIN(T a, T b) {
- return a > b ? b : a;
-}
-#endif
-
-#ifndef SWAP
-template<class T>
-inline void SWAP(T & a, T & b) {
- T t = a;
- a = b;
- b = t;
-}
-#endif
-
-#ifndef ABS
-template<class T>
-inline T ABS(T x) {
- T ox = -x;
- return x > 0 ? x : ox;
-}
-#endif
-
-#if defined __linux__ || defined sun || defined __solaris__ || defined __CYGWIN32__ || defined __MINGW32__ || defined __APPLE__
-#define FUNCNAME String(__PRETTY_FUNCTION__)
-#else
-#define FUNCNAME String(__FUNCSIG__)
-#endif
-
-#else // cplusplus
-
-#ifndef MAX
-#define MAX(__a,__b) ((__a)<(__b)?(__b):(__a))
-#endif
-
-#ifndef MIN
-#define MIN(__a,__b) ((__a)>(__b)?(__b):(__a))
-#endif
-
-#endif // !cplusplus
-
-#define BITCOUNT(x) (((BX_(x)+(BX_(x)>>4)) & 0x0F0F0F0F) % 255)
-#define BX_(x) ((x) - (((x)>>1)&0x77777777) \
- - (((x)>>2)&0x33333333) \
- - (((x)>>3)&0x11111111))
-#define ISPOT(x) (((x)&(x-1))==0?1:0)
-
-#if defined __linux__ || defined sun || defined __solaris__ || defined __CYGWIN32__ || defined __APPLE__
-#define MKDIR(name) mkdir(name, 0777)
-#else
-#if defined __WIN32__ || defined _WIN32
-#include <direct.h>
-#define MKDIR mkdir
-#else
-#error Unknow compiler/platform
-#endif
-#endif
-
-#endif
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: generic.h,v 1.31 2004-11-27 21:46:03 pixel Exp $ */
+
+#ifndef __GENERIC_H__
+#define __GENERIC_H__
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#define M_BARE -1
+#define M_ERROR 0
+#define M_STATUS 1
+#define M_WARNING 2
+#define M_INFO 3
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#ifndef bcopy
+#define bcopy(x,y,z) memcpy((y),(x),(z))
+#endif
+
+#if ! defined SDL_VERSIONNUM && ! defined Uint32
+typedef unsigned long int Uint32;
+#endif
+
+#ifndef int32
+typedef signed long int int32;
+#endif
+
+#ifndef Uint16
+typedef unsigned short int Uint16;
+#endif
+
+#ifndef int16
+typedef signed short int int16;
+#endif
+
+#ifndef Uint8
+typedef unsigned char Uint8;
+#endif
+
+#ifndef int8
+typedef signed char int8;
+#endif
+
+#ifndef Byte
+typedef Uint8 Byte;
+#endif
+
+#ifndef Word
+typedef Uint16 Word;
+#endif
+
+#ifndef DWord
+typedef Uint32 DWord;
+#endif
+
+#if !defined __ssize_t_defined && !defined _SSIZE_T && !defined ssize_t && !defined _BSD_SSIZE_T_DEFINED_
+typedef int32 ssize_t;
+#endif
+
+#if defined __linux__ || defined sun || defined __solaris__ || defined __CYGWIN32__ || defined __MINGW32__ || defined FORCE64 || defined __APPLE__
+typedef long long int64;
+typedef unsigned long long Uint64;
+#else
+#if defined _WIN32
+typedef _int64 int64;
+typedef unsigned _int64 Uint64;
+#else
+#error Unsupported platform (need 64 bits ints definition)
+#endif
+#endif
+
+#ifndef PACKED
+#if defined __linux__ || defined sun || defined __solaris__ || defined __CYGWIN32__ || defined __MINGW32__ || defined __APPLE__
+#define PACKED __attribute__((packed))
+#else // PACKED
+#define PACKED
+#endif
+#endif // !PACKED
+
+#ifndef PPACKED
+#if defined __linux__ || defined sun || defined __solaris__ || defined __CYGWIN32__ || defined __MINGW32__ || defined __APPLE__
+#define PPACKED
+#else // PPACKED
+#define PPACKED __declspec(align(1))
+#endif
+#endif // !PPACKED
+
+extern char verbosity;
+char ** split(char * s, char t);
+
+#ifdef _WIN32
+#define tolittle(x) x
+static Uint32 tobig(Uint32 x) {
+ return (x >> 24) | ((x >> 8) & 0x0000ff00) | ((x << 8) & 0x00ff0000) | (x << 24);
+}
+#else
+#define tolittle(x) x
+static Uint32 tobig(Uint32 x) {
+ return (x >> 24) | ((x >> 8) & 0x0000ff00) | ((x << 8) & 0x00ff0000) | (x << 24);
+}
+#endif
+
+#if defined __cplusplus
+
+#ifndef MAX
+template<class T>
+inline T MAX(T a, T b) {
+ return a < b ? b : a;
+}
+#endif
+
+#ifndef MIN
+template<class T>
+inline T MIN(T a, T b) {
+ return a > b ? b : a;
+}
+#endif
+
+#ifndef SWAP
+template<class T>
+inline void SWAP(T & a, T & b) {
+ T t = a;
+ a = b;
+ b = t;
+}
+#endif
+
+#ifndef ABS
+template<class T>
+inline T ABS(T x) {
+ T ox = -x;
+ return x > 0 ? x : ox;
+}
+#endif
+
+#if defined __linux__ || defined sun || defined __solaris__ || defined __CYGWIN32__ || defined __MINGW32__ || defined __APPLE__
+#define FUNCNAME String(__PRETTY_FUNCTION__)
+#else
+#define FUNCNAME String(__FUNCSIG__)
+#endif
+
+#else // cplusplus
+
+#ifndef MAX
+#define MAX(__a,__b) ((__a)<(__b)?(__b):(__a))
+#endif
+
+#ifndef MIN
+#define MIN(__a,__b) ((__a)>(__b)?(__b):(__a))
+#endif
+
+#endif // !cplusplus
+
+#define BITCOUNT(x) (((BX_(x)+(BX_(x)>>4)) & 0x0F0F0F0F) % 255)
+#define BX_(x) ((x) - (((x)>>1)&0x77777777) \
+ - (((x)>>2)&0x33333333) \
+ - (((x)>>3)&0x11111111))
+#define ISPOT(x) (((x)&(x-1))==0?1:0)
+
+#if defined __linux__ || defined sun || defined __solaris__ || defined __CYGWIN32__ || defined __APPLE__
+#define MKDIR(name) mkdir(name, 0777)
+#else
+#if defined __WIN32__ || defined _WIN32
+#include <direct.h>
+#define MKDIR mkdir
+#else
+#error Unknow compiler/platform
+#endif
+#endif
+
+#endif
diff --git a/include/gettext.h b/include/gettext.h
index 2a4856e..de7395c 100644
--- a/include/gettext.h
+++ b/include/gettext.h
@@ -1,64 +1,64 @@
-/* Convenience header for conditional use of GNU <libintl.h>.
- Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published
- by the Free Software Foundation; either version 2, 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library 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. */
-
-#ifndef _LIBGETTEXT_H
-#define _LIBGETTEXT_H 1
-
-/* NLS can be disabled through the configure --disable-nls option. */
-#if ENABLE_NLS && defined HAVE_LIBINTL_H
-
-/* Get declarations of GNU message catalog functions. */
-# include <libintl.h>
-
-#else
-
-/* Disabled NLS.
- The casts to 'const char *' serve the purpose of producing warnings
- for invalid uses of the value returned from these functions.
- On pre-ANSI systems without 'const', the config.h file is supposed to
- contain "#define const". */
-# define gettext(Msgid) ((const char *) (Msgid))
-# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
-# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
-# define ngettext(Msgid1, Msgid2, N) \
- ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
-# define dngettext(Domainname, Msgid1, Msgid2, N) \
- ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
-# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
- ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
-# define textdomain(Domainname) ((const char *) (Domainname))
-# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
-# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
-# define setlocale(category, locale)
-# define LC_ALL 0
-
-#endif
-
-/* A pseudo function call that serves as a marker for the automated
- extraction of messages, but does not call gettext(). The run-time
- translation is done at a different place in the code.
- The argument, String, should be a literal string. Concatenated strings
- and other string expressions won't work.
- The macro's expansion is not parenthesized, so that it is suitable as
- initializer for static 'char[]' or 'const char[]' variables. */
-#define gettext_noop(String) String
-
-#define _(Text) dgettext ("Baltisot", Text)
-#define N_(Text) Text
-
-#endif /* _LIBGETTEXT_H */
+/* Convenience header for conditional use of GNU <libintl.h>.
+ Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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. */
+
+#ifndef _LIBGETTEXT_H
+#define _LIBGETTEXT_H 1
+
+/* NLS can be disabled through the configure --disable-nls option. */
+#if ENABLE_NLS && defined HAVE_LIBINTL_H
+
+/* Get declarations of GNU message catalog functions. */
+# include <libintl.h>
+
+#else
+
+/* Disabled NLS.
+ The casts to 'const char *' serve the purpose of producing warnings
+ for invalid uses of the value returned from these functions.
+ On pre-ANSI systems without 'const', the config.h file is supposed to
+ contain "#define const". */
+# define gettext(Msgid) ((const char *) (Msgid))
+# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
+# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
+# define ngettext(Msgid1, Msgid2, N) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+# define dngettext(Domainname, Msgid1, Msgid2, N) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+# define textdomain(Domainname) ((const char *) (Domainname))
+# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
+# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
+# define setlocale(category, locale)
+# define LC_ALL 0
+
+#endif
+
+/* A pseudo function call that serves as a marker for the automated
+ extraction of messages, but does not call gettext(). The run-time
+ translation is done at a different place in the code.
+ The argument, String, should be a literal string. Concatenated strings
+ and other string expressions won't work.
+ The macro's expansion is not parenthesized, so that it is suitable as
+ initializer for static 'char[]' or 'const char[]' variables. */
+#define gettext_noop(String) String
+
+#define _(Text) dgettext ("Baltisot", Text)
+#define N_(Text) Text
+
+#endif /* _LIBGETTEXT_H */
diff --git a/include/template.h b/include/template.h
index 784dcd2..591bfcb 100644
--- a/include/template.h
+++ b/include/template.h
@@ -1,3 +1,3 @@
-#ifndef ___H__
-#define ___H__
-#endif
+#ifndef ___H__
+#define ___H__
+#endif
diff --git a/lib/Action.cc b/lib/Action.cc
index 8e8e98d..e5825b9 100644
--- a/lib/Action.cc
+++ b/lib/Action.cc
@@ -1,91 +1,91 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "BString.h"
-#include "Action.h"
-#include "HttpServ.h"
-
-Action * Action::start = 0;
-
-static int counter = 0;
-
-static String genurl(const String & u) {
- if (u.strlen()) {
- return u;
- } else {
- // Si l'url passée en paramètre est vide, on génère une URL
- // sous la forme TmpXXXX où XXXX est une valeur qui s'incrémente.
- return String("Tmp") + (counter++);
- }
-}
-
-Action::Action(const String & u) : next(start), prev(0), URL(genurl(u)), hastoclean(false), accessed(false) {
- start = this;
- if (next) next->prev = this;
-}
-
-Action::~Action() {
- if (start == this) {
- start = next;
- }
- if (next) next->prev = prev;
- if (prev) prev->next = next;
-}
-
-Action * Action::Look4URL(const String & URL) {
- Action * p;
-
-// cerr << "Looking for " << URL << endl;
- for (p = start; p; p = p->next) {
-// cerr << "p->GetURL() = " << p->GetURL() << endl;
- if (!p->GetURL().strlen()) {
- // Si l'action que l'on vient de tester n'a pas d'URL, elle ne sert à rien.
- // On l'efface donc de notre liste. GetURL renvoie une chaine vide si l'action
- // était déclarée en mode CleanUp, puis a été accédée.
- delete p;
- } else {
- if (URL == p->GetURL()) return p;
- }
- }
-
- return 0;
-}
-
-/*
- * Voici la skin principale. Elle nécessite un fichier 'grain.png' dans le répertoire datas
- * et un fichier 'style.css' (fournis)
- */
-
-void Action::SendHead(Handle * h) {
- (*h) << "<HTML><HEAD><TITLE>" << GetTitle() << "</TITLE>" << endnl <<
- "<META http-equiv=\"Content-Style-Type\" content=\"text/css\">" << endnl <<
- "<LINK REL=STYLESHEET HREF=\"/image/style.css\" TYPE=\"text/css\">" << endnl <<
- "</HEAD><BODY BGCOLOR=\"#aaaaaa\" BACKGROUND=\"/image/grain.png\">" << endnl <<
- "<center><TABLE WIDTH=\"50%\" BORDER=3 cellspacing=1 BGCOLOR=\"#ffffff\"><TR><TD>" << endnl <<
- "<center><b><h1>" << GetTitle() << "</h1></b></center></TD></TR></TABLE><P>" << endnl <<
- "<TABLE WIDTH=\"80%\" BORDER=2 cellspacing=1 BGCOLOR=\"#ffffff\"><TR><TD>" << endnl;
-}
-
-void Action::SendFoot(Handle * h) {
- (*h) << "</TABLE></TD></TR></BODY></HTML>" << endnl;
-}
-
-String Action::GetURL(void) {
- // Comme décrit plus haut, il faut renvoyer la chaîne vide si l'action est en
- // mode CleanUp et a été lue.
- return (hastoclean && accessed) ? "" : URL;
-}
-
-void Action::CleanUp(void) {
- hastoclean = true;
-}
-
-void Action::Accessed(void) {
- accessed = true;
-}
-
-void Action::ShowButton(Handle * h, const String & l, const String & u) {
- (*h) << "<CENTER><FORM METHOD=\"POST\" ACTION=\"/bin/" << u << "\">" << endnl <<
- "<INPUT TYPE=\"SUBMIT\" VALUE=\"" << l << "\">" << endnl
- << "</FORM></CENTER>" << endnl;
-}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "BString.h"
+#include "Action.h"
+#include "HttpServ.h"
+
+Action * Action::start = 0;
+
+static int counter = 0;
+
+static String genurl(const String & u) {
+ if (u.strlen()) {
+ return u;
+ } else {
+ // Si l'url passée en paramètre est vide, on génère une URL
+ // sous la forme TmpXXXX où XXXX est une valeur qui s'incrémente.
+ return String("Tmp") + (counter++);
+ }
+}
+
+Action::Action(const String & u) : next(start), prev(0), URL(genurl(u)), hastoclean(false), accessed(false) {
+ start = this;
+ if (next) next->prev = this;
+}
+
+Action::~Action() {
+ if (start == this) {
+ start = next;
+ }
+ if (next) next->prev = prev;
+ if (prev) prev->next = next;
+}
+
+Action * Action::Look4URL(const String & URL) {
+ Action * p;
+
+// cerr << "Looking for " << URL << endl;
+ for (p = start; p; p = p->next) {
+// cerr << "p->GetURL() = " << p->GetURL() << endl;
+ if (!p->GetURL().strlen()) {
+ // Si l'action que l'on vient de tester n'a pas d'URL, elle ne sert à rien.
+ // On l'efface donc de notre liste. GetURL renvoie une chaine vide si l'action
+ // était déclarée en mode CleanUp, puis a été accédée.
+ delete p;
+ } else {
+ if (URL == p->GetURL()) return p;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Voici la skin principale. Elle nécessite un fichier 'grain.png' dans le répertoire datas
+ * et un fichier 'style.css' (fournis)
+ */
+
+void Action::SendHead(Handle * h) {
+ (*h) << "<HTML><HEAD><TITLE>" << GetTitle() << "</TITLE>" << endnl <<
+ "<META http-equiv=\"Content-Style-Type\" content=\"text/css\">" << endnl <<
+ "<LINK REL=STYLESHEET HREF=\"/image/style.css\" TYPE=\"text/css\">" << endnl <<
+ "</HEAD><BODY BGCOLOR=\"#aaaaaa\" BACKGROUND=\"/image/grain.png\">" << endnl <<
+ "<center><TABLE WIDTH=\"50%\" BORDER=3 cellspacing=1 BGCOLOR=\"#ffffff\"><TR><TD>" << endnl <<
+ "<center><b><h1>" << GetTitle() << "</h1></b></center></TD></TR></TABLE><P>" << endnl <<
+ "<TABLE WIDTH=\"80%\" BORDER=2 cellspacing=1 BGCOLOR=\"#ffffff\"><TR><TD>" << endnl;
+}
+
+void Action::SendFoot(Handle * h) {
+ (*h) << "</TABLE></TD></TR></BODY></HTML>" << endnl;
+}
+
+String Action::GetURL(void) {
+ // Comme décrit plus haut, il faut renvoyer la chaîne vide si l'action est en
+ // mode CleanUp et a été lue.
+ return (hastoclean && accessed) ? "" : URL;
+}
+
+void Action::CleanUp(void) {
+ hastoclean = true;
+}
+
+void Action::Accessed(void) {
+ accessed = true;
+}
+
+void Action::ShowButton(Handle * h, const String & l, const String & u) {
+ (*h) << "<CENTER><FORM METHOD=\"POST\" ACTION=\"/bin/" << u << "\">" << endnl <<
+ "<INPUT TYPE=\"SUBMIT\" VALUE=\"" << l << "\">" << endnl
+ << "</FORM></CENTER>" << endnl;
+}
diff --git a/lib/BLua.cc b/lib/BLua.cc
index 9366dd8..51a5e97 100644
--- a/lib/BLua.cc
+++ b/lib/BLua.cc
@@ -1,667 +1,667 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: BLua.cc,v 1.21 2004-11-27 21:01:20 pixel Exp $ */
-
-#include "BLua.h"
-#include <lualib.h>
-
-#ifndef BUFFERSIZE
-#define BUFFERSIZE 2048
-#endif
-
-
-
-extern "C" {
- void do_lua_lock(lua_State * _L) {
- Lua * L;
- try {
- L = Lua::find(_L);
- } catch (GeneralException e) {
- return;
- }
- L->lock();
- }
-
- void do_lua_unlock(lua_State * _L) {
- Lua * L;
- try {
- L = Lua::find(_L);
- } catch (GeneralException e) {
- return;
- }
- L->unlock();
- }
-}
-
-class LuaStatics : public Base {
- public:
- static const char * getF(lua_State *, void *, size_t *);
- static int putF(lua_State *, const void *, size_t, void *);
- static int luapanic(lua_State *);
- static int trueluapanic(lua_State *) throw(GeneralException);
- static int collector(lua_State *);
- static int destructor(lua_State *);
-
- static int andB(lua_State *);
- static int orB(lua_State *);
- static int xorB(lua_State *);
- static int notB(lua_State *);
- static int hex(lua_State *);
- static int shl(lua_State *);
- static int shr(lua_State *);
-};
-
-std::map<lua_State *, Lua *> Lua::lualist;
-
-int LuaStatics::luapanic(lua_State * L) {
- return trueluapanic(L);
-}
-
-int LuaStatics::trueluapanic(lua_State * L) throw (GeneralException) {
- Lua::find(L)->showerror();
- throw LuaException("Error running Lua code, bailing out.");
-}
-
-int LuaStatics::andB(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
- L->error("Incorrect arguments to function `andB'");
- }
-
- a = L->tonumber(1);
- b = L->tonumber(2);
-
- L->push((lua_Number) (a & b));
-
- return 1;
-}
-
-int LuaStatics::orB(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
- L->error("Incorrect arguments to function `orB'");
- }
-
- a = L->tonumber(1);
- b = L->tonumber(2);
-
- L->push((lua_Number) (a | b));
-
- return 1;
-}
-
-int LuaStatics::xorB(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
- L->error("Incorrect arguments to function `xorB'");
- }
-
- a = L->tonumber(1);
- b = L->tonumber(2);
-
- L->push((lua_Number) (a ^ b));
-
- return 1;
-}
-
-int LuaStatics::notB(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 x;
-
- if ((n != 1) && !L->isnumber()) {
- L->error("Incorrect arguments to function `notB'");
- }
-
- x = L->tonumber();
-
- L->push((lua_Number) (~x));
-
- return 1;
-}
-
-int LuaStatics::shl(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) {
- L->error("Incorrect arguments to function `shl'");
- }
-
- a = L->tonumber(1);
- if (n == 2)
- b = L->tonumber(2);
- else
- b = 1;
-
- L->push((lua_Number) (a << b));
-
- return 1;
-}
-
-int LuaStatics::shr(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) {
- L->error("Incorrect arguments to function `shr'");
- }
-
- a = L->tonumber(1);
- if (n == 2)
- b = L->tonumber(2);
- else
- b = 1;
-
- L->push((lua_Number) (a >> b));
-
- return 1;
-}
-
-int LuaStatics::hex(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- int x;
- String r;
-
- if (((n != 1) || (n != 2)) && !L->isnumber(1) && ((n == 2) && !L->isstring(2))) {
- L->error("Incorrect arguments to function `hex'");
- }
-
- x = L->tonumber(1);
- String fmt = n == 2 ? L->tostring() : "%02x";
- r.set(fmt.to_charp(), x);
-
- L->push(r);
-
- return 1;
-}
-
-Lua::Lua() : L(lua_open()) {
- lua_atpanic(L, LuaStatics::luapanic);
- lualist[L] = this;
-
- declarefunc("andB", LuaStatics::andB);
- declarefunc("orB", LuaStatics::orB);
- declarefunc("xorB", LuaStatics::xorB);
- declarefunc("notB", LuaStatics::notB);
- declarefunc("shl", LuaStatics::shl);
- declarefunc("shr", LuaStatics::shr);
- declarefunc("hex", LuaStatics::hex);
-}
-
-Lua::Lua(lua_State * _L) : L(_L) {
- lua_atpanic(L, LuaStatics::luapanic);
- lualist[L] = this;
-}
-
-Lua::~Lua() {
- lua_setgcthreshold(L, 0);
- lua_close(L);
-}
-
-Lua::Lua(const Lua & l) throw (GeneralException) {
- throw GeneralException("Error: can't duplicate a Lua object.");
-}
-
-void Lua::open_base() {
- luaopen_base(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_table() {
- luaopen_table(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_io() {
- luaopen_io(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_string() {
- luaopen_string(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_math() {
- luaopen_math(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_debug() {
- luaopen_debug(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_dir() {
- luaopen_dir(L);
- lua_pop(L, 1);
-}
-
-void Lua::declarefunc(const String & name, lua_CFunction f, int i) {
- lua_pushstring(L, name.to_charp());
- lua_pushcfunction(L, f);
- lua_settable(L, i);
-}
-
-void Lua::call(const String & f, int i, int nargs, int nresults) {
- lua_pushstring(L, f.to_charp());
- lua_gettable(L, i);
- lua_insert(L, -1 - nargs - nresults);
- lua_call(L, nargs, nresults);
-}
-
-void Lua::call(int nargs, int nresults) {
- lua_call(L, nargs, nresults);
-}
-
-void Lua::push() {
- lua_pushnil(L);
-}
-
-void Lua::push(lua_Number n) {
- lua_pushnumber(L, n);
-}
-
-void Lua::push(const String & s) {
- lua_pushlstring(L, s.to_charp(), s.strlen());
-}
-
-void Lua::push(bool b) {
- lua_pushboolean(L, b);
-}
-
-void Lua::push(char * s, int size) {
- if (size < 0) {
- lua_pushstring(L, s);
- } else {
- lua_pushlstring(L, s, size);
- }
-}
-
-void Lua::push(void * p) {
- lua_pushlightuserdata(L, p);
-}
-
-void Lua::push(lua_CFunction f, int n) {
- lua_pushcclosure(L, f, n);
-}
-
-void Lua::pop(int n) {
- lua_pop(L, n);
-}
-
-void Lua::newtable() {
- lua_newtable(L);
-}
-
-void * Lua::newuser(size_t s) {
- return lua_newuserdata(L, s);
-}
-
-void Lua::settable(int i, bool raw) {
- if (raw) {
- lua_rawset(L, i);
- } else {
- lua_settable(L, i);
- }
-}
-
-void Lua::gettable(int i, bool raw) {
- if (raw) {
- lua_rawget(L, i);
- } else {
- lua_gettable(L, i);
- }
-}
-
-void Lua::setvar() {
- lua_settable(L, LUA_GLOBALSINDEX);
-}
-
-int Lua::gettop() {
- return lua_gettop(L);
-}
-
-void Lua::error(const String & msg) {
- push(msg);
- lua_error(L);
-}
-
-int Lua::type(int i) {
- return lua_type(L, i);
-}
-
-bool Lua::isnil(int i) {
- return lua_isnil(L, i);
-}
-
-bool Lua::isboolean(int i) {
- return lua_isboolean(L, i);
-}
-
-bool Lua::isnumber(int i) {
- return lua_isnumber(L, i);
-}
-
-bool Lua::isstring(int i) {
- return lua_isstring(L, i);
-}
-
-bool Lua::istable(int i) {
- return lua_istable(L, i);
-}
-
-bool Lua::isfunction(int i) {
- return lua_isfunction(L, i);
-}
-
-bool Lua::iscfunction(int i) {
- return lua_iscfunction(L, i);
-}
-
-bool Lua::isuserdata(int i) {
- return lua_isuserdata(L, i);
-}
-
-bool Lua::islightuserdata(int i) {
- return lua_islightuserdata(L, i);
-}
-
-bool Lua::toboolean(int i) {
- return lua_toboolean(L, i);
-}
-
-lua_Number Lua::tonumber(int i) {
- return lua_tonumber(L, i);
-}
-
-String Lua::tostring(int i) {
- if (isnil(i))
- return String();
- return String(lua_tostring(L, i));
-}
-
-lua_CFunction Lua::tocfunction(int i) {
- return lua_tocfunction(L, i);
-}
-
-void * Lua::touserdata(int i) {
- return lua_touserdata(L, i);
-}
-
-Lua * Lua::tothread(int i) {
- return find(lua_tothread(L, i));
-}
-
-struct LoadF {
- Handle * f;
- char buff[BUFFERSIZE];
-};
-
-const char * LuaStatics::getF(lua_State * L, void * ud, size_t * size) {
- LoadF *lf = (LoadF *)ud;
- (void)L;
-
- *size = lf->f->read(lf->buff, BUFFERSIZE);
- return (*size > 0) ? lf->buff : NULL;
-}
-
-struct DumpF {
- Handle * f;
-};
-
-int LuaStatics::putF(lua_State * L, const void * p, size_t size, void * ud) {
- DumpF *lf = (DumpF *)ud;
- (void)L;
-
- return lf->f->write(p, size) == size;
-}
-
-void Lua::load(Handle * h, bool docall) throw (GeneralException) {
- LoadF lf;
- int status;
-
- lf.f = h;
-
- status = lua_load(L, LuaStatics::getF, &lf, h->GetName().to_charp());
-
- if (status) {
- showerror();
- throw LuaException("Error loading lua chunk from Handle `" + h->GetName() + "'");
- }
-
- if (docall)
- call();
-}
-
-extern "C" void luacmain(lua_State * L, int stripping, lua_Chunkwriter w, void * uD);
-
-void Lua::dump(Handle * h, bool strip) {
- DumpF lf;
-
- lf.f = h;
-
- luacmain(L, strip, LuaStatics::putF, &lf);
-}
-
-Lua * Lua::thread() {
- return new Lua(lua_newthread(L));
-}
-
-int Lua::yield(int nargs) {
- return lua_yield(L, nargs);
-}
-
-int Lua::resume(int nresults) {
- return lua_resume(L, nresults);
-}
-
-Lua * Lua::find(lua_State * _L) throw (GeneralException) {
- std::map<lua_State *, Lua *>::iterator i;
-
- if ((i = lualist.find(_L)) == lualist.end()) {
- throw GeneralException("Unable to find the Lua object for this context");
- }
-
- return i->second;
-}
-
-void Lua::showerror() {
- int n = lua_gettop(L);
- int i;
- String t;
-
- printm(M_ERROR, "Lua object: Got an LUA error\n");
- printm(M_ERROR, "Inspecting LUA stack\n");
-
- if (n == 0) {
- printm(M_ERROR, "Stack empty\n");
- return;
- }
-
- for (i = 1; i <= n; i++) {
- switch(lua_type(L, i)) {
- case LUA_TNONE:
- t = "Invalid";
- break;
- case LUA_TNIL:
- t = "(Nil)";
- break;
- case LUA_TNUMBER:
- t.set("(Number) %f", lua_tonumber(L, i));
- break;
- case LUA_TBOOLEAN:
- t = String("(Bool) ") + (lua_toboolean(L, i) ? "true" : "false");
- break;
- case LUA_TSTRING:
- t = String("(String) ") + lua_tostring(L, i);
- break;
- case LUA_TTABLE:
- t = "(Table)";
- break;
- case LUA_TFUNCTION:
- t = "(Function)";
- break;
- default:
- t = "Unknown";
- }
-
- printm(M_ERROR, String(i) + ": " + t + "\n");
- }
-}
-
-int Lua::getmetatable(int i) {
- return lua_getmetatable(L, i);
-}
-
-int Lua::setmetatable(int i) {
- return lua_setmetatable(L, i);
-}
-
-int Lua::sethook(lua_Hook func, int mask, int count) {
- return lua_sethook(L, func, mask, count);
-}
-
-void Lua::do_break() {
- lua_break(L);
-}
-
-void LuaObject::push(Lua * L) throw (GeneralException) {
- if (pushed && wantdestruct) {
- throw GeneralException("Error: object is owned by the LUA script and can not be pushed.");
- }
- L->newtable();
- pushmembers(L);
- pushed = true;
-}
-
-void LuaObject::pushme(Lua * L, void * o, bool obj) {
- void ** u;
- bool * b;
- L->push("__obj");
- u = (void **) L->newuser(sizeof(o) + sizeof(bool));
- *u = o;
- b = (bool *) (u + 1);
- *b = obj;
- L->settable(-3, true);
-}
-
-void * LuaObject::getme(Lua * L, int i) {
- void ** r = 0;
-
- if (L->istable(i)) {
- L->push("__obj");
- L->gettable(i, true);
- if (!(r = (void **) L->touserdata()))
- L->error("Table is not an object.");
- if (!*r)
- L->error("Object already destroyed.");
- L->pop();
- } else if (L->isnil(i)) {
- r = 0;
- } else {
- L->error("Not an object (not even a table).");
- }
-
- return r ? *r : 0;
-}
-
-void LuaObject::pushit(Lua * L, const String & s, lua_CFunction f) {
- L->push(s);
- L->push(f);
- L->settable(-3, true);
-}
-
-void LuaObject::pushmeta(Lua * L, const String & s, lua_CFunction f) {
- if (!L->getmetatable()) {
- L->newtable();
- }
- L->push(s);
- L->push(f);
- L->settable();
- L->setmetatable();
-}
-
-int LuaStatics::collector(lua_State * _L) {
- Lua * L = Lua::find(_L);
- void ** u = (void **) L->touserdata();
- bool * obj = (bool *) (u + 1);
-// printm(M_INFO, "From LUA: collecting object\n");
- if (*obj) {
-// printm(M_INFO, "Is object at %p\n", *u);
- Base * b = (Base *) *u;
- delete b;
- } else {
-// printm(M_INFO, "Is struct at %p\n", *u);
- free(*u);
- }
- *u = 0;
- return 0;
-}
-
-int LuaStatics::destructor(lua_State * _L) {
- Lua * L = Lua::find(_L);
- Base * b = (Base *) LuaObject::getme(L);
- delete b;
- L->push("__obj");
- L->gettable(-2, true);
- void ** u = (void **) L->touserdata();
- bool * obj = (bool *) (u + 1);
- if (*obj) {
- Base * b = (Base *) *u;
- delete b;
- } else {
- free(*u);
- }
- *u = 0;
- L->pop();
- return 0;
-}
-
-void LuaObject::pushdestruct(Lua * L) throw (GeneralException) {
- if (pushed) {
- throw GeneralException("Error: can't push destructor, object already pushed");
- }
- push(L);
- L->push("__obj");
- L->gettable(-2, true);
- pushmeta(L, "__gc", LuaStatics::collector);
- L->pop();
- pushit(L, "destroy", LuaStatics::destructor);
-
- wantdestruct = true;
-}
-
-LuaException::LuaException(String fn) : GeneralException(fn) { }
-
-LuaException::LuaException() { }
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: BLua.cc,v 1.22 2004-11-27 21:46:04 pixel Exp $ */
+
+#include "BLua.h"
+#include <lualib.h>
+
+#ifndef BUFFERSIZE
+#define BUFFERSIZE 2048
+#endif
+
+
+
+extern "C" {
+ void do_lua_lock(lua_State * _L) {
+ Lua * L;
+ try {
+ L = Lua::find(_L);
+ } catch (GeneralException e) {
+ return;
+ }
+ L->lock();
+ }
+
+ void do_lua_unlock(lua_State * _L) {
+ Lua * L;
+ try {
+ L = Lua::find(_L);
+ } catch (GeneralException e) {
+ return;
+ }
+ L->unlock();
+ }
+}
+
+class LuaStatics : public Base {
+ public:
+ static const char * getF(lua_State *, void *, size_t *);
+ static int putF(lua_State *, const void *, size_t, void *);
+ static int luapanic(lua_State *);
+ static int trueluapanic(lua_State *) throw(GeneralException);
+ static int collector(lua_State *);
+ static int destructor(lua_State *);
+
+ static int andB(lua_State *);
+ static int orB(lua_State *);
+ static int xorB(lua_State *);
+ static int notB(lua_State *);
+ static int hex(lua_State *);
+ static int shl(lua_State *);
+ static int shr(lua_State *);
+};
+
+std::map<lua_State *, Lua *> Lua::lualist;
+
+int LuaStatics::luapanic(lua_State * L) {
+ return trueluapanic(L);
+}
+
+int LuaStatics::trueluapanic(lua_State * L) throw (GeneralException) {
+ Lua::find(L)->showerror();
+ throw LuaException("Error running Lua code, bailing out.");
+}
+
+int LuaStatics::andB(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Uint32 a, b;
+
+ if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
+ L->error("Incorrect arguments to function `andB'");
+ }
+
+ a = L->tonumber(1);
+ b = L->tonumber(2);
+
+ L->push((lua_Number) (a & b));
+
+ return 1;
+}
+
+int LuaStatics::orB(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Uint32 a, b;
+
+ if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
+ L->error("Incorrect arguments to function `orB'");
+ }
+
+ a = L->tonumber(1);
+ b = L->tonumber(2);
+
+ L->push((lua_Number) (a | b));
+
+ return 1;
+}
+
+int LuaStatics::xorB(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Uint32 a, b;
+
+ if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
+ L->error("Incorrect arguments to function `xorB'");
+ }
+
+ a = L->tonumber(1);
+ b = L->tonumber(2);
+
+ L->push((lua_Number) (a ^ b));
+
+ return 1;
+}
+
+int LuaStatics::notB(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Uint32 x;
+
+ if ((n != 1) && !L->isnumber()) {
+ L->error("Incorrect arguments to function `notB'");
+ }
+
+ x = L->tonumber();
+
+ L->push((lua_Number) (~x));
+
+ return 1;
+}
+
+int LuaStatics::shl(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Uint32 a, b;
+
+ if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) {
+ L->error("Incorrect arguments to function `shl'");
+ }
+
+ a = L->tonumber(1);
+ if (n == 2)
+ b = L->tonumber(2);
+ else
+ b = 1;
+
+ L->push((lua_Number) (a << b));
+
+ return 1;
+}
+
+int LuaStatics::shr(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Uint32 a, b;
+
+ if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) {
+ L->error("Incorrect arguments to function `shr'");
+ }
+
+ a = L->tonumber(1);
+ if (n == 2)
+ b = L->tonumber(2);
+ else
+ b = 1;
+
+ L->push((lua_Number) (a >> b));
+
+ return 1;
+}
+
+int LuaStatics::hex(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ int x;
+ String r;
+
+ if (((n != 1) || (n != 2)) && !L->isnumber(1) && ((n == 2) && !L->isstring(2))) {
+ L->error("Incorrect arguments to function `hex'");
+ }
+
+ x = L->tonumber(1);
+ String fmt = n == 2 ? L->tostring() : "%02x";
+ r.set(fmt.to_charp(), x);
+
+ L->push(r);
+
+ return 1;
+}
+
+Lua::Lua() : L(lua_open()) {
+ lua_atpanic(L, LuaStatics::luapanic);
+ lualist[L] = this;
+
+ declarefunc("andB", LuaStatics::andB);
+ declarefunc("orB", LuaStatics::orB);
+ declarefunc("xorB", LuaStatics::xorB);
+ declarefunc("notB", LuaStatics::notB);
+ declarefunc("shl", LuaStatics::shl);
+ declarefunc("shr", LuaStatics::shr);
+ declarefunc("hex", LuaStatics::hex);
+}
+
+Lua::Lua(lua_State * _L) : L(_L) {
+ lua_atpanic(L, LuaStatics::luapanic);
+ lualist[L] = this;
+}
+
+Lua::~Lua() {
+ lua_setgcthreshold(L, 0);
+ lua_close(L);
+}
+
+Lua::Lua(const Lua & l) throw (GeneralException) {
+ throw GeneralException("Error: can't duplicate a Lua object.");
+}
+
+void Lua::open_base() {
+ luaopen_base(L);
+ lua_pop(L, 1);
+}
+
+void Lua::open_table() {
+ luaopen_table(L);
+ lua_pop(L, 1);
+}
+
+void Lua::open_io() {
+ luaopen_io(L);
+ lua_pop(L, 1);
+}
+
+void Lua::open_string() {
+ luaopen_string(L);
+ lua_pop(L, 1);
+}
+
+void Lua::open_math() {
+ luaopen_math(L);
+ lua_pop(L, 1);
+}
+
+void Lua::open_debug() {
+ luaopen_debug(L);
+ lua_pop(L, 1);
+}
+
+void Lua::open_dir() {
+ luaopen_dir(L);
+ lua_pop(L, 1);
+}
+
+void Lua::declarefunc(const String & name, lua_CFunction f, int i) {
+ lua_pushstring(L, name.to_charp());
+ lua_pushcfunction(L, f);
+ lua_settable(L, i);
+}
+
+void Lua::call(const String & f, int i, int nargs, int nresults) {
+ lua_pushstring(L, f.to_charp());
+ lua_gettable(L, i);
+ lua_insert(L, -1 - nargs - nresults);
+ lua_call(L, nargs, nresults);
+}
+
+void Lua::call(int nargs, int nresults) {
+ lua_call(L, nargs, nresults);
+}
+
+void Lua::push() {
+ lua_pushnil(L);
+}
+
+void Lua::push(lua_Number n) {
+ lua_pushnumber(L, n);
+}
+
+void Lua::push(const String & s) {
+ lua_pushlstring(L, s.to_charp(), s.strlen());
+}
+
+void Lua::push(bool b) {
+ lua_pushboolean(L, b);
+}
+
+void Lua::push(char * s, int size) {
+ if (size < 0) {
+ lua_pushstring(L, s);
+ } else {
+ lua_pushlstring(L, s, size);
+ }
+}
+
+void Lua::push(void * p) {
+ lua_pushlightuserdata(L, p);
+}
+
+void Lua::push(lua_CFunction f, int n) {
+ lua_pushcclosure(L, f, n);
+}
+
+void Lua::pop(int n) {
+ lua_pop(L, n);
+}
+
+void Lua::newtable() {
+ lua_newtable(L);
+}
+
+void * Lua::newuser(size_t s) {
+ return lua_newuserdata(L, s);
+}
+
+void Lua::settable(int i, bool raw) {
+ if (raw) {
+ lua_rawset(L, i);
+ } else {
+ lua_settable(L, i);
+ }
+}
+
+void Lua::gettable(int i, bool raw) {
+ if (raw) {
+ lua_rawget(L, i);
+ } else {
+ lua_gettable(L, i);
+ }
+}
+
+void Lua::setvar() {
+ lua_settable(L, LUA_GLOBALSINDEX);
+}
+
+int Lua::gettop() {
+ return lua_gettop(L);
+}
+
+void Lua::error(const String & msg) {
+ push(msg);
+ lua_error(L);
+}
+
+int Lua::type(int i) {
+ return lua_type(L, i);
+}
+
+bool Lua::isnil(int i) {
+ return lua_isnil(L, i);
+}
+
+bool Lua::isboolean(int i) {
+ return lua_isboolean(L, i);
+}
+
+bool Lua::isnumber(int i) {
+ return lua_isnumber(L, i);
+}
+
+bool Lua::isstring(int i) {
+ return lua_isstring(L, i);
+}
+
+bool Lua::istable(int i) {
+ return lua_istable(L, i);
+}
+
+bool Lua::isfunction(int i) {
+ return lua_isfunction(L, i);
+}
+
+bool Lua::iscfunction(int i) {
+ return lua_iscfunction(L, i);
+}
+
+bool Lua::isuserdata(int i) {
+ return lua_isuserdata(L, i);
+}
+
+bool Lua::islightuserdata(int i) {
+ return lua_islightuserdata(L, i);
+}
+
+bool Lua::toboolean(int i) {
+ return lua_toboolean(L, i);
+}
+
+lua_Number Lua::tonumber(int i) {
+ return lua_tonumber(L, i);
+}
+
+String Lua::tostring(int i) {
+ if (isnil(i))
+ return String();
+ return String(lua_tostring(L, i));
+}
+
+lua_CFunction Lua::tocfunction(int i) {
+ return lua_tocfunction(L, i);
+}
+
+void * Lua::touserdata(int i) {
+ return lua_touserdata(L, i);
+}
+
+Lua * Lua::tothread(int i) {
+ return find(lua_tothread(L, i));
+}
+
+struct LoadF {
+ Handle * f;
+ char buff[BUFFERSIZE];
+};
+
+const char * LuaStatics::getF(lua_State * L, void * ud, size_t * size) {
+ LoadF *lf = (LoadF *)ud;
+ (void)L;
+
+ *size = lf->f->read(lf->buff, BUFFERSIZE);
+ return (*size > 0) ? lf->buff : NULL;
+}
+
+struct DumpF {
+ Handle * f;
+};
+
+int LuaStatics::putF(lua_State * L, const void * p, size_t size, void * ud) {
+ DumpF *lf = (DumpF *)ud;
+ (void)L;
+
+ return lf->f->write(p, size) == size;
+}
+
+void Lua::load(Handle * h, bool docall) throw (GeneralException) {
+ LoadF lf;
+ int status;
+
+ lf.f = h;
+
+ status = lua_load(L, LuaStatics::getF, &lf, h->GetName().to_charp());
+
+ if (status) {
+ showerror();
+ throw LuaException("Error loading lua chunk from Handle `" + h->GetName() + "'");
+ }
+
+ if (docall)
+ call();
+}
+
+extern "C" void luacmain(lua_State * L, int stripping, lua_Chunkwriter w, void * uD);
+
+void Lua::dump(Handle * h, bool strip) {
+ DumpF lf;
+
+ lf.f = h;
+
+ luacmain(L, strip, LuaStatics::putF, &lf);
+}
+
+Lua * Lua::thread() {
+ return new Lua(lua_newthread(L));
+}
+
+int Lua::yield(int nargs) {
+ return lua_yield(L, nargs);
+}
+
+int Lua::resume(int nresults) {
+ return lua_resume(L, nresults);
+}
+
+Lua * Lua::find(lua_State * _L) throw (GeneralException) {
+ std::map<lua_State *, Lua *>::iterator i;
+
+ if ((i = lualist.find(_L)) == lualist.end()) {
+ throw GeneralException("Unable to find the Lua object for this context");
+ }
+
+ return i->second;
+}
+
+void Lua::showerror() {
+ int n = lua_gettop(L);
+ int i;
+ String t;
+
+ printm(M_ERROR, "Lua object: Got an LUA error\n");
+ printm(M_ERROR, "Inspecting LUA stack\n");
+
+ if (n == 0) {
+ printm(M_ERROR, "Stack empty\n");
+ return;
+ }
+
+ for (i = 1; i <= n; i++) {
+ switch(lua_type(L, i)) {
+ case LUA_TNONE:
+ t = "Invalid";
+ break;
+ case LUA_TNIL:
+ t = "(Nil)";
+ break;
+ case LUA_TNUMBER:
+ t.set("(Number) %f", lua_tonumber(L, i));
+ break;
+ case LUA_TBOOLEAN:
+ t = String("(Bool) ") + (lua_toboolean(L, i) ? "true" : "false");
+ break;
+ case LUA_TSTRING:
+ t = String("(String) ") + lua_tostring(L, i);
+ break;
+ case LUA_TTABLE:
+ t = "(Table)";
+ break;
+ case LUA_TFUNCTION:
+ t = "(Function)";
+ break;
+ default:
+ t = "Unknown";
+ }
+
+ printm(M_ERROR, String(i) + ": " + t + "\n");
+ }
+}
+
+int Lua::getmetatable(int i) {
+ return lua_getmetatable(L, i);
+}
+
+int Lua::setmetatable(int i) {
+ return lua_setmetatable(L, i);
+}
+
+int Lua::sethook(lua_Hook func, int mask, int count) {
+ return lua_sethook(L, func, mask, count);
+}
+
+void Lua::do_break() {
+ lua_break(L);
+}
+
+void LuaObject::push(Lua * L) throw (GeneralException) {
+ if (pushed && wantdestruct) {
+ throw GeneralException("Error: object is owned by the LUA script and can not be pushed.");
+ }
+ L->newtable();
+ pushmembers(L);
+ pushed = true;
+}
+
+void LuaObject::pushme(Lua * L, void * o, bool obj) {
+ void ** u;
+ bool * b;
+ L->push("__obj");
+ u = (void **) L->newuser(sizeof(o) + sizeof(bool));
+ *u = o;
+ b = (bool *) (u + 1);
+ *b = obj;
+ L->settable(-3, true);
+}
+
+void * LuaObject::getme(Lua * L, int i) {
+ void ** r = 0;
+
+ if (L->istable(i)) {
+ L->push("__obj");
+ L->gettable(i, true);
+ if (!(r = (void **) L->touserdata()))
+ L->error("Table is not an object.");
+ if (!*r)
+ L->error("Object already destroyed.");
+ L->pop();
+ } else if (L->isnil(i)) {
+ r = 0;
+ } else {
+ L->error("Not an object (not even a table).");
+ }
+
+ return r ? *r : 0;
+}
+
+void LuaObject::pushit(Lua * L, const String & s, lua_CFunction f) {
+ L->push(s);
+ L->push(f);
+ L->settable(-3, true);
+}
+
+void LuaObject::pushmeta(Lua * L, const String & s, lua_CFunction f) {
+ if (!L->getmetatable()) {
+ L->newtable();
+ }
+ L->push(s);
+ L->push(f);
+ L->settable();
+ L->setmetatable();
+}
+
+int LuaStatics::collector(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ void ** u = (void **) L->touserdata();
+ bool * obj = (bool *) (u + 1);
+// printm(M_INFO, "From LUA: collecting object\n");
+ if (*obj) {
+// printm(M_INFO, "Is object at %p\n", *u);
+ Base * b = (Base *) *u;
+ delete b;
+ } else {
+// printm(M_INFO, "Is struct at %p\n", *u);
+ free(*u);
+ }
+ *u = 0;
+ return 0;
+}
+
+int LuaStatics::destructor(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ Base * b = (Base *) LuaObject::getme(L);
+ delete b;
+ L->push("__obj");
+ L->gettable(-2, true);
+ void ** u = (void **) L->touserdata();
+ bool * obj = (bool *) (u + 1);
+ if (*obj) {
+ Base * b = (Base *) *u;
+ delete b;
+ } else {
+ free(*u);
+ }
+ *u = 0;
+ L->pop();
+ return 0;
+}
+
+void LuaObject::pushdestruct(Lua * L) throw (GeneralException) {
+ if (pushed) {
+ throw GeneralException("Error: can't push destructor, object already pushed");
+ }
+ push(L);
+ L->push("__obj");
+ L->gettable(-2, true);
+ pushmeta(L, "__gc", LuaStatics::collector);
+ L->pop();
+ pushit(L, "destroy", LuaStatics::destructor);
+
+ wantdestruct = true;
+}
+
+LuaException::LuaException(String fn) : GeneralException(fn) { }
+
+LuaException::LuaException() { }
diff --git a/lib/Buffer.cc b/lib/Buffer.cc
index d3e836c..9d2f66a 100644
--- a/lib/Buffer.cc
+++ b/lib/Buffer.cc
@@ -1,208 +1,208 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: Buffer.cc,v 1.24 2004-11-27 21:35:19 pixel Exp $ */
-
-#include <string.h>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "Buffer.h"
-#include "generic.h"
-
-Buffer::Buffer(bool _seekable) : Handle(-1), buffer(0), zero(0), realsiz(0), bufsiz(0), ptr(0), wptr(0), seekable(_seekable) { }
-
-Buffer::~Buffer() {
- free(buffer);
-}
-
-Buffer::Buffer(const Buffer & b) : Handle(-1), buffer(0), zero(b.zero), realsiz(b.realsiz), bufsiz(b.bufsiz), ptr(b.ptr), wptr(b.wptr), seekable(b.seekable) {
- buffer = (Byte *) malloc(bufsiz);
- memcpy(buffer, b.buffer, bufsiz);
-}
-
-ssize_t Buffer::write(const void *buf, size_t count) throw (GeneralException) {
- if (!count) {
- return 0;
- }
- if (count + wptr > bufsiz) {
- int numblocks = (count + wptr) / realloc_threshold;
- int remains = (count + wptr) % realloc_threshold;
- buffer = (Byte *) realloc(buffer, bufsiz = ((numblocks + (remains ? 1 : 0)) * realloc_threshold));
- }
- memcpy(buffer + wptr, buf, count);
- wptr += count;
-
- if (wptr > realsiz) {
- realsiz = wptr;
- }
-
- return count;
-}
-
-ssize_t Buffer::read(void *buf, size_t count) throw (GeneralException) {
- count = MIN(count, realsiz - ptr);
-
- if (!count) {
- return 0;
- }
-
- memcpy(buf, buffer + ptr, count);
- ptr += count;
-
- if (!seekable) {
- if (ptr >= realloc_threshold) {
- int numblocks = (bufsiz / realloc_threshold) - (ptr / realloc_threshold);
- memmove(buffer, buffer + (bufsiz - numblocks * realloc_threshold), numblocks * realloc_threshold);
- ptr -= (bufsiz - numblocks * realloc_threshold);
- wptr -= (bufsiz - numblocks * realloc_threshold);
- realsiz -= (bufsiz - numblocks * realloc_threshold);
- buffer = (Byte *) realloc(buffer, bufsiz = (numblocks * realloc_threshold));
- }
- }
-
- return count;
-}
-
-bool Buffer::CanRead() const {
- return true;
-}
-
-bool Buffer::CanWrite() const {
- return true;
-}
-
-String Buffer::GetName() const {
- if (seekable)
- return "Buffer";
- else
- return "Fifo";
-}
-
-Buffer Buffer::operator=(const Buffer & b) {
- if (b.buffer != buffer) {
- free(buffer);
- realsiz = b.realsiz;
- ptr = b.ptr;
- wptr = b.wptr;
- seekable = b.seekable;
- if ((bufsiz = b.bufsiz)) {
- buffer = (Byte *) malloc(bufsiz);
- memcpy(buffer, b.buffer, realsiz);
- } else {
- buffer = 0;
- }
- }
- return *this;
-}
-
-bool Buffer::CanWatch() const {
- return false;
-}
-
-ssize_t Buffer::GetSize() const {
- return realsiz;
-}
-
-Byte Buffer::operator[](size_t p) const {
- if (p >= realsiz) {
- return 0;
- } else {
- if (seekable) {
- return buffer[p];
- } else {
- return buffer[ptr + p];
- }
- }
-}
-
-Byte & Buffer::operator[](size_t p) {
- p++;
- if (p > bufsiz) {
- int numblocks = p / realloc_threshold;
- int remains = p % realloc_threshold;
- buffer = (Byte *) realloc(buffer, bufsiz = ((numblocks + (remains ? 1 : 0)) * realloc_threshold));
- }
- if (p > realsiz) {
- memset(buffer + realsiz, 0, p - realsiz);
- realsiz = p;
- }
- p--;
-
- if (seekable) {
- return buffer[p];
- } else {
- return buffer[ptr + p];
- }
-}
-
-bool Buffer::CanSeek() const {
- return seekable;
-}
-
-off_t Buffer::seek(off_t off, int wheel) throw (GeneralException) {
- if (!seekable) {
- throw GeneralException("This buffer is a fifo, thus is not seekable");
- }
- switch (wheel) {
- case SEEK_SET:
- ptr = off;
- break;
- case SEEK_CUR:
- ptr += off;
- break;
- case SEEK_END:
- ptr = realsiz + off;
- break;
- }
- operator[](ptr);
- return ptr;
-}
-
-off_t Buffer::tell() const {
- return ptr;
-}
-
-off_t Buffer::wseek(off_t off, int wheel) throw (GeneralException) {
- if (!seekable) {
- throw GeneralException("This buffer is a fifo, thus is not seekable");
- }
- switch (wheel) {
- case SEEK_SET:
- wptr = off;
- break;
- case SEEK_CUR:
- wptr += off;
- break;
- case SEEK_END:
- wptr = realsiz + off;
- break;
- }
- operator[](wptr);
- return wptr;
-}
-
-off_t Buffer::wtell() const {
- return wptr;
-}
-
-void Buffer::reset() {
- free(buffer);
- realsiz = bufsiz = ptr = wptr = 0;
-}
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: Buffer.cc,v 1.25 2004-11-27 21:46:04 pixel Exp $ */
+
+#include <string.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "Buffer.h"
+#include "generic.h"
+
+Buffer::Buffer(bool _seekable) : Handle(-1), buffer(0), zero(0), realsiz(0), bufsiz(0), ptr(0), wptr(0), seekable(_seekable) { }
+
+Buffer::~Buffer() {
+ free(buffer);
+}
+
+Buffer::Buffer(const Buffer & b) : Handle(-1), buffer(0), zero(b.zero), realsiz(b.realsiz), bufsiz(b.bufsiz), ptr(b.ptr), wptr(b.wptr), seekable(b.seekable) {
+ buffer = (Byte *) malloc(bufsiz);
+ memcpy(buffer, b.buffer, bufsiz);
+}
+
+ssize_t Buffer::write(const void *buf, size_t count) throw (GeneralException) {
+ if (!count) {
+ return 0;
+ }
+ if (count + wptr > bufsiz) {
+ int numblocks = (count + wptr) / realloc_threshold;
+ int remains = (count + wptr) % realloc_threshold;
+ buffer = (Byte *) realloc(buffer, bufsiz = ((numblocks + (remains ? 1 : 0)) * realloc_threshold));
+ }
+ memcpy(buffer + wptr, buf, count);
+ wptr += count;
+
+ if (wptr > realsiz) {
+ realsiz = wptr;
+ }
+
+ return count;
+}
+
+ssize_t Buffer::read(void *buf, size_t count) throw (GeneralException) {
+ count = MIN(count, realsiz - ptr);
+
+ if (!count) {
+ return 0;
+ }
+
+ memcpy(buf, buffer + ptr, count);
+ ptr += count;
+
+ if (!seekable) {
+ if (ptr >= realloc_threshold) {
+ int numblocks = (bufsiz / realloc_threshold) - (ptr / realloc_threshold);
+ memmove(buffer, buffer + (bufsiz - numblocks * realloc_threshold), numblocks * realloc_threshold);
+ ptr -= (bufsiz - numblocks * realloc_threshold);
+ wptr -= (bufsiz - numblocks * realloc_threshold);
+ realsiz -= (bufsiz - numblocks * realloc_threshold);
+ buffer = (Byte *) realloc(buffer, bufsiz = (numblocks * realloc_threshold));
+ }
+ }
+
+ return count;
+}
+
+bool Buffer::CanRead() const {
+ return true;
+}
+
+bool Buffer::CanWrite() const {
+ return true;
+}
+
+String Buffer::GetName() const {
+ if (seekable)
+ return "Buffer";
+ else
+ return "Fifo";
+}
+
+Buffer Buffer::operator=(const Buffer & b) {
+ if (b.buffer != buffer) {
+ free(buffer);
+ realsiz = b.realsiz;
+ ptr = b.ptr;
+ wptr = b.wptr;
+ seekable = b.seekable;
+ if ((bufsiz = b.bufsiz)) {
+ buffer = (Byte *) malloc(bufsiz);
+ memcpy(buffer, b.buffer, realsiz);
+ } else {
+ buffer = 0;
+ }
+ }
+ return *this;
+}
+
+bool Buffer::CanWatch() const {
+ return false;
+}
+
+ssize_t Buffer::GetSize() const {
+ return realsiz;
+}
+
+Byte Buffer::operator[](size_t p) const {
+ if (p >= realsiz) {
+ return 0;
+ } else {
+ if (seekable) {
+ return buffer[p];
+ } else {
+ return buffer[ptr + p];
+ }
+ }
+}
+
+Byte & Buffer::operator[](size_t p) {
+ p++;
+ if (p > bufsiz) {
+ int numblocks = p / realloc_threshold;
+ int remains = p % realloc_threshold;
+ buffer = (Byte *) realloc(buffer, bufsiz = ((numblocks + (remains ? 1 : 0)) * realloc_threshold));
+ }
+ if (p > realsiz) {
+ memset(buffer + realsiz, 0, p - realsiz);
+ realsiz = p;
+ }
+ p--;
+
+ if (seekable) {
+ return buffer[p];
+ } else {
+ return buffer[ptr + p];
+ }
+}
+
+bool Buffer::CanSeek() const {
+ return seekable;
+}
+
+off_t Buffer::seek(off_t off, int wheel) throw (GeneralException) {
+ if (!seekable) {
+ throw GeneralException("This buffer is a fifo, thus is not seekable");
+ }
+ switch (wheel) {
+ case SEEK_SET:
+ ptr = off;
+ break;
+ case SEEK_CUR:
+ ptr += off;
+ break;
+ case SEEK_END:
+ ptr = realsiz + off;
+ break;
+ }
+ operator[](ptr);
+ return ptr;
+}
+
+off_t Buffer::tell() const {
+ return ptr;
+}
+
+off_t Buffer::wseek(off_t off, int wheel) throw (GeneralException) {
+ if (!seekable) {
+ throw GeneralException("This buffer is a fifo, thus is not seekable");
+ }
+ switch (wheel) {
+ case SEEK_SET:
+ wptr = off;
+ break;
+ case SEEK_CUR:
+ wptr += off;
+ break;
+ case SEEK_END:
+ wptr = realsiz + off;
+ break;
+ }
+ operator[](wptr);
+ return wptr;
+}
+
+off_t Buffer::wtell() const {
+ return wptr;
+}
+
+void Buffer::reset() {
+ free(buffer);
+ realsiz = bufsiz = ptr = wptr = 0;
+}
diff --git a/lib/ConfigFile.cc b/lib/ConfigFile.cc
index c765fae..85cbb00 100644
--- a/lib/ConfigFile.cc
+++ b/lib/ConfigFile.cc
@@ -1,43 +1,43 @@
-#include "ConfigFile.h"
-#include "Regex.h"
-
-ConfigFile::ConfigFile(Handle * f) throw (GeneralException) {
- Regex r("^\\[.*\\]$"), comment("^#.*$"), empty("^ *$"), line("^.*=.*$");
- bool started = false;
- String s, section, key, value;
- ConfigSectionContents contents;
- int pos;
-
- while (!f->IsClosed()) {
- (*f) >> s;
- if (comment.Match(s) || empty.Match(s))
- continue;
- if (r.Match(s)) {
- if (!started) {
- started = true;
- } else {
- c[section] = contents;
- contents.clear();
- }
- section = s.extract(1, s.strlen() - 2);
- continue;
- }
- if (line.Match(s)) {
- if (!started) {
- throw GeneralException("Config file must begin with a section");
- }
- pos = s.strchr('=');
- key = s.extract(0, pos - 1).trim();
- value = s.extract(pos + 1).trim();
- contents[key] = value;
- continue;
- }
- throw GeneralException("Invalid line: " + s);
- }
-
- c[section] = contents;
-}
-
-ConfigSectionContents & ConfigFile::operator[](String s) {
- return c[s];
-}
+#include "ConfigFile.h"
+#include "Regex.h"
+
+ConfigFile::ConfigFile(Handle * f) throw (GeneralException) {
+ Regex r("^\\[.*\\]$"), comment("^#.*$"), empty("^ *$"), line("^.*=.*$");
+ bool started = false;
+ String s, section, key, value;
+ ConfigSectionContents contents;
+ int pos;
+
+ while (!f->IsClosed()) {
+ (*f) >> s;
+ if (comment.Match(s) || empty.Match(s))
+ continue;
+ if (r.Match(s)) {
+ if (!started) {
+ started = true;
+ } else {
+ c[section] = contents;
+ contents.clear();
+ }
+ section = s.extract(1, s.strlen() - 2);
+ continue;
+ }
+ if (line.Match(s)) {
+ if (!started) {
+ throw GeneralException("Config file must begin with a section");
+ }
+ pos = s.strchr('=');
+ key = s.extract(0, pos - 1).trim();
+ value = s.extract(pos + 1).trim();
+ contents[key] = value;
+ continue;
+ }
+ throw GeneralException("Invalid line: " + s);
+ }
+
+ c[section] = contents;
+}
+
+ConfigSectionContents & ConfigFile::operator[](String s) {
+ return c[s];
+}
diff --git a/lib/Confirm.cc b/lib/Confirm.cc
index b3db8f3..18e56e6 100644
--- a/lib/Confirm.cc
+++ b/lib/Confirm.cc
@@ -1,35 +1,35 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "HttpServ.h"
-#include "Confirm.h"
-#include "Buffer.h"
-#include "CopyJob.h"
-
-Confirm::Confirm(const String & t, const String & m, const String & U, Action * y, Action * n) :
- Action(U), tit(t), msg(m), NYes(y), NNo(n) { }
-
-Task * Confirm::Do(Variables * v, Variables *, Handle * h) {
- Handle * b = new Buffer;
- Task * t = new CopyJob(b, h, -1, true);
- SendHead(b);
- (*b) << msg << "<CENTER><TABLE BORDER=0><tr><td>" << endnl <<
- "<FORM METHOD=\"POST\" ACTION=\"/bin/" << (NYes ? NYes->GetURL() : "start") << "\">" << endnl <<
- "<INPUT TYPE=\"HIDDEN\" VALUE=\"yes\" NAME=\"confirm\">" << endnl <<
- "<INPUT TYPE=\"SUBMIT\" VALUE=\" Oui \">" << endnl;
- v->Dump(b);
- (*b) << "</FORM></td><td>" << endnl <<
- "<FORM METHOD=\"POST\" ACTION=\"/bin/" << (NNo ? NNo->GetURL() : "start") << "\">" << endnl <<
- "<INPUT TYPE=\"HIDDEN\" VALUE=\"no\" NAME=\"confirm\">" << endnl <<
- "<INPUT TYPE=\"SUBMIT\" VALUE=\" Non \">" << endnl;
- v->Dump(b);
- (*b) << "</FORM></td></tr></TABLE></CENTER>" << endnl;
- SendFoot(b);
- Accessed();
-
- return t;
-}
-
-String Confirm::GetTitle(void) {
- return tit;
-}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "HttpServ.h"
+#include "Confirm.h"
+#include "Buffer.h"
+#include "CopyJob.h"
+
+Confirm::Confirm(const String & t, const String & m, const String & U, Action * y, Action * n) :
+ Action(U), tit(t), msg(m), NYes(y), NNo(n) { }
+
+Task * Confirm::Do(Variables * v, Variables *, Handle * h) {
+ Handle * b = new Buffer;
+ Task * t = new CopyJob(b, h, -1, true);
+ SendHead(b);
+ (*b) << msg << "<CENTER><TABLE BORDER=0><tr><td>" << endnl <<
+ "<FORM METHOD=\"POST\" ACTION=\"/bin/" << (NYes ? NYes->GetURL() : "start") << "\">" << endnl <<
+ "<INPUT TYPE=\"HIDDEN\" VALUE=\"yes\" NAME=\"confirm\">" << endnl <<
+ "<INPUT TYPE=\"SUBMIT\" VALUE=\" Oui \">" << endnl;
+ v->Dump(b);
+ (*b) << "</FORM></td><td>" << endnl <<
+ "<FORM METHOD=\"POST\" ACTION=\"/bin/" << (NNo ? NNo->GetURL() : "start") << "\">" << endnl <<
+ "<INPUT TYPE=\"HIDDEN\" VALUE=\"no\" NAME=\"confirm\">" << endnl <<
+ "<INPUT TYPE=\"SUBMIT\" VALUE=\" Non \">" << endnl;
+ v->Dump(b);
+ (*b) << "</FORM></td></tr></TABLE></CENTER>" << endnl;
+ SendFoot(b);
+ Accessed();
+
+ return t;
+}
+
+String Confirm::GetTitle(void) {
+ return tit;
+}
diff --git a/lib/CopyJob.cc b/lib/CopyJob.cc
index 29c662d..fc2a0ca 100644
--- a/lib/CopyJob.cc
+++ b/lib/CopyJob.cc
@@ -1,84 +1,84 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "CopyJob.h"
-#include "gettext.h"
-
-CopyJob::CopyJob(Handle * as, Handle * ad, ssize_t asiz, bool ads, bool add, int ashape) : s(as), d(ad), ds(ads), dd(add), siz(asiz), cursiz(0), r(0), w(0), tw(0), shape(ashape) {
- struct timezone tz;
-
- s->SetNonBlock();
- d->SetNonBlock();
- WaitFor(s, W4_READING);
-
- if (shape > 0) {
- gettimeofday(&start, &tz);
- }
-}
-
-CopyJob::~CopyJob() {
- if (ds) {
- delete s;
- }
-
- if (dd) {
- delete d;
- }
-}
-
-int CopyJob::Do() throw (GeneralException) {
- int tr;
- struct timeval now;
- struct timezone tz;
-
- if (shape > 0) {
- gettimeofday(&now, &tz);
- }
-
- switch (current) {
- case 0:
- tr = siz >= 0 ? siz - cursiz : COPY_BUFSIZ;
- try {
- r = s->read(buffer, MIN(COPY_BUFSIZ, tr));
-// cerr << "CopyJob: read " << r << " bytes." << endl;
- }
- catch (IOAgain e) {
- WaitFor(s, W4_READING);
- Suspend(TASK_ON_HOLD);
- }
- if (!r) {
- return TASK_DONE;
- }
- tw = 0;
- case 1:
- current = 1;
- try {
- w = d->write(buffer + tw, r - tw);
- }
- catch (IOAgain e) {
- WaitFor(d, W4_WRITING);
- Suspend(TASK_ON_HOLD);
- }
-// cerr << "CopyJob: wrote " << w << " bytes." << endl;
- tw += w;
- if (r != tw) {
-// cerr << "CopyJob: We did expect to write a total of " << r << " bytes and we achieved " << tw << " bytes so far.\n";
- WaitFor(d, W4_WRITING);
- Suspend(TASK_ON_HOLD);
- }
- current = 0;
- }
- cursiz += r;
-
- if (!s->IsClosed() && (siz != cursiz)) {
- WaitFor(s, W4_READING);
- Suspend(TASK_ON_HOLD);
- }
-
- return TASK_DONE;
-}
-
-String CopyJob::GetName() {
- return (String(_("CopyJob from ")) + s->GetName() + _(" to ") + d->GetName());
-}
-
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "CopyJob.h"
+#include "gettext.h"
+
+CopyJob::CopyJob(Handle * as, Handle * ad, ssize_t asiz, bool ads, bool add, int ashape) : s(as), d(ad), ds(ads), dd(add), siz(asiz), cursiz(0), r(0), w(0), tw(0), shape(ashape) {
+ struct timezone tz;
+
+ s->SetNonBlock();
+ d->SetNonBlock();
+ WaitFor(s, W4_READING);
+
+ if (shape > 0) {
+ gettimeofday(&start, &tz);
+ }
+}
+
+CopyJob::~CopyJob() {
+ if (ds) {
+ delete s;
+ }
+
+ if (dd) {
+ delete d;
+ }
+}
+
+int CopyJob::Do() throw (GeneralException) {
+ int tr;
+ struct timeval now;
+ struct timezone tz;
+
+ if (shape > 0) {
+ gettimeofday(&now, &tz);
+ }
+
+ switch (current) {
+ case 0:
+ tr = siz >= 0 ? siz - cursiz : COPY_BUFSIZ;
+ try {
+ r = s->read(buffer, MIN(COPY_BUFSIZ, tr));
+// cerr << "CopyJob: read " << r << " bytes." << endl;
+ }
+ catch (IOAgain e) {
+ WaitFor(s, W4_READING);
+ Suspend(TASK_ON_HOLD);
+ }
+ if (!r) {
+ return TASK_DONE;
+ }
+ tw = 0;
+ case 1:
+ current = 1;
+ try {
+ w = d->write(buffer + tw, r - tw);
+ }
+ catch (IOAgain e) {
+ WaitFor(d, W4_WRITING);
+ Suspend(TASK_ON_HOLD);
+ }
+// cerr << "CopyJob: wrote " << w << " bytes." << endl;
+ tw += w;
+ if (r != tw) {
+// cerr << "CopyJob: We did expect to write a total of " << r << " bytes and we achieved " << tw << " bytes so far.\n";
+ WaitFor(d, W4_WRITING);
+ Suspend(TASK_ON_HOLD);
+ }
+ current = 0;
+ }
+ cursiz += r;
+
+ if (!s->IsClosed() && (siz != cursiz)) {
+ WaitFor(s, W4_READING);
+ Suspend(TASK_ON_HOLD);
+ }
+
+ return TASK_DONE;
+}
+
+String CopyJob::GetName() {
+ return (String(_("CopyJob from ")) + s->GetName() + _(" to ") + d->GetName());
+}
+
diff --git a/lib/Exceptions.cc b/lib/Exceptions.cc
index 0925b21..2633902 100644
--- a/lib/Exceptions.cc
+++ b/lib/Exceptions.cc
@@ -1,275 +1,275 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: Exceptions.cc,v 1.34 2004-11-27 21:35:19 pixel Exp $ */
-
-#include <string.h>
-#include <errno.h>
-#include <stddef.h>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-#else
-#ifndef __APPLE__
-#include <malloc.h>
-#endif
-#endif
-#ifdef DEBUG
-#include <iostream>
-#endif
-#ifdef HAVE_PIPE
-#include <unistd.h>
-#endif
-#include "BString.h"
-#include "Exceptions.h"
-#include "generic.h"
-#include "gettext.h"
-
-char GeneralException::t[BUFSIZ];
-
-std::vector<String> Base::context;
-
-GeneralException::GeneralException(String emsg) : msg(emsg.strdup()) {
- UNLOCK;
-#ifdef DEBUG
- printm(M_BARE, String(_("Generating a General Exception error: '")) + msg + "'.\n");
-#endif
-}
-GeneralException::GeneralException() : msg(0) {
- UNLOCK;
-#ifdef DEBUG
- printm(M_BARE, String(_("Generating a General Exception error: '")) + msg + "'.\n");
-#endif
-}
-GeneralException::GeneralException(const GeneralException & e) : msg(strdup(e.msg)) {
- UNLOCK;
-#ifdef DEBUG
- printm(M_BARE, String(_("Generating a General Exception error: '")) + msg + "'.\n");
-#endif
-}
-
-GeneralException::~GeneralException() {
- free(msg);
-}
-
-TaskNotFound::TaskNotFound() : GeneralException(_("Task not found")) { }
-
-const char * GeneralException::GetMsg() const {
- return msg;
-}
-
-MemoryException::MemoryException(ssize_t s) {
- sprintf(t, _("Failed allocating %u bytes."), s);
- msg = strdup(t);
-}
-
-IOException::IOException(String fn, op_t op, ssize_t s) {
- sprintf(t, _("An error has occured while %s %u bytes on %s: %s"), op == IO_WRITE ? _("writing") : _("reading"),
- s, fn.to_charp(), strerror(errno));
- msg = strdup(t);
-}
-
-IOGeneral::IOGeneral(String fn) : GeneralException(fn) { }
-
-IOGeneral::IOGeneral() { }
-
-IOAgain::IOAgain() : IOGeneral(_("No more bytes for reading or writing.")) {
-#ifdef DEBUG
- printm(M_BARE, String(_("Generating an IOAgain exception: '")) + GetMsg() + "'.\n");
-#endif
-}
-
-TaskSwitch::TaskSwitch() : GeneralException(_("Switching task in a non-tasked environnement")) {
-#ifdef DEBUG
- printm(M_BARE, String(_("Generating a TaskSwitch exception: '")) + GetMsg() + "'.\n");
-#endif
-}
-
-Exit::Exit(int a_code) : GeneralException(_("Exitting with code " + a_code)), code(a_code) {
-#ifdef DEBUG
- printm(M_BARE, String(_("Generating an Exit exception: '")) + GetMsg() + "'.\n");
-#endif
-}
-
-int Exit::GetCode() {
- return code;
-}
-
-char * xstrdup(const char * s) {
- char * r;
-
- r = (char *) xmalloc(strlen(s) + 1);
- strcpy(r, s);
- return r;
-}
-
-void * xmalloc(size_t s) throw (GeneralException) {
- char * r;
-
- if (s == 0) {
- return 0;
- }
-
- if (!(r = (char *) ::malloc(s))) {
- throw MemoryException(s);
- }
-#ifdef DEBUG
-// Base::printm(M_BARE, String(_("Allocating %i bytes of memory, got it at %p\n")), s, r);
-#endif
-
- memset(r, 0, s);
-
- return (void *)(r);
-}
-
-void * xrealloc(void * ptr, size_t s) {
-#ifdef DEBUG
- void * r = realloc(ptr, s);
- Base::printm(M_BARE, String(_("Reallocating pointer at %p for %i bytes, now at %p\n")), ptr, s, r);
- return r;
-#else
- return realloc(ptr, s);
-#endif
-}
-
-void xfree(unsigned char *& p) {
-#ifdef DEBUG
-// Base::printm(M_BARE, String(_("Freeing pointer at %p\n")), p);
-#endif
- if (p) {
- ::free(p);
- p = 0;
- }
-}
-
-#ifdef HAVE_PIPE
-int xpipe(int * p, int flag) throw (GeneralException) {
- if (pipe(p)) {
- throw GeneralException(String(_("Error creating pipe: ")) + strerror(errno));
- }
-
- return p[flag];
-}
-#else
-int xpipe(int *, int) throw (GeneralException) {
- throw GeneralException(_("Function pipe() not supported by this system.\n"));
-}
-#endif
-
-#ifdef HAVE_FORK
-pid_t xfork() throw (GeneralException) {
- pid_t p;
-
- p = fork();
-
- if (p == -1) {
- throw GeneralException(_("Was not able to fork().\n"));
- }
-
- return p;
-}
-#else
-pid_t xfork() throw (GeneralException) {
- throw GeneralException(_("Function fork() not supported by this system.\n"));
-}
-#endif
-
-void xexit(int status) throw (GeneralException) {
- throw Exit(status);
-}
-
-void xexception(const String & err) throw (GeneralException) {
- throw GeneralException(err);
-}
-
-char * Base::strdup(const char * s) {
- return xstrdup(s);
-}
-
-void * Base::malloc(ssize_t s) {
- return xmalloc(s);
-}
-
-void * Base::realloc(void * p, size_t s) {
- return xrealloc(p, s);
-}
-
-void * Base::calloc(size_t n, size_t s) {
- return xmalloc(n * s);
-}
-
-void * Base::operator new(size_t s) {
-#ifdef DEBUG
- printm(M_BARE, _("Operator new(s) called. Allocating memory.\n"));
-#endif
- return xmalloc(s);
-}
-
-void * Base::operator new(size_t s, void * p) {
-#ifdef DEBUG
- printm(M_BARE, String(_("Operator new(s, p) called with p = %p and s = %i. Erasing memory.\n")), p, s);
-#endif
- return memset(p, 0, s);
-}
-
-void Base::operator delete(void * p) {
-#ifdef DEBUG
- printm(M_BARE, _("Operator delete(p) called. Freeing memory.\n"));
-#endif
- free(p);
-}
-
-int Base::pipe(int * p, int flag) {
- return xpipe(p, flag);
-}
-
-pid_t Base::fork() {
- return xfork();
-}
-
-void Base::exit(int status) {
- xexit(status);
-}
-
-void Base::flushcontext() {
- context.clear();
-}
-
-void Base::pushcontext(const String & c) {
- context.push_back(c);
-}
-
-void Base::popcontext() {
- context.pop_back();
-}
-
-void Base::exception(const String & err) {
- int c;
- std::vector<String>::iterator i;
- printm(M_ERROR, "Error detected, showing context.\n");
- for (i = context.begin(), c = 0; i != context.end(); i++, c++) {
- printm(M_ERROR, " (%i) - " + *i + "\n", c);
- }
-
- printm(M_ERROR, " Error description: " + err);
-
- xexception(err);
-}
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: Exceptions.cc,v 1.35 2004-11-27 21:46:04 pixel Exp $ */
+
+#include <string.h>
+#include <errno.h>
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#else
+#ifndef __APPLE__
+#include <malloc.h>
+#endif
+#endif
+#ifdef DEBUG
+#include <iostream>
+#endif
+#ifdef HAVE_PIPE
+#include <unistd.h>
+#endif
+#include "BString.h"
+#include "Exceptions.h"
+#include "generic.h"
+#include "gettext.h"
+
+char GeneralException::t[BUFSIZ];
+
+std::vector<String> Base::context;
+
+GeneralException::GeneralException(String emsg) : msg(emsg.strdup()) {
+ UNLOCK;
+#ifdef DEBUG
+ printm(M_BARE, String(_("Generating a General Exception error: '")) + msg + "'.\n");
+#endif
+}
+GeneralException::GeneralException() : msg(0) {
+ UNLOCK;
+#ifdef DEBUG
+ printm(M_BARE, String(_("Generating a General Exception error: '")) + msg + "'.\n");
+#endif
+}
+GeneralException::GeneralException(const GeneralException & e) : msg(strdup(e.msg)) {
+ UNLOCK;
+#ifdef DEBUG
+ printm(M_BARE, String(_("Generating a General Exception error: '")) + msg + "'.\n");
+#endif
+}
+
+GeneralException::~GeneralException() {
+ free(msg);
+}
+
+TaskNotFound::TaskNotFound() : GeneralException(_("Task not found")) { }
+
+const char * GeneralException::GetMsg() const {
+ return msg;
+}
+
+MemoryException::MemoryException(ssize_t s) {
+ sprintf(t, _("Failed allocating %u bytes."), s);
+ msg = strdup(t);
+}
+
+IOException::IOException(String fn, op_t op, ssize_t s) {
+ sprintf(t, _("An error has occured while %s %u bytes on %s: %s"), op == IO_WRITE ? _("writing") : _("reading"),
+ s, fn.to_charp(), strerror(errno));
+ msg = strdup(t);
+}
+
+IOGeneral::IOGeneral(String fn) : GeneralException(fn) { }
+
+IOGeneral::IOGeneral() { }
+
+IOAgain::IOAgain() : IOGeneral(_("No more bytes for reading or writing.")) {
+#ifdef DEBUG
+ printm(M_BARE, String(_("Generating an IOAgain exception: '")) + GetMsg() + "'.\n");
+#endif
+}
+
+TaskSwitch::TaskSwitch() : GeneralException(_("Switching task in a non-tasked environnement")) {
+#ifdef DEBUG
+ printm(M_BARE, String(_("Generating a TaskSwitch exception: '")) + GetMsg() + "'.\n");
+#endif
+}
+
+Exit::Exit(int a_code) : GeneralException(_("Exitting with code " + a_code)), code(a_code) {
+#ifdef DEBUG
+ printm(M_BARE, String(_("Generating an Exit exception: '")) + GetMsg() + "'.\n");
+#endif
+}
+
+int Exit::GetCode() {
+ return code;
+}
+
+char * xstrdup(const char * s) {
+ char * r;
+
+ r = (char *) xmalloc(strlen(s) + 1);
+ strcpy(r, s);
+ return r;
+}
+
+void * xmalloc(size_t s) throw (GeneralException) {
+ char * r;
+
+ if (s == 0) {
+ return 0;
+ }
+
+ if (!(r = (char *) ::malloc(s))) {
+ throw MemoryException(s);
+ }
+#ifdef DEBUG
+// Base::printm(M_BARE, String(_("Allocating %i bytes of memory, got it at %p\n")), s, r);
+#endif
+
+ memset(r, 0, s);
+
+ return (void *)(r);
+}
+
+void * xrealloc(void * ptr, size_t s) {
+#ifdef DEBUG
+ void * r = realloc(ptr, s);
+ Base::printm(M_BARE, String(_("Reallocating pointer at %p for %i bytes, now at %p\n")), ptr, s, r);
+ return r;
+#else
+ return realloc(ptr, s);
+#endif
+}
+
+void xfree(unsigned char *& p) {
+#ifdef DEBUG
+// Base::printm(M_BARE, String(_("Freeing pointer at %p\n")), p);
+#endif
+ if (p) {
+ ::free(p);
+ p = 0;
+ }
+}
+
+#ifdef HAVE_PIPE
+int xpipe(int * p, int flag) throw (GeneralException) {
+ if (pipe(p)) {
+ throw GeneralException(String(_("Error creating pipe: ")) + strerror(errno));
+ }
+
+ return p[flag];
+}
+#else
+int xpipe(int *, int) throw (GeneralException) {
+ throw GeneralException(_("Function pipe() not supported by this system.\n"));
+}
+#endif
+
+#ifdef HAVE_FORK
+pid_t xfork() throw (GeneralException) {
+ pid_t p;
+
+ p = fork();
+
+ if (p == -1) {
+ throw GeneralException(_("Was not able to fork().\n"));
+ }
+
+ return p;
+}
+#else
+pid_t xfork() throw (GeneralException) {
+ throw GeneralException(_("Function fork() not supported by this system.\n"));
+}
+#endif
+
+void xexit(int status) throw (GeneralException) {
+ throw Exit(status);
+}
+
+void xexception(const String & err) throw (GeneralException) {
+ throw GeneralException(err);
+}
+
+char * Base::strdup(const char * s) {
+ return xstrdup(s);
+}
+
+void * Base::malloc(ssize_t s) {
+ return xmalloc(s);
+}
+
+void * Base::realloc(void * p, size_t s) {
+ return xrealloc(p, s);
+}
+
+void * Base::calloc(size_t n, size_t s) {
+ return xmalloc(n * s);
+}
+
+void * Base::operator new(size_t s) {
+#ifdef DEBUG
+ printm(M_BARE, _("Operator new(s) called. Allocating memory.\n"));
+#endif
+ return xmalloc(s);
+}
+
+void * Base::operator new(size_t s, void * p) {
+#ifdef DEBUG
+ printm(M_BARE, String(_("Operator new(s, p) called with p = %p and s = %i. Erasing memory.\n")), p, s);
+#endif
+ return memset(p, 0, s);
+}
+
+void Base::operator delete(void * p) {
+#ifdef DEBUG
+ printm(M_BARE, _("Operator delete(p) called. Freeing memory.\n"));
+#endif
+ free(p);
+}
+
+int Base::pipe(int * p, int flag) {
+ return xpipe(p, flag);
+}
+
+pid_t Base::fork() {
+ return xfork();
+}
+
+void Base::exit(int status) {
+ xexit(status);
+}
+
+void Base::flushcontext() {
+ context.clear();
+}
+
+void Base::pushcontext(const String & c) {
+ context.push_back(c);
+}
+
+void Base::popcontext() {
+ context.pop_back();
+}
+
+void Base::exception(const String & err) {
+ int c;
+ std::vector<String>::iterator i;
+ printm(M_ERROR, "Error detected, showing context.\n");
+ for (i = context.begin(), c = 0; i != context.end(); i++, c++) {
+ printm(M_ERROR, " (%i) - " + *i + "\n", c);
+ }
+
+ printm(M_ERROR, " Error description: " + err);
+
+ xexception(err);
+}
diff --git a/lib/Form.cc b/lib/Form.cc
index 122f0a5..fedfc3e 100644
--- a/lib/Form.cc
+++ b/lib/Form.cc
@@ -1,65 +1,65 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "Form.h"
-#include "HttpServ.h"
-#include "Buffer.h"
-#include "CopyJob.h"
-
-Form::Form(const String & titre, const String & url, const String & inv, String * names, String * invs,
- String * defaults, String ** lists, String ** descs, int nb, Action * na) :
- Action(url), tit(titre), iv(inv), nms(names), ivs(invs), defs(defaults), lsts(lists), dscs(descs), n(nb), Next(na) { }
-
-String Form::GetTitle(void) {
- return tit;
-}
-
-Task * Form::Do(Variables * v, Variables *, Handle * h) {
- Handle * b = new Buffer();
- Task * t = new CopyJob(b, h, -1, true);
- SendHead(b);
-
- (*b) <<
-"<center>" << endnl <<
-"<form ACTION=\"/bin/" << (Next ? Next->GetURL() : "start") << "\" METHOD=POST>" << endnl;
-
- v->Dump(b);
-
- (*b) <<
-"<table BORDER=0 CELLSPACING=0 BGCOLOR=\"#000000\"><tr><td>" << endnl <<
-"<table BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH=\"300\" BGCOLOR=\"#FFFFCC\">" << endnl <<
-"<tr><td ALIGN=CENTER WIDTH=\"100%\" BGCOLOR=\"#000000\"><b><font FACE=\"arial,helvetica\" COLOR=\"#FFFFFF\">" << endnl <<
-iv << endnl <<
-"</font></b></td></tr>" << endnl;
-
- for (int i = 0; i < n; i++) {
- (*b) <<
-"<tr><td>" << ivs[i] << "</td></tr>" << endnl;
- if (lsts[i]) {
- String * s, * t;
- (*b) <<
-"<tr><td><select NAME=\"" << nms[i] << "\">" << endnl;
- for (s = lsts[i], t = dscs[i]; s->strlen(); s++, t++) {
- (*b) <<
-"<option VALUE=\"" << *s << "\">" << *t << "</option>" << endnl;
- }
- (*b) <<
-"</select></td></tr>" << endnl;
- } else {
- (*b) <<
-"<tr><td><input TYPE=\"text\" NAME=\"" << nms[i] << "\" VALUE=\"" << defs[i] << "\" size=40></tr></td>" << endnl;
- }
- }
-
- (*b) <<
-
-"<tr><td ALIGN=\"center\"><input TYPE=\"submit\" VALUE=\" Ok \"></td></tr>" << endnl <<
-"</table></td></tr></table></form></center>" << endnl;
-
- SendFoot(b);
-
- Accessed();
-
- return t;
-}
-
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "Form.h"
+#include "HttpServ.h"
+#include "Buffer.h"
+#include "CopyJob.h"
+
+Form::Form(const String & titre, const String & url, const String & inv, String * names, String * invs,
+ String * defaults, String ** lists, String ** descs, int nb, Action * na) :
+ Action(url), tit(titre), iv(inv), nms(names), ivs(invs), defs(defaults), lsts(lists), dscs(descs), n(nb), Next(na) { }
+
+String Form::GetTitle(void) {
+ return tit;
+}
+
+Task * Form::Do(Variables * v, Variables *, Handle * h) {
+ Handle * b = new Buffer();
+ Task * t = new CopyJob(b, h, -1, true);
+ SendHead(b);
+
+ (*b) <<
+"<center>" << endnl <<
+"<form ACTION=\"/bin/" << (Next ? Next->GetURL() : "start") << "\" METHOD=POST>" << endnl;
+
+ v->Dump(b);
+
+ (*b) <<
+"<table BORDER=0 CELLSPACING=0 BGCOLOR=\"#000000\"><tr><td>" << endnl <<
+"<table BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH=\"300\" BGCOLOR=\"#FFFFCC\">" << endnl <<
+"<tr><td ALIGN=CENTER WIDTH=\"100%\" BGCOLOR=\"#000000\"><b><font FACE=\"arial,helvetica\" COLOR=\"#FFFFFF\">" << endnl <<
+iv << endnl <<
+"</font></b></td></tr>" << endnl;
+
+ for (int i = 0; i < n; i++) {
+ (*b) <<
+"<tr><td>" << ivs[i] << "</td></tr>" << endnl;
+ if (lsts[i]) {
+ String * s, * t;
+ (*b) <<
+"<tr><td><select NAME=\"" << nms[i] << "\">" << endnl;
+ for (s = lsts[i], t = dscs[i]; s->strlen(); s++, t++) {
+ (*b) <<
+"<option VALUE=\"" << *s << "\">" << *t << "</option>" << endnl;
+ }
+ (*b) <<
+"</select></td></tr>" << endnl;
+ } else {
+ (*b) <<
+"<tr><td><input TYPE=\"text\" NAME=\"" << nms[i] << "\" VALUE=\"" << defs[i] << "\" size=40></tr></td>" << endnl;
+ }
+ }
+
+ (*b) <<
+
+"<tr><td ALIGN=\"center\"><input TYPE=\"submit\" VALUE=\" Ok \"></td></tr>" << endnl <<
+"</table></td></tr></table></form></center>" << endnl;
+
+ SendFoot(b);
+
+ Accessed();
+
+ return t;
+}
+
diff --git a/lib/GMPString.cc b/lib/GMPString.cc
index 5fb76c8..be39e38 100644
--- a/lib/GMPString.cc
+++ b/lib/GMPString.cc
@@ -1,30 +1,30 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef HAVE_GMP
-#include <gmpxx.h>
-#include "GMPString.h"
-
-GMPString::GMPString(const GMPString & s) : str(s.str) {
-}
-
-GMPString::GMPString(const mpz_class & z) {
- gmp_asprintf(&str, "%Zd", z.get_mpz_t());
-}
-
-GMPString::GMPString(const mpq_class & q) {
- gmp_asprintf(&str, "%Qd", q.get_mpq_t());
-}
-
-GMPString::GMPString(const mpf_class & f) {
- gmp_asprintf(&str, "%Ff", f.get_mpf_t());
-}
-
-GMPString::operator String() const {
- return String(str);
-}
-
-GMPString::~GMPString() {
-}
-
-#endif
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_GMP
+#include <gmpxx.h>
+#include "GMPString.h"
+
+GMPString::GMPString(const GMPString & s) : str(s.str) {
+}
+
+GMPString::GMPString(const mpz_class & z) {
+ gmp_asprintf(&str, "%Zd", z.get_mpz_t());
+}
+
+GMPString::GMPString(const mpq_class & q) {
+ gmp_asprintf(&str, "%Qd", q.get_mpq_t());
+}
+
+GMPString::GMPString(const mpf_class & f) {
+ gmp_asprintf(&str, "%Ff", f.get_mpf_t());
+}
+
+GMPString::operator String() const {
+ return String(str);
+}
+
+GMPString::~GMPString() {
+}
+
+#endif
diff --git a/lib/Handle.cc b/lib/Handle.cc
index bbd3e04..ef5aa80 100644
--- a/lib/Handle.cc
+++ b/lib/Handle.cc
@@ -1,658 +1,658 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: Handle.cc,v 1.72 2004-11-27 21:35:19 pixel Exp $ */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "generic.h"
-
-#if defined WORDS_BIGENDIAN
-#if defined HAVE_BYTESWAP_H
-#include <byteswap.h>
-#else
-inline Uint16 bswap_16(Uint16 w) {
- return (w >> 8) | (w << 8);
-}
-
-inline Uint32 bswap_32(Uint32 w) {
- return (w >> 24) | ((w >> 8) & 0x0000ff00) | ((w << 8) & 0x00ff0000) | (w << 24);
-}
-#endif
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-
-#ifndef _WIN32
-#include <sys/mman.h>
-#endif
-
-#include "Handle.h"
-#include "gettext.h"
-
-enum {
- DEFLATE,
- INFLATE
-};
-
-Handle::Handle(const Handle & nh) : itell(0), hFile(0), h(nh.h >= 0 ? dup(nh.h) : nh.h), closed(nh.closed), nonblock(nh.closed), zfile(0), z(0), hMapObject(0), mapped(0)
-{
-#ifdef DEBUG
- printm(M_INFO, String(_("Duplication of handle ")) + nh.h + _(" to ") + h + "\n");
-#endif
- if ((h >= 0) && (nh.z)) {
- SetZ(nh.z);
- }
-}
-
-Handle::~Handle() {
-#ifdef DEBUG
- printm(M_INFO, String(_("Destroying handle ")) + h + "\n");
-#endif
- close();
-}
-
-Handle::Handle(int nh) : h(nh), closed(false), nonblock(false), zfile(0), z(0), hMapObject(0), mapped(0)
-{
-#ifdef DEBUG
- printm(M_INFO, String(_("Initialising handle ")) + h + "\n");
-#endif
-}
-
-int Handle::GetHandle() {
- return h;
-}
-
-void * Handle::GetHFile() {
- return hFile;
-}
-
-int Handle::GetHandle() const {
- return h;
-}
-
-ssize_t Handle::write(const void *cbuf, size_t count) throw (GeneralException) {
- ssize_t r, tr = 0;
- bool done, full = false;
- const char * buf = (const char *)cbuf;
-
- if (closed) {
- throw IOGeneral("Unable to write: handle `" + GetName() + "' is closed.");
- }
-
- if (!count)
- return 0;
-
- do {
- done = true;
- errno = 0;
- if ((r = uwrite(buf, count)) < 0) {
- if ((!errno) || (errno == EAGAIN) || (errno == EINTR)) {
- // Avant de déclarer une erreur, on vérifie si ce n'est pas un
- // problème lié au fait qu'il n'y a plus de place libre. Cela peut
- // arriver si l'on agit sur un pipe ou un handle. Nous
- // attendons encore une fois avant de déclarer l'erreur,
- // grace au drapeau full.
- if (full) {
- throw IOException(GetName(), IO_WRITE, count);
- } else {
- done = false;
- full = true;
- if (nonblock) {
-#ifdef DEBUG
- printm(M_INFO, _("write: throwing IOAgain for handle ") + GetName() + "\n");
-#endif
- throw IOAgain();
- } else {
-#ifdef HAVE_SLEEP
- sleep(1);
-#endif
- }
- }
- } else {
- throw IOException(GetName(), IO_WRITE, count);
- }
- } else if (((size_t) r) != count) {
- if (nonblock) {
- return r;
- }
- full = done = false;
- buf += r;
- tr += r;
- }
- } while (!done);
-
- return r + tr;
-}
-
-ssize_t Handle::read(void *buf, size_t count) throw (GeneralException) {
- ssize_t r;
-
- if (closed) {
- throw IOGeneral("Unable to read: handle `" + GetName() + "' is closed.");
- }
-
- if (!count)
- return 0;
-
-#ifdef FULLDEBUG
- printm(M_INFO, String(_("read: reading ")) + count + _(" bytes from handle ") + GetHandle() + "\n");
-#endif
-
- errno = 0;
- while ((r = uread(buf, count)) < 0) {
- if ((!errno) || (errno == EAGAIN) || (errno == EINTR)) {
- // Avant de déclarer une erreur, on vérifie si ce n'est pas un
- // problème lié au fait qu'il n'y a plus d'octets.
- if (nonblock) {
-#ifdef DEBUG
- printm(M_INFO, _("read: throwing IOAgain for handle ") + GetName() + "\n");
-#endif
- throw IOAgain();
- }
- } else {
- throw IOException(GetName(), IO_READ, count);
- }
- }
-
- if (!r) {
- close();
- }
-
- return r;
-}
-
-bool Handle::IsClosed(void) const {
- return closed;
-}
-
-bool Handle::IsNonBlock(void) const {
- return nonblock;
-}
-
-void Handle::SetNonBlock(void) {
-#ifdef HAVE_FCNTL
- if ((h >= 0) || !nonblock) {
- fcntl(h, F_SETFL, O_NONBLOCK);
- }
- nonblock = true;
-#endif
-}
-
-Handle & operator<<(Handle & h, const String & s) {
- const char * p;
-
- p = s.to_charp();
- h.write(p, strlen(p));
-
- return h;
-}
-
-Handle & operator>>(Handle & h, String & s) {
- char t[BUFSIZ];
- int i = 0, r;
-
- while ((r = h.read(&(t[i]), 1)) && (i != (BUFSIZ - 1))) {
- // Il y a souvent des \r\n dans les sockets par exemple,
- // ou bien en lisant des fichiers au format MS-DOS. On
- // ignore le \r pour ne garder que le \n, standard sous Unix.
- if (t[i] == '\r') {
- continue;
- }
- if (t[i] == '\n') {
- break;
- } else {
- i++;
- }
- }
-
- t[i] = '\0';
- s = t;
- return h;
-}
-
-void Handle::close() throw (GeneralException) {
- if (IsClosed()) {
- return;
- }
-
- Flush();
-
- if (h >= 0) {
- if (z >= 10) {
- int err;
- if (c == DEFLATE) {
- err = deflateEnd(&zstrm);
- if (err != Z_OK) {
- throw GeneralException(String(_("Error during deflateEnd: ")) + zstrm.msg);
- }
- } else {
- err = inflateEnd(&zstrm);
- if (err != Z_OK) {
- throw GeneralException(String(_("Error during inflateEnd: ")) + zstrm.msg);
- }
- }
- err = ::close(h);
- if (err) {
- throw GeneralException(String(_("Error during (zstream) close: ")) + strerror(errno));
- }
- } else if (z) {
-#ifdef DEBUG
- printm(M_INFO, String(_("Performing gzclose on handle ")) + h + "\n");
-#endif
- int err = gzclose(zfile);
-#ifdef DEBUG
- printm(M_INFO, String(_("gzclose returned ")) + err + "\n");
-#endif
- if (err) {
- if (err == Z_ERRNO) {
- throw GeneralException(String(_("Error during close: ")) + strerror(errno));
- } else {
- throw GeneralException(String(_("Error in zlib during gzclose: ")) + gzerror(zfile, &err));
- }
- }
- } else {
- if (!hFile) {
- int err = ::close(h);
- if (err) {
- throw GeneralException(String(_("Error during close: ")) + strerror(errno));
- }
- }
- }
-#if defined (_WIN32) && !defined (NO_HFILE)
- if (hFile) {
- CloseHandle(hFile);
- hFile = 0;
- }
-#endif
- }
-
- if (mapped) {
- munmap();
- }
-
- h = -1;
- closed = 1;
-}
-
-bool Handle::CanRead(void) const {
- return false;
-}
-
-bool Handle::CanWrite(void) const {
- return false;
-}
-
-String Handle::GetName(void) const {
- return _("Bare Handle - should not happend");
-}
-
-ssize_t Handle::GetSize(void) const {
- return -1;
-}
-
-time_t Handle::GetModif(void) const {
- return -1;
-}
-
-bool Handle::CanWatch(void) const {
- return true;
-}
-
-int Handle::Dup() const throw (GeneralException) {
- int d;
-
- if ((d = dup(h)) < 0) {
- throw IOGeneral(String(_("Error dupping file `")) + GetName() + _("' (handle ") + h + "): " + strerror(errno) + " (" + errno + ")");
- }
- return d;
-}
-
-void Handle::SetZ(int az) throw (GeneralException) {
- if (z) {
- throw GeneralException(_("Can't SetZ a Handle twice."));
- }
- if (h < 0) {
- throw GeneralException(_("Can't SetZ a virtual Handle."));
- }
- if (az >= 10) {
-#ifdef DEBUG
- printm(M_INFO, _("Setting up zstream using inflate/deflate...\n"));
-#endif
- int err;
- zstrm.zalloc = Z_NULL;
- zstrm.zfree = Z_NULL;
- if (CanWrite()) {
- c = DEFLATE;
- err = deflateInit(&zstrm, az - 10);
- if (err != Z_OK) {
- throw GeneralException(String(_("Error in deflateInit: ")) + zstrm.msg);
- }
- } else {
- c = INFLATE;
- zstrm.next_in = 0;
- zstrm.avail_in = 0;
- err = inflateInit(&zstrm);
- if (err != Z_OK) {
- throw GeneralException(String(_("Error in inflateInit: ")) + zstrm.msg);
- }
- }
- } else if (az) {
- char format[5];
- int index = 0;
- if (CanRead()) {
- format[index++] = 'r';
- }
- if (CanWrite()) {
- format[index++] = 'w';
- }
- format[index++] = (char) (az + '0');
- format[index++] = 'b';
- format[index] = 0;
-#ifdef FULLDEBUG
- printm(M_INFO, String(_("Performing gzdopen on handle ")) + h + _(" with mode \"") + format + "\"\n");
-#endif
- if (!(zfile = gzdopen(h, format))) {
- throw GeneralException(String(_("Was not able to gzdopen: ")) + strerror(errno));
- }
- z = az;
- }
-}
-
-ssize_t Handle::uwrite(const void * buf, size_t count) throw (GeneralException) {
- if (z >= 10) {
- } else if (z) {
-#ifdef FULLDEBUG
- printm(M_INFO, String(_("Performing gzwrite of ")) + count + _(" byte(s) for handle ") + h + "\n");
-#endif
-#ifdef HAVE_WD_ZLIB
- int err = gzwrite(zfile, buf, count);
-#else
- int err = gzwrite(zfile, (char *) buf, count);
-#endif
- if (err == 0) {
- const char * m = gzerror(zfile, &err);
- if (err == Z_ERRNO) {
- return -1;
- } else {
- throw GeneralException(String(_("Error in zlib during gzwrite: ")) + m);
- }
- }
- itell += err;
- return err;
- } else {
- itell += count = ::write(h, buf, count);
- return count;
- }
-}
-
-ssize_t Handle::uread(void * buf, size_t count) {
- if (z >= 10) {
- } if (z) {
-#ifdef DEBUG
- printm(M_BARE, String(_("Performing gzread of ")) + count + _(" byte(s) for handle ") + h + "\n");
-#endif
- int err = gzread(zfile, buf, count);
- if (err == -1) {
- gzerror(zfile, &err);
- if (err == Z_ERRNO) {
- return -1;
- } else {
- return 0;
- }
- }
- itell += err;
- return err;
- } else {
-#if defined (_WIN32) && !defined (NO_HFILE)
- if (hFile) {
- DWORD rcount;
- if (!ReadFile(hFile, buf, count, &rcount, 0)) {
- // Error..
- }
- itell += count = rcount;
- } else
-#endif
- itell += count = ::read(h, buf, count);
- return count;
- }
-}
-
-off_t Handle::tell() const {
- if (z) {
- return gztell(zfile);
- } else {
- return itell;
- }
-}
-
-bool Handle::CanSeek() const {
- return 0;
-}
-
-off_t Handle::seek(off_t offset, int whence) throw(GeneralException) {
- if (z) {
- return itell = gzseek(zfile, offset, whence);
- } else {
- throw IOGeneral(_("Handle ") + GetName() + _(" can't seek"));
- }
-}
-
-Uint8 Handle::readU8() {
- Uint8 r;
- read(&r, 1);
- return r;
-}
-
-Uint16 Handle::readU16() {
- Uint16 r;
- read(&r, 2);
-#ifdef WORDS_BIGENDIAN
- return bswap_16(r);
-#else
- return r;
-#endif
-}
-
-Uint32 Handle::readU32() {
- Uint32 r;
- read(&r, 4);
-#ifdef WORDS_BIGENDIAN
- return bswap_32(r);
-#else
- return r;
-#endif
-}
-
-void Handle::writeU8(Uint8 v) {
- write(&v, 1);
-}
-
-void Handle::writeU16(Uint16 v) {
-#ifdef WORDS_BIGENDIAN
- Uint16 t = bswap_16(v);
- write(&t, 2);
-#else
- write(&v, 2);
-#endif
-}
-
-void Handle::writeU32(Uint32 v) {
-#ifdef WORDS_BIGENDIAN
- Uint32 t = bswap_32(v);
- write(&t, 4);
-#else
- write(&v, 4);
-#endif
-}
-
-void Handle::copyto(Handle * dest, ssize_t s) {
- copy(this, dest, s);
-}
-
-void Handle::copyfrom(Handle * src, ssize_t s) {
- copy(src, this, s);
-}
-
-void copyone(Handle * s, Handle * d, ssize_t size) {
- long i;
- unsigned char c;
- long r;
-
- if (size < 0)
- size = s->GetSize();
-
- for (i = 0; (i < size) || (size < 0); i++) {
- r = s->read(&c, 1);
- if (r == 0) {
- break;
- }
- d->write(&c, 1);
- }
-}
-
-#define BSIZE 20480
-
-void copy(Handle * s, Handle * d, ssize_t size) {
- long i;
- static unsigned char b[BSIZE];
- long r;
-
- if (size < 0)
- size = s->GetSize();
-
- LOCK;
-
- while (size) {
- if ((size > BSIZE) || (size < 0)) {
- r = s->read(b, BSIZE);
- if (r)
- d->write(b, r);
- } else {
- r = s->read(b, size);
- if (r)
- d->write(b, r);
- }
- if (!r)
- break;
- if (size > 0)
- size -= r;
- }
-
- UNLOCK;
-}
-
-void Handle::Flush() {
- if (!CanWrite())
- return;
- if (h < 0)
- return;
- if (z >= 10) {
-
- } else if (z) {
- gzflush(&z, Z_FULL_FLUSH);
- } else {
-#ifdef HAVE_FSYNC
- fsync(h);
-#endif
- }
-}
-
-void * Handle::mmap(off_t offset, size_t length) throw (GeneralException) {
- void * r;
-
- if (h == -1) {
- throw GeneralException("Can't mmap() a virtual handle");
- }
-#ifdef _WIN32
- if (!hFile) {
- throw GeneralException("Can't mmap() a non-hFile handle under windows");
- }
-#endif
- if (mapped) {
- throw GeneralException("Handle already mmap()ped");
- }
- mapped = true;
- if (length == -1) {
- length = GetSize();
- }
- maplength = length;
-#ifndef _WIN32
- r = ::mmap(0, length, (CanRead() ? PROT_READ : 0) | (CanWrite() ? PROT_WRITE : 0), MAP_SHARED, h, offset);
- if (!r) {
- throw GeneralException(String("Was not able to mmap(): ") + strerror(errno));
- }
-#else
- hMapObject = CreateFileMapping(
- hFile,
- 0,
- CanWrite() ? PAGE_READWRITE : PAGE_READONLY,
- 0,
- length,
- GetName().to_charp());
- if (hMapObject != NULL) {
- r = MapViewOfFile(
- hMapObject,
- CanWrite() ? FILE_MAP_WRITE : FILE_MAP_READ,
- 0,
- offset,
- length);
- if (!r) {
- CloseHandle(hMapObject);
- throw GeneralException("Was not able to MapViewOfFile()");
- }
- } else {
- throw GeneralException("Was not able to CreateFileMapping()");
- }
-#endif
-
- mappedarea = r;
-
- return r;
-}
-
-void Handle::munmap() throw (GeneralException) {
- if (!mapped) {
- throw GeneralException("Can't munmap, was not mapped");
- }
-#ifndef _WIN32
- if (::munmap(mappedarea, maplength)) {
- throw GeneralException(String("Was not able to munmap(): ") + strerror(errno));
- }
-#else
- if (!UnmapViewOfFile(mappedarea)) {
- throw GeneralException("Was not able to UnmapViewOfFile()");
- }
- CloseHandle(hMapObject);
-#endif
- mapped = false;
- mappedarea = 0;
- maplength = 0;
-}
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: Handle.cc,v 1.73 2004-11-27 21:46:04 pixel Exp $ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "generic.h"
+
+#if defined WORDS_BIGENDIAN
+#if defined HAVE_BYTESWAP_H
+#include <byteswap.h>
+#else
+inline Uint16 bswap_16(Uint16 w) {
+ return (w >> 8) | (w << 8);
+}
+
+inline Uint32 bswap_32(Uint32 w) {
+ return (w >> 24) | ((w >> 8) & 0x0000ff00) | ((w << 8) & 0x00ff0000) | (w << 24);
+}
+#endif
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
+#ifndef _WIN32
+#include <sys/mman.h>
+#endif
+
+#include "Handle.h"
+#include "gettext.h"
+
+enum {
+ DEFLATE,
+ INFLATE
+};
+
+Handle::Handle(const Handle & nh) : itell(0), hFile(0), h(nh.h >= 0 ? dup(nh.h) : nh.h), closed(nh.closed), nonblock(nh.closed), zfile(0), z(0), hMapObject(0), mapped(0)
+{
+#ifdef DEBUG
+ printm(M_INFO, String(_("Duplication of handle ")) + nh.h + _(" to ") + h + "\n");
+#endif
+ if ((h >= 0) && (nh.z)) {
+ SetZ(nh.z);
+ }
+}
+
+Handle::~Handle() {
+#ifdef DEBUG
+ printm(M_INFO, String(_("Destroying handle ")) + h + "\n");
+#endif
+ close();
+}
+
+Handle::Handle(int nh) : h(nh), closed(false), nonblock(false), zfile(0), z(0), hMapObject(0), mapped(0)
+{
+#ifdef DEBUG
+ printm(M_INFO, String(_("Initialising handle ")) + h + "\n");
+#endif
+}
+
+int Handle::GetHandle() {
+ return h;
+}
+
+void * Handle::GetHFile() {
+ return hFile;
+}
+
+int Handle::GetHandle() const {
+ return h;
+}
+
+ssize_t Handle::write(const void *cbuf, size_t count) throw (GeneralException) {
+ ssize_t r, tr = 0;
+ bool done, full = false;
+ const char * buf = (const char *)cbuf;
+
+ if (closed) {
+ throw IOGeneral("Unable to write: handle `" + GetName() + "' is closed.");
+ }
+
+ if (!count)
+ return 0;
+
+ do {
+ done = true;
+ errno = 0;
+ if ((r = uwrite(buf, count)) < 0) {
+ if ((!errno) || (errno == EAGAIN) || (errno == EINTR)) {
+ // Avant de déclarer une erreur, on vérifie si ce n'est pas un
+ // problème lié au fait qu'il n'y a plus de place libre. Cela peut
+ // arriver si l'on agit sur un pipe ou un handle. Nous
+ // attendons encore une fois avant de déclarer l'erreur,
+ // grace au drapeau full.
+ if (full) {
+ throw IOException(GetName(), IO_WRITE, count);
+ } else {
+ done = false;
+ full = true;
+ if (nonblock) {
+#ifdef DEBUG
+ printm(M_INFO, _("write: throwing IOAgain for handle ") + GetName() + "\n");
+#endif
+ throw IOAgain();
+ } else {
+#ifdef HAVE_SLEEP
+ sleep(1);
+#endif
+ }
+ }
+ } else {
+ throw IOException(GetName(), IO_WRITE, count);
+ }
+ } else if (((size_t) r) != count) {
+ if (nonblock) {
+ return r;
+ }
+ full = done = false;
+ buf += r;
+ tr += r;
+ }
+ } while (!done);
+
+ return r + tr;
+}
+
+ssize_t Handle::read(void *buf, size_t count) throw (GeneralException) {
+ ssize_t r;
+
+ if (closed) {
+ throw IOGeneral("Unable to read: handle `" + GetName() + "' is closed.");
+ }
+
+ if (!count)
+ return 0;
+
+#ifdef FULLDEBUG
+ printm(M_INFO, String(_("read: reading ")) + count + _(" bytes from handle ") + GetHandle() + "\n");
+#endif
+
+ errno = 0;
+ while ((r = uread(buf, count)) < 0) {
+ if ((!errno) || (errno == EAGAIN) || (errno == EINTR)) {
+ // Avant de déclarer une erreur, on vérifie si ce n'est pas un
+ // problème lié au fait qu'il n'y a plus d'octets.
+ if (nonblock) {
+#ifdef DEBUG
+ printm(M_INFO, _("read: throwing IOAgain for handle ") + GetName() + "\n");
+#endif
+ throw IOAgain();
+ }
+ } else {
+ throw IOException(GetName(), IO_READ, count);
+ }
+ }
+
+ if (!r) {
+ close();
+ }
+
+ return r;
+}
+
+bool Handle::IsClosed(void) const {
+ return closed;
+}
+
+bool Handle::IsNonBlock(void) const {
+ return nonblock;
+}
+
+void Handle::SetNonBlock(void) {
+#ifdef HAVE_FCNTL
+ if ((h >= 0) || !nonblock) {
+ fcntl(h, F_SETFL, O_NONBLOCK);
+ }
+ nonblock = true;
+#endif
+}
+
+Handle & operator<<(Handle & h, const String & s) {
+ const char * p;
+
+ p = s.to_charp();
+ h.write(p, strlen(p));
+
+ return h;
+}
+
+Handle & operator>>(Handle & h, String & s) {
+ char t[BUFSIZ];
+ int i = 0, r;
+
+ while ((r = h.read(&(t[i]), 1)) && (i != (BUFSIZ - 1))) {
+ // Il y a souvent des \r\n dans les sockets par exemple,
+ // ou bien en lisant des fichiers au format MS-DOS. On
+ // ignore le \r pour ne garder que le \n, standard sous Unix.
+ if (t[i] == '\r') {
+ continue;
+ }
+ if (t[i] == '\n') {
+ break;
+ } else {
+ i++;
+ }
+ }
+
+ t[i] = '\0';
+ s = t;
+ return h;
+}
+
+void Handle::close() throw (GeneralException) {
+ if (IsClosed()) {
+ return;
+ }
+
+ Flush();
+
+ if (h >= 0) {
+ if (z >= 10) {
+ int err;
+ if (c == DEFLATE) {
+ err = deflateEnd(&zstrm);
+ if (err != Z_OK) {
+ throw GeneralException(String(_("Error during deflateEnd: ")) + zstrm.msg);
+ }
+ } else {
+ err = inflateEnd(&zstrm);
+ if (err != Z_OK) {
+ throw GeneralException(String(_("Error during inflateEnd: ")) + zstrm.msg);
+ }
+ }
+ err = ::close(h);
+ if (err) {
+ throw GeneralException(String(_("Error during (zstream) close: ")) + strerror(errno));
+ }
+ } else if (z) {
+#ifdef DEBUG
+ printm(M_INFO, String(_("Performing gzclose on handle ")) + h + "\n");
+#endif
+ int err = gzclose(zfile);
+#ifdef DEBUG
+ printm(M_INFO, String(_("gzclose returned ")) + err + "\n");
+#endif
+ if (err) {
+ if (err == Z_ERRNO) {
+ throw GeneralException(String(_("Error during close: ")) + strerror(errno));
+ } else {
+ throw GeneralException(String(_("Error in zlib during gzclose: ")) + gzerror(zfile, &err));
+ }
+ }
+ } else {
+ if (!hFile) {
+ int err = ::close(h);
+ if (err) {
+ throw GeneralException(String(_("Error during close: ")) + strerror(errno));
+ }
+ }
+ }
+#if defined (_WIN32) && !defined (NO_HFILE)
+ if (hFile) {
+ CloseHandle(hFile);
+ hFile = 0;
+ }
+#endif
+ }
+
+ if (mapped) {
+ munmap();
+ }
+
+ h = -1;
+ closed = 1;
+}
+
+bool Handle::CanRead(void) const {
+ return false;
+}
+
+bool Handle::CanWrite(void) const {
+ return false;
+}
+
+String Handle::GetName(void) const {
+ return _("Bare Handle - should not happend");
+}
+
+ssize_t Handle::GetSize(void) const {
+ return -1;
+}
+
+time_t Handle::GetModif(void) const {
+ return -1;
+}
+
+bool Handle::CanWatch(void) const {
+ return true;
+}
+
+int Handle::Dup() const throw (GeneralException) {
+ int d;
+
+ if ((d = dup(h)) < 0) {
+ throw IOGeneral(String(_("Error dupping file `")) + GetName() + _("' (handle ") + h + "): " + strerror(errno) + " (" + errno + ")");
+ }
+ return d;
+}
+
+void Handle::SetZ(int az) throw (GeneralException) {
+ if (z) {
+ throw GeneralException(_("Can't SetZ a Handle twice."));
+ }
+ if (h < 0) {
+ throw GeneralException(_("Can't SetZ a virtual Handle."));
+ }
+ if (az >= 10) {
+#ifdef DEBUG
+ printm(M_INFO, _("Setting up zstream using inflate/deflate...\n"));
+#endif
+ int err;
+ zstrm.zalloc = Z_NULL;
+ zstrm.zfree = Z_NULL;
+ if (CanWrite()) {
+ c = DEFLATE;
+ err = deflateInit(&zstrm, az - 10);
+ if (err != Z_OK) {
+ throw GeneralException(String(_("Error in deflateInit: ")) + zstrm.msg);
+ }
+ } else {
+ c = INFLATE;
+ zstrm.next_in = 0;
+ zstrm.avail_in = 0;
+ err = inflateInit(&zstrm);
+ if (err != Z_OK) {
+ throw GeneralException(String(_("Error in inflateInit: ")) + zstrm.msg);
+ }
+ }
+ } else if (az) {
+ char format[5];
+ int index = 0;
+ if (CanRead()) {
+ format[index++] = 'r';
+ }
+ if (CanWrite()) {
+ format[index++] = 'w';
+ }
+ format[index++] = (char) (az + '0');
+ format[index++] = 'b';
+ format[index] = 0;
+#ifdef FULLDEBUG
+ printm(M_INFO, String(_("Performing gzdopen on handle ")) + h + _(" with mode \"") + format + "\"\n");
+#endif
+ if (!(zfile = gzdopen(h, format))) {
+ throw GeneralException(String(_("Was not able to gzdopen: ")) + strerror(errno));
+ }
+ z = az;
+ }
+}
+
+ssize_t Handle::uwrite(const void * buf, size_t count) throw (GeneralException) {
+ if (z >= 10) {
+ } else if (z) {
+#ifdef FULLDEBUG
+ printm(M_INFO, String(_("Performing gzwrite of ")) + count + _(" byte(s) for handle ") + h + "\n");
+#endif
+#ifdef HAVE_WD_ZLIB
+ int err = gzwrite(zfile, buf, count);
+#else
+ int err = gzwrite(zfile, (char *) buf, count);
+#endif
+ if (err == 0) {
+ const char * m = gzerror(zfile, &err);
+ if (err == Z_ERRNO) {
+ return -1;
+ } else {
+ throw GeneralException(String(_("Error in zlib during gzwrite: ")) + m);
+ }
+ }
+ itell += err;
+ return err;
+ } else {
+ itell += count = ::write(h, buf, count);
+ return count;
+ }
+}
+
+ssize_t Handle::uread(void * buf, size_t count) {
+ if (z >= 10) {
+ } if (z) {
+#ifdef DEBUG
+ printm(M_BARE, String(_("Performing gzread of ")) + count + _(" byte(s) for handle ") + h + "\n");
+#endif
+ int err = gzread(zfile, buf, count);
+ if (err == -1) {
+ gzerror(zfile, &err);
+ if (err == Z_ERRNO) {
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+ itell += err;
+ return err;
+ } else {
+#if defined (_WIN32) && !defined (NO_HFILE)
+ if (hFile) {
+ DWORD rcount;
+ if (!ReadFile(hFile, buf, count, &rcount, 0)) {
+ // Error..
+ }
+ itell += count = rcount;
+ } else
+#endif
+ itell += count = ::read(h, buf, count);
+ return count;
+ }
+}
+
+off_t Handle::tell() const {
+ if (z) {
+ return gztell(zfile);
+ } else {
+ return itell;
+ }
+}
+
+bool Handle::CanSeek() const {
+ return 0;
+}
+
+off_t Handle::seek(off_t offset, int whence) throw(GeneralException) {
+ if (z) {
+ return itell = gzseek(zfile, offset, whence);
+ } else {
+ throw IOGeneral(_("Handle ") + GetName() + _(" can't seek"));
+ }
+}
+
+Uint8 Handle::readU8() {
+ Uint8 r;
+ read(&r, 1);
+ return r;
+}
+
+Uint16 Handle::readU16() {
+ Uint16 r;
+ read(&r, 2);
+#ifdef WORDS_BIGENDIAN
+ return bswap_16(r);
+#else
+ return r;
+#endif
+}
+
+Uint32 Handle::readU32() {
+ Uint32 r;
+ read(&r, 4);
+#ifdef WORDS_BIGENDIAN
+ return bswap_32(r);
+#else
+ return r;
+#endif
+}
+
+void Handle::writeU8(Uint8 v) {
+ write(&v, 1);
+}
+
+void Handle::writeU16(Uint16 v) {
+#ifdef WORDS_BIGENDIAN
+ Uint16 t = bswap_16(v);
+ write(&t, 2);
+#else
+ write(&v, 2);
+#endif
+}
+
+void Handle::writeU32(Uint32 v) {
+#ifdef WORDS_BIGENDIAN
+ Uint32 t = bswap_32(v);
+ write(&t, 4);
+#else
+ write(&v, 4);
+#endif
+}
+
+void Handle::copyto(Handle * dest, ssize_t s) {
+ copy(this, dest, s);
+}
+
+void Handle::copyfrom(Handle * src, ssize_t s) {
+ copy(src, this, s);
+}
+
+void copyone(Handle * s, Handle * d, ssize_t size) {
+ long i;
+ unsigned char c;
+ long r;
+
+ if (size < 0)
+ size = s->GetSize();
+
+ for (i = 0; (i < size) || (size < 0); i++) {
+ r = s->read(&c, 1);
+ if (r == 0) {
+ break;
+ }
+ d->write(&c, 1);
+ }
+}
+
+#define BSIZE 20480
+
+void copy(Handle * s, Handle * d, ssize_t size) {
+ long i;
+ static unsigned char b[BSIZE];
+ long r;
+
+ if (size < 0)
+ size = s->GetSize();
+
+ LOCK;
+
+ while (size) {
+ if ((size > BSIZE) || (size < 0)) {
+ r = s->read(b, BSIZE);
+ if (r)
+ d->write(b, r);
+ } else {
+ r = s->read(b, size);
+ if (r)
+ d->write(b, r);
+ }
+ if (!r)
+ break;
+ if (size > 0)
+ size -= r;
+ }
+
+ UNLOCK;
+}
+
+void Handle::Flush() {
+ if (!CanWrite())
+ return;
+ if (h < 0)
+ return;
+ if (z >= 10) {
+
+ } else if (z) {
+ gzflush(&z, Z_FULL_FLUSH);
+ } else {
+#ifdef HAVE_FSYNC
+ fsync(h);
+#endif
+ }
+}
+
+void * Handle::mmap(off_t offset, size_t length) throw (GeneralException) {
+ void * r;
+
+ if (h == -1) {
+ throw GeneralException("Can't mmap() a virtual handle");
+ }
+#ifdef _WIN32
+ if (!hFile) {
+ throw GeneralException("Can't mmap() a non-hFile handle under windows");
+ }
+#endif
+ if (mapped) {
+ throw GeneralException("Handle already mmap()ped");
+ }
+ mapped = true;
+ if (length == -1) {
+ length = GetSize();
+ }
+ maplength = length;
+#ifndef _WIN32
+ r = ::mmap(0, length, (CanRead() ? PROT_READ : 0) | (CanWrite() ? PROT_WRITE : 0), MAP_SHARED, h, offset);
+ if (!r) {
+ throw GeneralException(String("Was not able to mmap(): ") + strerror(errno));
+ }
+#else
+ hMapObject = CreateFileMapping(
+ hFile,
+ 0,
+ CanWrite() ? PAGE_READWRITE : PAGE_READONLY,
+ 0,
+ length,
+ GetName().to_charp());
+ if (hMapObject != NULL) {
+ r = MapViewOfFile(
+ hMapObject,
+ CanWrite() ? FILE_MAP_WRITE : FILE_MAP_READ,
+ 0,
+ offset,
+ length);
+ if (!r) {
+ CloseHandle(hMapObject);
+ throw GeneralException("Was not able to MapViewOfFile()");
+ }
+ } else {
+ throw GeneralException("Was not able to CreateFileMapping()");
+ }
+#endif
+
+ mappedarea = r;
+
+ return r;
+}
+
+void Handle::munmap() throw (GeneralException) {
+ if (!mapped) {
+ throw GeneralException("Can't munmap, was not mapped");
+ }
+#ifndef _WIN32
+ if (::munmap(mappedarea, maplength)) {
+ throw GeneralException(String("Was not able to munmap(): ") + strerror(errno));
+ }
+#else
+ if (!UnmapViewOfFile(mappedarea)) {
+ throw GeneralException("Was not able to UnmapViewOfFile()");
+ }
+ CloseHandle(hMapObject);
+#endif
+ mapped = false;
+ mappedarea = 0;
+ maplength = 0;
+}
diff --git a/lib/HttpServ.cc b/lib/HttpServ.cc
index a8e7301..a4101a7 100644
--- a/lib/HttpServ.cc
+++ b/lib/HttpServ.cc
@@ -1,473 +1,473 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "Socket.h"
-#include "Action.h"
-#include "HttpServ.h"
-#include "Buffer.h"
-#include "ReadJob.h"
-#include "CopyJob.h"
-#include "Task.h"
-#include "gettext.h"
-
-String endhl = "\r\n", endnl = "\n";
-
-class ProcessRequest : public Task {
- public:
- ProcessRequest(Action *, const Socket &, const String &, int);
- virtual ~ProcessRequest() {}
- virtual String GetName();
- protected:
- virtual int Do() throw (GeneralException);
- private:
- String GetMime(const String &);
- bool ParseUri(String &, String &, String &, Handle *);
- void ParseVars(Handle *, int);
- void ShowError(Handle *);
- void SendHeads(Handle *, const String &, const String & = "", time_t = -1);
- void SendRedirect(Handle *);
-
- String file, domain, t;
- Buffer b;
- Task * c, * a;
- Action * f;
- int len, localport;
- Action * p;
- Socket s;
-
- String name, host, gvars;
- Variables * Vars, * Heads;
- bool bad, hasvars, post;
-};
-
-ProcessRequest::ProcessRequest(Action * ap, const Socket & as, const String & aname, int aport) : localport(aport), p(ap), s(as), name(aname) {
- SetBurst();
-}
-
-String ProcessRequest::GetName() {
- return _("Processing HTTP request");
-}
-
-int ProcessRequest::Do() throw(GeneralException) {
- switch (current) {
- case 0:
- if (!s.IsConnected()) return TASK_DONE;
-
- c = new ReadJob(&s, &b);
- WaitFor(c);
- current = 1;
- Suspend(TASK_ON_HOLD);
-
- case 1:
- delete c;
-
- bad = false;
-
-// std::cerr << "---- Got a request from handle " << s.GetHandle() << " \n";
-
- post = ParseUri(file, domain, gvars, &b);
-
- Heads = new Variables();
- Vars = new Variables();
-
- len = -1;
- do {
- int p;
- b >> t;
-// std::cerr << "Read Request (n): " << t << std::endl;
- if ((t.strstr("Content-Length: ") == 0) || (t.strstr("Content-length: ") == 0)) {
-// std::cerr << "Saw 'Content-Lenght:', reading length from '" << t.extract(16) << "'\n";
- len = t.extract(16).to_int();
- }
- if (t.strstr("Host: ") == 0) {
- host = t.extract(6);
- }
-
- if ((p = t.strchr(':')) >= 0) {
- String s = t.extract(0, p - 1);
- s += '=';
- s += t.extract(p + 2);
- Heads->Add(s);
- }
- } while (t.strlen());
-
-// std::cerr << "---- Processing it.\n";
-
- hasvars = false;
-
- if (post) {
- // On a pas eu de ligne 'Content-Length' mais on a eu une méthode POST.
- // Cela est une erreur.
- if (len == -1) {
-// std::cerr << "Error: method POST but no Content-Length\n";
- bad = true;
- } else {
-// std::cerr << "Got a POST request. Parsing variables. (len = " << len << ")\n";
- // Les variables seront initialisées ici.
- hasvars = true;
- }
- }
-
- current = 2;
- if (hasvars && (len)) {
- c = new CopyJob(&s, &b, len);
- WaitFor(c);
- Suspend();
- } else {
- c = 0;
- }
-
- case 2:
- if (gvars != "") {
- Buffer b2;
- b2 << gvars;
- ParseVars(&b2, gvars.strlen());
- }
- if (hasvars) {
- if (c) delete c;
- ParseVars(&b, len);
- }
-
- std::cerr << " Domain = '" << domain << "' - File = '" << file << "'\n";
-
- if (!bad) {
- // Nous vérifions le domaine.
- if (domain != "") {
- bad = true;
- // Les domaines valides sont '/', '/bin' et '/image'.
- if (domain == "/image") bad = false;
- if (domain == "/bin") bad = false;
- if (domain == "/") bad = false;
- if (bad) {
- std::cerr << _("Error: bad domain.\n");
- }
- } else {
- // L'url sans domaine ni fichier est valide. (cela arrive sur certains navigateurs...)
- bad = (file != "");
- }
- }
-
- a = 0;
-
- if (bad) {
- ShowError(&b);
- } else {
- if (((domain == "") || (domain == "/")) && (file == "")) {
- // Si le navigateur a demandé l'URL '/', alors on renvoie une notification
- // de redirection.
- SendRedirect(&b);
- } else if (domain == "/bin") {
- // Le domaine 'bin' est réservé aux actions. On cherche donc l'action à effectuer.
- if ((f = p->Look4URL(file))) {
- SendHeads(&b, "text/html");
- a = f->Do(Vars, Heads, &s);
- } else {
- ShowError(&b);
- }
- } else {
- // Dans tous les autres cas de domaine, on cherche le fichier dans le répertoire datas.
- // On utilise try au cas où le fichier n'existe pas et donc que le constructeur
- // d'input renvoie une erreur.
- try {
- Handle * i = new Input(String("datas/") + file);
- SendHeads(&b, GetMime(file), String("Accept-Ranges: bytes") + endhl + "Content-Length: " + (unsigned long long int) i->GetSize() + endhl, i->GetModif());
- i->SetNonBlock();
- a = new CopyJob(i, &s);
- std::cerr << _("File found, dumping.\n");
- }
- catch (IOGeneral e) {
- ShowError(&b);
- std::cerr << _("File not found, error showed.\n");
- }
- }
- }
-
- if (a) a->Stop();
-
- delete Vars;
- delete Heads;
-// std::cerr << "---- Sending header buffer.\n";
- c = new CopyJob(&b, &s, -1, false);
- WaitFor(c);
- current = 3;
- Suspend();
-
- case 3:
- delete c;
-
- if (a) {
-// std::cerr << "---- Sending contents.\n";
- a->Restart();
- WaitFor(a);
- current = 4;
- Suspend();
- }
-
- case 4:
- if (a) delete a;
-// std::cerr << "---- End of Request.\n";
- }
- return TASK_DONE;
-}
-
-void ProcessRequest::ParseVars(Handle * s, int len) {
- String t, v;
- char conv[3], l;
- int hconv, nbvars;
- ssize_t pos = 0, next;
-
- t = "";
- for (int i = 0; i < len; i++) {
- s->read(&l, 1);
- t += l;
- }
-// std::cerr << "Post variables line: '" << t << "'\n";
-
-
- // Les variables sont sous la forme 'var1=val1&var2=val2&val3=var3'. Donc le nombre d'occurences
- // du caractère '=' indique le nombre de variables.
- nbvars = t.strchrcnt('=');
-
- for (int i = 0; i < nbvars; i++) {
- // Les variables sont sous la forme 'var1=val1&var2=val2&val3=var3'. Donc on cherche le caractère
- // & dans la chaine POST.
- next = t.strchr('&', pos);
- if (next < 0) next = t.strlen();
- v = "";
- while (pos != next) {
- switch (t[pos]) {
- // Le navigateur encode les caractères spéciaux à l'aide du format %XX où XX indique
- // la valeur hexadécimale du caractère. Nous encodons surtout les caractères
- // ' ', '=', '%', et '/' avec cette technique.
- case '%':
- pos++;
- conv[0] = t[pos++];
- conv[1] = t[pos++];
- conv[2] = '\0';
- sscanf(conv, "%x", &hconv);
- v += ((char) hconv);
- break;
- // Certains navigateurs utilisent '+' pour indiquer ' ' (qui est illégal) au lieu
- // d'utiliser %20.
- case '+':
- v += ' ';
- pos++;
- break;
- default:
- v += t[pos++];
- }
- }
-// std::cerr << "Pushing HTTP variable: " << v << std::endl;
- Vars->Add(v);
- pos++;
- }
-}
-
-/*
- * Cette fonction renverra true si la méthode est une méthode POST.
- * Les Strings domain et file seront modifiées afin de renvoyer le domaine
- * et le fichier lut. La string s doit donner la première ligne de la requète,
- * c'est à dire la méthode demandée par le client.
- */
-
-bool ProcessRequest::ParseUri(String & file, String & domain, String & gvars, Handle * s) {
- String t, Uri;
- bool post = false;
- const char * p = 0;
- ssize_t sppos;
-
- *s >> t;
- std::cerr << _("Read Request (1): ") << t << std::endl;
-
- int IPos = t.strchr('?');
-
- gvars = "";
-
- if (IPos >= 0) {
- int HPos = t.strchr(' ', IPos);
- char * sdup = t.strdup(0, IPos - 1);
- gvars = t.extract(IPos + 1, HPos - 1);
- t = sdup;
- free(sdup);
- }
-
-// std::cerr << "New request: " << t << ", gvars = " << gvars << std::endl;
-
- bad = false;
-
- // p nous indiquera la position de la chaîne URL.
- switch (t[0]) {
- case 'P': /* POST? */
- if (t.extract(1, 4) == "OST ") {
- p = t.to_charp(5);
- post = true;
- } else {
-// std::cerr << "Error: unknow request.\n";
- bad = true;
- }
- break;
- case 'G': /* GET? */
- if (t.extract(1, 3) == "ET ") {
- p = t.to_charp(4);
- } else {
-// std::cerr << "Error: unknow request.\n";
- bad = true;
- }
- break;
- default:
-// std::cerr << "Error: unknow request.\n";
- bad = true;
- }
-
- if (!bad) {
- ssize_t poshttp, posslash;
- Uri = p;
- sppos = Uri.strrchr(' ');
- p = Uri.to_charp(0, sppos - 1);
- Uri = p;
- // On enlève tout le host spécifié éventuellement dans la requete.
- if ((poshttp = Uri.strstr("http://")) > 0) {
- Uri = Uri.to_charp(poshttp + 7);
- posslash = Uri.strchr('/');
- // Certains navigateurs indiqueront uniquement http://host comme URL.
- if (posslash >= 0) {
- host = Uri.extract(0, posslash - 1);
- Uri = Uri.to_charp(posslash);
- } else {
- host = Uri;
- Uri = "";
- }
- }
- posslash = Uri.strrchr('/');
- file = Uri.to_charp(posslash + 1);
- if (posslash > 0) {
- domain = Uri.to_charp(0, posslash - 1);
- } else {
- domain = "";
- }
- }
- return post;
-}
-
-/*
- * Ceci sert à rediriger le navigateur vers l'url de démarrage.
- */
-void ProcessRequest::SendRedirect(Handle * s) {
- *s << "HTTP/1.1 301 Moved Permanently" << endhl <<
- "Server: " << name << endhl <<
- "Location: http://" << host << "/bin/start" << endhl <<
- "Cache-Control: no-cache" << endhl <<
- "Connection: closed" << endhl <<
- "Content-Type: text/html" << endhl << endhl <<
- "<HTML><HEAD><TITLE>301 - Moved Permanently</TITLE></HEAD>" << endnl <<
- "<BODY><center><b><h2>You should be redirected to the " << endnl << endnl <<
- "<a href=\"http://" << host << "/bin/start\">start page</a></h2></b></center>" << endnl <<
- "</BODY></HTML>" << endnl;
-}
-
-/*
- * Nous envoyons les entetes de réponse HTTP.
- */
-
-void ProcessRequest::SendHeads(Handle * s, const String & mime, const String & extra, time_t lm) {
- time_t t = time(NULL);
- struct tm * ft = gmtime(&t);
- char buf[1024];
- strftime(buf, 1024, "%a, %d %b %Y %H:%M:%S GMT", ft);
- *s << "HTTP/1.1 200 OK" << endhl <<
- "Date: " << buf << endhl <<
- "Server: " << name << endhl;
- if (lm >=0) {
- ft = gmtime(&lm);
- strftime(buf, 1024, "%a, %d %b %Y %H:%M:%S GMT", ft);
- }
- *s << "Last-Modified: " << buf << endhl << extra <<
- "Connection: closed" << endhl <<
- "Content-Type: " << mime << endhl << endhl;
-}
-
-/*
- * Affichage d'une erreur 404.
- */
-
-void ProcessRequest::ShowError(Handle * s) {
- *s << "HTTP/1.1 404 Not Found" << endhl <<
- "Server: " << name << endhl <<
- "Cache-Control: no-cache" << endhl <<
- "Connection: closed" << endhl <<
- "Content-Type: text/html" << endhl << endhl <<
- "<HTML><HEAD><TITLE>404 - Error</TITLE></HEAD>" << endnl <<
- "<BODY><center><b><h2>The server was unable to process your query</h2></b></center>" << endnl <<
- "Click <A HREF=\"/\">here</A> to go the main page." <<
- "</BODY></HTML>" << endnl;
-}
-
-/*
- * Sert à déterminer le type mime à partir de l'extension du fichier.
- * Par défaut, nous mettons "text/plain".
- */
-
-String ProcessRequest::GetMime(const String & f) {
- String ext;
- size_t ppos;
-
- ppos = f.strrchr('.');
-
- if (ppos >= 0) {
- ext = f.extract(ppos + 1);
- if (ext == "jpg") return "image/jpeg";
- if (ext == "jpeg") return "image/jpeg";
- if (ext == "htm") return "text/html";
- if (ext == "html") return "text/html";
- if (ext == "gif") return "image/gif";
- if (ext == "png") return "image/png";
- if (ext == "class") return "application/octet-stream";
- }
-
- return "text/plain";
-}
-
-HttpServ::HttpServ(Action * ap, int port, const String & nname) throw (GeneralException) {
- bool r = true;
-
- p = ap;
- name = nname;
- localport = port;
-
-// std::cerr << "Initialising Mini HTTP-Server on port " << localport << std::endl;
-
- r = Listener.SetLocal("", port);
- if (!r) {
- throw GeneralException(_("Initialisation of the Mini HTTP-Server failed: can't bind"));
- }
-
- r = Listener.Listen();
-
- if (!r) {
- throw GeneralException(_("Initialisation of the Mini HTTP-Server failed: can't listen"));
- }
-
- Listener.SetNonBlock();
- WaitFor(&Listener, W4_STICKY | W4_READING);
-
-// std::cerr << "Mini HTTP-Server '" << name << "' ready and listening for port " << port << std::endl;
-}
-
-HttpServ::~HttpServ(void) {
- Listener.close();
-}
-
-int HttpServ::Do() throw (GeneralException) {
- try {
- Socket s = Listener.Accept();
- s.SetNonBlock();
- new ProcessRequest(p, s, name, localport);
- }
- catch (GeneralException) {
- }
- return TASK_ON_HOLD;
-}
-
-String HttpServ::GetName() {
- return String("Mini HTTP-Server '") + name + "'";
-}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "Socket.h"
+#include "Action.h"
+#include "HttpServ.h"
+#include "Buffer.h"
+#include "ReadJob.h"
+#include "CopyJob.h"
+#include "Task.h"
+#include "gettext.h"
+
+String endhl = "\r\n", endnl = "\n";
+
+class ProcessRequest : public Task {
+ public:
+ ProcessRequest(Action *, const Socket &, const String &, int);
+ virtual ~ProcessRequest() {}
+ virtual String GetName();
+ protected:
+ virtual int Do() throw (GeneralException);
+ private:
+ String GetMime(const String &);
+ bool ParseUri(String &, String &, String &, Handle *);
+ void ParseVars(Handle *, int);
+ void ShowError(Handle *);
+ void SendHeads(Handle *, const String &, const String & = "", time_t = -1);
+ void SendRedirect(Handle *);
+
+ String file, domain, t;
+ Buffer b;
+ Task * c, * a;
+ Action * f;
+ int len, localport;
+ Action * p;
+ Socket s;
+
+ String name, host, gvars;
+ Variables * Vars, * Heads;
+ bool bad, hasvars, post;
+};
+
+ProcessRequest::ProcessRequest(Action * ap, const Socket & as, const String & aname, int aport) : localport(aport), p(ap), s(as), name(aname) {
+ SetBurst();
+}
+
+String ProcessRequest::GetName() {
+ return _("Processing HTTP request");
+}
+
+int ProcessRequest::Do() throw(GeneralException) {
+ switch (current) {
+ case 0:
+ if (!s.IsConnected()) return TASK_DONE;
+
+ c = new ReadJob(&s, &b);
+ WaitFor(c);
+ current = 1;
+ Suspend(TASK_ON_HOLD);
+
+ case 1:
+ delete c;
+
+ bad = false;
+
+// std::cerr << "---- Got a request from handle " << s.GetHandle() << " \n";
+
+ post = ParseUri(file, domain, gvars, &b);
+
+ Heads = new Variables();
+ Vars = new Variables();
+
+ len = -1;
+ do {
+ int p;
+ b >> t;
+// std::cerr << "Read Request (n): " << t << std::endl;
+ if ((t.strstr("Content-Length: ") == 0) || (t.strstr("Content-length: ") == 0)) {
+// std::cerr << "Saw 'Content-Lenght:', reading length from '" << t.extract(16) << "'\n";
+ len = t.extract(16).to_int();
+ }
+ if (t.strstr("Host: ") == 0) {
+ host = t.extract(6);
+ }
+
+ if ((p = t.strchr(':')) >= 0) {
+ String s = t.extract(0, p - 1);
+ s += '=';
+ s += t.extract(p + 2);
+ Heads->Add(s);
+ }
+ } while (t.strlen());
+
+// std::cerr << "---- Processing it.\n";
+
+ hasvars = false;
+
+ if (post) {
+ // On a pas eu de ligne 'Content-Length' mais on a eu une méthode POST.
+ // Cela est une erreur.
+ if (len == -1) {
+// std::cerr << "Error: method POST but no Content-Length\n";
+ bad = true;
+ } else {
+// std::cerr << "Got a POST request. Parsing variables. (len = " << len << ")\n";
+ // Les variables seront initialisées ici.
+ hasvars = true;
+ }
+ }
+
+ current = 2;
+ if (hasvars && (len)) {
+ c = new CopyJob(&s, &b, len);
+ WaitFor(c);
+ Suspend();
+ } else {
+ c = 0;
+ }
+
+ case 2:
+ if (gvars != "") {
+ Buffer b2;
+ b2 << gvars;
+ ParseVars(&b2, gvars.strlen());
+ }
+ if (hasvars) {
+ if (c) delete c;
+ ParseVars(&b, len);
+ }
+
+ std::cerr << " Domain = '" << domain << "' - File = '" << file << "'\n";
+
+ if (!bad) {
+ // Nous vérifions le domaine.
+ if (domain != "") {
+ bad = true;
+ // Les domaines valides sont '/', '/bin' et '/image'.
+ if (domain == "/image") bad = false;
+ if (domain == "/bin") bad = false;
+ if (domain == "/") bad = false;
+ if (bad) {
+ std::cerr << _("Error: bad domain.\n");
+ }
+ } else {
+ // L'url sans domaine ni fichier est valide. (cela arrive sur certains navigateurs...)
+ bad = (file != "");
+ }
+ }
+
+ a = 0;
+
+ if (bad) {
+ ShowError(&b);
+ } else {
+ if (((domain == "") || (domain == "/")) && (file == "")) {
+ // Si le navigateur a demandé l'URL '/', alors on renvoie une notification
+ // de redirection.
+ SendRedirect(&b);
+ } else if (domain == "/bin") {
+ // Le domaine 'bin' est réservé aux actions. On cherche donc l'action à effectuer.
+ if ((f = p->Look4URL(file))) {
+ SendHeads(&b, "text/html");
+ a = f->Do(Vars, Heads, &s);
+ } else {
+ ShowError(&b);
+ }
+ } else {
+ // Dans tous les autres cas de domaine, on cherche le fichier dans le répertoire datas.
+ // On utilise try au cas où le fichier n'existe pas et donc que le constructeur
+ // d'input renvoie une erreur.
+ try {
+ Handle * i = new Input(String("datas/") + file);
+ SendHeads(&b, GetMime(file), String("Accept-Ranges: bytes") + endhl + "Content-Length: " + (unsigned long long int) i->GetSize() + endhl, i->GetModif());
+ i->SetNonBlock();
+ a = new CopyJob(i, &s);
+ std::cerr << _("File found, dumping.\n");
+ }
+ catch (IOGeneral e) {
+ ShowError(&b);
+ std::cerr << _("File not found, error showed.\n");
+ }
+ }
+ }
+
+ if (a) a->Stop();
+
+ delete Vars;
+ delete Heads;
+// std::cerr << "---- Sending header buffer.\n";
+ c = new CopyJob(&b, &s, -1, false);
+ WaitFor(c);
+ current = 3;
+ Suspend();
+
+ case 3:
+ delete c;
+
+ if (a) {
+// std::cerr << "---- Sending contents.\n";
+ a->Restart();
+ WaitFor(a);
+ current = 4;
+ Suspend();
+ }
+
+ case 4:
+ if (a) delete a;
+// std::cerr << "---- End of Request.\n";
+ }
+ return TASK_DONE;
+}
+
+void ProcessRequest::ParseVars(Handle * s, int len) {
+ String t, v;
+ char conv[3], l;
+ int hconv, nbvars;
+ ssize_t pos = 0, next;
+
+ t = "";
+ for (int i = 0; i < len; i++) {
+ s->read(&l, 1);
+ t += l;
+ }
+// std::cerr << "Post variables line: '" << t << "'\n";
+
+
+ // Les variables sont sous la forme 'var1=val1&var2=val2&val3=var3'. Donc le nombre d'occurences
+ // du caractère '=' indique le nombre de variables.
+ nbvars = t.strchrcnt('=');
+
+ for (int i = 0; i < nbvars; i++) {
+ // Les variables sont sous la forme 'var1=val1&var2=val2&val3=var3'. Donc on cherche le caractère
+ // & dans la chaine POST.
+ next = t.strchr('&', pos);
+ if (next < 0) next = t.strlen();
+ v = "";
+ while (pos != next) {
+ switch (t[pos]) {
+ // Le navigateur encode les caractères spéciaux à l'aide du format %XX où XX indique
+ // la valeur hexadécimale du caractère. Nous encodons surtout les caractères
+ // ' ', '=', '%', et '/' avec cette technique.
+ case '%':
+ pos++;
+ conv[0] = t[pos++];
+ conv[1] = t[pos++];
+ conv[2] = '\0';
+ sscanf(conv, "%x", &hconv);
+ v += ((char) hconv);
+ break;
+ // Certains navigateurs utilisent '+' pour indiquer ' ' (qui est illégal) au lieu
+ // d'utiliser %20.
+ case '+':
+ v += ' ';
+ pos++;
+ break;
+ default:
+ v += t[pos++];
+ }
+ }
+// std::cerr << "Pushing HTTP variable: " << v << std::endl;
+ Vars->Add(v);
+ pos++;
+ }
+}
+
+/*
+ * Cette fonction renverra true si la méthode est une méthode POST.
+ * Les Strings domain et file seront modifiées afin de renvoyer le domaine
+ * et le fichier lut. La string s doit donner la première ligne de la requète,
+ * c'est à dire la méthode demandée par le client.
+ */
+
+bool ProcessRequest::ParseUri(String & file, String & domain, String & gvars, Handle * s) {
+ String t, Uri;
+ bool post = false;
+ const char * p = 0;
+ ssize_t sppos;
+
+ *s >> t;
+ std::cerr << _("Read Request (1): ") << t << std::endl;
+
+ int IPos = t.strchr('?');
+
+ gvars = "";
+
+ if (IPos >= 0) {
+ int HPos = t.strchr(' ', IPos);
+ char * sdup = t.strdup(0, IPos - 1);
+ gvars = t.extract(IPos + 1, HPos - 1);
+ t = sdup;
+ free(sdup);
+ }
+
+// std::cerr << "New request: " << t << ", gvars = " << gvars << std::endl;
+
+ bad = false;
+
+ // p nous indiquera la position de la chaîne URL.
+ switch (t[0]) {
+ case 'P': /* POST? */
+ if (t.extract(1, 4) == "OST ") {
+ p = t.to_charp(5);
+ post = true;
+ } else {
+// std::cerr << "Error: unknow request.\n";
+ bad = true;
+ }
+ break;
+ case 'G': /* GET? */
+ if (t.extract(1, 3) == "ET ") {
+ p = t.to_charp(4);
+ } else {
+// std::cerr << "Error: unknow request.\n";
+ bad = true;
+ }
+ break;
+ default:
+// std::cerr << "Error: unknow request.\n";
+ bad = true;
+ }
+
+ if (!bad) {
+ ssize_t poshttp, posslash;
+ Uri = p;
+ sppos = Uri.strrchr(' ');
+ p = Uri.to_charp(0, sppos - 1);
+ Uri = p;
+ // On enlève tout le host spécifié éventuellement dans la requete.
+ if ((poshttp = Uri.strstr("http://")) > 0) {
+ Uri = Uri.to_charp(poshttp + 7);
+ posslash = Uri.strchr('/');
+ // Certains navigateurs indiqueront uniquement http://host comme URL.
+ if (posslash >= 0) {
+ host = Uri.extract(0, posslash - 1);
+ Uri = Uri.to_charp(posslash);
+ } else {
+ host = Uri;
+ Uri = "";
+ }
+ }
+ posslash = Uri.strrchr('/');
+ file = Uri.to_charp(posslash + 1);
+ if (posslash > 0) {
+ domain = Uri.to_charp(0, posslash - 1);
+ } else {
+ domain = "";
+ }
+ }
+ return post;
+}
+
+/*
+ * Ceci sert à rediriger le navigateur vers l'url de démarrage.
+ */
+void ProcessRequest::SendRedirect(Handle * s) {
+ *s << "HTTP/1.1 301 Moved Permanently" << endhl <<
+ "Server: " << name << endhl <<
+ "Location: http://" << host << "/bin/start" << endhl <<
+ "Cache-Control: no-cache" << endhl <<
+ "Connection: closed" << endhl <<
+ "Content-Type: text/html" << endhl << endhl <<
+ "<HTML><HEAD><TITLE>301 - Moved Permanently</TITLE></HEAD>" << endnl <<
+ "<BODY><center><b><h2>You should be redirected to the " << endnl << endnl <<
+ "<a href=\"http://" << host << "/bin/start\">start page</a></h2></b></center>" << endnl <<
+ "</BODY></HTML>" << endnl;
+}
+
+/*
+ * Nous envoyons les entetes de réponse HTTP.
+ */
+
+void ProcessRequest::SendHeads(Handle * s, const String & mime, const String & extra, time_t lm) {
+ time_t t = time(NULL);
+ struct tm * ft = gmtime(&t);
+ char buf[1024];
+ strftime(buf, 1024, "%a, %d %b %Y %H:%M:%S GMT", ft);
+ *s << "HTTP/1.1 200 OK" << endhl <<
+ "Date: " << buf << endhl <<
+ "Server: " << name << endhl;
+ if (lm >=0) {
+ ft = gmtime(&lm);
+ strftime(buf, 1024, "%a, %d %b %Y %H:%M:%S GMT", ft);
+ }
+ *s << "Last-Modified: " << buf << endhl << extra <<
+ "Connection: closed" << endhl <<
+ "Content-Type: " << mime << endhl << endhl;
+}
+
+/*
+ * Affichage d'une erreur 404.
+ */
+
+void ProcessRequest::ShowError(Handle * s) {
+ *s << "HTTP/1.1 404 Not Found" << endhl <<
+ "Server: " << name << endhl <<
+ "Cache-Control: no-cache" << endhl <<
+ "Connection: closed" << endhl <<
+ "Content-Type: text/html" << endhl << endhl <<
+ "<HTML><HEAD><TITLE>404 - Error</TITLE></HEAD>" << endnl <<
+ "<BODY><center><b><h2>The server was unable to process your query</h2></b></center>" << endnl <<
+ "Click <A HREF=\"/\">here</A> to go the main page." <<
+ "</BODY></HTML>" << endnl;
+}
+
+/*
+ * Sert à déterminer le type mime à partir de l'extension du fichier.
+ * Par défaut, nous mettons "text/plain".
+ */
+
+String ProcessRequest::GetMime(const String & f) {
+ String ext;
+ size_t ppos;
+
+ ppos = f.strrchr('.');
+
+ if (ppos >= 0) {
+ ext = f.extract(ppos + 1);
+ if (ext == "jpg") return "image/jpeg";
+ if (ext == "jpeg") return "image/jpeg";
+ if (ext == "htm") return "text/html";
+ if (ext == "html") return "text/html";
+ if (ext == "gif") return "image/gif";
+ if (ext == "png") return "image/png";
+ if (ext == "class") return "application/octet-stream";
+ }
+
+ return "text/plain";
+}
+
+HttpServ::HttpServ(Action * ap, int port, const String & nname) throw (GeneralException) {
+ bool r = true;
+
+ p = ap;
+ name = nname;
+ localport = port;
+
+// std::cerr << "Initialising Mini HTTP-Server on port " << localport << std::endl;
+
+ r = Listener.SetLocal("", port);
+ if (!r) {
+ throw GeneralException(_("Initialisation of the Mini HTTP-Server failed: can't bind"));
+ }
+
+ r = Listener.Listen();
+
+ if (!r) {
+ throw GeneralException(_("Initialisation of the Mini HTTP-Server failed: can't listen"));
+ }
+
+ Listener.SetNonBlock();
+ WaitFor(&Listener, W4_STICKY | W4_READING);
+
+// std::cerr << "Mini HTTP-Server '" << name << "' ready and listening for port " << port << std::endl;
+}
+
+HttpServ::~HttpServ(void) {
+ Listener.close();
+}
+
+int HttpServ::Do() throw (GeneralException) {
+ try {
+ Socket s = Listener.Accept();
+ s.SetNonBlock();
+ new ProcessRequest(p, s, name, localport);
+ }
+ catch (GeneralException) {
+ }
+ return TASK_ON_HOLD;
+}
+
+String HttpServ::GetName() {
+ return String("Mini HTTP-Server '") + name + "'";
+}
diff --git a/lib/IRC.cc b/lib/IRC.cc
index ad1a763..f29b2c1 100644
--- a/lib/IRC.cc
+++ b/lib/IRC.cc
@@ -1,234 +1,234 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "BString.h"
-#include "IRC.h"
-#include "HttpServ.h"
-
-ircmsg_t ircmsgs[MSG_COUNT] =
-
-{
- { "RPL_WELCOME", RPL_WELCOME },
- { "RPL_YOURHOST", RPL_YOURHOST },
- { "RPL_CREATED", RPL_CREATED },
- { "RPL_MYINFO", RPL_MYINFO },
- { "RPL_BOUNCE", RPL_BOUNCE },
- { "RPL_TRACELINK", RPL_TRACELINK },
- { "RPL_TRACECONNECTING", RPL_TRACECONNECTING },
- { "RPL_TRACEHANDSHAKE", RPL_TRACEHANDSHAKE },
- { "RPL_TRACEUNKNOWN", RPL_TRACEUNKNOWN },
- { "RPL_TRACEOPERATOR", RPL_TRACEOPERATOR },
- { "RPL_TRACEUSER", RPL_TRACEUSER },
- { "RPL_TRACESERVER", RPL_TRACESERVER },
- { "RPL_TRACESERVICE", RPL_TRACESERVICE },
- { "RPL_TRACENEWTYPE", RPL_TRACENEWTYPE },
- { "RPL_TRACECLASS", RPL_TRACECLASS },
- { "RPL_TRACERECONNECT", RPL_TRACERECONNECT },
- { "RPL_STATSLINKINFO", RPL_STATSLINKINFO },
- { "RPL_STATSCOMMANDS", RPL_STATSCOMMANDS },
- { "RPL_STATSCLINE", RPL_STATSCLINE },
- { "RPL_STATSILINE", RPL_STATSILINE },
- { "RPL_STATSQLINE", RPL_STATSQLINE },
- { "RPL_ENDOFSTATS", RPL_ENDOFSTATS },
- { "RPL_UMODEIS", RPL_UMODEIS },
- { "RPL_SERVICEINFO", RPL_SERVICEINFO },
- { "RPL_SERVICE", RPL_SERVICE },
- { "RPL_SERVLIST", RPL_SERVLIST },
- { "RPL_SERVLISTEND", RPL_SERVLISTEND },
- { "RPL_STATSVLINE", RPL_STATSVLINE },
- { "RPL_STATSUPTIME", RPL_STATSUPTIME },
- { "RPL_STATSOLINE", RPL_STATSOLINE },
- { "RPL_STATSHLINE", RPL_STATSHLINE },
- { "RPL_STATSPING", RPL_STATSPING },
- { "RPL_STATSDLINE", RPL_STATSDLINE },
- { "RPL_LUSERCLIENT", RPL_LUSERCLIENT },
- { "RPL_LUSEROP", RPL_LUSEROP },
- { "RPL_LUSERUNKNOWN", RPL_LUSERUNKNOWN },
- { "RPL_LUSERCHANNELS", RPL_LUSERCHANNELS },
- { "RPL_LUSERME", RPL_LUSERME },
- { "RPL_ADMINME", RPL_ADMINME },
- { "RPL_ADMINLOC1", RPL_ADMINLOC1 },
- { "RPL_ADMINLOC2", RPL_ADMINLOC2 },
- { "RPL_ADMINEMAIL", RPL_ADMINEMAIL },
- { "RPL_TRACELOG", RPL_TRACELOG },
- { "RPL_TRACEEND", RPL_TRACEEND },
- { "RPL_TRYAGAIN", RPL_TRYAGAIN },
- { "RPL_NONE", RPL_NONE },
- { "RPL_AWAY", RPL_AWAY },
- { "RPL_USERHOST", RPL_USERHOST },
- { "RPL_ISON", RPL_ISON },
- { "RPL_UNAWAY", RPL_UNAWAY },
- { "RPL_NOWAWAY", RPL_NOWAWAY },
- { "RPL_WHOISUSER", RPL_WHOISUSER },
- { "RPL_WHOISSERVER", RPL_WHOISSERVER },
- { "RPL_WHOISOPERATOR", RPL_WHOISOPERATOR },
- { "RPL_WHOWASUSER", RPL_WHOWASUSER },
- { "RPL_ENDOFWHO", RPL_ENDOFWHO },
- { "RPL_WHOISIDLE", RPL_WHOISIDLE },
- { "RPL_ENDOFWHOIS", RPL_ENDOFWHOIS },
- { "RPL_WHOISCHANNELS", RPL_WHOISCHANNELS },
- { "RPL_LISTSTART", RPL_LISTSTART },
- { "RPL_LIST", RPL_LIST },
- { "RPL_LISTEND", RPL_LISTEND },
- { "RPL_CHANNELMODEIS", RPL_CHANNELMODEIS },
- { "RPL_UNIQOPIS", RPL_UNIQOPIS },
- { "RPL_NOTOPIC", RPL_NOTOPIC },
- { "RPL_TOPIC", RPL_TOPIC },
- { "RPL_INVITING", RPL_INVITING },
- { "RPL_SUMMONING", RPL_SUMMONING },
- { "RPL_INVITELIST", RPL_INVITELIST },
- { "RPL_ENDOFINVITELIST", RPL_ENDOFINVITELIST },
- { "RPL_EXCEPTLIST", RPL_EXCEPTLIST },
- { "RPL_ENDOFEXCEPTLIST", RPL_ENDOFEXCEPTLIST },
- { "RPL_VERSION", RPL_VERSION },
- { "RPL_WHOREPLY", RPL_WHOREPLY },
- { "RPL_NAMREPLY", RPL_NAMREPLY },
- { "RPL_KILLDONE", RPL_KILLDONE },
- { "RPL_CLOSEEND", RPL_CLOSEEND },
- { "RPL_LINKS", RPL_LINKS },
- { "RPL_ENDOFLINKS", RPL_ENDOFLINKS },
- { "RPL_ENDOFNAMES", RPL_ENDOFNAMES },
- { "RPL_BANLIST", RPL_BANLIST },
- { "RPL_ENDOFBANLIST", RPL_ENDOFBANLIST },
- { "RPL_ENDOFWHOWAS", RPL_ENDOFWHOWAS },
- { "RPL_INFO", RPL_INFO },
- { "RPL_MOTD", RPL_MOTD },
- { "RPL_ENDOFINFO", RPL_ENDOFINFO },
- { "RPL_MOTDSTART", RPL_MOTDSTART },
- { "RPL_ENDOFMOTD", RPL_ENDOFMOTD },
- { "RPL_YOUREOPER", RPL_YOUREOPER },
- { "RPL_REHASHING", RPL_REHASHING },
- { "RPL_YOURESERVICE", RPL_YOURESERVICE },
- { "RPL_MYPORTIS", RPL_MYPORTIS },
- { "RPL_TIME", RPL_TIME },
- { "RPL_USERSSTART", RPL_USERSSTART },
- { "RPL_USERS", RPL_USERS },
- { "RPL_ENDOFUSERS", RPL_ENDOFUSERS },
- { "RPL_NOUSERS", RPL_NOUSERS },
- { "ERR_NOSUCHNICK", ERR_NOSUCHNICK },
- { "ERR_NOSUCHSERVER", ERR_NOSUCHSERVER },
- { "ERR_NOSUCHCHANNEL", ERR_NOSUCHCHANNEL },
- { "ERR_CANNOTSENDTOCHAN", ERR_CANNOTSENDTOCHAN },
- { "ERR_TOOMANYCHANNELS", ERR_TOOMANYCHANNELS },
- { "ERR_WASNOSUCHNICK", ERR_WASNOSUCHNICK },
- { "ERR_TOOMANYTARGETS", ERR_TOOMANYTARGETS },
- { "ERR_NOSUCHSERVICE", ERR_NOSUCHSERVICE },
- { "ERR_NOORIGIN", ERR_NOORIGIN },
- { "ERR_NORECIPIENT", ERR_NORECIPIENT },
- { "ERR_NOTEXTTOSEND", ERR_NOTEXTTOSEND },
- { "ERR_NOTOPLEVEL", ERR_NOTOPLEVEL },
- { "ERR_WILDTOPLEVEL", ERR_WILDTOPLEVEL },
- { "ERR_BADMASK", ERR_BADMASK },
- { "ERR_UNKNOWNCOMMAND", ERR_UNKNOWNCOMMAND },
- { "ERR_NOMOTD", ERR_NOMOTD },
- { "ERR_NOADMININFO", ERR_NOADMININFO },
- { "ERR_FILEERROR", ERR_FILEERROR },
- { "ERR_NONICKNAMEGIVEN", ERR_NONICKNAMEGIVEN },
- { "ERR_ERRONEUSNICKNAME", ERR_ERRONEUSNICKNAME },
- { "ERR_NICKNAMEINUSE", ERR_NICKNAMEINUSE },
- { "ERR_NICKCOLLISION", ERR_NICKCOLLISION },
- { "ERR_UNAVAILRESOURCE", ERR_UNAVAILRESOURCE },
- { "ERR_USERNOTINCHANNEL", ERR_USERNOTINCHANNEL },
- { "ERR_NOTONCHANNEL", ERR_NOTONCHANNEL },
- { "ERR_USERONCHANNEL", ERR_USERONCHANNEL },
- { "ERR_NOLOGIN", ERR_NOLOGIN },
- { "ERR_SUMMONDISABLED", ERR_SUMMONDISABLED },
- { "ERR_USERSDISABLED", ERR_USERSDISABLED },
- { "ERR_NOTREGISTERED", ERR_NOTREGISTERED },
- { "ERR_NEEDMOREPARAMS", ERR_NEEDMOREPARAMS },
- { "ERR_ALREADYREGISTRED", ERR_ALREADYREGISTRED },
- { "ERR_NOPERMFORHOST", ERR_NOPERMFORHOST },
- { "ERR_PASSWDMISMATCH", ERR_PASSWDMISMATCH },
- { "ERR_YOUREBANNEDCREEP", ERR_YOUREBANNEDCREEP },
- { "ERR_YOUWILLBEBANNED", ERR_YOUWILLBEBANNED },
- { "ERR_KEYSET", ERR_KEYSET },
- { "ERR_CHANNELISFULL", ERR_CHANNELISFULL },
- { "ERR_UNKNOWNMODE", ERR_UNKNOWNMODE },
- { "ERR_INVITEONLYCHAN", ERR_INVITEONLYCHAN },
- { "ERR_BANNEDFROMCHAN", ERR_BANNEDFROMCHAN },
- { "ERR_BADCHANNELKEY", ERR_BADCHANNELKEY },
- { "ERR_BADCHANMASK", ERR_BADCHANMASK },
- { "ERR_NOCHANMODES", ERR_NOCHANMODES },
- { "ERR_BANLISTFULL", ERR_BANLISTFULL },
- { "ERR_NOPRIVILEGES", ERR_NOPRIVILEGES },
- { "ERR_CHANOPRIVSNEEDED", ERR_CHANOPRIVSNEEDED },
- { "ERR_CANTKILLSERVER", ERR_CANTKILLSERVER },
- { "ERR_RESTRICTED", ERR_RESTRICTED },
- { "ERR_UNIQOPPRIVSNEEDED", ERR_UNIQOPPRIVSNEEDED },
- { "ERR_NOOPERHOST", ERR_NOOPERHOST },
- { "ERR_NOSERVICEHOST", ERR_NOSERVICEHOST },
- { "ERR_UMODEUNKNOWNFLAG", ERR_UMODEUNKNOWNFLAG },
- { "ERR_USERSDONTMATCH", ERR_USERSDONTMATCH },
-};
-
-Channel * Channel::start = 0;
-
-Channel::Channel(const String & Name, const String & Key) : next(0), prev(0) {
- next = start->next;
- prev = start;
- start = this;
- if (next) next->prev = this;
-}
-
-Channel::~Channel() {
- if (next) next->prev = prev;
- if (prev) prev->next = next; else start = next;
-}
-
-ircmsg_t find_msg(int code) {
- int i;
-
- ircmsg_t ret = {"", code};
-
- for (i = 0; i < MSG_COUNT; i++) {
- if (code == ircmsgs[i].code) return ircmsgs[i];
- }
-
- return ret;
-}
-
-IRC::IRC(const String & nick_n, const String & server_n, const String & user_n, const String & name_n, int port_n) :
- nick(nick_n), server(server_n), user(user_n), name(name_n), port(port_n), loginsequence(1) {
-}
-
-IRC::~IRC() {
-}
-
-bool IRC::Connect() {
- return sock.Connect(server, port);
-}
-
-int IRC::Parse(const String & line) {
- if (line.extract(0, 3) == "PING") {
- sock << "PONG" << line.extract(4) << endhl;
- std::cerr << "PING/PONG" << line.extract(4) << endhl;
- return 0;
- }
-
- return 1;
-}
-
-void IRC::MainLoop() {
- String line;
- int code, count = 0;
-
- while (true) {
- switch (loginsequence) {
- case 1:
- std::cerr << "Trying the login sequence..." << std::endl;
- sock << "NICK " << nick << endhl;
- sock << "USER " << user << " 8 * :" << name << endhl;
- loginsequence = 0;
- }
- sock >> line;
- if ((code = Parse(line))) {
- std::cerr << "Unparsable: " << line << std::endl;
- }
-
- if (count == 20) {
- sock << "JOIN #linuxdjeunz" << endhl;
- }
-
- count++;
- }
-}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "BString.h"
+#include "IRC.h"
+#include "HttpServ.h"
+
+ircmsg_t ircmsgs[MSG_COUNT] =
+
+{
+ { "RPL_WELCOME", RPL_WELCOME },
+ { "RPL_YOURHOST", RPL_YOURHOST },
+ { "RPL_CREATED", RPL_CREATED },
+ { "RPL_MYINFO", RPL_MYINFO },
+ { "RPL_BOUNCE", RPL_BOUNCE },
+ { "RPL_TRACELINK", RPL_TRACELINK },
+ { "RPL_TRACECONNECTING", RPL_TRACECONNECTING },
+ { "RPL_TRACEHANDSHAKE", RPL_TRACEHANDSHAKE },
+ { "RPL_TRACEUNKNOWN", RPL_TRACEUNKNOWN },
+ { "RPL_TRACEOPERATOR", RPL_TRACEOPERATOR },
+ { "RPL_TRACEUSER", RPL_TRACEUSER },
+ { "RPL_TRACESERVER", RPL_TRACESERVER },
+ { "RPL_TRACESERVICE", RPL_TRACESERVICE },
+ { "RPL_TRACENEWTYPE", RPL_TRACENEWTYPE },
+ { "RPL_TRACECLASS", RPL_TRACECLASS },
+ { "RPL_TRACERECONNECT", RPL_TRACERECONNECT },
+ { "RPL_STATSLINKINFO", RPL_STATSLINKINFO },
+ { "RPL_STATSCOMMANDS", RPL_STATSCOMMANDS },
+ { "RPL_STATSCLINE", RPL_STATSCLINE },
+ { "RPL_STATSILINE", RPL_STATSILINE },
+ { "RPL_STATSQLINE", RPL_STATSQLINE },
+ { "RPL_ENDOFSTATS", RPL_ENDOFSTATS },
+ { "RPL_UMODEIS", RPL_UMODEIS },
+ { "RPL_SERVICEINFO", RPL_SERVICEINFO },
+ { "RPL_SERVICE", RPL_SERVICE },
+ { "RPL_SERVLIST", RPL_SERVLIST },
+ { "RPL_SERVLISTEND", RPL_SERVLISTEND },
+ { "RPL_STATSVLINE", RPL_STATSVLINE },
+ { "RPL_STATSUPTIME", RPL_STATSUPTIME },
+ { "RPL_STATSOLINE", RPL_STATSOLINE },
+ { "RPL_STATSHLINE", RPL_STATSHLINE },
+ { "RPL_STATSPING", RPL_STATSPING },
+ { "RPL_STATSDLINE", RPL_STATSDLINE },
+ { "RPL_LUSERCLIENT", RPL_LUSERCLIENT },
+ { "RPL_LUSEROP", RPL_LUSEROP },
+ { "RPL_LUSERUNKNOWN", RPL_LUSERUNKNOWN },
+ { "RPL_LUSERCHANNELS", RPL_LUSERCHANNELS },
+ { "RPL_LUSERME", RPL_LUSERME },
+ { "RPL_ADMINME", RPL_ADMINME },
+ { "RPL_ADMINLOC1", RPL_ADMINLOC1 },
+ { "RPL_ADMINLOC2", RPL_ADMINLOC2 },
+ { "RPL_ADMINEMAIL", RPL_ADMINEMAIL },
+ { "RPL_TRACELOG", RPL_TRACELOG },
+ { "RPL_TRACEEND", RPL_TRACEEND },
+ { "RPL_TRYAGAIN", RPL_TRYAGAIN },
+ { "RPL_NONE", RPL_NONE },
+ { "RPL_AWAY", RPL_AWAY },
+ { "RPL_USERHOST", RPL_USERHOST },
+ { "RPL_ISON", RPL_ISON },
+ { "RPL_UNAWAY", RPL_UNAWAY },
+ { "RPL_NOWAWAY", RPL_NOWAWAY },
+ { "RPL_WHOISUSER", RPL_WHOISUSER },
+ { "RPL_WHOISSERVER", RPL_WHOISSERVER },
+ { "RPL_WHOISOPERATOR", RPL_WHOISOPERATOR },
+ { "RPL_WHOWASUSER", RPL_WHOWASUSER },
+ { "RPL_ENDOFWHO", RPL_ENDOFWHO },
+ { "RPL_WHOISIDLE", RPL_WHOISIDLE },
+ { "RPL_ENDOFWHOIS", RPL_ENDOFWHOIS },
+ { "RPL_WHOISCHANNELS", RPL_WHOISCHANNELS },
+ { "RPL_LISTSTART", RPL_LISTSTART },
+ { "RPL_LIST", RPL_LIST },
+ { "RPL_LISTEND", RPL_LISTEND },
+ { "RPL_CHANNELMODEIS", RPL_CHANNELMODEIS },
+ { "RPL_UNIQOPIS", RPL_UNIQOPIS },
+ { "RPL_NOTOPIC", RPL_NOTOPIC },
+ { "RPL_TOPIC", RPL_TOPIC },
+ { "RPL_INVITING", RPL_INVITING },
+ { "RPL_SUMMONING", RPL_SUMMONING },
+ { "RPL_INVITELIST", RPL_INVITELIST },
+ { "RPL_ENDOFINVITELIST", RPL_ENDOFINVITELIST },
+ { "RPL_EXCEPTLIST", RPL_EXCEPTLIST },
+ { "RPL_ENDOFEXCEPTLIST", RPL_ENDOFEXCEPTLIST },
+ { "RPL_VERSION", RPL_VERSION },
+ { "RPL_WHOREPLY", RPL_WHOREPLY },
+ { "RPL_NAMREPLY", RPL_NAMREPLY },
+ { "RPL_KILLDONE", RPL_KILLDONE },
+ { "RPL_CLOSEEND", RPL_CLOSEEND },
+ { "RPL_LINKS", RPL_LINKS },
+ { "RPL_ENDOFLINKS", RPL_ENDOFLINKS },
+ { "RPL_ENDOFNAMES", RPL_ENDOFNAMES },
+ { "RPL_BANLIST", RPL_BANLIST },
+ { "RPL_ENDOFBANLIST", RPL_ENDOFBANLIST },
+ { "RPL_ENDOFWHOWAS", RPL_ENDOFWHOWAS },
+ { "RPL_INFO", RPL_INFO },
+ { "RPL_MOTD", RPL_MOTD },
+ { "RPL_ENDOFINFO", RPL_ENDOFINFO },
+ { "RPL_MOTDSTART", RPL_MOTDSTART },
+ { "RPL_ENDOFMOTD", RPL_ENDOFMOTD },
+ { "RPL_YOUREOPER", RPL_YOUREOPER },
+ { "RPL_REHASHING", RPL_REHASHING },
+ { "RPL_YOURESERVICE", RPL_YOURESERVICE },
+ { "RPL_MYPORTIS", RPL_MYPORTIS },
+ { "RPL_TIME", RPL_TIME },
+ { "RPL_USERSSTART", RPL_USERSSTART },
+ { "RPL_USERS", RPL_USERS },
+ { "RPL_ENDOFUSERS", RPL_ENDOFUSERS },
+ { "RPL_NOUSERS", RPL_NOUSERS },
+ { "ERR_NOSUCHNICK", ERR_NOSUCHNICK },
+ { "ERR_NOSUCHSERVER", ERR_NOSUCHSERVER },
+ { "ERR_NOSUCHCHANNEL", ERR_NOSUCHCHANNEL },
+ { "ERR_CANNOTSENDTOCHAN", ERR_CANNOTSENDTOCHAN },
+ { "ERR_TOOMANYCHANNELS", ERR_TOOMANYCHANNELS },
+ { "ERR_WASNOSUCHNICK", ERR_WASNOSUCHNICK },
+ { "ERR_TOOMANYTARGETS", ERR_TOOMANYTARGETS },
+ { "ERR_NOSUCHSERVICE", ERR_NOSUCHSERVICE },
+ { "ERR_NOORIGIN", ERR_NOORIGIN },
+ { "ERR_NORECIPIENT", ERR_NORECIPIENT },
+ { "ERR_NOTEXTTOSEND", ERR_NOTEXTTOSEND },
+ { "ERR_NOTOPLEVEL", ERR_NOTOPLEVEL },
+ { "ERR_WILDTOPLEVEL", ERR_WILDTOPLEVEL },
+ { "ERR_BADMASK", ERR_BADMASK },
+ { "ERR_UNKNOWNCOMMAND", ERR_UNKNOWNCOMMAND },
+ { "ERR_NOMOTD", ERR_NOMOTD },
+ { "ERR_NOADMININFO", ERR_NOADMININFO },
+ { "ERR_FILEERROR", ERR_FILEERROR },
+ { "ERR_NONICKNAMEGIVEN", ERR_NONICKNAMEGIVEN },
+ { "ERR_ERRONEUSNICKNAME", ERR_ERRONEUSNICKNAME },
+ { "ERR_NICKNAMEINUSE", ERR_NICKNAMEINUSE },
+ { "ERR_NICKCOLLISION", ERR_NICKCOLLISION },
+ { "ERR_UNAVAILRESOURCE", ERR_UNAVAILRESOURCE },
+ { "ERR_USERNOTINCHANNEL", ERR_USERNOTINCHANNEL },
+ { "ERR_NOTONCHANNEL", ERR_NOTONCHANNEL },
+ { "ERR_USERONCHANNEL", ERR_USERONCHANNEL },
+ { "ERR_NOLOGIN", ERR_NOLOGIN },
+ { "ERR_SUMMONDISABLED", ERR_SUMMONDISABLED },
+ { "ERR_USERSDISABLED", ERR_USERSDISABLED },
+ { "ERR_NOTREGISTERED", ERR_NOTREGISTERED },
+ { "ERR_NEEDMOREPARAMS", ERR_NEEDMOREPARAMS },
+ { "ERR_ALREADYREGISTRED", ERR_ALREADYREGISTRED },
+ { "ERR_NOPERMFORHOST", ERR_NOPERMFORHOST },
+ { "ERR_PASSWDMISMATCH", ERR_PASSWDMISMATCH },
+ { "ERR_YOUREBANNEDCREEP", ERR_YOUREBANNEDCREEP },
+ { "ERR_YOUWILLBEBANNED", ERR_YOUWILLBEBANNED },
+ { "ERR_KEYSET", ERR_KEYSET },
+ { "ERR_CHANNELISFULL", ERR_CHANNELISFULL },
+ { "ERR_UNKNOWNMODE", ERR_UNKNOWNMODE },
+ { "ERR_INVITEONLYCHAN", ERR_INVITEONLYCHAN },
+ { "ERR_BANNEDFROMCHAN", ERR_BANNEDFROMCHAN },
+ { "ERR_BADCHANNELKEY", ERR_BADCHANNELKEY },
+ { "ERR_BADCHANMASK", ERR_BADCHANMASK },
+ { "ERR_NOCHANMODES", ERR_NOCHANMODES },
+ { "ERR_BANLISTFULL", ERR_BANLISTFULL },
+ { "ERR_NOPRIVILEGES", ERR_NOPRIVILEGES },
+ { "ERR_CHANOPRIVSNEEDED", ERR_CHANOPRIVSNEEDED },
+ { "ERR_CANTKILLSERVER", ERR_CANTKILLSERVER },
+ { "ERR_RESTRICTED", ERR_RESTRICTED },
+ { "ERR_UNIQOPPRIVSNEEDED", ERR_UNIQOPPRIVSNEEDED },
+ { "ERR_NOOPERHOST", ERR_NOOPERHOST },
+ { "ERR_NOSERVICEHOST", ERR_NOSERVICEHOST },
+ { "ERR_UMODEUNKNOWNFLAG", ERR_UMODEUNKNOWNFLAG },
+ { "ERR_USERSDONTMATCH", ERR_USERSDONTMATCH },
+};
+
+Channel * Channel::start = 0;
+
+Channel::Channel(const String & Name, const String & Key) : next(0), prev(0) {
+ next = start->next;
+ prev = start;
+ start = this;
+ if (next) next->prev = this;
+}
+
+Channel::~Channel() {
+ if (next) next->prev = prev;
+ if (prev) prev->next = next; else start = next;
+}
+
+ircmsg_t find_msg(int code) {
+ int i;
+
+ ircmsg_t ret = {"", code};
+
+ for (i = 0; i < MSG_COUNT; i++) {
+ if (code == ircmsgs[i].code) return ircmsgs[i];
+ }
+
+ return ret;
+}
+
+IRC::IRC(const String & nick_n, const String & server_n, const String & user_n, const String & name_n, int port_n) :
+ nick(nick_n), server(server_n), user(user_n), name(name_n), port(port_n), loginsequence(1) {
+}
+
+IRC::~IRC() {
+}
+
+bool IRC::Connect() {
+ return sock.Connect(server, port);
+}
+
+int IRC::Parse(const String & line) {
+ if (line.extract(0, 3) == "PING") {
+ sock << "PONG" << line.extract(4) << endhl;
+ std::cerr << "PING/PONG" << line.extract(4) << endhl;
+ return 0;
+ }
+
+ return 1;
+}
+
+void IRC::MainLoop() {
+ String line;
+ int code, count = 0;
+
+ while (true) {
+ switch (loginsequence) {
+ case 1:
+ std::cerr << "Trying the login sequence..." << std::endl;
+ sock << "NICK " << nick << endhl;
+ sock << "USER " << user << " 8 * :" << name << endhl;
+ loginsequence = 0;
+ }
+ sock >> line;
+ if ((code = Parse(line))) {
+ std::cerr << "Unparsable: " << line << std::endl;
+ }
+
+ if (count == 20) {
+ sock << "JOIN #linuxdjeunz" << endhl;
+ }
+
+ count++;
+ }
+}
diff --git a/lib/Image.cc b/lib/Image.cc
index 19d8aff..d098de3 100644
--- a/lib/Image.cc
+++ b/lib/Image.cc
@@ -1,88 +1,88 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "Image.h"
-#include "gettext.h"
-
-Image::Image(unsigned int ax, unsigned int ay) : x(ax), y(ay), img((Color *) malloc(x * y * sizeof(Color))) {
- Fill();
-}
-
-Image::~Image() {
- free(img);
-}
-
-bool Image::CanWrite() const {
- return false;
-}
-
-String Image::GetName() const {
- return String(_("Image ")) + x + "x" + y;
-}
-
-void Image::Fill(Color c) {
- for (unsigned int i = 0; i < x * y; i++) {
- img[i] = c;
- }
-}
-
-Color Image::GetPixel(unsigned int px, unsigned int py) const {
- if ((px >= x) || (py >= y)) {
- return Color(0, 0, 0, 0);
- }
-
- return img[x * py + px];
-}
-
-void Image::SetPixel(unsigned int px, unsigned int py, Color c) {
- if ((px >= x) || (py >= y)) {
- return;
- }
-
- img[x * py + px] = c;
-}
-
-#ifndef WORDS_BIGENDIAN
-#define WORDS_BIGENDIAN 0
-#else
-#undef WORDS_BIGENDIAN
-#define WORDS_BIGENDIAN 1
-#endif
-
-bool Image::Prepare(unsigned int f) {
- if (GetSize()) return false;
-
- switch (f) {
- case FORMAT_TGA_BASIC:
- TGAHeader Header;
- TGAFooter Footer;
-
- Header.IDLength = 0;
- Header.ColorMapType = 0;
- Header.ImageType = 2;
- Header.CM_FirstEntry = 0;
- Header.CM_Length = 0;
- Header.CM_EntrySize = 0;
- Header.IS_XOrigin = 0;
- Header.IS_YOrigin = 0;
- Header.IS_Width = WORDS_BIGENDIAN ? ((x & 0xff) << 8) | ((x & 0xff00) >> 8) : x;
- Header.IS_Height = WORDS_BIGENDIAN ? ((y & 0xff) << 8) | ((y & 0xff00) >> 8) : y;
- Header.IS_Depth = 32;
- Header.IS_Descriptor = 0x20;
-
- Footer.ExtOffset = 0;
- Footer.DevOffset = 0;
- strcpy(Footer.Sig, "TRUEVISION-XFILE.");
-
- write(&Header, sizeof(Header));
- write(img, x * y * sizeof(Color));
- write(&Footer, sizeof(Footer));
-
- return true;
-
- break;
- default:
- return false;
- }
-}
-
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "Image.h"
+#include "gettext.h"
+
+Image::Image(unsigned int ax, unsigned int ay) : x(ax), y(ay), img((Color *) malloc(x * y * sizeof(Color))) {
+ Fill();
+}
+
+Image::~Image() {
+ free(img);
+}
+
+bool Image::CanWrite() const {
+ return false;
+}
+
+String Image::GetName() const {
+ return String(_("Image ")) + x + "x" + y;
+}
+
+void Image::Fill(Color c) {
+ for (unsigned int i = 0; i < x * y; i++) {
+ img[i] = c;
+ }
+}
+
+Color Image::GetPixel(unsigned int px, unsigned int py) const {
+ if ((px >= x) || (py >= y)) {
+ return Color(0, 0, 0, 0);
+ }
+
+ return img[x * py + px];
+}
+
+void Image::SetPixel(unsigned int px, unsigned int py, Color c) {
+ if ((px >= x) || (py >= y)) {
+ return;
+ }
+
+ img[x * py + px] = c;
+}
+
+#ifndef WORDS_BIGENDIAN
+#define WORDS_BIGENDIAN 0
+#else
+#undef WORDS_BIGENDIAN
+#define WORDS_BIGENDIAN 1
+#endif
+
+bool Image::Prepare(unsigned int f) {
+ if (GetSize()) return false;
+
+ switch (f) {
+ case FORMAT_TGA_BASIC:
+ TGAHeader Header;
+ TGAFooter Footer;
+
+ Header.IDLength = 0;
+ Header.ColorMapType = 0;
+ Header.ImageType = 2;
+ Header.CM_FirstEntry = 0;
+ Header.CM_Length = 0;
+ Header.CM_EntrySize = 0;
+ Header.IS_XOrigin = 0;
+ Header.IS_YOrigin = 0;
+ Header.IS_Width = WORDS_BIGENDIAN ? ((x & 0xff) << 8) | ((x & 0xff00) >> 8) : x;
+ Header.IS_Height = WORDS_BIGENDIAN ? ((y & 0xff) << 8) | ((y & 0xff00) >> 8) : y;
+ Header.IS_Depth = 32;
+ Header.IS_Descriptor = 0x20;
+
+ Footer.ExtOffset = 0;
+ Footer.DevOffset = 0;
+ strcpy(Footer.Sig, "TRUEVISION-XFILE.");
+
+ write(&Header, sizeof(Header));
+ write(img, x * y * sizeof(Color));
+ write(&Footer, sizeof(Footer));
+
+ return true;
+
+ break;
+ default:
+ return false;
+ }
+}
+
diff --git a/lib/InPipe.cc b/lib/InPipe.cc
index fcbd1c6..efcab10 100644
--- a/lib/InPipe.cc
+++ b/lib/InPipe.cc
@@ -1,42 +1,42 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "InPipe.h"
-#include "Output.h"
-#include "gettext.h"
-
-InPipe::InPipe() : Handle(pipe(p, 0)), hooked(0) {
-}
-
-InPipe::InPipe(const InPipe & i) : Handle(i), hooked(i.hooked) {
- p[0] = GetHandle();
- p[1] = dup(i.p[1]);
-}
-
-InPipe::~InPipe() {
- if (hooked) {
- ::close(1);
- dup(Stdout.GetHandle());
- }
-}
-
-void InPipe::Hook() {
- if (!hooked) {
- hooked = 1;
- ::close(1);
- dup(p[1]);
- ::close(p[1]);
- }
-}
-
-bool InPipe::CanWrite() {
- return false;
-}
-
-bool InPipe::CanRead() {
- return true;
-}
-
-String InPipe::GetName() {
- return (String(_("Input pipe from stdout (")) + (hooked ? "" : _("not ")) + _("hooked)"));
-}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "InPipe.h"
+#include "Output.h"
+#include "gettext.h"
+
+InPipe::InPipe() : Handle(pipe(p, 0)), hooked(0) {
+}
+
+InPipe::InPipe(const InPipe & i) : Handle(i), hooked(i.hooked) {
+ p[0] = GetHandle();
+ p[1] = dup(i.p[1]);
+}
+
+InPipe::~InPipe() {
+ if (hooked) {
+ ::close(1);
+ dup(Stdout.GetHandle());
+ }
+}
+
+void InPipe::Hook() {
+ if (!hooked) {
+ hooked = 1;
+ ::close(1);
+ dup(p[1]);
+ ::close(p[1]);
+ }
+}
+
+bool InPipe::CanWrite() {
+ return false;
+}
+
+bool InPipe::CanRead() {
+ return true;
+}
+
+String InPipe::GetName() {
+ return (String(_("Input pipe from stdout (")) + (hooked ? "" : _("not ")) + _("hooked)"));
+}
diff --git a/lib/Input.cc b/lib/Input.cc
index 2e91e03..c27e168 100644
--- a/lib/Input.cc
+++ b/lib/Input.cc
@@ -1,580 +1,580 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: Input.cc,v 1.48 2004-11-27 21:35:19 pixel Exp $ */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-
-#include "Input.h"
-#include "Exceptions.h"
-#include "gettext.h"
-
-#ifndef S_ISREG
-#define S_ISREG(x) 1
-#endif
-
-#ifdef WORDS_BIGENDIAN
-#define BUILTIN_SIG 0x4e504151
-#else
-#define BUILTIN_SIG 0x5141504e
-#endif
-
-/*
-
- NPAQ file format
- ================
-
-off|siz|description
----+---+-----------
- 0 | 4 | Magic: NPAQ
- 4 | X | Index
-4+X| Y | Files
-
-Index:
-It's composed of entries. Each entries have the same format:
-
-off|siz|description
----+---+-----------
- 0 | 1 | name size = n
- 1 | n | file name
-1+n| 4 | file size
-5+n| 1 | type --> 0 = file / 1 = directory
-
-If it's a directory, it means the following entries belongs to this directory.
-If n = 0, there is nothing else afterward (no filesize nor type) and it
-means the end of the current directory. The end of the root directory
-means the end of the index.
-
-Files:
-Each file are gzipped. They are all concatenated after the index. They
-all start with a four bytes length which correspond to the unpacked size.
-The size in the index corresponds to the size of the gzipped result plus
-those 4 bytes.
-
-*/
-
-static Input::openresults_t gresults;
-
-Input::Input(const String & no) throw (GeneralException) :
- Handle(no.strlen() ? wrapopen(no, &gresults) : dup(0)),
- n(no) {
-
-#ifdef DEBUG
- printm(M_BARE, String(_("Opening file")) + no + _("Input at %p\n"), this);
-#endif
-
- if (GetHandle() < 0) {
-#ifdef DEBUG
- printm(M_BARE, "Got handle: %i opening file " + no + "\n", GetHandle());
-#endif
- throw IOGeneral(String(_("Error opening file ")) + no + _(" for reading: ") + strerror(errno));
- }
-
- results = gresults;
-
- UNLOCK
-
- fromarchive = false;
- if (results.name == "") {
- struct stat s;
- fstat(GetHandle(), &s);
- date_modif = s.st_mtime;
-
-#ifdef __linux__
- if (S_ISREG(s.st_mode)) {
-#endif
-#if 0
-#if defined (_WIN32) && !defined (NO_HFILE)
- if (hFile) {
- GetFileSize(hFile, (LPDWORD)&size);
- } else
-#endif
-#endif
- {
- size = seek(0, SEEK_END);
- seek(0, SEEK_SET);
- }
-#ifdef __linux__
- }
-#endif
- } else {
-#ifdef DEBUG
- printm(M_INFO, String(_("Opening file in archive, position ")) + results.ptr + "\n");
-#endif
- size = results.size;
- seek(results.ptr, SEEK_SET);
- size = readU32();
- date_modif = 0;
- SetZ();
- fromarchive = true;
- itell = 0;
- }
-}
-
-Input::Input(const Input & i) : Handle(i), n(i.n), size(i.size), date_modif(i.date_modif) {
-}
-
-bool Input::CanWrite() const {
- return 0;
-}
-
-bool Input::CanRead() const {
- return 1;
-}
-
-bool Input::CanSeek() const {
- struct stat s;
-
- fstat(GetHandle(), &s);
-
- return S_ISREG(s.st_mode);
-}
-
-String Input::GetName() const {
- return n;
-}
-
-ssize_t Input::GetSize() const {
- return size;
-}
-
-time_t Input::GetModif() const {
- return date_modif;
-}
-
-off_t Input::seek(off_t offset, int whence) throw (GeneralException) {
- if (!fromarchive) {
- if ((itell = lseek(GetHandle(), offset, whence)) < 0) {
- throw IOGeneral(String(_("Error seeking file ")) + GetName() + _(": ") + strerror(errno));
- }
-#ifdef PARANOID_SEEK
- if (itell != lseek(GetHandle(), 0, SEEK_CUR)) {
- throw IOGeneral(String(_("Error seeking file ")) + GetName() + _(": the position does not match"));
- }
-#endif
- return itell;
- } else {
- return Handle::seek(offset, whence);
- }
-}
-
-int Input::wrapopen(const String & fname, openresults_t * results) {
- LOCK;
-#ifdef DEBUG
- printm(M_INFO, _("Wrap-opening ") + fname + "\n");
-#endif
- if (fname[0] != '/') {
- Archive * t;
- t = Archive::inarchive(fname);
- if (t) {
-#ifdef DEBUG
- printm(M_BARE, _("Trying to open the file in archive, since it seems to be here\n"));
-#endif
- hFile = 0;
-#if defined (_WIN32) && !defined (NO_HFILE)
-// hFile = t->GetHandle()->GetHFile();
-#endif
- return t->open(fname, results);
- }
- }
- results->name = "";
- hFile = 0;
-#if !defined (_WIN32) || defined (NO_HFILE)
- return open(fname.to_charp(), O_RDONLY
-#ifdef _WIN32
- | O_BINARY
-#endif
- );
-#else
- hFile = CreateFile(fname.to_charp(), GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
- return _open_osfhandle((INT_PTR) hFile, O_RDONLY | O_BINARY);
-#endif
-}
-
-void Input::SetZ(int l) throw(GeneralException) {
- if (!fromarchive)
- Handle::SetZ(l);
-}
-
-Stdin_t::Stdin_t() { }
-
-bool Stdin_t::CanSeek() const {
- return 0;
-}
-
-String Stdin_t::GetName() const {
- return "Stdin";
-}
-
-#ifdef HOOK_STDS
-Stdin_t Stdin;
-#endif
-
-Archive * Archive::header = 0;
-
-Archive::Archive(const String & fname, int atype) :
- name(fname), archive(new Input(fname)), type(atype) {
- create();
-}
-
-Archive::Archive(Handle * hand, int atype) :
- name(hand->GetName()), archive(hand), type(atype) {
- create();
-}
-
-#ifdef _MSC_VER
-#pragma pack(1)
-#endif
-
-struct PEsection_t {
- char name[8];
- Uint32 VSize, VAdd, SizeOf, Pointer, PTRelocs, PTLNs;
- Uint16 NR, NLN;
- Uint32 Chars;
-} PACKED;
-
-struct elf_header_t {
- union {
- Uint8 raw[16];
- struct e_ident_t {
- Uint8 ei_magic[4];
- Uint8 ei_class;
- Uint8 ei_data;
- Uint8 ei_version;
- } cook;
- } e_ident;
- Uint16 e_type;
- Uint16 e_machine;
- Uint32 e_version;
- Uint32 e_entry;
- Uint32 e_phoff;
- Uint32 e_shoff;
- Uint32 e_flags;
- Uint16 e_ehsize;
- Uint16 e_phentsize;
- Uint16 e_phnum;
- Uint16 e_shentsize;
- Uint16 e_shnum;
- Uint16 e_shstrndx;
-} PACKED;
-
-struct elf_section_t {
- Uint32 sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size;
- Uint32 sh_link, sh_info, sh_addralign, sh_entsize;
-} PACKED;
-
-void Archive::create() throw (GeneralException) {
- char buffer[1024];
- int len;
- Uint32 sig, ptr, maxptr = 0, startptr;
- Uint16 sections;
- PEsection_t PEsection;
- size_t size;
- FileTree * p = &filetree, * t;
- String ifname;
- int i;
-
- switch(type) {
- case ARCHIVE_EXECUTABLE:
- startptr = archive->tell();
- sig = archive->readU32();
- archive->seek(-4, SEEK_CUR);
- if ((sig & 0xffff) == 0x5a4d) { /* MZ */
- archive->seek(60, SEEK_CUR);
- sig = archive->readU32();
- archive->seek(sig - 64, SEEK_CUR);
- sig = archive->readU32();
- if (sig != 0x4550)
- throw GeneralException(_("Archive: file is not a PE."));
- archive->seek(2, SEEK_CUR);
- sections = archive->readU16();
- archive->seek(240, SEEK_CUR);
- for (i = 0; i < sections; i++) {
- archive->read(&PEsection, sizeof(PEsection));
- printm(M_INFO, "Section: %s\n", PEsection.name);
- ptr = PEsection.Pointer + PEsection.SizeOf;
- if (ptr > maxptr)
- maxptr = ptr;
- }
- archive->seek(startptr - archive->tell() + maxptr, SEEK_CUR);
- } else if (sig == 0x464c457f) { /* ELF */
- elf_header_t head;
- elf_section_t sec;
- int cur_end, max_end = 0;
- int i;
-
- archive->read(&head, sizeof(head));
- archive->seek(startptr + head.e_shoff);
-
- for (i = 0; i < head.e_shnum; i++) {
- archive->read(&sec, sizeof(elf_section_t));
- archive->seek(head.e_shentsize - sizeof(elf_section_t), SEEK_CUR);
- if (sec.sh_type == 8)
- continue;
- cur_end = sec.sh_offset + sec.sh_size;
- if (cur_end > max_end)
- max_end = cur_end;
- }
- archive->seek(startptr + max_end);
- }
- case ARCHIVE_BUILTIN:
- memset(buffer, 0, 4);
- archive->read(buffer, 4);
- if (*((Uint32 *)buffer) != BUILTIN_SIG)
- throw GeneralException(_("Archive: not in built-in format."));
- while (p) {
- archive->read(buffer, 1);
- len = *buffer;
- if (len) {
- archive->read(buffer, len);
- buffer[len] = 0;
- ifname = buffer;
- size = archive->readU32();
- archive->read(buffer, 1);
-#ifdef DEBUG
- printm(M_BARE, _("Adding file `") + ifname + _("' to node `") + p->name + "'\n");
-#endif
- t = new FileTree(ifname, size, buffer[0], p);
- if (buffer[0])
- p = t;
- } else {
- p = p->Father();
- }
- }
- filetree.compute_ptrs(archive->tell());
- break;
- default:
- throw GeneralException(_("Archive: unsupported archive format."));
- }
-
- next = header;
- prev = 0;
- header = this;
- if (next)
- next->prev = this;
-}
-
-Archive::~Archive() {
- if (prev)
- prev->next = next;
- if (next)
- next->prev = prev;
- if (header == this)
- header = next;
-
- delete archive;
-}
-
-Archive * Archive::inarchive(const String & fname) {
- Archive * p;
- for (p = header; p; p = p->next) {
-#ifdef DEBUG
- printm(M_BARE, _("Looking for file `") + fname + _("' in archive ") + p->name + "\n");
-#endif
- if (p->inarchivein(fname)) {
-#ifdef DEBUG
- printm(M_BARE, _("File `") + fname + _("' found in archive ") + p->name + "\n");
-#endif
- return p;
- }
- }
- return 0;
-}
-
-int Archive::open(const String & fname, Input::openresults_t * results) {
-#if 0
- Archive * p;
-
- for (p = header; p; p = p->next) {
- bool t;
- t = p->inarchive(fname);
- if (t)
- return p->openin(fname, results);
- }
- throw IOGeneral(_("File `") + fname + _("' not found in archive collection."));
-#endif
- return openin(fname, results);
-}
-
-Handle * Archive::GetHandle() {
- return archive;
-}
-
-bool Archive::inarchivein(const String & fname) {
- Archive::FileTree * p = filetree.Child();
- ssize_t pos;
- String name = fname;
- String reste;
-
- while((name != "") && p) {
- pos = name.strchr('/');
- if (pos >= 0) {
- reste = name.extract(0, pos - 1);
- name = name.extract(pos + 1);
- } else {
- reste = name;
- name = "";
- }
-#ifdef DEBUG
- printm(M_BARE, _("Checking against node `") + p->name + "'\n");
-#endif
- while (p) {
- if (p->name == reste) {
- if (name != "")
- p = p->Child();
- break;
- } else {
- p = p->Next();
- }
- }
- }
-
- return p != 0;
-}
-
-int Archive::openin(const String & fname, Input::openresults_t * results) throw (GeneralException) {
- Archive::FileTree * p = filetree.Child();
- ssize_t pos;
- String name = fname;
- String reste;
-
- while((name != "") && p) {
- pos = name.strchr('/');
- if (pos >= 0) {
- reste = name.extract(0, pos - 1);
- name = name.extract(pos + 1);
- } else {
- reste = name;
- name = "";
- }
-
- while (p) {
- if (p->name == reste) {
- if (name != "")
- p = p->Child();
- break;
- } else {
- p = p->Next();
- }
- }
- }
-
- if (!p)
- throw IOGeneral(_("File `") + fname + _("' not in archive ") + this->name);
-
- if (p->Child())
- throw IOGeneral(_("File `") + fname + _("' in archive ") + this->name + _(" is a directory - can't open."));
-
- results->name = p->name;
- results->ptr = p->ptr;
- results->size = p->size;
- results->type = p->type;
- return archive->Dup();
-}
-
-Archive::FileTree::FileTree(const String & fname, size_t fsize, int ftype, Archive::FileTree * fFather) :
- name(fname), type(ftype), size(fsize), next(0), prev(0), father(fFather), child(0) {
- if (father) {
- if (father->child) {
- FileTree * p;
- for (p = father->child; p->next; p = p->next);
- p->next = this;
- prev = p;
- } else {
-#ifdef DEBUG
- std::cerr << _("Adding `") << fname << _("' as first child of node `") << father->name << "'\n";
-#endif
- father->child = this;
- }
- }
-}
-
-Archive::FileTree::~FileTree() {
- if (child)
- delete child;
- if (next)
- next->prev = prev;
- if (prev)
- prev->next = next;
- if (father) {
- if (father->child == this)
- father->child = next;
- father->touched();
- }
-}
-
-void Archive::FileTree::touched() {
- if (father)
- father->touched();
- else
- compute_ptrs(ptr);
-}
-
-int Archive::FileTree::compute_ptrs(size_t cptr) {
- ptr = cptr;
-
-#ifdef DEBUG
- std::cerr << _("Computed pointer for `") << name << "' = " << ptr << std::endl;
- if (child)
- std::cerr << _("Node has child\n");
- else
- std::cerr << _("Node is ") << size << _(" bytes large.\n");
-#endif
-
- if (child) {
- FileTree * p;
- size = 0;
- for (p = child; p; p = p->next) {
- size = p->compute_ptrs(ptr + size) - ptr;
- }
- }
-
- return size + ptr;
-}
-
-Archive::FileTree * Archive::FileTree::Father() {
- return father;
-}
-
-Archive::FileTree * Archive::FileTree::Child() {
- return child;
-}
-
-Archive::FileTree * Archive::FileTree::Next() {
- return next;
-}
-
-Archive::FileTree * Archive::FileTree::Prev() {
- return prev;
-}
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: Input.cc,v 1.49 2004-11-27 21:46:04 pixel Exp $ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
+#include "Input.h"
+#include "Exceptions.h"
+#include "gettext.h"
+
+#ifndef S_ISREG
+#define S_ISREG(x) 1
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define BUILTIN_SIG 0x4e504151
+#else
+#define BUILTIN_SIG 0x5141504e
+#endif
+
+/*
+
+ NPAQ file format
+ ================
+
+off|siz|description
+---+---+-----------
+ 0 | 4 | Magic: NPAQ
+ 4 | X | Index
+4+X| Y | Files
+
+Index:
+It's composed of entries. Each entries have the same format:
+
+off|siz|description
+---+---+-----------
+ 0 | 1 | name size = n
+ 1 | n | file name
+1+n| 4 | file size
+5+n| 1 | type --> 0 = file / 1 = directory
+
+If it's a directory, it means the following entries belongs to this directory.
+If n = 0, there is nothing else afterward (no filesize nor type) and it
+means the end of the current directory. The end of the root directory
+means the end of the index.
+
+Files:
+Each file are gzipped. They are all concatenated after the index. They
+all start with a four bytes length which correspond to the unpacked size.
+The size in the index corresponds to the size of the gzipped result plus
+those 4 bytes.
+
+*/
+
+static Input::openresults_t gresults;
+
+Input::Input(const String & no) throw (GeneralException) :
+ Handle(no.strlen() ? wrapopen(no, &gresults) : dup(0)),
+ n(no) {
+
+#ifdef DEBUG
+ printm(M_BARE, String(_("Opening file")) + no + _("Input at %p\n"), this);
+#endif
+
+ if (GetHandle() < 0) {
+#ifdef DEBUG
+ printm(M_BARE, "Got handle: %i opening file " + no + "\n", GetHandle());
+#endif
+ throw IOGeneral(String(_("Error opening file ")) + no + _(" for reading: ") + strerror(errno));
+ }
+
+ results = gresults;
+
+ UNLOCK
+
+ fromarchive = false;
+ if (results.name == "") {
+ struct stat s;
+ fstat(GetHandle(), &s);
+ date_modif = s.st_mtime;
+
+#ifdef __linux__
+ if (S_ISREG(s.st_mode)) {
+#endif
+#if 0
+#if defined (_WIN32) && !defined (NO_HFILE)
+ if (hFile) {
+ GetFileSize(hFile, (LPDWORD)&size);
+ } else
+#endif
+#endif
+ {
+ size = seek(0, SEEK_END);
+ seek(0, SEEK_SET);
+ }
+#ifdef __linux__
+ }
+#endif
+ } else {
+#ifdef DEBUG
+ printm(M_INFO, String(_("Opening file in archive, position ")) + results.ptr + "\n");
+#endif
+ size = results.size;
+ seek(results.ptr, SEEK_SET);
+ size = readU32();
+ date_modif = 0;
+ SetZ();
+ fromarchive = true;
+ itell = 0;
+ }
+}
+
+Input::Input(const Input & i) : Handle(i), n(i.n), size(i.size), date_modif(i.date_modif) {
+}
+
+bool Input::CanWrite() const {
+ return 0;
+}
+
+bool Input::CanRead() const {
+ return 1;
+}
+
+bool Input::CanSeek() const {
+ struct stat s;
+
+ fstat(GetHandle(), &s);
+
+ return S_ISREG(s.st_mode);
+}
+
+String Input::GetName() const {
+ return n;
+}
+
+ssize_t Input::GetSize() const {
+ return size;
+}
+
+time_t Input::GetModif() const {
+ return date_modif;
+}
+
+off_t Input::seek(off_t offset, int whence) throw (GeneralException) {
+ if (!fromarchive) {
+ if ((itell = lseek(GetHandle(), offset, whence)) < 0) {
+ throw IOGeneral(String(_("Error seeking file ")) + GetName() + _(": ") + strerror(errno));
+ }
+#ifdef PARANOID_SEEK
+ if (itell != lseek(GetHandle(), 0, SEEK_CUR)) {
+ throw IOGeneral(String(_("Error seeking file ")) + GetName() + _(": the position does not match"));
+ }
+#endif
+ return itell;
+ } else {
+ return Handle::seek(offset, whence);
+ }
+}
+
+int Input::wrapopen(const String & fname, openresults_t * results) {
+ LOCK;
+#ifdef DEBUG
+ printm(M_INFO, _("Wrap-opening ") + fname + "\n");
+#endif
+ if (fname[0] != '/') {
+ Archive * t;
+ t = Archive::inarchive(fname);
+ if (t) {
+#ifdef DEBUG
+ printm(M_BARE, _("Trying to open the file in archive, since it seems to be here\n"));
+#endif
+ hFile = 0;
+#if defined (_WIN32) && !defined (NO_HFILE)
+// hFile = t->GetHandle()->GetHFile();
+#endif
+ return t->open(fname, results);
+ }
+ }
+ results->name = "";
+ hFile = 0;
+#if !defined (_WIN32) || defined (NO_HFILE)
+ return open(fname.to_charp(), O_RDONLY
+#ifdef _WIN32
+ | O_BINARY
+#endif
+ );
+#else
+ hFile = CreateFile(fname.to_charp(), GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+ return _open_osfhandle((INT_PTR) hFile, O_RDONLY | O_BINARY);
+#endif
+}
+
+void Input::SetZ(int l) throw(GeneralException) {
+ if (!fromarchive)
+ Handle::SetZ(l);
+}
+
+Stdin_t::Stdin_t() { }
+
+bool Stdin_t::CanSeek() const {
+ return 0;
+}
+
+String Stdin_t::GetName() const {
+ return "Stdin";
+}
+
+#ifdef HOOK_STDS
+Stdin_t Stdin;
+#endif
+
+Archive * Archive::header = 0;
+
+Archive::Archive(const String & fname, int atype) :
+ name(fname), archive(new Input(fname)), type(atype) {
+ create();
+}
+
+Archive::Archive(Handle * hand, int atype) :
+ name(hand->GetName()), archive(hand), type(atype) {
+ create();
+}
+
+#ifdef _MSC_VER
+#pragma pack(1)
+#endif
+
+struct PEsection_t {
+ char name[8];
+ Uint32 VSize, VAdd, SizeOf, Pointer, PTRelocs, PTLNs;
+ Uint16 NR, NLN;
+ Uint32 Chars;
+} PACKED;
+
+struct elf_header_t {
+ union {
+ Uint8 raw[16];
+ struct e_ident_t {
+ Uint8 ei_magic[4];
+ Uint8 ei_class;
+ Uint8 ei_data;
+ Uint8 ei_version;
+ } cook;
+ } e_ident;
+ Uint16 e_type;
+ Uint16 e_machine;
+ Uint32 e_version;
+ Uint32 e_entry;
+ Uint32 e_phoff;
+ Uint32 e_shoff;
+ Uint32 e_flags;
+ Uint16 e_ehsize;
+ Uint16 e_phentsize;
+ Uint16 e_phnum;
+ Uint16 e_shentsize;
+ Uint16 e_shnum;
+ Uint16 e_shstrndx;
+} PACKED;
+
+struct elf_section_t {
+ Uint32 sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size;
+ Uint32 sh_link, sh_info, sh_addralign, sh_entsize;
+} PACKED;
+
+void Archive::create() throw (GeneralException) {
+ char buffer[1024];
+ int len;
+ Uint32 sig, ptr, maxptr = 0, startptr;
+ Uint16 sections;
+ PEsection_t PEsection;
+ size_t size;
+ FileTree * p = &filetree, * t;
+ String ifname;
+ int i;
+
+ switch(type) {
+ case ARCHIVE_EXECUTABLE:
+ startptr = archive->tell();
+ sig = archive->readU32();
+ archive->seek(-4, SEEK_CUR);
+ if ((sig & 0xffff) == 0x5a4d) { /* MZ */
+ archive->seek(60, SEEK_CUR);
+ sig = archive->readU32();
+ archive->seek(sig - 64, SEEK_CUR);
+ sig = archive->readU32();
+ if (sig != 0x4550)
+ throw GeneralException(_("Archive: file is not a PE."));
+ archive->seek(2, SEEK_CUR);
+ sections = archive->readU16();
+ archive->seek(240, SEEK_CUR);
+ for (i = 0; i < sections; i++) {
+ archive->read(&PEsection, sizeof(PEsection));
+ printm(M_INFO, "Section: %s\n", PEsection.name);
+ ptr = PEsection.Pointer + PEsection.SizeOf;
+ if (ptr > maxptr)
+ maxptr = ptr;
+ }
+ archive->seek(startptr - archive->tell() + maxptr, SEEK_CUR);
+ } else if (sig == 0x464c457f) { /* ELF */
+ elf_header_t head;
+ elf_section_t sec;
+ int cur_end, max_end = 0;
+ int i;
+
+ archive->read(&head, sizeof(head));
+ archive->seek(startptr + head.e_shoff);
+
+ for (i = 0; i < head.e_shnum; i++) {
+ archive->read(&sec, sizeof(elf_section_t));
+ archive->seek(head.e_shentsize - sizeof(elf_section_t), SEEK_CUR);
+ if (sec.sh_type == 8)
+ continue;
+ cur_end = sec.sh_offset + sec.sh_size;
+ if (cur_end > max_end)
+ max_end = cur_end;
+ }
+ archive->seek(startptr + max_end);
+ }
+ case ARCHIVE_BUILTIN:
+ memset(buffer, 0, 4);
+ archive->read(buffer, 4);
+ if (*((Uint32 *)buffer) != BUILTIN_SIG)
+ throw GeneralException(_("Archive: not in built-in format."));
+ while (p) {
+ archive->read(buffer, 1);
+ len = *buffer;
+ if (len) {
+ archive->read(buffer, len);
+ buffer[len] = 0;
+ ifname = buffer;
+ size = archive->readU32();
+ archive->read(buffer, 1);
+#ifdef DEBUG
+ printm(M_BARE, _("Adding file `") + ifname + _("' to node `") + p->name + "'\n");
+#endif
+ t = new FileTree(ifname, size, buffer[0], p);
+ if (buffer[0])
+ p = t;
+ } else {
+ p = p->Father();
+ }
+ }
+ filetree.compute_ptrs(archive->tell());
+ break;
+ default:
+ throw GeneralException(_("Archive: unsupported archive format."));
+ }
+
+ next = header;
+ prev = 0;
+ header = this;
+ if (next)
+ next->prev = this;
+}
+
+Archive::~Archive() {
+ if (prev)
+ prev->next = next;
+ if (next)
+ next->prev = prev;
+ if (header == this)
+ header = next;
+
+ delete archive;
+}
+
+Archive * Archive::inarchive(const String & fname) {
+ Archive * p;
+ for (p = header; p; p = p->next) {
+#ifdef DEBUG
+ printm(M_BARE, _("Looking for file `") + fname + _("' in archive ") + p->name + "\n");
+#endif
+ if (p->inarchivein(fname)) {
+#ifdef DEBUG
+ printm(M_BARE, _("File `") + fname + _("' found in archive ") + p->name + "\n");
+#endif
+ return p;
+ }
+ }
+ return 0;
+}
+
+int Archive::open(const String & fname, Input::openresults_t * results) {
+#if 0
+ Archive * p;
+
+ for (p = header; p; p = p->next) {
+ bool t;
+ t = p->inarchive(fname);
+ if (t)
+ return p->openin(fname, results);
+ }
+ throw IOGeneral(_("File `") + fname + _("' not found in archive collection."));
+#endif
+ return openin(fname, results);
+}
+
+Handle * Archive::GetHandle() {
+ return archive;
+}
+
+bool Archive::inarchivein(const String & fname) {
+ Archive::FileTree * p = filetree.Child();
+ ssize_t pos;
+ String name = fname;
+ String reste;
+
+ while((name != "") && p) {
+ pos = name.strchr('/');
+ if (pos >= 0) {
+ reste = name.extract(0, pos - 1);
+ name = name.extract(pos + 1);
+ } else {
+ reste = name;
+ name = "";
+ }
+#ifdef DEBUG
+ printm(M_BARE, _("Checking against node `") + p->name + "'\n");
+#endif
+ while (p) {
+ if (p->name == reste) {
+ if (name != "")
+ p = p->Child();
+ break;
+ } else {
+ p = p->Next();
+ }
+ }
+ }
+
+ return p != 0;
+}
+
+int Archive::openin(const String & fname, Input::openresults_t * results) throw (GeneralException) {
+ Archive::FileTree * p = filetree.Child();
+ ssize_t pos;
+ String name = fname;
+ String reste;
+
+ while((name != "") && p) {
+ pos = name.strchr('/');
+ if (pos >= 0) {
+ reste = name.extract(0, pos - 1);
+ name = name.extract(pos + 1);
+ } else {
+ reste = name;
+ name = "";
+ }
+
+ while (p) {
+ if (p->name == reste) {
+ if (name != "")
+ p = p->Child();
+ break;
+ } else {
+ p = p->Next();
+ }
+ }
+ }
+
+ if (!p)
+ throw IOGeneral(_("File `") + fname + _("' not in archive ") + this->name);
+
+ if (p->Child())
+ throw IOGeneral(_("File `") + fname + _("' in archive ") + this->name + _(" is a directory - can't open."));
+
+ results->name = p->name;
+ results->ptr = p->ptr;
+ results->size = p->size;
+ results->type = p->type;
+ return archive->Dup();
+}
+
+Archive::FileTree::FileTree(const String & fname, size_t fsize, int ftype, Archive::FileTree * fFather) :
+ name(fname), type(ftype), size(fsize), next(0), prev(0), father(fFather), child(0) {
+ if (father) {
+ if (father->child) {
+ FileTree * p;
+ for (p = father->child; p->next; p = p->next);
+ p->next = this;
+ prev = p;
+ } else {
+#ifdef DEBUG
+ std::cerr << _("Adding `") << fname << _("' as first child of node `") << father->name << "'\n";
+#endif
+ father->child = this;
+ }
+ }
+}
+
+Archive::FileTree::~FileTree() {
+ if (child)
+ delete child;
+ if (next)
+ next->prev = prev;
+ if (prev)
+ prev->next = next;
+ if (father) {
+ if (father->child == this)
+ father->child = next;
+ father->touched();
+ }
+}
+
+void Archive::FileTree::touched() {
+ if (father)
+ father->touched();
+ else
+ compute_ptrs(ptr);
+}
+
+int Archive::FileTree::compute_ptrs(size_t cptr) {
+ ptr = cptr;
+
+#ifdef DEBUG
+ std::cerr << _("Computed pointer for `") << name << "' = " << ptr << std::endl;
+ if (child)
+ std::cerr << _("Node has child\n");
+ else
+ std::cerr << _("Node is ") << size << _(" bytes large.\n");
+#endif
+
+ if (child) {
+ FileTree * p;
+ size = 0;
+ for (p = child; p; p = p->next) {
+ size = p->compute_ptrs(ptr + size) - ptr;
+ }
+ }
+
+ return size + ptr;
+}
+
+Archive::FileTree * Archive::FileTree::Father() {
+ return father;
+}
+
+Archive::FileTree * Archive::FileTree::Child() {
+ return child;
+}
+
+Archive::FileTree * Archive::FileTree::Next() {
+ return next;
+}
+
+Archive::FileTree * Archive::FileTree::Prev() {
+ return prev;
+}
diff --git a/lib/LuaHandle.cc b/lib/LuaHandle.cc
index a363cdc..40b24be 100644
--- a/lib/LuaHandle.cc
+++ b/lib/LuaHandle.cc
@@ -1,680 +1,680 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: LuaHandle.cc,v 1.14 2004-11-27 21:35:19 pixel Exp $ */
-
-#include "LuaHandle.h"
-
-LuaInput::LuaInput(Input * h) : LuaHandle(h) { }
-LuaOutput::LuaOutput(Output * h) : LuaHandle(h) { }
-LuaBuffer::LuaBuffer(Buffer * h) : LuaHandle(h) { }
-LuaHandle::LuaHandle(Handle * _h) : h(_h) { }
-
-class sLuaHandle : public Base {
- public:
- static int newinput(lua_State * L);
- static int newoutput(lua_State * L);
- static int newbuffer(lua_State * L);
- static int read(lua_State * L);
- static int readstring(lua_State * L);
- static int readU8(lua_State * L);
- static int readU16(lua_State * L);
- static int readU32(lua_State * L);
- static int write(lua_State * L);
- static int writestring(lua_State * L);
- static int writeU8(lua_State * L);
- static int writeU16(lua_State * L);
- static int writeU32(lua_State * L);
- static int copyfrom(lua_State * L);
- static int copyto(lua_State * L);
- static int isclosed(lua_State * L);
- static int isnonblock(lua_State * L);
- static int canread(lua_State * L);
- static int canwrite(lua_State * L);
- static int canseek(lua_State * L);
- static int canwatch(lua_State * L);
- static int setnonblock(lua_State * L);
- static int tell(lua_State * L);
- static int getname(lua_State * L);
- static int getsize(lua_State * L);
- static int getmodif(lua_State * L);
- static int close(lua_State * L);
- static int flush(lua_State * L);
- static int seek(lua_State * L);
- static int setz(lua_State * L);
- static int bindex(lua_State * L);
- static int bnewindex(lua_State * L);
- static int bseek(lua_State * L);
- static int btell(lua_State * L);
- static int exists(lua_State * L);
- private:
- static int read(lua_State * L, int);
- static int write(lua_State * L, int);
- static int copy(lua_State * L, int);
- static int getcaps(lua_State * L, int);
- static int action(lua_State * L, int);
- enum {
- U8, U16, U32
- };
- enum {
- from, to
- };
- enum {
- capisclosed, capisnonblock, capcanread, capcanwrite, capcanseek, capcanwatch
- };
- enum {
- Asetnonblock, Atell, Agetname, Agetsize, Agetmodif, Aclose, Aflush
- };
-};
-
-void LuaInput::pushconstruct(Lua * L) {
- L->declarefunc("Input", sLuaHandle::newinput);
-}
-
-void LuaOutput::pushconstruct(Lua * L) {
- L->declarefunc("Output", sLuaHandle::newoutput);
-}
-
-void LuaBuffer::pushconstruct(Lua * L) {
- L->declarefunc("Buffer", sLuaHandle::newbuffer);
-}
-
-int sLuaHandle::newinput(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
-
- if ((n != 1) || !L->isstring()) {
- L->error("Incorrect arguments to constructor `Input'");
- }
-
- LuaInput i(new Input(L->tostring()));
- i.pushdestruct(L);
-
- return 1;
-}
-
-int sLuaHandle::newoutput(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
-
- if ((n != 1) || !L->isstring()) {
- L->error("Incorrect arguments to constructor `Input'");
- }
-
- LuaOutput o(new Output(L->tostring()));
- o.pushdestruct(L);
-
- return 1;
-}
-
-int sLuaHandle::newbuffer(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- bool seekable = false;
-
- if ((n > 1) || ((n == 1) && (!L->isboolean()))) {
- L->error("Incorrect arguments to constructor `Buffer'");
- }
-
- if (n == 1)
- seekable = L->toboolean();
-
- LuaBuffer o(new Buffer(seekable));
- o.pushdestruct(L);
-
- return 1;
-}
-
-int sLuaHandle::read(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop(), i;
- size_t t;
- ssize_t r;
- Handle * h;
- Byte * b;
-
- if (n == 1) {
- return readstring(_L);
- }
-
- if ((n != 2) || !L->isnumber()) {
- L->error("Incorrect arguments to method `Headle::read'");
- }
-
- t = L->tonumber();
- b = (Byte *) malloc(t);
- h = (Handle *) LuaObject::getme(L);
-
- L->newtable();
-
- r = h->read(b, t);
-
- for (i = 0; i < r; i++) {
- L->push((lua_Number) i);
- L->push((lua_Number) b[i]);
- L->settable();
- }
-
- free(b);
-
- L->push((lua_Number) r);
-
- return 2;
-}
-
-int sLuaHandle::readstring(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop(), i;
- Handle * h;
- String r;
-
- if (n != 1) {
- L->error("Incorrect arguments to method `Headle::readstring'");
- }
-
- h = (Handle *) LuaObject::getme(L);
-
- (*h) >> r;
-
- L->push(r);
-
- return 1;
-}
-
-int sLuaHandle::readU8(lua_State * L) {
- return read(L, U8);
-}
-
-int sLuaHandle::readU16(lua_State * L) {
- return read(L, U16);
-}
-
-int sLuaHandle::readU32(lua_State * L) {
- return read(L, U32);
-}
-
-int sLuaHandle::write(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop(), i;
- size_t t;
- ssize_t r;
- Handle * h;
- Byte * b;
-
- if ((n == 2) && L->isstring()) {
- return writestring(_L);
- }
-
- if ((n != 3) || !L->isnumber() || !L->istable(2)) {
- L->error("Incorrect arguments to method `Headle::write'");
- }
-
- t = L->tonumber();
- b = (Byte *) malloc(t);
- h = (Handle *) LuaObject::getme(L);
-
- for (i = 0; i < t; i++) {
- L->push((lua_Number) i);
- L->gettable(2);
- b[i] = L->tonumber();
- L->pop();
- }
-
- r = h->write(b, t);
-
- free(b);
-
- L->push((lua_Number) r);
-
- return 1;
-}
-
-int sLuaHandle::writestring(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop(), i;
- Handle * h;
- String r;
-
- if ((n != 2) || !L->isstring()) {
- L->error("Incorrect arguments to method `Headle::writestring'");
- }
-
- h = (Handle *) LuaObject::getme(L);
- r = L->tostring();
-
- (*h) << r;
-
- return 0;
-}
-
-int sLuaHandle::writeU8(lua_State * L) {
- return write(L, U8);
-}
-
-int sLuaHandle::writeU16(lua_State * L) {
- return write(L, U16);
-}
-
-int sLuaHandle::writeU32(lua_State * L) {
- return write(L, U32);
-}
-
-int sLuaHandle::read(lua_State * _L, int t) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- lua_Number r;
- Handle * h;
-
- if (n != 1) {
- L->error("Incorrect arguments to method `Headle::readUx'");
- }
-
- h = (Handle *) LuaObject::getme(L);
-
- switch (t) {
- case U8: r = h->readU8(); break;
- case U16: r = h->readU16(); break;
- case U32: r = h->readU32(); break;
- }
-
- L->push(r);
-
- return 1;
-}
-
-int sLuaHandle::write(lua_State * _L, int t) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- lua_Number r;
- Handle * h;
-
- if ((n != 2) || !L->isnumber()) {
- L->error("Incorrect arguments to method `Headle::writeUx'");
- }
-
- h = (Handle *) LuaObject::getme(L);
- r = L->tonumber();
-
- switch (t) {
- case U8: h->writeU8(r); break;
- case U16: h->writeU16(r); break;
- case U32: h->writeU32(r); break;
- }
-
- return 0;
-}
-
-int sLuaHandle::copyfrom(lua_State * L) {
- return copy(L, from);
-}
-
-int sLuaHandle::copyto(lua_State * L) {
- return copy(L, to);
-}
-
-int sLuaHandle::copy(lua_State * _L, int dir) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- lua_Number r;
- Handle * s, * d;
-
- if ((n < 2) || (n > 3) || ((n == 3) && !L->isnumber(3))) {
- L->error("Incorrect arguments to function `handlecopy'");
- }
-
- s = (Handle *) LuaObject::getme(L, 1);
- d = (Handle *) LuaObject::getme(L, 2);
-
- if (n == 3) {
- r = L->tonumber();
- } else {
- r = -1;
- }
-
- if (dir == from) {
- SWAP(s, d);
- }
-
- s->copyto(d, r);
-
- return 0;
-}
-
-int sLuaHandle::isclosed(lua_State * L) {
- return getcaps(L, capisclosed);
-}
-
-int sLuaHandle::isnonblock(lua_State * L) {
- return getcaps(L, capisnonblock);
-}
-
-int sLuaHandle::canread(lua_State * L) {
- return getcaps(L, capcanread);
-}
-
-int sLuaHandle::canwrite(lua_State * L) {
- return getcaps(L, capcanwrite);
-}
-
-int sLuaHandle::canseek(lua_State * L) {
- return getcaps(L, capcanseek);
-}
-
-int sLuaHandle::canwatch(lua_State * L) {
- return getcaps(L, capcanwatch);
-}
-
-int sLuaHandle::getcaps(lua_State * _L, int cap) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- bool r;
- Handle * h;
-
- if (n != 1) {
- L->error("Incorrect arguments to method `Handle::getcaps'");
- }
-
- h = (Handle *) LuaObject::getme(L);
-
- switch (cap) {
- case capisclosed: r = h->IsClosed(); break;
- case capisnonblock: r = h->IsNonBlock(); break;
- case capcanread: r = h->CanRead(); break;
- case capcanwrite: r = h->CanWrite(); break;
- case capcanseek: r = h->CanSeek(); break;
- case capcanwatch: r = h->CanWatch(); break;
- }
-
- L->push(r);
-
- return 1;
-}
-
-int sLuaHandle::setnonblock(lua_State * L) {
- return action(L, Asetnonblock);
-}
-
-int sLuaHandle::tell(lua_State * L) {
- return action(L, Atell);
-}
-
-int sLuaHandle::getname(lua_State * L) {
- return action(L, Agetname);
-}
-
-int sLuaHandle::getsize(lua_State * L) {
- return action(L, Agetsize);
-}
-
-int sLuaHandle::getmodif(lua_State * L) {
- return action(L, Agetmodif);
-}
-
-int sLuaHandle::close(lua_State * L) {
- return action(L, Aclose);
-}
-
-int sLuaHandle::flush(lua_State * L) {
- return action(L, Aflush);
-}
-
-int sLuaHandle::action(lua_State * _L, int act) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- int r = 1;
- Handle * h;
-
- if (n != 1) {
- L->error("Incorrect arguments to method `Handle::action'");
- }
-
- h = (Handle *) LuaObject::getme(L);
-
- switch (act) {
- case Asetnonblock: r = 0; h->SetNonBlock(); break;
- case Atell: L->push((lua_Number) h->tell()); break;
- case Agetname: L->push(h->GetName()); break;
- case Agetsize: L->push((lua_Number) h->GetSize()); break;
- case Agetmodif: L->push((lua_Number) h->GetModif()); break;
- case Aclose: r = 0; h->close(); break;
- case Aflush: r = 0; h->Flush(); break;
- }
-
- return r;
-}
-
-int sLuaHandle::setz(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- int z = 9;
- Handle * h;
-
- if ((n < 1) || (n > 2) || ((n == 2) && !L->isnumber(2))) {
- L->error("Incorrect arguments to method `Handle::setz'");
- }
-
- h = (Handle *) LuaObject::getme(L);
-
- if (n == 2) {
- z = L->tonumber(2);
- }
-
- h->SetZ(z);
-
- return 0;
-}
-
-int sLuaHandle::seek(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- off_t off;
- int wheel;
- Handle * h;
-
- if ((n < 2) || (n > 3) || !L->isnumber(2) || ((n == 3) && !L->isnumber(3))) {
- L->error("Incorrect arguments to method `Handle::seek'");
- }
-
- h = (Handle *) LuaObject::getme(L);
-
- off = L->tonumber(2);
-
- if (n == 3) {
- wheel = L->tonumber(3);
- } else {
- wheel = SEEK_SET;
- }
-
- L->push((lua_Number) h->seek(off, wheel));
-
- return 1;
-}
-
-int sLuaHandle::bindex(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- const Buffer * b;
-
- if (n != 2) {
- L->error("Inconsistant call to metamethod Buffer::index");
- }
-
- if (!L->isnumber()) {
- L->push();
- return 1;
- }
-
- b = (Buffer *) LuaObject::getme(L);
-
- L->push((lua_Number) (*b)[L->tonumber()]);
-
- return 1;
-}
-
-int sLuaHandle::bnewindex(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Buffer * b;
-
- if (n != 3) {
- L->error("Inconsistant call to metamethod Buffer::newindex");
- }
-
- if (!L->isnumber(2)) {
- L->settable(1, true);
- return 0;
- }
-
- if (!L->isnumber(3)) {
- L->error("Can't write a non-number to buffer");
- }
-
- b = (Buffer *) LuaObject::getme(L);
-
- (*b)[L->tonumber(2)] = L->tonumber(3);
-
- return 0;
-}
-
-int sLuaHandle::btell(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Buffer * h;
-
- if (n != 1) {
- L->error("Incorrect arguments to method `Buffer::wtell'");
- }
-
- h = (Buffer *) LuaObject::getme(L);
- L->push((lua_Number) h->wtell());
- return 1;
-}
-
-int sLuaHandle::bseek(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- off_t off;
- int wheel;
- Buffer * h;
-
- if ((n < 2) || (n > 3) || !L->isnumber(2) || ((n == 3) && !L->isnumber(3))) {
- L->error("Incorrect arguments to method `Buffer::wseek'");
- }
-
- h = (Buffer *) LuaObject::getme(L);
-
- off = L->tonumber(2);
-
- if (n == 3) {
- wheel = L->tonumber(3);
- } else {
- wheel = SEEK_SET;
- }
-
- L->push((lua_Number) h->wseek(off, wheel));
-
- return 1;
-}
-
-int sLuaHandle::exists(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- bool r = true;
-
- if (n != 1) {
- L->error("Incorrect number of arguments to function exists");
- }
-
- try {
- Input testing(L->tostring());
- }
- catch (IOGeneral & e) {
- r = false;
- }
-
- L->push(r);
-
- return 1;
-}
-
-void LuaInput::pushmembers(Lua * L) {
- LuaHandle::pushmembers(L);
-}
-
-void LuaOutput::pushmembers(Lua * L) {
- LuaHandle::pushmembers(L);
-}
-
-void LuaBuffer::pushmembers(Lua * L) {
- LuaHandle::pushmembers(L);
- pushmeta(L, "__index", sLuaHandle::bindex);
- pushmeta(L, "__newindex", sLuaHandle::bnewindex);
- pushit(L, "wtell", sLuaHandle::btell);
- pushit(L, "wseek", sLuaHandle::bseek);
-}
-
-void LuaHandle::pushmembers(Lua * L) {
- pushme(L, h);
-
- pushit(L, "read", &sLuaHandle::read);
- pushit(L, "write", &sLuaHandle::write);
-
- pushit(L, "readU8", sLuaHandle::readU8);
- pushit(L, "readU16", sLuaHandle::readU16);
- pushit(L, "readU32", sLuaHandle::readU32);
- pushit(L, "writeU8", sLuaHandle::writeU8);
- pushit(L, "writeU16", sLuaHandle::writeU16);
- pushit(L, "writeU32", sLuaHandle::writeU32);
-
- pushit(L, "copyfrom", sLuaHandle::copyfrom);
- pushit(L, "copyto", sLuaHandle::copyto);
- L->declarefunc("handlecopy", sLuaHandle::copyfrom);
-
- pushit(L, "isclosed", sLuaHandle::isclosed);
- pushit(L, "isnonblock", sLuaHandle::isnonblock);
- pushit(L, "canread", sLuaHandle::canread);
- pushit(L, "canwrite", sLuaHandle::canwatch);
- pushit(L, "canseek", sLuaHandle::canseek);
- pushit(L, "canwatch", sLuaHandle::canwatch);
-
- pushit(L, "setnonblock", sLuaHandle::setnonblock);
- pushit(L, "tell", sLuaHandle::tell);
- pushit(L, "getname", sLuaHandle::getname);
- pushit(L, "getsize", sLuaHandle::getsize);
- pushit(L, "getmodif", sLuaHandle::getmodif);
- pushit(L, "close", sLuaHandle::close);
- pushit(L, "flush", sLuaHandle::flush);
-
- pushit(L, "seek", sLuaHandle::seek);
- pushit(L, "setz", sLuaHandle::setz);
-
- L->declarefunc("exists", sLuaHandle::exists);
-
- L->push("SEEK_SET");
- L->push((lua_Number) SEEK_SET);
- L->settable(LUA_GLOBALSINDEX);
-
- L->push("SEEK_CUR");
- L->push((lua_Number) SEEK_CUR);
- L->settable(LUA_GLOBALSINDEX);
-
- L->push("SEEK_END");
- L->push((lua_Number) SEEK_END);
- L->settable(LUA_GLOBALSINDEX);
-}
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: LuaHandle.cc,v 1.15 2004-11-27 21:46:04 pixel Exp $ */
+
+#include "LuaHandle.h"
+
+LuaInput::LuaInput(Input * h) : LuaHandle(h) { }
+LuaOutput::LuaOutput(Output * h) : LuaHandle(h) { }
+LuaBuffer::LuaBuffer(Buffer * h) : LuaHandle(h) { }
+LuaHandle::LuaHandle(Handle * _h) : h(_h) { }
+
+class sLuaHandle : public Base {
+ public:
+ static int newinput(lua_State * L);
+ static int newoutput(lua_State * L);
+ static int newbuffer(lua_State * L);
+ static int read(lua_State * L);
+ static int readstring(lua_State * L);
+ static int readU8(lua_State * L);
+ static int readU16(lua_State * L);
+ static int readU32(lua_State * L);
+ static int write(lua_State * L);
+ static int writestring(lua_State * L);
+ static int writeU8(lua_State * L);
+ static int writeU16(lua_State * L);
+ static int writeU32(lua_State * L);
+ static int copyfrom(lua_State * L);
+ static int copyto(lua_State * L);
+ static int isclosed(lua_State * L);
+ static int isnonblock(lua_State * L);
+ static int canread(lua_State * L);
+ static int canwrite(lua_State * L);
+ static int canseek(lua_State * L);
+ static int canwatch(lua_State * L);
+ static int setnonblock(lua_State * L);
+ static int tell(lua_State * L);
+ static int getname(lua_State * L);
+ static int getsize(lua_State * L);
+ static int getmodif(lua_State * L);
+ static int close(lua_State * L);
+ static int flush(lua_State * L);
+ static int seek(lua_State * L);
+ static int setz(lua_State * L);
+ static int bindex(lua_State * L);
+ static int bnewindex(lua_State * L);
+ static int bseek(lua_State * L);
+ static int btell(lua_State * L);
+ static int exists(lua_State * L);
+ private:
+ static int read(lua_State * L, int);
+ static int write(lua_State * L, int);
+ static int copy(lua_State * L, int);
+ static int getcaps(lua_State * L, int);
+ static int action(lua_State * L, int);
+ enum {
+ U8, U16, U32
+ };
+ enum {
+ from, to
+ };
+ enum {
+ capisclosed, capisnonblock, capcanread, capcanwrite, capcanseek, capcanwatch
+ };
+ enum {
+ Asetnonblock, Atell, Agetname, Agetsize, Agetmodif, Aclose, Aflush
+ };
+};
+
+void LuaInput::pushconstruct(Lua * L) {
+ L->declarefunc("Input", sLuaHandle::newinput);
+}
+
+void LuaOutput::pushconstruct(Lua * L) {
+ L->declarefunc("Output", sLuaHandle::newoutput);
+}
+
+void LuaBuffer::pushconstruct(Lua * L) {
+ L->declarefunc("Buffer", sLuaHandle::newbuffer);
+}
+
+int sLuaHandle::newinput(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+
+ if ((n != 1) || !L->isstring()) {
+ L->error("Incorrect arguments to constructor `Input'");
+ }
+
+ LuaInput i(new Input(L->tostring()));
+ i.pushdestruct(L);
+
+ return 1;
+}
+
+int sLuaHandle::newoutput(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+
+ if ((n != 1) || !L->isstring()) {
+ L->error("Incorrect arguments to constructor `Input'");
+ }
+
+ LuaOutput o(new Output(L->tostring()));
+ o.pushdestruct(L);
+
+ return 1;
+}
+
+int sLuaHandle::newbuffer(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ bool seekable = false;
+
+ if ((n > 1) || ((n == 1) && (!L->isboolean()))) {
+ L->error("Incorrect arguments to constructor `Buffer'");
+ }
+
+ if (n == 1)
+ seekable = L->toboolean();
+
+ LuaBuffer o(new Buffer(seekable));
+ o.pushdestruct(L);
+
+ return 1;
+}
+
+int sLuaHandle::read(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop(), i;
+ size_t t;
+ ssize_t r;
+ Handle * h;
+ Byte * b;
+
+ if (n == 1) {
+ return readstring(_L);
+ }
+
+ if ((n != 2) || !L->isnumber()) {
+ L->error("Incorrect arguments to method `Headle::read'");
+ }
+
+ t = L->tonumber();
+ b = (Byte *) malloc(t);
+ h = (Handle *) LuaObject::getme(L);
+
+ L->newtable();
+
+ r = h->read(b, t);
+
+ for (i = 0; i < r; i++) {
+ L->push((lua_Number) i);
+ L->push((lua_Number) b[i]);
+ L->settable();
+ }
+
+ free(b);
+
+ L->push((lua_Number) r);
+
+ return 2;
+}
+
+int sLuaHandle::readstring(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop(), i;
+ Handle * h;
+ String r;
+
+ if (n != 1) {
+ L->error("Incorrect arguments to method `Headle::readstring'");
+ }
+
+ h = (Handle *) LuaObject::getme(L);
+
+ (*h) >> r;
+
+ L->push(r);
+
+ return 1;
+}
+
+int sLuaHandle::readU8(lua_State * L) {
+ return read(L, U8);
+}
+
+int sLuaHandle::readU16(lua_State * L) {
+ return read(L, U16);
+}
+
+int sLuaHandle::readU32(lua_State * L) {
+ return read(L, U32);
+}
+
+int sLuaHandle::write(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop(), i;
+ size_t t;
+ ssize_t r;
+ Handle * h;
+ Byte * b;
+
+ if ((n == 2) && L->isstring()) {
+ return writestring(_L);
+ }
+
+ if ((n != 3) || !L->isnumber() || !L->istable(2)) {
+ L->error("Incorrect arguments to method `Headle::write'");
+ }
+
+ t = L->tonumber();
+ b = (Byte *) malloc(t);
+ h = (Handle *) LuaObject::getme(L);
+
+ for (i = 0; i < t; i++) {
+ L->push((lua_Number) i);
+ L->gettable(2);
+ b[i] = L->tonumber();
+ L->pop();
+ }
+
+ r = h->write(b, t);
+
+ free(b);
+
+ L->push((lua_Number) r);
+
+ return 1;
+}
+
+int sLuaHandle::writestring(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop(), i;
+ Handle * h;
+ String r;
+
+ if ((n != 2) || !L->isstring()) {
+ L->error("Incorrect arguments to method `Headle::writestring'");
+ }
+
+ h = (Handle *) LuaObject::getme(L);
+ r = L->tostring();
+
+ (*h) << r;
+
+ return 0;
+}
+
+int sLuaHandle::writeU8(lua_State * L) {
+ return write(L, U8);
+}
+
+int sLuaHandle::writeU16(lua_State * L) {
+ return write(L, U16);
+}
+
+int sLuaHandle::writeU32(lua_State * L) {
+ return write(L, U32);
+}
+
+int sLuaHandle::read(lua_State * _L, int t) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ lua_Number r;
+ Handle * h;
+
+ if (n != 1) {
+ L->error("Incorrect arguments to method `Headle::readUx'");
+ }
+
+ h = (Handle *) LuaObject::getme(L);
+
+ switch (t) {
+ case U8: r = h->readU8(); break;
+ case U16: r = h->readU16(); break;
+ case U32: r = h->readU32(); break;
+ }
+
+ L->push(r);
+
+ return 1;
+}
+
+int sLuaHandle::write(lua_State * _L, int t) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ lua_Number r;
+ Handle * h;
+
+ if ((n != 2) || !L->isnumber()) {
+ L->error("Incorrect arguments to method `Headle::writeUx'");
+ }
+
+ h = (Handle *) LuaObject::getme(L);
+ r = L->tonumber();
+
+ switch (t) {
+ case U8: h->writeU8(r); break;
+ case U16: h->writeU16(r); break;
+ case U32: h->writeU32(r); break;
+ }
+
+ return 0;
+}
+
+int sLuaHandle::copyfrom(lua_State * L) {
+ return copy(L, from);
+}
+
+int sLuaHandle::copyto(lua_State * L) {
+ return copy(L, to);
+}
+
+int sLuaHandle::copy(lua_State * _L, int dir) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ lua_Number r;
+ Handle * s, * d;
+
+ if ((n < 2) || (n > 3) || ((n == 3) && !L->isnumber(3))) {
+ L->error("Incorrect arguments to function `handlecopy'");
+ }
+
+ s = (Handle *) LuaObject::getme(L, 1);
+ d = (Handle *) LuaObject::getme(L, 2);
+
+ if (n == 3) {
+ r = L->tonumber();
+ } else {
+ r = -1;
+ }
+
+ if (dir == from) {
+ SWAP(s, d);
+ }
+
+ s->copyto(d, r);
+
+ return 0;
+}
+
+int sLuaHandle::isclosed(lua_State * L) {
+ return getcaps(L, capisclosed);
+}
+
+int sLuaHandle::isnonblock(lua_State * L) {
+ return getcaps(L, capisnonblock);
+}
+
+int sLuaHandle::canread(lua_State * L) {
+ return getcaps(L, capcanread);
+}
+
+int sLuaHandle::canwrite(lua_State * L) {
+ return getcaps(L, capcanwrite);
+}
+
+int sLuaHandle::canseek(lua_State * L) {
+ return getcaps(L, capcanseek);
+}
+
+int sLuaHandle::canwatch(lua_State * L) {
+ return getcaps(L, capcanwatch);
+}
+
+int sLuaHandle::getcaps(lua_State * _L, int cap) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ bool r;
+ Handle * h;
+
+ if (n != 1) {
+ L->error("Incorrect arguments to method `Handle::getcaps'");
+ }
+
+ h = (Handle *) LuaObject::getme(L);
+
+ switch (cap) {
+ case capisclosed: r = h->IsClosed(); break;
+ case capisnonblock: r = h->IsNonBlock(); break;
+ case capcanread: r = h->CanRead(); break;
+ case capcanwrite: r = h->CanWrite(); break;
+ case capcanseek: r = h->CanSeek(); break;
+ case capcanwatch: r = h->CanWatch(); break;
+ }
+
+ L->push(r);
+
+ return 1;
+}
+
+int sLuaHandle::setnonblock(lua_State * L) {
+ return action(L, Asetnonblock);
+}
+
+int sLuaHandle::tell(lua_State * L) {
+ return action(L, Atell);
+}
+
+int sLuaHandle::getname(lua_State * L) {
+ return action(L, Agetname);
+}
+
+int sLuaHandle::getsize(lua_State * L) {
+ return action(L, Agetsize);
+}
+
+int sLuaHandle::getmodif(lua_State * L) {
+ return action(L, Agetmodif);
+}
+
+int sLuaHandle::close(lua_State * L) {
+ return action(L, Aclose);
+}
+
+int sLuaHandle::flush(lua_State * L) {
+ return action(L, Aflush);
+}
+
+int sLuaHandle::action(lua_State * _L, int act) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ int r = 1;
+ Handle * h;
+
+ if (n != 1) {
+ L->error("Incorrect arguments to method `Handle::action'");
+ }
+
+ h = (Handle *) LuaObject::getme(L);
+
+ switch (act) {
+ case Asetnonblock: r = 0; h->SetNonBlock(); break;
+ case Atell: L->push((lua_Number) h->tell()); break;
+ case Agetname: L->push(h->GetName()); break;
+ case Agetsize: L->push((lua_Number) h->GetSize()); break;
+ case Agetmodif: L->push((lua_Number) h->GetModif()); break;
+ case Aclose: r = 0; h->close(); break;
+ case Aflush: r = 0; h->Flush(); break;
+ }
+
+ return r;
+}
+
+int sLuaHandle::setz(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ int z = 9;
+ Handle * h;
+
+ if ((n < 1) || (n > 2) || ((n == 2) && !L->isnumber(2))) {
+ L->error("Incorrect arguments to method `Handle::setz'");
+ }
+
+ h = (Handle *) LuaObject::getme(L);
+
+ if (n == 2) {
+ z = L->tonumber(2);
+ }
+
+ h->SetZ(z);
+
+ return 0;
+}
+
+int sLuaHandle::seek(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ off_t off;
+ int wheel;
+ Handle * h;
+
+ if ((n < 2) || (n > 3) || !L->isnumber(2) || ((n == 3) && !L->isnumber(3))) {
+ L->error("Incorrect arguments to method `Handle::seek'");
+ }
+
+ h = (Handle *) LuaObject::getme(L);
+
+ off = L->tonumber(2);
+
+ if (n == 3) {
+ wheel = L->tonumber(3);
+ } else {
+ wheel = SEEK_SET;
+ }
+
+ L->push((lua_Number) h->seek(off, wheel));
+
+ return 1;
+}
+
+int sLuaHandle::bindex(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ const Buffer * b;
+
+ if (n != 2) {
+ L->error("Inconsistant call to metamethod Buffer::index");
+ }
+
+ if (!L->isnumber()) {
+ L->push();
+ return 1;
+ }
+
+ b = (Buffer *) LuaObject::getme(L);
+
+ L->push((lua_Number) (*b)[L->tonumber()]);
+
+ return 1;
+}
+
+int sLuaHandle::bnewindex(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Buffer * b;
+
+ if (n != 3) {
+ L->error("Inconsistant call to metamethod Buffer::newindex");
+ }
+
+ if (!L->isnumber(2)) {
+ L->settable(1, true);
+ return 0;
+ }
+
+ if (!L->isnumber(3)) {
+ L->error("Can't write a non-number to buffer");
+ }
+
+ b = (Buffer *) LuaObject::getme(L);
+
+ (*b)[L->tonumber(2)] = L->tonumber(3);
+
+ return 0;
+}
+
+int sLuaHandle::btell(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Buffer * h;
+
+ if (n != 1) {
+ L->error("Incorrect arguments to method `Buffer::wtell'");
+ }
+
+ h = (Buffer *) LuaObject::getme(L);
+ L->push((lua_Number) h->wtell());
+ return 1;
+}
+
+int sLuaHandle::bseek(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ off_t off;
+ int wheel;
+ Buffer * h;
+
+ if ((n < 2) || (n > 3) || !L->isnumber(2) || ((n == 3) && !L->isnumber(3))) {
+ L->error("Incorrect arguments to method `Buffer::wseek'");
+ }
+
+ h = (Buffer *) LuaObject::getme(L);
+
+ off = L->tonumber(2);
+
+ if (n == 3) {
+ wheel = L->tonumber(3);
+ } else {
+ wheel = SEEK_SET;
+ }
+
+ L->push((lua_Number) h->wseek(off, wheel));
+
+ return 1;
+}
+
+int sLuaHandle::exists(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ bool r = true;
+
+ if (n != 1) {
+ L->error("Incorrect number of arguments to function exists");
+ }
+
+ try {
+ Input testing(L->tostring());
+ }
+ catch (IOGeneral & e) {
+ r = false;
+ }
+
+ L->push(r);
+
+ return 1;
+}
+
+void LuaInput::pushmembers(Lua * L) {
+ LuaHandle::pushmembers(L);
+}
+
+void LuaOutput::pushmembers(Lua * L) {
+ LuaHandle::pushmembers(L);
+}
+
+void LuaBuffer::pushmembers(Lua * L) {
+ LuaHandle::pushmembers(L);
+ pushmeta(L, "__index", sLuaHandle::bindex);
+ pushmeta(L, "__newindex", sLuaHandle::bnewindex);
+ pushit(L, "wtell", sLuaHandle::btell);
+ pushit(L, "wseek", sLuaHandle::bseek);
+}
+
+void LuaHandle::pushmembers(Lua * L) {
+ pushme(L, h);
+
+ pushit(L, "read", &sLuaHandle::read);
+ pushit(L, "write", &sLuaHandle::write);
+
+ pushit(L, "readU8", sLuaHandle::readU8);
+ pushit(L, "readU16", sLuaHandle::readU16);
+ pushit(L, "readU32", sLuaHandle::readU32);
+ pushit(L, "writeU8", sLuaHandle::writeU8);
+ pushit(L, "writeU16", sLuaHandle::writeU16);
+ pushit(L, "writeU32", sLuaHandle::writeU32);
+
+ pushit(L, "copyfrom", sLuaHandle::copyfrom);
+ pushit(L, "copyto", sLuaHandle::copyto);
+ L->declarefunc("handlecopy", sLuaHandle::copyfrom);
+
+ pushit(L, "isclosed", sLuaHandle::isclosed);
+ pushit(L, "isnonblock", sLuaHandle::isnonblock);
+ pushit(L, "canread", sLuaHandle::canread);
+ pushit(L, "canwrite", sLuaHandle::canwatch);
+ pushit(L, "canseek", sLuaHandle::canseek);
+ pushit(L, "canwatch", sLuaHandle::canwatch);
+
+ pushit(L, "setnonblock", sLuaHandle::setnonblock);
+ pushit(L, "tell", sLuaHandle::tell);
+ pushit(L, "getname", sLuaHandle::getname);
+ pushit(L, "getsize", sLuaHandle::getsize);
+ pushit(L, "getmodif", sLuaHandle::getmodif);
+ pushit(L, "close", sLuaHandle::close);
+ pushit(L, "flush", sLuaHandle::flush);
+
+ pushit(L, "seek", sLuaHandle::seek);
+ pushit(L, "setz", sLuaHandle::setz);
+
+ L->declarefunc("exists", sLuaHandle::exists);
+
+ L->push("SEEK_SET");
+ L->push((lua_Number) SEEK_SET);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("SEEK_CUR");
+ L->push((lua_Number) SEEK_CUR);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("SEEK_END");
+ L->push((lua_Number) SEEK_END);
+ L->settable(LUA_GLOBALSINDEX);
+}
diff --git a/lib/Main.cc b/lib/Main.cc
index 840fbd9..b690532 100644
--- a/lib/Main.cc
+++ b/lib/Main.cc
@@ -1,75 +1,75 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: Main.cc,v 1.11 2004-11-27 21:35:19 pixel Exp $ */
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "Exceptions.h"
-#include "Main.h"
-#include "generic.h"
-//#include "gettext.h"
-
-Main::Main() : setted(false) {}
-
-Main::~Main() {}
-
-void Main::set_args(int a_argc, char ** a_argv, char ** a_enve) {
- if (setted) {
- return;
- }
- argc = a_argc;
- argv = a_argv;
- enve = a_enve;
- setted = true;
-}
-
-/*
-_open_osfhandle
-CreateFileMapping
-*/
-
-int Main::truemain(Main * Application, int argc, char ** argv, char ** enve) {
- int r;
-
- try {
- Application->set_args(argc, argv, enve);
- r = Application->startup();
- }
- catch (Exit e) {
- r = e.GetCode();
- }
- catch (GeneralException e) {
-#ifdef _WIN32
- MessageBox(0, e.GetMsg(), "Application caused an exception", MB_ICONEXCLAMATION | MB_OK);
-#endif
- Base::printm(M_ERROR, _("The application caused an exception: %s\n"), e.GetMsg());
- return -1;
- }
- catch (...) {
- Base::printm(M_ERROR, _("The application caused an unknow exception\n"));
- return -1;
- }
- return r;
-}
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: Main.cc,v 1.12 2004-11-27 21:46:04 pixel Exp $ */
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "Exceptions.h"
+#include "Main.h"
+#include "generic.h"
+//#include "gettext.h"
+
+Main::Main() : setted(false) {}
+
+Main::~Main() {}
+
+void Main::set_args(int a_argc, char ** a_argv, char ** a_enve) {
+ if (setted) {
+ return;
+ }
+ argc = a_argc;
+ argv = a_argv;
+ enve = a_enve;
+ setted = true;
+}
+
+/*
+_open_osfhandle
+CreateFileMapping
+*/
+
+int Main::truemain(Main * Application, int argc, char ** argv, char ** enve) {
+ int r;
+
+ try {
+ Application->set_args(argc, argv, enve);
+ r = Application->startup();
+ }
+ catch (Exit e) {
+ r = e.GetCode();
+ }
+ catch (GeneralException e) {
+#ifdef _WIN32
+ MessageBox(0, e.GetMsg(), "Application caused an exception", MB_ICONEXCLAMATION | MB_OK);
+#endif
+ Base::printm(M_ERROR, _("The application caused an exception: %s\n"), e.GetMsg());
+ return -1;
+ }
+ catch (...) {
+ Base::printm(M_ERROR, _("The application caused an unknow exception\n"));
+ return -1;
+ }
+ return r;
+}
diff --git a/lib/Menu.cc b/lib/Menu.cc
index ec6f187..361189f 100644
--- a/lib/Menu.cc
+++ b/lib/Menu.cc
@@ -1,35 +1,35 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "Menu.h"
-#include "HttpServ.h"
-#include "CopyJob.h"
-#include "Buffer.h"
-
-Menu::Menu(const String & t, const String & U, String * ts, Action ** as, int nb) :
- Action(U), tit(t), lt(ts), la(as), nba(nb) { }
-
-Task * Menu::Do(Variables * v, Variables *, Handle * h) {
- int i, f = 0;
- Handle * b = new Buffer();
- Task * t = new CopyJob(b, h, -1, true);
-
- SendHead(b);
- (*b) << "<center><TABLE BORDER=0>" << endnl;
- for (i = 0; i < nba; i++) {
- (*b) << "<TR BGCOLOR=\"#" << (f ? "dddddd" : "cccccc") << "\"><TD ALIGN=\"center\">" << (i + 1) << "</TD><TD>";
- (*b) << "<A HREF=\"/bin/" << (la[i] ? la[i]->GetURL() : "start") << "\">";
- (*b) << lt[i] << "</A></TD></TR>" << endnl;
- f = f ? 0 : 1;
- }
- (*b) << "</TABLE></center>" << endnl;
- SendFoot(b);
-
- Accessed();
-
- return t;
-}
-
-String Menu::GetTitle(void) {
- return tit;
-}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "Menu.h"
+#include "HttpServ.h"
+#include "CopyJob.h"
+#include "Buffer.h"
+
+Menu::Menu(const String & t, const String & U, String * ts, Action ** as, int nb) :
+ Action(U), tit(t), lt(ts), la(as), nba(nb) { }
+
+Task * Menu::Do(Variables * v, Variables *, Handle * h) {
+ int i, f = 0;
+ Handle * b = new Buffer();
+ Task * t = new CopyJob(b, h, -1, true);
+
+ SendHead(b);
+ (*b) << "<center><TABLE BORDER=0>" << endnl;
+ for (i = 0; i < nba; i++) {
+ (*b) << "<TR BGCOLOR=\"#" << (f ? "dddddd" : "cccccc") << "\"><TD ALIGN=\"center\">" << (i + 1) << "</TD><TD>";
+ (*b) << "<A HREF=\"/bin/" << (la[i] ? la[i]->GetURL() : "start") << "\">";
+ (*b) << lt[i] << "</A></TD></TR>" << endnl;
+ f = f ? 0 : 1;
+ }
+ (*b) << "</TABLE></center>" << endnl;
+ SendFoot(b);
+
+ Accessed();
+
+ return t;
+}
+
+String Menu::GetTitle(void) {
+ return tit;
+}
diff --git a/lib/Message.cc b/lib/Message.cc
index 1a381da..5cb8859 100644
--- a/lib/Message.cc
+++ b/lib/Message.cc
@@ -1,30 +1,30 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "HttpServ.h"
-#include "Message.h"
-#include "Buffer.h"
-#include "CopyJob.h"
-
-Message::Message(const String & t, const String & m, const String & U, Action * n) :
- Action(U), tit(t), msg(m), Next(n) { }
-
-Task * Message::Do(Variables * v, Variables *, Handle * h) {
- Handle * b = new Buffer();
- Task * t = new CopyJob(b, h, -1, true);
-
- SendHead(b);
- (*b) << msg << "<CENTER><FORM METHOD=\"POST\" ACTION=\"/bin/" << (Next ? Next->GetURL() : "start") << "\">" << endnl <<
- "<INPUT TYPE=\"SUBMIT\" VALUE=\" Ok \">" << endnl;
- v->Dump(b);
- (*b) << "</FORM></CENTER>" << endnl;
- SendFoot(b);
-
- Accessed();
-
- return t;
-}
-
-String Message::GetTitle(void) {
- return tit;
-}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "HttpServ.h"
+#include "Message.h"
+#include "Buffer.h"
+#include "CopyJob.h"
+
+Message::Message(const String & t, const String & m, const String & U, Action * n) :
+ Action(U), tit(t), msg(m), Next(n) { }
+
+Task * Message::Do(Variables * v, Variables *, Handle * h) {
+ Handle * b = new Buffer();
+ Task * t = new CopyJob(b, h, -1, true);
+
+ SendHead(b);
+ (*b) << msg << "<CENTER><FORM METHOD=\"POST\" ACTION=\"/bin/" << (Next ? Next->GetURL() : "start") << "\">" << endnl <<
+ "<INPUT TYPE=\"SUBMIT\" VALUE=\" Ok \">" << endnl;
+ v->Dump(b);
+ (*b) << "</FORM></CENTER>" << endnl;
+ SendFoot(b);
+
+ Accessed();
+
+ return t;
+}
+
+String Message::GetTitle(void) {
+ return tit;
+}
diff --git a/lib/OutPipe.cc b/lib/OutPipe.cc
index 943bef0..c8d979c 100644
--- a/lib/OutPipe.cc
+++ b/lib/OutPipe.cc
@@ -1,41 +1,41 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "OutPipe.h"
-#include "Input.h"
-#include "gettext.h"
-
-OutPipe::OutPipe() : Handle(pipe(p, 1)), hooked(0) { }
-
-OutPipe::~OutPipe() {
- if (hooked) {
- ::close(0);
- dup(Stdin.GetHandle());
- }
-}
-
-OutPipe::OutPipe(const OutPipe & o) : Handle(o), hooked(o.hooked) {
- p[0] = dup(o.p[0]);
- p[1] = GetHandle();
-}
-
-void OutPipe::Hook() {
- if (!hooked) {
- hooked = 1;
- ::close(0);
- dup(p[0]);
- ::close(p[0]);
- }
-}
-
-bool OutPipe::CanWrite() {
- return true;
-}
-
-bool OutPipe::CanRead() {
- return false;
-}
-
-String OutPipe::GetName() {
- return (String(_("Output pipe to stdin (")) + (hooked ? "" : _("not ")) + _("hooked)"));
-}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "OutPipe.h"
+#include "Input.h"
+#include "gettext.h"
+
+OutPipe::OutPipe() : Handle(pipe(p, 1)), hooked(0) { }
+
+OutPipe::~OutPipe() {
+ if (hooked) {
+ ::close(0);
+ dup(Stdin.GetHandle());
+ }
+}
+
+OutPipe::OutPipe(const OutPipe & o) : Handle(o), hooked(o.hooked) {
+ p[0] = dup(o.p[0]);
+ p[1] = GetHandle();
+}
+
+void OutPipe::Hook() {
+ if (!hooked) {
+ hooked = 1;
+ ::close(0);
+ dup(p[0]);
+ ::close(p[0]);
+ }
+}
+
+bool OutPipe::CanWrite() {
+ return true;
+}
+
+bool OutPipe::CanRead() {
+ return false;
+}
+
+String OutPipe::GetName() {
+ return (String(_("Output pipe to stdin (")) + (hooked ? "" : _("not ")) + _("hooked)"));
+}
diff --git a/lib/Output.cc b/lib/Output.cc
index 8ae02b7..310ca79 100644
--- a/lib/Output.cc
+++ b/lib/Output.cc
@@ -1,164 +1,164 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: Output.cc,v 1.21 2004-11-27 21:35:19 pixel Exp $ */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-#include <fcntl.h>
-#include "Output.h"
-#include "Exceptions.h"
-#include "gettext.h"
-
-#ifndef S_ISREG
-#define S_ISREG(x) 1
-#endif
-
-Output::Output(String no, int create, int trunc) throw (GeneralException) :
- Handle(no.strlen() ? wrapopen(no.to_charp(), create, trunc) : dup(1)),
- n(no) {
- if (GetHandle() < 0) {
- throw IOGeneral(String(_("Error opening file ")) + no + _(" for writing: ") + strerror(errno));
- }
-
- size = lseek(GetHandle(), 0, SEEK_END);
- lseek(GetHandle(), 0, SEEK_SET);
-
- struct stat s;
-
- fstat(GetHandle(), &s);
-
- date_modif = s.st_mtime;
-}
-
-int Output::wrapopen(const String & n, int create, int trunc) {
- hFile = 0;
-#ifndef _WIN32
- return open(n.to_charp(), (create ? O_CREAT : 0) |
- (trunc ? O_TRUNC : 0) | O_WRONLY, 00666);
-#else
-#ifdef NO_HFILE
- return _creat(n.to_charp(), _S_IREAD | _S_IWRITE);
-#else
- DWORD dwCreationDisposition;
- switch ((create ? 1 : 0) | (trunc ? 2 : 0)) {
- case 0: // no creation, no trunc
- dwCreationDisposition = OPEN_EXISTING;
- break;
- case 1: // creation, no trunc if existing
- dwCreationDisposition = OPEN_ALWAYS;
- break;
- case 2: // no creation, trunc of existing file
- dwCreationDisposition = TRUNCATE_EXISTING;
- break;
- case 3: // creation, truc if existing
- dwCreationDisposition = CREATE_ALWAYS;
- break;
- }
- hFile = CreateFile(
- n.to_charp(),
- GENERIC_WRITE,
- FILE_SHARE_READ,
- 0,
- dwCreationDisposition,
- FILE_ATTRIBUTE_ARCHIVE,
- 0);
- return _open_osfhandle((INT_PTR) hFile, O_WRONLY | O_BINARY);
-#endif
-#endif
-}
-
-Output::Output(const Output & o) : Handle(o), n(o.n) {
-}
-
-bool Output::CanWrite() const {
- return 1;
-}
-
-bool Output::CanRead() const {
- return 0;
-}
-
-bool Output::CanSeek() const {
- struct stat s;
-
- fstat(GetHandle(), &s);
-
- return S_ISREG(s.st_mode);
-}
-
-off_t Output::seek(off_t offset, int whence) throw (GeneralException) {
- if ((itell = lseek(GetHandle(), offset, whence)) < 0) {
- throw IOGeneral(String(_("Error seeking file ")) + n + _(": ") + strerror(errno));
- }
-#ifdef PARANOID_SEEK
- if (itell != lseek(GetHandle(), 0, SEEK_CUR)) {
- throw IOGeneral(String(_("Error seeking file ")) + n + _(": the position does not match"));
- }
-#endif
- return itell;
-}
-
-String Output::GetName() const {
- return n;
-}
-
-Stdout_t::Stdout_t() {}
-
-bool Stdout_t::CanSeek() const {
- return 0;
-}
-
-String Stdout_t::GetName() const {
- return "Stdout";
-}
-
-Stderr_t::Stderr_t() : Handle(dup(2)) {}
-
-bool Stderr_t::CanWrite() const {
- return 1;
-}
-
-bool Stderr_t::CanRead() const {
- return 0;
-}
-
-bool Stderr_t::CanSeek() const {
- return 0;
-}
-
-String Stderr_t::GetName() const {
- return "Stderr";
-}
-
-#ifdef HOOK_STDS
-Stdout_t Stdout;
-Stderr_t Stderr;
-#endif
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: Output.cc,v 1.22 2004-11-27 21:46:04 pixel Exp $ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+#include <fcntl.h>
+#include "Output.h"
+#include "Exceptions.h"
+#include "gettext.h"
+
+#ifndef S_ISREG
+#define S_ISREG(x) 1
+#endif
+
+Output::Output(String no, int create, int trunc) throw (GeneralException) :
+ Handle(no.strlen() ? wrapopen(no.to_charp(), create, trunc) : dup(1)),
+ n(no) {
+ if (GetHandle() < 0) {
+ throw IOGeneral(String(_("Error opening file ")) + no + _(" for writing: ") + strerror(errno));
+ }
+
+ size = lseek(GetHandle(), 0, SEEK_END);
+ lseek(GetHandle(), 0, SEEK_SET);
+
+ struct stat s;
+
+ fstat(GetHandle(), &s);
+
+ date_modif = s.st_mtime;
+}
+
+int Output::wrapopen(const String & n, int create, int trunc) {
+ hFile = 0;
+#ifndef _WIN32
+ return open(n.to_charp(), (create ? O_CREAT : 0) |
+ (trunc ? O_TRUNC : 0) | O_WRONLY, 00666);
+#else
+#ifdef NO_HFILE
+ return _creat(n.to_charp(), _S_IREAD | _S_IWRITE);
+#else
+ DWORD dwCreationDisposition;
+ switch ((create ? 1 : 0) | (trunc ? 2 : 0)) {
+ case 0: // no creation, no trunc
+ dwCreationDisposition = OPEN_EXISTING;
+ break;
+ case 1: // creation, no trunc if existing
+ dwCreationDisposition = OPEN_ALWAYS;
+ break;
+ case 2: // no creation, trunc of existing file
+ dwCreationDisposition = TRUNCATE_EXISTING;
+ break;
+ case 3: // creation, truc if existing
+ dwCreationDisposition = CREATE_ALWAYS;
+ break;
+ }
+ hFile = CreateFile(
+ n.to_charp(),
+ GENERIC_WRITE,
+ FILE_SHARE_READ,
+ 0,
+ dwCreationDisposition,
+ FILE_ATTRIBUTE_ARCHIVE,
+ 0);
+ return _open_osfhandle((INT_PTR) hFile, O_WRONLY | O_BINARY);
+#endif
+#endif
+}
+
+Output::Output(const Output & o) : Handle(o), n(o.n) {
+}
+
+bool Output::CanWrite() const {
+ return 1;
+}
+
+bool Output::CanRead() const {
+ return 0;
+}
+
+bool Output::CanSeek() const {
+ struct stat s;
+
+ fstat(GetHandle(), &s);
+
+ return S_ISREG(s.st_mode);
+}
+
+off_t Output::seek(off_t offset, int whence) throw (GeneralException) {
+ if ((itell = lseek(GetHandle(), offset, whence)) < 0) {
+ throw IOGeneral(String(_("Error seeking file ")) + n + _(": ") + strerror(errno));
+ }
+#ifdef PARANOID_SEEK
+ if (itell != lseek(GetHandle(), 0, SEEK_CUR)) {
+ throw IOGeneral(String(_("Error seeking file ")) + n + _(": the position does not match"));
+ }
+#endif
+ return itell;
+}
+
+String Output::GetName() const {
+ return n;
+}
+
+Stdout_t::Stdout_t() {}
+
+bool Stdout_t::CanSeek() const {
+ return 0;
+}
+
+String Stdout_t::GetName() const {
+ return "Stdout";
+}
+
+Stderr_t::Stderr_t() : Handle(dup(2)) {}
+
+bool Stderr_t::CanWrite() const {
+ return 1;
+}
+
+bool Stderr_t::CanRead() const {
+ return 0;
+}
+
+bool Stderr_t::CanSeek() const {
+ return 0;
+}
+
+String Stderr_t::GetName() const {
+ return "Stderr";
+}
+
+#ifdef HOOK_STDS
+Stdout_t Stdout;
+Stderr_t Stderr;
+#endif
diff --git a/lib/ReadJob.cc b/lib/ReadJob.cc
index 63557c2..c31b894 100644
--- a/lib/ReadJob.cc
+++ b/lib/ReadJob.cc
@@ -1,52 +1,52 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "ReadJob.h"
-#include "HttpServ.h"
-#include "Regex.h"
-#include "gettext.h"
-
-ReadJob::ReadJob(Handle * as, Handle * ad, const Regex & aregex) : s(as), d(ad), regex(&aregex) {
- s->SetNonBlock();
- d->SetNonBlock();
- WaitFor(s, W4_READING);
-}
-
-ReadJob::~ReadJob() { }
-
-int ReadJob::Do() throw (GeneralException) {
- String buff;
-
- switch (current) {
- case 0:
- try {
- *s >> buff;
- }
- catch (IOAgain e) {
- WaitFor(s, W4_READING);
- Suspend(TASK_ON_HOLD);
- }
- case 1:
- try {
- *d << buff << endnl;
- }
- catch (IOAgain e) {
- current = 1;
- WaitFor(d, W4_WRITING);
- Suspend(TASK_ON_HOLD);
- }
- current = 0;
- if (regex->Match(buff)) return TASK_DONE;
- }
-
- if (!s->IsClosed()) {
- WaitFor(s, W4_READING);
- Suspend(TASK_ON_HOLD);
- }
-
- return TASK_DONE;
-}
-
-String ReadJob::GetName() {
- return (String(_("ReadJob from ")) + s->GetName() + _(" to ") + d->GetName());
-}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "ReadJob.h"
+#include "HttpServ.h"
+#include "Regex.h"
+#include "gettext.h"
+
+ReadJob::ReadJob(Handle * as, Handle * ad, const Regex & aregex) : s(as), d(ad), regex(&aregex) {
+ s->SetNonBlock();
+ d->SetNonBlock();
+ WaitFor(s, W4_READING);
+}
+
+ReadJob::~ReadJob() { }
+
+int ReadJob::Do() throw (GeneralException) {
+ String buff;
+
+ switch (current) {
+ case 0:
+ try {
+ *s >> buff;
+ }
+ catch (IOAgain e) {
+ WaitFor(s, W4_READING);
+ Suspend(TASK_ON_HOLD);
+ }
+ case 1:
+ try {
+ *d << buff << endnl;
+ }
+ catch (IOAgain e) {
+ current = 1;
+ WaitFor(d, W4_WRITING);
+ Suspend(TASK_ON_HOLD);
+ }
+ current = 0;
+ if (regex->Match(buff)) return TASK_DONE;
+ }
+
+ if (!s->IsClosed()) {
+ WaitFor(s, W4_READING);
+ Suspend(TASK_ON_HOLD);
+ }
+
+ return TASK_DONE;
+}
+
+String ReadJob::GetName() {
+ return (String(_("ReadJob from ")) + s->GetName() + _(" to ") + d->GetName());
+}
diff --git a/lib/Regex.cc b/lib/Regex.cc
index 2a86db8..258d378 100644
--- a/lib/Regex.cc
+++ b/lib/Regex.cc
@@ -1,44 +1,44 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "Regex.h"
-#include "gettext.h"
-
-char t[1024];
-
-Regex empty("^$"), any(".*");
-
-Regex::Regex(const String & regex, int acflags, int aeflags) throw (GeneralException) : cflags(acflags), eflags(aeflags), pattern(regex.strdup()) {
- int r;
-
- if ((r = regcomp(&preg, pattern, cflags | REG_NOSUB))) {
- std::cerr << _("Error in regcomp:");
- regerror(r, &preg, t, sizeof(t));
- std::cerr << t << std::endl;
- throw GeneralException(String(_("Regex \"")) + regex + _("\" failed to compile: ") + t + "\n");
- }
-}
-
-Regex::Regex(const Regex & regex) : pattern(Base::strdup(pattern)) {
- int r;
-
- if ((r = regcomp(&preg, pattern, cflags | REG_NOSUB))) {
- printm(M_ERROR, _("Error in regcomp:"));
- regerror(r, &preg, t, sizeof(t));
- printm(M_ERROR, "%s\n", t);
- throw GeneralException(String(_("Regex \"")) + pattern + _("\" failed to compile: ") + t + "\n");
- }
-}
-
-Regex::~Regex() {
- regfree(&preg);
- free(pattern);
-}
-
-bool Regex::Match(const String & s) const {
- if (regexec(&preg, s.to_charp(), 0, 0, eflags)) {
- return false;
- } else {
- return true;
- }
-}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "Regex.h"
+#include "gettext.h"
+
+char t[1024];
+
+Regex empty("^$"), any(".*");
+
+Regex::Regex(const String & regex, int acflags, int aeflags) throw (GeneralException) : cflags(acflags), eflags(aeflags), pattern(regex.strdup()) {
+ int r;
+
+ if ((r = regcomp(&preg, pattern, cflags | REG_NOSUB))) {
+ std::cerr << _("Error in regcomp:");
+ regerror(r, &preg, t, sizeof(t));
+ std::cerr << t << std::endl;
+ throw GeneralException(String(_("Regex \"")) + regex + _("\" failed to compile: ") + t + "\n");
+ }
+}
+
+Regex::Regex(const Regex & regex) : pattern(Base::strdup(pattern)) {
+ int r;
+
+ if ((r = regcomp(&preg, pattern, cflags | REG_NOSUB))) {
+ printm(M_ERROR, _("Error in regcomp:"));
+ regerror(r, &preg, t, sizeof(t));
+ printm(M_ERROR, "%s\n", t);
+ throw GeneralException(String(_("Regex \"")) + pattern + _("\" failed to compile: ") + t + "\n");
+ }
+}
+
+Regex::~Regex() {
+ regfree(&preg);
+ free(pattern);
+}
+
+bool Regex::Match(const String & s) const {
+ if (regexec(&preg, s.to_charp(), 0, 0, eflags)) {
+ return false;
+ } else {
+ return true;
+ }
+}
diff --git a/lib/SQL.cc b/lib/SQL.cc
index 7c1bc96..26620e4 100644
--- a/lib/SQL.cc
+++ b/lib/SQL.cc
@@ -1,76 +1,76 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef HAVE_MYSQL
-
-#include "SQL.h"
-
-SQLConnection::SQLConnection(String host, String user, String passwd,
- String db, int port, String socket,
- unsigned long cflags) throw (GeneralException) : res(0) {
- mysql_init(&con);
-
- const char * phost = ((ugly_string) host).p;
- const char * puser = ((ugly_string) user).p;
- const char * ppasswd = ((ugly_string) passwd).p;
- const char * pdb = ((ugly_string) db).p;
- const char * psocket = ((ugly_string) socket).p;
-
- phost = *phost ? phost : 0;
- psocket = *psocket ? psocket : 0;
-
- if (!mysql_real_connect(&con, phost, puser, ppasswd, pdb, port, psocket, cflags)) {
- throw GeneralException("Could not connect to MySQL host " + host);
- }
-}
-
-SQLConnection::~SQLConnection() {
- mysql_close(&con);
-}
-
-void SQLConnection::query(String q) throw(GeneralException) {
- if (res) {
- mysql_free_result(res);
- }
-
- if (mysql_real_query(&con, ((ugly_string)q).p, q.strlen())) {
- throw GeneralException(String("Couldn't run query ") + q);
- }
-
- res = mysql_store_result(&con);
-
- if (res) {
- nr = mysql_num_rows(res);
- nf = mysql_num_fields(res);
- fields = mysql_fetch_fields(res);
- } else {
- nr = 0;
- nf = 0;
- fields = 0;
- }
-}
-
-int SQLConnection::numrows() {
- return nr;
-}
-
-int SQLConnection::numfields() {
- return nf;
-}
-
-AssocArray SQLConnection::fetchrow() {
- AssocArray r;
- MYSQL_ROW row;
- int i;
-
- row = mysql_fetch_row(res);
-
- for (i = 0; i < nf; i++) {
- r[fields[i].name] = row[i];
- }
-
- return r;
-}
-
-#endif
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_MYSQL
+
+#include "SQL.h"
+
+SQLConnection::SQLConnection(String host, String user, String passwd,
+ String db, int port, String socket,
+ unsigned long cflags) throw (GeneralException) : res(0) {
+ mysql_init(&con);
+
+ const char * phost = ((ugly_string) host).p;
+ const char * puser = ((ugly_string) user).p;
+ const char * ppasswd = ((ugly_string) passwd).p;
+ const char * pdb = ((ugly_string) db).p;
+ const char * psocket = ((ugly_string) socket).p;
+
+ phost = *phost ? phost : 0;
+ psocket = *psocket ? psocket : 0;
+
+ if (!mysql_real_connect(&con, phost, puser, ppasswd, pdb, port, psocket, cflags)) {
+ throw GeneralException("Could not connect to MySQL host " + host);
+ }
+}
+
+SQLConnection::~SQLConnection() {
+ mysql_close(&con);
+}
+
+void SQLConnection::query(String q) throw(GeneralException) {
+ if (res) {
+ mysql_free_result(res);
+ }
+
+ if (mysql_real_query(&con, ((ugly_string)q).p, q.strlen())) {
+ throw GeneralException(String("Couldn't run query ") + q);
+ }
+
+ res = mysql_store_result(&con);
+
+ if (res) {
+ nr = mysql_num_rows(res);
+ nf = mysql_num_fields(res);
+ fields = mysql_fetch_fields(res);
+ } else {
+ nr = 0;
+ nf = 0;
+ fields = 0;
+ }
+}
+
+int SQLConnection::numrows() {
+ return nr;
+}
+
+int SQLConnection::numfields() {
+ return nf;
+}
+
+AssocArray SQLConnection::fetchrow() {
+ AssocArray r;
+ MYSQL_ROW row;
+ int i;
+
+ row = mysql_fetch_row(res);
+
+ for (i = 0; i < nf; i++) {
+ r[fields[i].name] = row[i];
+ }
+
+ return r;
+}
+
+#endif
diff --git a/lib/Socket.cc b/lib/Socket.cc
index 86b229f..f3e28df 100644
--- a/lib/Socket.cc
+++ b/lib/Socket.cc
@@ -1,163 +1,163 @@
-#define _BSD_SOCKLEN_T_ int
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <string.h>
-#include <strings.h>
-#include <errno.h>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "BString.h"
-#include "Socket.h"
-#include "Exceptions.h"
-#include "Input.h"
-#include "Output.h"
-#include "gettext.h"
-
-Socket::Socket() throw (GeneralException) : Handle(socket(AF_INET, SOCK_STREAM, 0)), connected(false), listening(false), writeclosed(false), readclosed(false) {
-// cerr << "Socket(): connected = " << connected << "; readclosed = " << readclosed << "; writeclosed = " << writeclosed << endl;
- if (GetHandle() < 0) {
- throw GeneralException(_("Error creating socket."));
- }
-}
-
-Socket::Socket(const Socket & s) : Handle(s), connected(s.connected), listening(s.listening), writeclosed(s.writeclosed), readclosed(s.readclosed) {
-// cerr << "Constructing a socket by copy...\n";
-// cerr << "Socket(const Socket &): connected = " << connected << "; readclosed = " << readclosed << "; writeclosed = " << writeclosed << endl;
-}
-
-Socket::Socket(int h) : Handle(h), connected(true), listening(false), writeclosed(false), readclosed(false) { }
-
-String Socket::GetName(void) {
- return String("socket");
-}
-
-bool Socket::IsConnected(void) {
- return connected;
-}
-
-bool Socket::IsListening(void) {
- return listening;
-}
-
-bool Socket::CanRead(void) {
-// cerr << "CanRead: connected = " << connected << "; readclosed = " << readclosed << endl;
- return connected && !readclosed;
-}
-
-bool Socket::CanWrite(void) {
-// cerr << "CanWrite: connected = " << connected << "; writeclosed = " << writeclosed << endl;
- return connected && !writeclosed;
-}
-
-void Socket::CloseWrite(void) {
- if (!writeclosed) {
- writeclosed = true;
- shutdown(GetHandle(), 1);
- }
-}
-
-void Socket::CloseRead(void) {
- if (!readclosed) {
- readclosed = true;
- shutdown(GetHandle(), 0);
- }
-}
-
- /***********************************************\
- * Toute la suite n'est pas à décrire. Consulter *
- * plutôt un document décrivant les sockets. *
- \***********************************************/
-
-
-bool Socket::SetLocal(const String & vhost, int port) {
- struct hostent * localhostent;
- struct in_addr localhostaddr;
- struct sockaddr_in localsocketaddr;
-
-
- memset((void *)&localhostaddr, 0, sizeof(localhostaddr));
-
- if (vhost.strlen() != 0) {
- if ((localhostent = gethostbyname(vhost.to_charp()))) {
- memcpy((void *)&localhostaddr, localhostent->h_addr, sizeof(localhostaddr));
- } else {
- return false;
- }
- } else {
- localhostaddr.s_addr = htonl(INADDR_ANY);
- }
-
- memset(&localsocketaddr, 0, sizeof(struct sockaddr_in));
- localsocketaddr.sin_family = AF_INET;
- localsocketaddr.sin_addr = localhostaddr;
- localsocketaddr.sin_port = htons(port);
-
- if (bind(GetHandle(), (struct sockaddr *) &localsocketaddr, sizeof(localsocketaddr)) < 0) {
- return false;
- } else {
- return true;
- }
-}
-
-bool Socket::Connect(const String & host, int port) {
- struct hostent * remotehostent;
- struct sockaddr_in remotesocketaddr;
-
- if (!listening && !connected) {
-// cerr << " - Resolving '" << host << "'..." << endl;
- if (!(remotehostent = gethostbyname(host.to_charp()))) {
- return false;
- }
-
- remotesocketaddr.sin_family = AF_INET;
- remotesocketaddr.sin_port = htons(port);
- bcopy(remotehostent->h_addr, &remotesocketaddr.sin_addr, remotehostent->h_length);
-// cerr << " - Connecting to port " << port << " ..." << endl;
- if (!connect(GetHandle(), (struct sockaddr *)&remotesocketaddr, sizeof(remotesocketaddr))) {
-// cerr << " - Connected." << endl;
- connected = true;
- } else {
-// cerr << " - Error connecting: " << strerror(errno) << endl;
- }
- }
- return connected;
-}
-
-bool Socket::Listen(void) {
- if (!listening && !connected) {
- if (!listen(GetHandle(), 10)) {
- listening = true;
- }
- }
- return listening;
-}
-
-Socket Socket::Accept(void) throw (GeneralException) {
- struct sockaddr inaddr;
- socklen_t inlen = sizeof(inaddr);
- int h;
-
- if ((h = accept(GetHandle(), &inaddr, &inlen)) < 0) {
- throw GeneralException(_("Failed accepting."));
- } else {
- return Socket(h);
- }
-}
-
-int Socket::GetPort() {
- int r;
- struct sockaddr_in localsocketaddr;
- socklen_t locallen = sizeof(localsocketaddr);
-
- if (getsockname(GetHandle(), (struct sockaddr *) &localsocketaddr, &locallen)) {
- return -1;
- }
-
- r = ntohs(localsocketaddr.sin_port);
-
- return r;
-}
+#define _BSD_SOCKLEN_T_ int
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "BString.h"
+#include "Socket.h"
+#include "Exceptions.h"
+#include "Input.h"
+#include "Output.h"
+#include "gettext.h"
+
+Socket::Socket() throw (GeneralException) : Handle(socket(AF_INET, SOCK_STREAM, 0)), connected(false), listening(false), writeclosed(false), readclosed(false) {
+// cerr << "Socket(): connected = " << connected << "; readclosed = " << readclosed << "; writeclosed = " << writeclosed << endl;
+ if (GetHandle() < 0) {
+ throw GeneralException(_("Error creating socket."));
+ }
+}
+
+Socket::Socket(const Socket & s) : Handle(s), connected(s.connected), listening(s.listening), writeclosed(s.writeclosed), readclosed(s.readclosed) {
+// cerr << "Constructing a socket by copy...\n";
+// cerr << "Socket(const Socket &): connected = " << connected << "; readclosed = " << readclosed << "; writeclosed = " << writeclosed << endl;
+}
+
+Socket::Socket(int h) : Handle(h), connected(true), listening(false), writeclosed(false), readclosed(false) { }
+
+String Socket::GetName(void) {
+ return String("socket");
+}
+
+bool Socket::IsConnected(void) {
+ return connected;
+}
+
+bool Socket::IsListening(void) {
+ return listening;
+}
+
+bool Socket::CanRead(void) {
+// cerr << "CanRead: connected = " << connected << "; readclosed = " << readclosed << endl;
+ return connected && !readclosed;
+}
+
+bool Socket::CanWrite(void) {
+// cerr << "CanWrite: connected = " << connected << "; writeclosed = " << writeclosed << endl;
+ return connected && !writeclosed;
+}
+
+void Socket::CloseWrite(void) {
+ if (!writeclosed) {
+ writeclosed = true;
+ shutdown(GetHandle(), 1);
+ }
+}
+
+void Socket::CloseRead(void) {
+ if (!readclosed) {
+ readclosed = true;
+ shutdown(GetHandle(), 0);
+ }
+}
+
+ /***********************************************\
+ * Toute la suite n'est pas à décrire. Consulter *
+ * plutôt un document décrivant les sockets. *
+ \***********************************************/
+
+
+bool Socket::SetLocal(const String & vhost, int port) {
+ struct hostent * localhostent;
+ struct in_addr localhostaddr;
+ struct sockaddr_in localsocketaddr;
+
+
+ memset((void *)&localhostaddr, 0, sizeof(localhostaddr));
+
+ if (vhost.strlen() != 0) {
+ if ((localhostent = gethostbyname(vhost.to_charp()))) {
+ memcpy((void *)&localhostaddr, localhostent->h_addr, sizeof(localhostaddr));
+ } else {
+ return false;
+ }
+ } else {
+ localhostaddr.s_addr = htonl(INADDR_ANY);
+ }
+
+ memset(&localsocketaddr, 0, sizeof(struct sockaddr_in));
+ localsocketaddr.sin_family = AF_INET;
+ localsocketaddr.sin_addr = localhostaddr;
+ localsocketaddr.sin_port = htons(port);
+
+ if (bind(GetHandle(), (struct sockaddr *) &localsocketaddr, sizeof(localsocketaddr)) < 0) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+bool Socket::Connect(const String & host, int port) {
+ struct hostent * remotehostent;
+ struct sockaddr_in remotesocketaddr;
+
+ if (!listening && !connected) {
+// cerr << " - Resolving '" << host << "'..." << endl;
+ if (!(remotehostent = gethostbyname(host.to_charp()))) {
+ return false;
+ }
+
+ remotesocketaddr.sin_family = AF_INET;
+ remotesocketaddr.sin_port = htons(port);
+ bcopy(remotehostent->h_addr, &remotesocketaddr.sin_addr, remotehostent->h_length);
+// cerr << " - Connecting to port " << port << " ..." << endl;
+ if (!connect(GetHandle(), (struct sockaddr *)&remotesocketaddr, sizeof(remotesocketaddr))) {
+// cerr << " - Connected." << endl;
+ connected = true;
+ } else {
+// cerr << " - Error connecting: " << strerror(errno) << endl;
+ }
+ }
+ return connected;
+}
+
+bool Socket::Listen(void) {
+ if (!listening && !connected) {
+ if (!listen(GetHandle(), 10)) {
+ listening = true;
+ }
+ }
+ return listening;
+}
+
+Socket Socket::Accept(void) throw (GeneralException) {
+ struct sockaddr inaddr;
+ socklen_t inlen = sizeof(inaddr);
+ int h;
+
+ if ((h = accept(GetHandle(), &inaddr, &inlen)) < 0) {
+ throw GeneralException(_("Failed accepting."));
+ } else {
+ return Socket(h);
+ }
+}
+
+int Socket::GetPort() {
+ int r;
+ struct sockaddr_in localsocketaddr;
+ socklen_t locallen = sizeof(localsocketaddr);
+
+ if (getsockname(GetHandle(), (struct sockaddr *) &localsocketaddr, &locallen)) {
+ return -1;
+ }
+
+ r = ntohs(localsocketaddr.sin_port);
+
+ return r;
+}
diff --git a/lib/String.cc b/lib/String.cc
index c833134..084831c 100644
--- a/lib/String.cc
+++ b/lib/String.cc
@@ -1,558 +1,558 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: String.cc,v 1.35 2004-11-27 21:35:19 pixel Exp $ */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <iostream>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef HAVE_GMP
-#include <gmpxx.h>
-#endif
-#include "BString.h"
-#include "Exceptions.h"
-#include "gettext.h"
-
-char ** gruikptr;
-
-extern "C" {
- double dateCalc(char *, char *);
- int isDateArgument(char *);
-}
-
-char String::t[BUFSIZ + 1];
-
-String::String(const String & s) : str(Base::strdup(s.str)), siz(s.siz) {
-#ifdef DEBUG
- fprintf(stderr, _("Duplicating string `%s', from %p to %p, from this %p to this %p\n"), str, s.str, str, &s, this);
-#endif
-}
-
-#ifndef asprintf
-extern "C" int asprintf(char **, const char *, ...);
-#endif
-
-String::String(char c) : siz(1) {
-#ifdef DEBUG
- fprintf(stderr, _("Creating a string with `%c' at %p, this = %p\n"), c, str, this);
-#endif
-#ifndef HAVE_ASPRINTF
- char * t = (char *) malloc(2);
- sprintf(t, "%c", c);
- str = t;
-#else
- asprintf(&str, "%c", c);
-#endif
-}
-
-String::String(const char * s) : str(Base::strdup(s)), siz(::strlen(str)) {
-#ifdef DEBUG
- fprintf(stderr, _("Creating a string with `%s' at %p from %p, this = %p\n"), str, str, s, this);
-#endif
-}
-
-String::String(int hs, char * s) : str(s), siz(hs) {
-#ifdef DEBUG
- fprintf(stderr, _("Fast-Creating a string with `%s' at %p from %p, this = %p\n"), str, str, s, this);
-#endif
-}
-
-String::String(int i) {
-#ifndef HAVE_ASPRINTF
- char t[20];
- sprintf(t, "%i", i);
- str = Base::strdup(t);
-#else
- asprintf(&str, "%i", i);
-#endif
- siz = ::strlen(str);
-}
-
-String::String(unsigned int i) {
-#ifndef HAVE_ASPRINTF
- char t[20];
- sprintf(t, "%u", i);
- str = Base::strdup(t);
-#else
- asprintf(&str, "%u", i);
-#endif
- siz = ::strlen(str);
-}
-
-String::String(int64 l) {
-#ifndef HAVE_ASPRINTF
- char t[40];
- sprintf(t, "%lld", l);
- str = Base::strdup(t);
-#else
- asprintf(&str, "%lld", l);
-#endif
- siz = ::strlen(str);
-}
-
-String::String(Uint64 l) {
-#ifndef HAVE_ASPRINTF
- char t[40];
- sprintf(t, "%llu", l);
- str = Base::strdup(t);
-#else
- asprintf(&str, "%llu", l);
-#endif
- siz = ::strlen(str);
-}
-
-String::String(double d) {
-#ifndef HAVE_ASPRINTF
- char t[30];
- sprintf(t, "%g", d);
- str = Base::strdup(t);
-#else
- asprintf(&str, "%g", d);
-#endif
- siz = ::strlen(str);
-}
-
-String::~String() {
-#ifdef DEBUG
- fprintf(stderr, _("Destroying string @ %p, freeing %p.\n"), this, str);
-#endif
- free(str);
-}
-
-const char * String::set(const char * s, va_list ap) {
- const char * r;
- free(str);
- if (!s) {
- str = Base::strdup("");
- return str;
- }
-
-#ifdef HAVE_GMP
- gmp_vasprintf(&str, s, ap);
- r = str;
-#else // !HAVE_GMP
-#ifdef HAVE_VASPRINTF
- vasprintf(&str, s, ap);
- r = str;
-#else // !HAVE_VASPRINTF
-#ifdef HAVE_VSNPRINTF
- LOCK;
- vsnprintf(t, BUFSIZ, s, ap);
- str = Base::strdup(r = t);
- UNLOCK;
-#else // !HAVE_VSNPRINTF
-#ifdef _WIN32
-#ifdef _MSC_VER
- r = str = (char *) malloc(_vscprintf(s, ap) + 1);
- vsprintf(str, s, ap);
-#else
- LOCK;
- _vsnprintf(t, BUFSIZ, s, ap);
- str = Base::strdup(r = t);
- UNLOCK;
-#endif
-#else
- LOCK;
- vsprintf(t, s, ap);
- str = Base::strdup(r = t);
- UNLOCK;
-#endif
-#endif // HAVE_VSNPRINTF
-#endif // HAVE_VASPRINTF
-#endif // HAVE_GMP
- siz = ::strlen(str);
- return r;
-}
-
-const char * String::set(const char * s, ...) {
- const char * r;
- va_list ap;
- va_start(ap, s);
- r = set(s, ap);
- va_end(ap);
- return r;
-}
-
-const char * String::set(const ugly_string & s, ...) {
- const char * r;
- va_list ap;
- va_start(ap, s);
- r = set(s.p, ap);
- va_end(ap);
- return r;
-}
-
-#ifdef HAVE_VSSCANF
-int String::scanf(const char * s, ...) const {
- va_list ap;
- int t;
-
- va_start(ap, s);
-#ifdef HAVE_GMP
- t = gmp_vsscanf(str, s, ap);
-#else
- t = vsscanf(str, s, ap);
-#endif
- va_end(ap);
- return t;
-}
-
-int String::scanf(const ugly_string & s, ...) const {
- va_list ap;
- int t;
-
- va_start(ap, s);
-#ifdef HAVE_GMP
- t = gmp_vsscanf(str, s.p, ap);
-#else
- t = vsscanf(str, s.p, ap);
-#endif
- va_end(ap);
- return t;
-}
-#endif
-
-const char * String::to_charp(size_t from, ssize_t to) const {
- if (to < 0) {
- if (from)
- strncpy(t, &(str[from]), BUFSIZ);
- else
- return str;
- } else {
- if (((size_t) to) >= siz) {
- to = siz - 1;
- }
-
- if ((((size_t) to) - from) > BUFSIZ) {
- from -= (to - from) - BUFSIZ;
- }
-
- if (((size_t) to) >= from) {
- size_t i;
- for (i = 0; i <= ((size_t) to) - from; i++) {
- t[i] = str[i + from];
- }
- t[i] = '\0';
- } else {
- t[0] = '\0';
- }
- }
- return t;
-}
-
-String String::extract(size_t from, ssize_t to) const {
- return String(to_charp(from, to));
-}
-
-char * String::strdup(size_t from, ssize_t to) const {
- char * r;
-
- LOCK;
- r = Base::strdup(to_charp(from, to));
- UNLOCK;
-
- return r;
-}
-
-int String::to_int(void) const {
- int r;
-
- sscanf(str, "%i", &r);
- return r;
-}
-
-double String::to_double(void) const {
- double r;
-
- sscanf(str, "%lf", &r);
- return r;
-}
-
-String & String::operator=(const String & s) {
- if (str != s.str) {
- // On évite l'autodestruction...
- free(str);
- str = s.strdup();
- siz = s.siz;
- }
- return *this;
-}
-
-String String::operator+(const String & s) const {
- char * t = (char *) malloc(s.siz + siz + 1), * u;
-
- strcpy((u = t), str);
- u += siz;
- strcpy(u, s.str);
- return String(siz + s.siz, t);
-}
-
-String & String::operator+=(const String & s) {
- char * t = (char *) malloc(s.siz + siz + 1), * u;
-
- strcpy((u = t), str);
- u += siz;
- strcat(u, s.str);
- free(str);
- str = t;
- siz += s.siz;
- return (*this);
-}
-
-std::ostream & operator<<(std::ostream & os, const String & s) {
- return (os << s.to_charp());
-}
-
-std::istream & operator>>(std::istream & is, String & s) {
- char c = 0;
-
- s.set("");
-
- while (!is.eof()) {
- c = is.get();
- if (c == '\n') return is;
- if (c == '\r') continue;
- s += c;
- }
-
- return is;
-}
-
-bool String::operator!=(const String & s) const {
- return (strcmp(str, s.str) != 0);
-}
-
-bool String::operator==(const String & s) const {
- return (strcmp(str, s.str) == 0);
-}
-
-bool String::operator<=(const String & s) const {
- return (strcmp(str, s.str) <= 0);
-}
-
-bool String::operator>=(const String & s) const {
- return (strcmp(str, s.str) >= 0);
-}
-
-bool String::operator<(const String & s) const {
- return (strcmp(str, s.str) < 0);
-}
-
-bool String::operator>(const String & s) const {
- return (strcmp(str, s.str) > 0);
-}
-
-size_t String::strlen() const {
- return (siz);
-}
-
-char String::operator[](size_t i) const {
- if (i >= siz) {
- return 0;
- } else {
- return str[i];
- }
-}
-
-char & String::operator[](size_t i) {
- static char zero = 0;
-
- if (i >= siz) {
- return zero;
- } else {
- return str[i];
- }
-}
-
-ssize_t String::strchr(char c, size_t from) const {
- for (size_t i = from; i < siz; i++) {
- if (str[i] == c) return i;
- }
-
- return -1;
-}
-
-ssize_t String::strrchr(char c) const {
- for (size_t i = siz - 1; i >= 0; i--) {
- if (str[i] == c) return i;
- }
-
- return -1;
-}
-
-ssize_t String::strstr(const String & s) const {
- char * p = ::strstr(str, s.str);
-
- if (p) {
- return p - str;
- } else {
- return -1;
- }
-}
-
-int String::strchrcnt(char c) const {
- size_t i, cnt = 0;
- for (i = 0; i < siz; i++) {
- if (str[i] == c) cnt++;
- }
-
- return cnt;
-}
-
-String String::to_sqldate(void) const {
-/* DD/MM/YYYY ==> YYYYMMMDD */
- return (is_date() ? extract(6, 9) + extract(3, 4) + extract(0, 1) : "");
-}
-
-String String::to_sqltime(void) const {
-/* h:m ==> h * 60 + m */
- int p = strchr(':');
- return (is_time() ? String(extract(0, p - 1).to_int() * 60 + extract(p + 1).to_int()) : "");
-}
-
-String String::from_sqldate(void) const {
-/* YYYYMMDD ==> DD/MM/YYYY */
- return ((strlen() == 8) && is_number() ? extract(6, 7) + '/' + extract(4, 5) + '/' + extract(0, 3) : "");
-}
-
-String String::from_sqltime(void) const {
-/* t ==> (t / 60):(t % 60) */
- int t = to_int();
- return (is_number() ? String((int) (t / 60)) + ':' + (t % 60) : "");
-}
-
-bool String::is_date(void) const {
-/* 'DD/MM/YYYY'
- 0123456789 */
-
- if (strlen() != 10) return false;
- if ((str[2] != '/') || (str[5] != '/') ||
- (!extract(0, 1).is_number()) ||
- (!extract(3, 4).is_number()) ||
- (!extract(6, 9).is_number())) {
- return (isDateArgument(to_sqldate().str) != 0);
- }
-
- return true;
-}
-
-double String::datedif(const String & s) const {
- double r;
- if (is_date() && s.is_date()) {
- r = dateCalc(str, s.str);
- return r < 0 ? -r : r;
- }
-
- return -1;
-}
-
-bool String::is_number(void) const {
- for (size_t i = ((str[0] == '-') ? 1 : 0); i < siz; i++) {
- if ((str[i] > '9') || (str[i] < '0')) return false;
- }
- return true;
-}
-
-bool String::is_float(void) const {
- bool seendot = false;
-
- for (size_t i = ((str[0] == '-') ? 1 : 0); i < siz; i++) {
- if ((str[i] > '9') || (str[i] < '0')) {
- if ((str[i] == '.') && !seendot) {
- seendot = true;
- } else {
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool String::is_time(void) const {
- int p = strchr(':');
-
- if (p == -1) return false;
-
- // On accepte les heures sous le format xxxxxx:yy pour pouvoir indiquer des durées.
-
- if ((!extract(0, p - 1).is_number()) || (!extract(p + 1).is_number()))
- return false;
-
- return (extract(p + 1).to_int() < 60) ? true : false;
-}
-
-String operator+(const char * a, const String & b) {
- return String(a) + b;
-}
-
-String::operator ugly_string() const {
- ugly_string r;
- r.p = str;
- return r;
-}
-
-String & String::toupper() {
- for (unsigned int i = 0; i < strlen(); i++) {
- str[i] = ::toupper(str[i]);
- }
-
- return *this;
-}
-
-String & String::tolower() {
- for (unsigned int i = 0; i < strlen(); i++) {
- str[i] = ::tolower(str[i]);
- }
-
- return *this;
-}
-
-String String::ltrim() const {
- char * d = (char *) malloc(strlen() + 1), * p, * r;
- int s;
-
- r = d;
-
- for (p = str; *p && *p == ' '; p++);
- for (s = 0; *p; *(d++) = *(p++), s++);
- *d = 0;
-
- return String(s, r);
-}
-
-String String::rtrim() const {
- char * d = strdup(), * r;
- int s = strlen();
-
- r = d;
-
- for (d += s - 1; s && (*d == ' '); *(d--) = 0, s--);
-
- return String(s, r);
-}
-
-String String::trim() const {
- return rtrim().ltrim();
-}
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: String.cc,v 1.36 2004-11-27 21:46:04 pixel Exp $ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <iostream>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_GMP
+#include <gmpxx.h>
+#endif
+#include "BString.h"
+#include "Exceptions.h"
+#include "gettext.h"
+
+char ** gruikptr;
+
+extern "C" {
+ double dateCalc(char *, char *);
+ int isDateArgument(char *);
+}
+
+char String::t[BUFSIZ + 1];
+
+String::String(const String & s) : str(Base::strdup(s.str)), siz(s.siz) {
+#ifdef DEBUG
+ fprintf(stderr, _("Duplicating string `%s', from %p to %p, from this %p to this %p\n"), str, s.str, str, &s, this);
+#endif
+}
+
+#ifndef asprintf
+extern "C" int asprintf(char **, const char *, ...);
+#endif
+
+String::String(char c) : siz(1) {
+#ifdef DEBUG
+ fprintf(stderr, _("Creating a string with `%c' at %p, this = %p\n"), c, str, this);
+#endif
+#ifndef HAVE_ASPRINTF
+ char * t = (char *) malloc(2);
+ sprintf(t, "%c", c);
+ str = t;
+#else
+ asprintf(&str, "%c", c);
+#endif
+}
+
+String::String(const char * s) : str(Base::strdup(s)), siz(::strlen(str)) {
+#ifdef DEBUG
+ fprintf(stderr, _("Creating a string with `%s' at %p from %p, this = %p\n"), str, str, s, this);
+#endif
+}
+
+String::String(int hs, char * s) : str(s), siz(hs) {
+#ifdef DEBUG
+ fprintf(stderr, _("Fast-Creating a string with `%s' at %p from %p, this = %p\n"), str, str, s, this);
+#endif
+}
+
+String::String(int i) {
+#ifndef HAVE_ASPRINTF
+ char t[20];
+ sprintf(t, "%i", i);
+ str = Base::strdup(t);
+#else
+ asprintf(&str, "%i", i);
+#endif
+ siz = ::strlen(str);
+}
+
+String::String(unsigned int i) {
+#ifndef HAVE_ASPRINTF
+ char t[20];
+ sprintf(t, "%u", i);
+ str = Base::strdup(t);
+#else
+ asprintf(&str, "%u", i);
+#endif
+ siz = ::strlen(str);
+}
+
+String::String(int64 l) {
+#ifndef HAVE_ASPRINTF
+ char t[40];
+ sprintf(t, "%lld", l);
+ str = Base::strdup(t);
+#else
+ asprintf(&str, "%lld", l);
+#endif
+ siz = ::strlen(str);
+}
+
+String::String(Uint64 l) {
+#ifndef HAVE_ASPRINTF
+ char t[40];
+ sprintf(t, "%llu", l);
+ str = Base::strdup(t);
+#else
+ asprintf(&str, "%llu", l);
+#endif
+ siz = ::strlen(str);
+}
+
+String::String(double d) {
+#ifndef HAVE_ASPRINTF
+ char t[30];
+ sprintf(t, "%g", d);
+ str = Base::strdup(t);
+#else
+ asprintf(&str, "%g", d);
+#endif
+ siz = ::strlen(str);
+}
+
+String::~String() {
+#ifdef DEBUG
+ fprintf(stderr, _("Destroying string @ %p, freeing %p.\n"), this, str);
+#endif
+ free(str);
+}
+
+const char * String::set(const char * s, va_list ap) {
+ const char * r;
+ free(str);
+ if (!s) {
+ str = Base::strdup("");
+ return str;
+ }
+
+#ifdef HAVE_GMP
+ gmp_vasprintf(&str, s, ap);
+ r = str;
+#else // !HAVE_GMP
+#ifdef HAVE_VASPRINTF
+ vasprintf(&str, s, ap);
+ r = str;
+#else // !HAVE_VASPRINTF
+#ifdef HAVE_VSNPRINTF
+ LOCK;
+ vsnprintf(t, BUFSIZ, s, ap);
+ str = Base::strdup(r = t);
+ UNLOCK;
+#else // !HAVE_VSNPRINTF
+#ifdef _WIN32
+#ifdef _MSC_VER
+ r = str = (char *) malloc(_vscprintf(s, ap) + 1);
+ vsprintf(str, s, ap);
+#else
+ LOCK;
+ _vsnprintf(t, BUFSIZ, s, ap);
+ str = Base::strdup(r = t);
+ UNLOCK;
+#endif
+#else
+ LOCK;
+ vsprintf(t, s, ap);
+ str = Base::strdup(r = t);
+ UNLOCK;
+#endif
+#endif // HAVE_VSNPRINTF
+#endif // HAVE_VASPRINTF
+#endif // HAVE_GMP
+ siz = ::strlen(str);
+ return r;
+}
+
+const char * String::set(const char * s, ...) {
+ const char * r;
+ va_list ap;
+ va_start(ap, s);
+ r = set(s, ap);
+ va_end(ap);
+ return r;
+}
+
+const char * String::set(const ugly_string & s, ...) {
+ const char * r;
+ va_list ap;
+ va_start(ap, s);
+ r = set(s.p, ap);
+ va_end(ap);
+ return r;
+}
+
+#ifdef HAVE_VSSCANF
+int String::scanf(const char * s, ...) const {
+ va_list ap;
+ int t;
+
+ va_start(ap, s);
+#ifdef HAVE_GMP
+ t = gmp_vsscanf(str, s, ap);
+#else
+ t = vsscanf(str, s, ap);
+#endif
+ va_end(ap);
+ return t;
+}
+
+int String::scanf(const ugly_string & s, ...) const {
+ va_list ap;
+ int t;
+
+ va_start(ap, s);
+#ifdef HAVE_GMP
+ t = gmp_vsscanf(str, s.p, ap);
+#else
+ t = vsscanf(str, s.p, ap);
+#endif
+ va_end(ap);
+ return t;
+}
+#endif
+
+const char * String::to_charp(size_t from, ssize_t to) const {
+ if (to < 0) {
+ if (from)
+ strncpy(t, &(str[from]), BUFSIZ);
+ else
+ return str;
+ } else {
+ if (((size_t) to) >= siz) {
+ to = siz - 1;
+ }
+
+ if ((((size_t) to) - from) > BUFSIZ) {
+ from -= (to - from) - BUFSIZ;
+ }
+
+ if (((size_t) to) >= from) {
+ size_t i;
+ for (i = 0; i <= ((size_t) to) - from; i++) {
+ t[i] = str[i + from];
+ }
+ t[i] = '\0';
+ } else {
+ t[0] = '\0';
+ }
+ }
+ return t;
+}
+
+String String::extract(size_t from, ssize_t to) const {
+ return String(to_charp(from, to));
+}
+
+char * String::strdup(size_t from, ssize_t to) const {
+ char * r;
+
+ LOCK;
+ r = Base::strdup(to_charp(from, to));
+ UNLOCK;
+
+ return r;
+}
+
+int String::to_int(void) const {
+ int r;
+
+ sscanf(str, "%i", &r);
+ return r;
+}
+
+double String::to_double(void) const {
+ double r;
+
+ sscanf(str, "%lf", &r);
+ return r;
+}
+
+String & String::operator=(const String & s) {
+ if (str != s.str) {
+ // On évite l'autodestruction...
+ free(str);
+ str = s.strdup();
+ siz = s.siz;
+ }
+ return *this;
+}
+
+String String::operator+(const String & s) const {
+ char * t = (char *) malloc(s.siz + siz + 1), * u;
+
+ strcpy((u = t), str);
+ u += siz;
+ strcpy(u, s.str);
+ return String(siz + s.siz, t);
+}
+
+String & String::operator+=(const String & s) {
+ char * t = (char *) malloc(s.siz + siz + 1), * u;
+
+ strcpy((u = t), str);
+ u += siz;
+ strcat(u, s.str);
+ free(str);
+ str = t;
+ siz += s.siz;
+ return (*this);
+}
+
+std::ostream & operator<<(std::ostream & os, const String & s) {
+ return (os << s.to_charp());
+}
+
+std::istream & operator>>(std::istream & is, String & s) {
+ char c = 0;
+
+ s.set("");
+
+ while (!is.eof()) {
+ c = is.get();
+ if (c == '\n') return is;
+ if (c == '\r') continue;
+ s += c;
+ }
+
+ return is;
+}
+
+bool String::operator!=(const String & s) const {
+ return (strcmp(str, s.str) != 0);
+}
+
+bool String::operator==(const String & s) const {
+ return (strcmp(str, s.str) == 0);
+}
+
+bool String::operator<=(const String & s) const {
+ return (strcmp(str, s.str) <= 0);
+}
+
+bool String::operator>=(const String & s) const {
+ return (strcmp(str, s.str) >= 0);
+}
+
+bool String::operator<(const String & s) const {
+ return (strcmp(str, s.str) < 0);
+}
+
+bool String::operator>(const String & s) const {
+ return (strcmp(str, s.str) > 0);
+}
+
+size_t String::strlen() const {
+ return (siz);
+}
+
+char String::operator[](size_t i) const {
+ if (i >= siz) {
+ return 0;
+ } else {
+ return str[i];
+ }
+}
+
+char & String::operator[](size_t i) {
+ static char zero = 0;
+
+ if (i >= siz) {
+ return zero;
+ } else {
+ return str[i];
+ }
+}
+
+ssize_t String::strchr(char c, size_t from) const {
+ for (size_t i = from; i < siz; i++) {
+ if (str[i] == c) return i;
+ }
+
+ return -1;
+}
+
+ssize_t String::strrchr(char c) const {
+ for (size_t i = siz - 1; i >= 0; i--) {
+ if (str[i] == c) return i;
+ }
+
+ return -1;
+}
+
+ssize_t String::strstr(const String & s) const {
+ char * p = ::strstr(str, s.str);
+
+ if (p) {
+ return p - str;
+ } else {
+ return -1;
+ }
+}
+
+int String::strchrcnt(char c) const {
+ size_t i, cnt = 0;
+ for (i = 0; i < siz; i++) {
+ if (str[i] == c) cnt++;
+ }
+
+ return cnt;
+}
+
+String String::to_sqldate(void) const {
+/* DD/MM/YYYY ==> YYYYMMMDD */
+ return (is_date() ? extract(6, 9) + extract(3, 4) + extract(0, 1) : "");
+}
+
+String String::to_sqltime(void) const {
+/* h:m ==> h * 60 + m */
+ int p = strchr(':');
+ return (is_time() ? String(extract(0, p - 1).to_int() * 60 + extract(p + 1).to_int()) : "");
+}
+
+String String::from_sqldate(void) const {
+/* YYYYMMDD ==> DD/MM/YYYY */
+ return ((strlen() == 8) && is_number() ? extract(6, 7) + '/' + extract(4, 5) + '/' + extract(0, 3) : "");
+}
+
+String String::from_sqltime(void) const {
+/* t ==> (t / 60):(t % 60) */
+ int t = to_int();
+ return (is_number() ? String((int) (t / 60)) + ':' + (t % 60) : "");
+}
+
+bool String::is_date(void) const {
+/* 'DD/MM/YYYY'
+ 0123456789 */
+
+ if (strlen() != 10) return false;
+ if ((str[2] != '/') || (str[5] != '/') ||
+ (!extract(0, 1).is_number()) ||
+ (!extract(3, 4).is_number()) ||
+ (!extract(6, 9).is_number())) {
+ return (isDateArgument(to_sqldate().str) != 0);
+ }
+
+ return true;
+}
+
+double String::datedif(const String & s) const {
+ double r;
+ if (is_date() && s.is_date()) {
+ r = dateCalc(str, s.str);
+ return r < 0 ? -r : r;
+ }
+
+ return -1;
+}
+
+bool String::is_number(void) const {
+ for (size_t i = ((str[0] == '-') ? 1 : 0); i < siz; i++) {
+ if ((str[i] > '9') || (str[i] < '0')) return false;
+ }
+ return true;
+}
+
+bool String::is_float(void) const {
+ bool seendot = false;
+
+ for (size_t i = ((str[0] == '-') ? 1 : 0); i < siz; i++) {
+ if ((str[i] > '9') || (str[i] < '0')) {
+ if ((str[i] == '.') && !seendot) {
+ seendot = true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool String::is_time(void) const {
+ int p = strchr(':');
+
+ if (p == -1) return false;
+
+ // On accepte les heures sous le format xxxxxx:yy pour pouvoir indiquer des durées.
+
+ if ((!extract(0, p - 1).is_number()) || (!extract(p + 1).is_number()))
+ return false;
+
+ return (extract(p + 1).to_int() < 60) ? true : false;
+}
+
+String operator+(const char * a, const String & b) {
+ return String(a) + b;
+}
+
+String::operator ugly_string() const {
+ ugly_string r;
+ r.p = str;
+ return r;
+}
+
+String & String::toupper() {
+ for (unsigned int i = 0; i < strlen(); i++) {
+ str[i] = ::toupper(str[i]);
+ }
+
+ return *this;
+}
+
+String & String::tolower() {
+ for (unsigned int i = 0; i < strlen(); i++) {
+ str[i] = ::tolower(str[i]);
+ }
+
+ return *this;
+}
+
+String String::ltrim() const {
+ char * d = (char *) malloc(strlen() + 1), * p, * r;
+ int s;
+
+ r = d;
+
+ for (p = str; *p && *p == ' '; p++);
+ for (s = 0; *p; *(d++) = *(p++), s++);
+ *d = 0;
+
+ return String(s, r);
+}
+
+String String::rtrim() const {
+ char * d = strdup(), * r;
+ int s = strlen();
+
+ r = d;
+
+ for (d += s - 1; s && (*d == ' '); *(d--) = 0, s--);
+
+ return String(s, r);
+}
+
+String String::trim() const {
+ return rtrim().ltrim();
+}
diff --git a/lib/Table.cc b/lib/Table.cc
index 7d0941a..2509e4e 100644
--- a/lib/Table.cc
+++ b/lib/Table.cc
@@ -1,50 +1,50 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "Table.h"
-#include "HttpServ.h"
-#include "CopyJob.h"
-#include "Buffer.h"
-
-Table::Table(const String & titre, const String & url, String * heads, String * cells, int nbc, int nbl, Action * na) :
- Action(url), tit(titre), hds(heads), cls(cells), nc(nbc), nl(nbl), Next(na) { }
-
-String Table::GetTitle(void) {
- return tit;
-}
-
-Task * Table::Do(Variables * v, Variables *, Handle * h) {
- Handle * b = new Buffer();
- Task * t = new CopyJob(b, h, -1, true);
-
- SendHead(b);
-
- (*b) << "<center><TABLE BORDER=0>" << endnl;
-
- if (hds) {
- (*b) << "<TR>" << endnl;
- for (int i = 0; i < nc; i++) {
- (*b) << "<TH BGCOLOR=\"#bbbbbb\">" << hds[i] << "</TH>" << endnl;
- }
- (*b) << "</TR>" << endnl;
- }
-
- for (int l = 0; l < nl; l++) {
- (*b) << "<TR>" << endnl;
- for (int c = 0; c < nc; c++) {
- (*b) << "<TD BGCOLOR=\"#" << (l % 2 ? "cccccc" : "dddddd") << "\">" << cls[l * nc + c] << "</TD>" << endnl;
- }
- (*b) << "</TR>" << endnl;
- }
-
- (*b) << "</TABLE>"
-
-"<FORM METHOD=\"POST\" ACTION=\"/bin/" << (Next ? Next->GetURL() : "start") << "\">" << endnl <<
-"<INPUT TYPE=\"SUBMIT\" VALUE=\" Ok \">" << endnl;
-(*b) << "</FORM></CENTER>" << endnl;
-
- SendFoot(b);
- Accessed();
-
- return t;
-}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "Table.h"
+#include "HttpServ.h"
+#include "CopyJob.h"
+#include "Buffer.h"
+
+Table::Table(const String & titre, const String & url, String * heads, String * cells, int nbc, int nbl, Action * na) :
+ Action(url), tit(titre), hds(heads), cls(cells), nc(nbc), nl(nbl), Next(na) { }
+
+String Table::GetTitle(void) {
+ return tit;
+}
+
+Task * Table::Do(Variables * v, Variables *, Handle * h) {
+ Handle * b = new Buffer();
+ Task * t = new CopyJob(b, h, -1, true);
+
+ SendHead(b);
+
+ (*b) << "<center><TABLE BORDER=0>" << endnl;
+
+ if (hds) {
+ (*b) << "<TR>" << endnl;
+ for (int i = 0; i < nc; i++) {
+ (*b) << "<TH BGCOLOR=\"#bbbbbb\">" << hds[i] << "</TH>" << endnl;
+ }
+ (*b) << "</TR>" << endnl;
+ }
+
+ for (int l = 0; l < nl; l++) {
+ (*b) << "<TR>" << endnl;
+ for (int c = 0; c < nc; c++) {
+ (*b) << "<TD BGCOLOR=\"#" << (l % 2 ? "cccccc" : "dddddd") << "\">" << cls[l * nc + c] << "</TD>" << endnl;
+ }
+ (*b) << "</TR>" << endnl;
+ }
+
+ (*b) << "</TABLE>"
+
+"<FORM METHOD=\"POST\" ACTION=\"/bin/" << (Next ? Next->GetURL() : "start") << "\">" << endnl <<
+"<INPUT TYPE=\"SUBMIT\" VALUE=\" Ok \">" << endnl;
+(*b) << "</FORM></CENTER>" << endnl;
+
+ SendFoot(b);
+ Accessed();
+
+ return t;
+}
diff --git a/lib/Task.cc b/lib/Task.cc
index 55a4540..afa697c 100644
--- a/lib/Task.cc
+++ b/lib/Task.cc
@@ -1,110 +1,110 @@
-#include <sys/time.h>
-#include <iostream>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "TaskMan.h"
-#include "Task.h"
-#include "BString.h"
-#include "gettext.h"
-
-Task::Task() : current(0), state(TASK_ON_HOLD), stopped(false), suspended(false), wbta(0) {
- TaskMan::AddTask(this);
-}
-
-Task::~Task() {
- TaskMan::RemoveFromWatches(this);
-}
-
-int Task::Do() throw (GeneralException) {
- return TASK_ON_HOLD;
-}
-
-int Task::Run() {
- try {
- state = Do();
- }
- catch (TaskSwitch) {
- return state;
- }
- catch (GeneralException e) {
- std::cerr << _("Task ") << GetName() << _(" caused an unexpected exception: \"") << e.GetMsg() << _("\". Terminating.\n");
- state = TASK_DONE;
- return TASK_DONE;
- }
-
- return state;
-}
-
-int Task::DryRun() {
- while (state != TASK_DONE) {
- try {
- state = Do();
- }
- catch (TaskSwitch) {
- }
- catch (GeneralException e) {
- std::cerr << _("Task ") << GetName() << _(" caused an unexpected exception during dry-run: \"") << e.GetMsg() << _("\". Terminating.\n");
- state = TASK_DONE;
- }
- }
-
- return state;
-}
-
-int Task::GetState() {
- return state;
-}
-
-String Task::GetName() {
- return _("Unknow Task");
-}
-
-void Task::Suspend(int newstate) throw (GeneralException) {
- if (newstate != -1) {
- state = newstate;
- }
- suspended = true;
- throw TaskSwitch();
-}
-
-void Task::WaitFor(Handle * h, int flags) {
- h->SetNonBlock();
- TaskMan::WaitFor(h, this, flags);
-}
-
-void Task::WaitFor(Task * t) {
- t->wbta = this;
-}
-
-void Task::WaitFor(pid_t p) {
- TaskMan::WaitFor(p, this);
-}
-
-void Task::WaitFor(timeval t, int flags) {
- TaskMan::WaitFor(t, this, flags);
-}
-
-void Task::SetBurst() {
- state = TASK_BURST;
-}
-
-void Task::Stop() {
- stopped = true;
-}
-
-void Task::Restart() {
- stopped = false;
-}
-
-bool Task::IsStopped() {
- return stopped;
-}
-
-Task * Task::WaitedBy() {
- return wbta;
-}
-
-void Task::RemoveFromWatches() {
- wbta = 0;
-}
+#include <sys/time.h>
+#include <iostream>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "TaskMan.h"
+#include "Task.h"
+#include "BString.h"
+#include "gettext.h"
+
+Task::Task() : current(0), state(TASK_ON_HOLD), stopped(false), suspended(false), wbta(0) {
+ TaskMan::AddTask(this);
+}
+
+Task::~Task() {
+ TaskMan::RemoveFromWatches(this);
+}
+
+int Task::Do() throw (GeneralException) {
+ return TASK_ON_HOLD;
+}
+
+int Task::Run() {
+ try {
+ state = Do();
+ }
+ catch (TaskSwitch) {
+ return state;
+ }
+ catch (GeneralException e) {
+ std::cerr << _("Task ") << GetName() << _(" caused an unexpected exception: \"") << e.GetMsg() << _("\". Terminating.\n");
+ state = TASK_DONE;
+ return TASK_DONE;
+ }
+
+ return state;
+}
+
+int Task::DryRun() {
+ while (state != TASK_DONE) {
+ try {
+ state = Do();
+ }
+ catch (TaskSwitch) {
+ }
+ catch (GeneralException e) {
+ std::cerr << _("Task ") << GetName() << _(" caused an unexpected exception during dry-run: \"") << e.GetMsg() << _("\". Terminating.\n");
+ state = TASK_DONE;
+ }
+ }
+
+ return state;
+}
+
+int Task::GetState() {
+ return state;
+}
+
+String Task::GetName() {
+ return _("Unknow Task");
+}
+
+void Task::Suspend(int newstate) throw (GeneralException) {
+ if (newstate != -1) {
+ state = newstate;
+ }
+ suspended = true;
+ throw TaskSwitch();
+}
+
+void Task::WaitFor(Handle * h, int flags) {
+ h->SetNonBlock();
+ TaskMan::WaitFor(h, this, flags);
+}
+
+void Task::WaitFor(Task * t) {
+ t->wbta = this;
+}
+
+void Task::WaitFor(pid_t p) {
+ TaskMan::WaitFor(p, this);
+}
+
+void Task::WaitFor(timeval t, int flags) {
+ TaskMan::WaitFor(t, this, flags);
+}
+
+void Task::SetBurst() {
+ state = TASK_BURST;
+}
+
+void Task::Stop() {
+ stopped = true;
+}
+
+void Task::Restart() {
+ stopped = false;
+}
+
+bool Task::IsStopped() {
+ return stopped;
+}
+
+Task * Task::WaitedBy() {
+ return wbta;
+}
+
+void Task::RemoveFromWatches() {
+ wbta = 0;
+}
diff --git a/lib/TaskMan.cc b/lib/TaskMan.cc
index 89d65be..1dcf331 100644
--- a/lib/TaskMan.cc
+++ b/lib/TaskMan.cc
@@ -1,456 +1,456 @@
-#include <signal.h>
-#include <sys/wait.h>
-#include <sys/poll.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <vector>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "TaskMan.h"
-#include "gettext.h"
-
-#define USE_POLL 1
-
-TaskMan::TaskList_t TaskMan::TaskList;
-TaskMan::TaskList_t TaskMan::Zombies;
-std::vector<TaskMan::w4ha_t> TaskMan::w4ha;
-std::vector<TaskMan::w4pr_t> TaskMan::w4pr;
-std::vector<TaskMan::w4to_t> TaskMan::w4to;
-bool TaskMan::stopped = false;
-
-int TaskMan::number = 0;
-bool TaskMan::inited = false;
-
-int TaskMan::event, TaskMan::eprocess, TaskMan::estatus;
-Task * TaskMan::etask;
-Handle * TaskMan::ehandle;
-
-sigset_t TaskMan::sigchildset;
-
-static int got_sigchild = 0;
-
-void taskman_sigchild(int sig) {
- int status;
- pid_t pid;
-
- pid = wait(&status);
- if (TaskMan::GotChild(pid, status)) {
- got_sigchild++;
- } else {
- TaskMan::WaitFor(pid, 0, status);
- }
-
-// cerr << "Got SIGCHILD, pid = " << pid << " and status = " << status << endl;
- signal(SIGCHLD, taskman_sigchild);
-}
-
-void taskman_sighole(int sig) {
- signal(sig, taskman_sighole);
-}
-
-int TaskMan::GotChild(pid_t pid, int status) {
- int r = 0;
- unsigned int i;
-
- for (i = 0; i < w4pr.size(); i++) {
- if (w4pr[i].pr == pid) {
- w4pr[i].flag = true;
- w4pr[i].status = status;
- r = 1;
- }
- }
-
- return r;
-}
-
-void TaskMan::Init() throw (GeneralException) {
- if (inited) {
- throw GeneralException(_("Task Manager already initialised."));
- }
-
- signal(SIGCHLD, taskman_sigchild);
- signal(SIGPIPE, taskman_sighole);
- signal(SIGHUP, taskman_sighole);
-
- sigemptyset(&sigchildset);
- sigaddset(&sigchildset, SIGCHLD);
- sigprocmask(SIG_BLOCK, &sigchildset, 0);
-
- inited = true;
- number = 0;
-}
-
-void TaskMan::Stop() {
- stopped = true;
-}
-
-int TaskMan::Event() {
- return event;
-}
-
-Task * TaskMan::Etask() {
- return etask;
-}
-
-Handle * TaskMan::Ehandle() {
- return ehandle;
-}
-
-int TaskMan::Eprocess() {
- return eprocess;
-}
-
-int TaskMan::Estatus() {
- return estatus;
-}
-
-void TaskMan::AddTask(Task * t) {
- if (!inited) {
- Init();
- }
-
- if (t) {
- TaskList.push_back(t);
- number++;
- }
-}
-
-std::vector<Task *>::iterator TaskMan::FindTask(Task * t) throw (GeneralException) {
- if (!inited) {
- Init();
- }
-
- if (TaskList.empty())
- throw TaskNotFound();
-
- for (std::vector<Task *>::iterator p = TaskList.begin(); p != TaskList.end(); p++) {
- if (*p == t) {
- return p;
- }
- }
-
- throw TaskNotFound();
-}
-
-void TaskMan::RemoveFromWatches(Task * t) {
- if (!w4ha.empty()) {
- for (std::vector<w4ha_t>::iterator p = w4ha.begin(); p != w4ha.end(); p++) {
- if (p->T == t) {
- w4ha.erase(p);
- p--;
- }
- }
- }
-
- if (!w4pr.empty()) {
- for (std::vector<w4pr_t>::iterator p = w4pr.begin(); p != w4pr.end(); p++) {
- if (p->T == t) {
- w4pr.erase(p);
- p--;
- }
- }
- }
-
- if (!w4to.empty()) {
- for (std::vector<w4to_t>::iterator p = w4to.begin(); p != w4to.end(); p++) {
- if (p->T == t) {
- w4to.erase(p);
- p--;
- }
- }
- }
-
- if (!TaskList.empty()) {
- for (TaskList_t::iterator p = TaskList.begin(); p != TaskList.end(); p++) {
- if ((*p)->WaitedBy() == t) {
- Zombies.push_back(*p);
- (*p)->RemoveFromWatches();
- TaskList.erase(p);
- number--;
- p--;
- } else if ((*p) == t) {
- TaskList.erase(p);
- number--;
- p--;
- }
- }
- }
-}
-
-void TaskMan::WaitFor(Handle * h, Task * t, int flags) {
- h->SetNonBlock();
- w4ha.push_back(w4ha_t(h, flags, t));
-}
-
-void TaskMan::WaitFor(pid_t pid, Task * t, int status) {
- if (status == -1) {
- if (!w4pr.empty()) {
- for (std::vector<w4pr_t>::iterator p = w4pr.begin(); p != w4pr.end(); p++) {
- if (p->pr == pid) {
- p->T = t;
- p->flag = true;
- got_sigchild++;
- return;
- }
- }
- }
- }
- w4pr.push_back(w4pr_t(pid, t));
- w4pr[w4pr.size() - 1].status = status;
-}
-
-void TaskMan::WaitFor(timeval t, Task * T, int flags) {
- w4to.push_back(w4to_t(t, flags, T));
-}
-
-void TaskMan::MainLoop() throw (GeneralException) {
- struct pollfd * ufsd;
- unsigned int nfds;
-
- int no_burst;
-
- if (!inited) {
- Init();
- }
-
- while (1) {
- if (number == 0) {
- throw GeneralException(_("TaskMan: No more task to manage."));
- }
-
- if (stopped) return;
-
-// cerr << "-=- TaskMan: begin main loop with " << number << " task to manage.\n";
- if (!TaskList.empty()) {
- for (TaskList_t::iterator p = TaskList.begin(); p != TaskList.end(); p++) {
- Task * t = *p;
-// cerr << "-=- TaskMan: task " << t->GetName() << endl;
- }
- }
-
-// cerr << "-=- TaskMan: processing burning tasks.\n";
-
- no_burst = 0;
- while (!no_burst) {
- no_burst = 1;
- /* First, we will check for any burning task and run 'em */
- event = E_BURST;
- if (!TaskList.empty()) {
- for (TaskList_t::iterator p = TaskList.begin(); p != TaskList.end(); p++) {
- Task * t = *p;
-
- if (t->IsStopped()) {
- continue;
- }
-
- if (t->GetState() == TASK_BURST) {
-// cerr << "-=- TaskMan: running burning task " << t->GetName() << endl;
- t->Run();
- /* if the task added some new tasks, we have to rerun the loop */
- no_burst = 0;
- break;
- }
-
- if (t->GetState() == TASK_DONE) {
- TaskList.erase(p);
- number--;
- p--;
- Zombies.push_back(t);
- }
- }
- }
- }
-
- /* Let's compute the nearest timeout, and eventually, launch the outdated timeouts. */
- int timeout = -1;
- event = E_TIMEOUT;
-
- if (!w4to.empty()) {
- time_t curtime = time(NULL);
- for (std::vector<w4to_t>::iterator p = w4to.begin(); p != w4to.end(); p++) {
- int cur_to;
- cur_to = (p->to.tv_sec - curtime) * 1000 + p->to.tv_usec;
- if (cur_to < 0) {
-
- }
- }
- }
-
- /* Now is time to check all the handle and enter into a wait state. */
-
- event = E_HANDLE;
-// cerr << "-=- TaskMan: processing handle-waiting tasks.\n";
-
- nfds = w4ha.size();
- no_burst = 1;
-
- if (nfds != 0) {
- int r;
- std::vector<w4ha_t>::iterator p;
- struct pollfd * q;
-
- ufsd = (struct pollfd *) malloc(nfds * sizeof(struct pollfd));
- if (!w4ha.empty()) {
- for (q = ufsd, p = w4ha.begin(); p != w4ha.end(); p++, q++) {
- p->dirthy = false;
- if (p->T->IsStopped()) {
- q->fd = 0;
- q->events = 0;
- } else {
- if (p->ha->CanWatch()) {
- q->fd = p->ha->GetHandle();
- q->events = (p->flags & W4_READING ? POLLIN : 0) | (p->flags & W4_WRITING ? POLLOUT : 0);
- } else {
- p->T->SetBurst();
- no_burst = 0;
- p->dirthy = true;
- if (!(p->flags & W4_STICKY)) {
- w4ha.erase(p);
- p--;
- }
- q->fd = 0;
- q->events = 0;
- }
- }
- }
- }
-
- sigprocmask(SIG_UNBLOCK, &sigchildset, 0);
- r = poll(ufsd, nfds, (no_burst) && !(Zombies.size()) && !(got_sigchild) ? -1: 0);
- sigprocmask(SIG_BLOCK, &sigchildset, 0);
-
- if (r < 0) {
- if (errno != EINTR) {
- throw GeneralException(String(_("Error during poll: ")) + strerror(errno));
- }
- } else if (r == 0) {
- // timeout.
- // **FIXME**
-#warning FIXME
- } else {
- int fd;
- struct pollfd * q;
- unsigned int i;
- for (q = ufsd, i = 0; i < nfds; i++, q++) {
- if (q->revents & POLLNVAL) {
- throw GeneralException(String(_("Error with poll, handle ")) + q->fd + _(" invalid."));
- }
-
-// if (q->revents & POLLERR) {
-// cerr << _("Error condition with poll, handle ") << q->fd << endl;
-// }
-
-// if (q->revents & POLLHUP) {
-// cerr << _("Handle ") << q->fd << _(" hung up.\n");
-// }
-
- fd = q->fd;
- if (q->revents & (POLLIN | POLLOUT | POLLERR | POLLHUP)) {
- // We have to look into the handle structure now...
- bool touched;
- if (!w4ha.empty()) {
- for (std::vector<w4ha_t>::iterator p = w4ha.begin(); p != w4ha.end(); p = touched ? w4ha.begin() : p + 1) {
- touched = false;
- if ((p->ha->GetHandle() == fd) && (!p->T->IsStopped()) && (p->T->GetState() != TASK_DONE) && (!p->dirthy)) {
- // We've got one, launch it.
-// cerr << "-=- TaskMan: launching task " << p->T->GetName() << " for handle " << p->ha->GetHandle() << endl;
- w4ha_t w4 = *p;
- p->dirthy = true;
-
- if (!(p->flags & W4_STICKY)) {
- w4ha.erase(p);
- }
-
- touched = true;
-
- ehandle = p->ha;
- w4.T->Run();
-
- if (w4.T->GetState() == TASK_DONE) {
- // This task died, remove it.
- try {
- std::vector<Task *>::iterator q = FindTask(w4.T);
- TaskList.erase(q);
- number--;
- Zombies.push_back(w4.T);
- }
- catch (TaskNotFound) {
- }
- }
- }
- }
- }
- }
- }
- }
- free(ufsd);
- }
-
- /* And finally, let's clean-up all the zombies around here. */
-
- int no_zombies;
- no_zombies = 0;
-
- event = E_TASK;
-// cerr << "-=- TaskMan: processing zombies loop.\n";
-
- while (!no_zombies) {
- no_zombies = 1;
- while (Zombies.size()) {
- Task * t = Zombies[0], * o;
-
- if (!t) {
-// cerr << "!?!?!? We have t = NULL ?!?!?! WTF\n";
- break;
- }
-
- if ((o = t->WaitedBy())) {
-// cerr << "-=- TaskMan: running task " << o->GetName() << " for task " << t->GetName() << endl;
- etask = t;
- o->Run();
-
- if (o->GetState() == TASK_DONE) {
- TaskList_t::iterator f = FindTask(o);
- TaskList.erase(f);
- number--;
- Zombies.push_back(o);
- no_zombies = 0;
- }
- } else {
- delete t;
- }
- Zombies.erase(Zombies.begin());
- }
- }
-
- /* To end up the loop, let's recall task waiting for processes */
-
- event = E_PROCESS;
-// cerr << "-=- TaskMan: processing child-waiting tasks.\n";
-
- if (got_sigchild) {
- if (!w4pr.empty()) {
- for (std::vector<w4pr_t>::iterator p = w4pr.begin(); p != w4pr.end(); p++) {
- if (p->flag) {
- Task * t;
- if (p->T->IsStopped()) {
- continue;
- }
- eprocess = p->pr;
- estatus = p->status;
-// cerr << "-=- TaskMan: running task " << p->T->GetName() << " for process " << p->pr << " (" << p->status << ")\n";
- t = p->T;
- w4pr.erase(p);
- got_sigchild--;
- t->Run();
- break;
- }
- }
- }
- }
- }
-}
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/poll.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <vector>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "TaskMan.h"
+#include "gettext.h"
+
+#define USE_POLL 1
+
+TaskMan::TaskList_t TaskMan::TaskList;
+TaskMan::TaskList_t TaskMan::Zombies;
+std::vector<TaskMan::w4ha_t> TaskMan::w4ha;
+std::vector<TaskMan::w4pr_t> TaskMan::w4pr;
+std::vector<TaskMan::w4to_t> TaskMan::w4to;
+bool TaskMan::stopped = false;
+
+int TaskMan::number = 0;
+bool TaskMan::inited = false;
+
+int TaskMan::event, TaskMan::eprocess, TaskMan::estatus;
+Task * TaskMan::etask;
+Handle * TaskMan::ehandle;
+
+sigset_t TaskMan::sigchildset;
+
+static int got_sigchild = 0;
+
+void taskman_sigchild(int sig) {
+ int status;
+ pid_t pid;
+
+ pid = wait(&status);
+ if (TaskMan::GotChild(pid, status)) {
+ got_sigchild++;
+ } else {
+ TaskMan::WaitFor(pid, 0, status);
+ }
+
+// cerr << "Got SIGCHILD, pid = " << pid << " and status = " << status << endl;
+ signal(SIGCHLD, taskman_sigchild);
+}
+
+void taskman_sighole(int sig) {
+ signal(sig, taskman_sighole);
+}
+
+int TaskMan::GotChild(pid_t pid, int status) {
+ int r = 0;
+ unsigned int i;
+
+ for (i = 0; i < w4pr.size(); i++) {
+ if (w4pr[i].pr == pid) {
+ w4pr[i].flag = true;
+ w4pr[i].status = status;
+ r = 1;
+ }
+ }
+
+ return r;
+}
+
+void TaskMan::Init() throw (GeneralException) {
+ if (inited) {
+ throw GeneralException(_("Task Manager already initialised."));
+ }
+
+ signal(SIGCHLD, taskman_sigchild);
+ signal(SIGPIPE, taskman_sighole);
+ signal(SIGHUP, taskman_sighole);
+
+ sigemptyset(&sigchildset);
+ sigaddset(&sigchildset, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &sigchildset, 0);
+
+ inited = true;
+ number = 0;
+}
+
+void TaskMan::Stop() {
+ stopped = true;
+}
+
+int TaskMan::Event() {
+ return event;
+}
+
+Task * TaskMan::Etask() {
+ return etask;
+}
+
+Handle * TaskMan::Ehandle() {
+ return ehandle;
+}
+
+int TaskMan::Eprocess() {
+ return eprocess;
+}
+
+int TaskMan::Estatus() {
+ return estatus;
+}
+
+void TaskMan::AddTask(Task * t) {
+ if (!inited) {
+ Init();
+ }
+
+ if (t) {
+ TaskList.push_back(t);
+ number++;
+ }
+}
+
+std::vector<Task *>::iterator TaskMan::FindTask(Task * t) throw (GeneralException) {
+ if (!inited) {
+ Init();
+ }
+
+ if (TaskList.empty())
+ throw TaskNotFound();
+
+ for (std::vector<Task *>::iterator p = TaskList.begin(); p != TaskList.end(); p++) {
+ if (*p == t) {
+ return p;
+ }
+ }
+
+ throw TaskNotFound();
+}
+
+void TaskMan::RemoveFromWatches(Task * t) {
+ if (!w4ha.empty()) {
+ for (std::vector<w4ha_t>::iterator p = w4ha.begin(); p != w4ha.end(); p++) {
+ if (p->T == t) {
+ w4ha.erase(p);
+ p--;
+ }
+ }
+ }
+
+ if (!w4pr.empty()) {
+ for (std::vector<w4pr_t>::iterator p = w4pr.begin(); p != w4pr.end(); p++) {
+ if (p->T == t) {
+ w4pr.erase(p);
+ p--;
+ }
+ }
+ }
+
+ if (!w4to.empty()) {
+ for (std::vector<w4to_t>::iterator p = w4to.begin(); p != w4to.end(); p++) {
+ if (p->T == t) {
+ w4to.erase(p);
+ p--;
+ }
+ }
+ }
+
+ if (!TaskList.empty()) {
+ for (TaskList_t::iterator p = TaskList.begin(); p != TaskList.end(); p++) {
+ if ((*p)->WaitedBy() == t) {
+ Zombies.push_back(*p);
+ (*p)->RemoveFromWatches();
+ TaskList.erase(p);
+ number--;
+ p--;
+ } else if ((*p) == t) {
+ TaskList.erase(p);
+ number--;
+ p--;
+ }
+ }
+ }
+}
+
+void TaskMan::WaitFor(Handle * h, Task * t, int flags) {
+ h->SetNonBlock();
+ w4ha.push_back(w4ha_t(h, flags, t));
+}
+
+void TaskMan::WaitFor(pid_t pid, Task * t, int status) {
+ if (status == -1) {
+ if (!w4pr.empty()) {
+ for (std::vector<w4pr_t>::iterator p = w4pr.begin(); p != w4pr.end(); p++) {
+ if (p->pr == pid) {
+ p->T = t;
+ p->flag = true;
+ got_sigchild++;
+ return;
+ }
+ }
+ }
+ }
+ w4pr.push_back(w4pr_t(pid, t));
+ w4pr[w4pr.size() - 1].status = status;
+}
+
+void TaskMan::WaitFor(timeval t, Task * T, int flags) {
+ w4to.push_back(w4to_t(t, flags, T));
+}
+
+void TaskMan::MainLoop() throw (GeneralException) {
+ struct pollfd * ufsd;
+ unsigned int nfds;
+
+ int no_burst;
+
+ if (!inited) {
+ Init();
+ }
+
+ while (1) {
+ if (number == 0) {
+ throw GeneralException(_("TaskMan: No more task to manage."));
+ }
+
+ if (stopped) return;
+
+// cerr << "-=- TaskMan: begin main loop with " << number << " task to manage.\n";
+ if (!TaskList.empty()) {
+ for (TaskList_t::iterator p = TaskList.begin(); p != TaskList.end(); p++) {
+ Task * t = *p;
+// cerr << "-=- TaskMan: task " << t->GetName() << endl;
+ }
+ }
+
+// cerr << "-=- TaskMan: processing burning tasks.\n";
+
+ no_burst = 0;
+ while (!no_burst) {
+ no_burst = 1;
+ /* First, we will check for any burning task and run 'em */
+ event = E_BURST;
+ if (!TaskList.empty()) {
+ for (TaskList_t::iterator p = TaskList.begin(); p != TaskList.end(); p++) {
+ Task * t = *p;
+
+ if (t->IsStopped()) {
+ continue;
+ }
+
+ if (t->GetState() == TASK_BURST) {
+// cerr << "-=- TaskMan: running burning task " << t->GetName() << endl;
+ t->Run();
+ /* if the task added some new tasks, we have to rerun the loop */
+ no_burst = 0;
+ break;
+ }
+
+ if (t->GetState() == TASK_DONE) {
+ TaskList.erase(p);
+ number--;
+ p--;
+ Zombies.push_back(t);
+ }
+ }
+ }
+ }
+
+ /* Let's compute the nearest timeout, and eventually, launch the outdated timeouts. */
+ int timeout = -1;
+ event = E_TIMEOUT;
+
+ if (!w4to.empty()) {
+ time_t curtime = time(NULL);
+ for (std::vector<w4to_t>::iterator p = w4to.begin(); p != w4to.end(); p++) {
+ int cur_to;
+ cur_to = (p->to.tv_sec - curtime) * 1000 + p->to.tv_usec;
+ if (cur_to < 0) {
+
+ }
+ }
+ }
+
+ /* Now is time to check all the handle and enter into a wait state. */
+
+ event = E_HANDLE;
+// cerr << "-=- TaskMan: processing handle-waiting tasks.\n";
+
+ nfds = w4ha.size();
+ no_burst = 1;
+
+ if (nfds != 0) {
+ int r;
+ std::vector<w4ha_t>::iterator p;
+ struct pollfd * q;
+
+ ufsd = (struct pollfd *) malloc(nfds * sizeof(struct pollfd));
+ if (!w4ha.empty()) {
+ for (q = ufsd, p = w4ha.begin(); p != w4ha.end(); p++, q++) {
+ p->dirthy = false;
+ if (p->T->IsStopped()) {
+ q->fd = 0;
+ q->events = 0;
+ } else {
+ if (p->ha->CanWatch()) {
+ q->fd = p->ha->GetHandle();
+ q->events = (p->flags & W4_READING ? POLLIN : 0) | (p->flags & W4_WRITING ? POLLOUT : 0);
+ } else {
+ p->T->SetBurst();
+ no_burst = 0;
+ p->dirthy = true;
+ if (!(p->flags & W4_STICKY)) {
+ w4ha.erase(p);
+ p--;
+ }
+ q->fd = 0;
+ q->events = 0;
+ }
+ }
+ }
+ }
+
+ sigprocmask(SIG_UNBLOCK, &sigchildset, 0);
+ r = poll(ufsd, nfds, (no_burst) && !(Zombies.size()) && !(got_sigchild) ? -1: 0);
+ sigprocmask(SIG_BLOCK, &sigchildset, 0);
+
+ if (r < 0) {
+ if (errno != EINTR) {
+ throw GeneralException(String(_("Error during poll: ")) + strerror(errno));
+ }
+ } else if (r == 0) {
+ // timeout.
+ // **FIXME**
+#warning FIXME
+ } else {
+ int fd;
+ struct pollfd * q;
+ unsigned int i;
+ for (q = ufsd, i = 0; i < nfds; i++, q++) {
+ if (q->revents & POLLNVAL) {
+ throw GeneralException(String(_("Error with poll, handle ")) + q->fd + _(" invalid."));
+ }
+
+// if (q->revents & POLLERR) {
+// cerr << _("Error condition with poll, handle ") << q->fd << endl;
+// }
+
+// if (q->revents & POLLHUP) {
+// cerr << _("Handle ") << q->fd << _(" hung up.\n");
+// }
+
+ fd = q->fd;
+ if (q->revents & (POLLIN | POLLOUT | POLLERR | POLLHUP)) {
+ // We have to look into the handle structure now...
+ bool touched;
+ if (!w4ha.empty()) {
+ for (std::vector<w4ha_t>::iterator p = w4ha.begin(); p != w4ha.end(); p = touched ? w4ha.begin() : p + 1) {
+ touched = false;
+ if ((p->ha->GetHandle() == fd) && (!p->T->IsStopped()) && (p->T->GetState() != TASK_DONE) && (!p->dirthy)) {
+ // We've got one, launch it.
+// cerr << "-=- TaskMan: launching task " << p->T->GetName() << " for handle " << p->ha->GetHandle() << endl;
+ w4ha_t w4 = *p;
+ p->dirthy = true;
+
+ if (!(p->flags & W4_STICKY)) {
+ w4ha.erase(p);
+ }
+
+ touched = true;
+
+ ehandle = p->ha;
+ w4.T->Run();
+
+ if (w4.T->GetState() == TASK_DONE) {
+ // This task died, remove it.
+ try {
+ std::vector<Task *>::iterator q = FindTask(w4.T);
+ TaskList.erase(q);
+ number--;
+ Zombies.push_back(w4.T);
+ }
+ catch (TaskNotFound) {
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ free(ufsd);
+ }
+
+ /* And finally, let's clean-up all the zombies around here. */
+
+ int no_zombies;
+ no_zombies = 0;
+
+ event = E_TASK;
+// cerr << "-=- TaskMan: processing zombies loop.\n";
+
+ while (!no_zombies) {
+ no_zombies = 1;
+ while (Zombies.size()) {
+ Task * t = Zombies[0], * o;
+
+ if (!t) {
+// cerr << "!?!?!? We have t = NULL ?!?!?! WTF\n";
+ break;
+ }
+
+ if ((o = t->WaitedBy())) {
+// cerr << "-=- TaskMan: running task " << o->GetName() << " for task " << t->GetName() << endl;
+ etask = t;
+ o->Run();
+
+ if (o->GetState() == TASK_DONE) {
+ TaskList_t::iterator f = FindTask(o);
+ TaskList.erase(f);
+ number--;
+ Zombies.push_back(o);
+ no_zombies = 0;
+ }
+ } else {
+ delete t;
+ }
+ Zombies.erase(Zombies.begin());
+ }
+ }
+
+ /* To end up the loop, let's recall task waiting for processes */
+
+ event = E_PROCESS;
+// cerr << "-=- TaskMan: processing child-waiting tasks.\n";
+
+ if (got_sigchild) {
+ if (!w4pr.empty()) {
+ for (std::vector<w4pr_t>::iterator p = w4pr.begin(); p != w4pr.end(); p++) {
+ if (p->flag) {
+ Task * t;
+ if (p->T->IsStopped()) {
+ continue;
+ }
+ eprocess = p->pr;
+ estatus = p->status;
+// cerr << "-=- TaskMan: running task " << p->T->GetName() << " for process " << p->pr << " (" << p->status << ")\n";
+ t = p->T;
+ w4pr.erase(p);
+ got_sigchild--;
+ t->Run();
+ break;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/Variables.cc b/lib/Variables.cc
index b4f93c8..94c4c27 100644
--- a/lib/Variables.cc
+++ b/lib/Variables.cc
@@ -1,85 +1,85 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "Variables.h"
-#include "HttpServ.h"
-#include "BString.h"
-
-Variables::Variables(int nb) : Vars(nb), nbvars(nb) { }
-
-Variables::Variables(const Variables & v) : nbvars(v.nbvars) {
- for (int i = 0; i < nbvars; i++) {
- Vars.push_back(v.Vars[i]);
- }
-}
-
-Variables::~Variables() { }
-
-void Variables::SetTo(int i, const String & s) {
- Vars[i] = s;
-}
-
-String Variables::operator[](const String & name) {
- int i;
- String r;
-
- for (i = 0; i < nbvars; i++) {
- if (Vars[i].strstr(name) == 0) break;
- }
-
- if (i == nbvars) {
- r = "";
- } else {
- r = Vars[i].extract(Vars[i].strchr('=') + 1);
- }
-
- return r;
-}
-
-String Variables::operator[](int i) {
- return Vars[i];
-}
-
-int Variables::GetNb(void) {
- return nbvars;
-}
-
-void Variables::Dump(Handle * h, const String & format) {
- int i, eqp;
- String Vn, Vv;
-
- for (i = 0; i < nbvars; i++) {
- eqp = Vars[i].strchr('=');
- Vn = Vars[i].extract(0, eqp - 1);
- Vv = Vars[i].extract(eqp + 1);
- if (format == "") {
- (*h) << "<INPUT TYPE=\"HIDDEN\" NAME=\"" << Vn << "\" VALUE=\"" << Vv << "\">" << endnl;
- } else {
- // Use format here...
- // **FIXME**
-#warning FIXME
- }
- }
-}
-
-void Variables::Add(const String & s) {
- nbvars++;
- Vars.push_back(s);
-}
-
-void Variables::Del(int i) {
- nbvars--;
- Vars.erase(Vars.begin() + i, Vars.begin() + i);
-}
-
-void Variables::Del(const String & name) {
- int i;
-
- for (i = 0; i < nbvars; i++) {
- if (Vars[i].strstr(name) == 0) break;
- }
-
- if (i != nbvars) {
- Del(i);
- }
-}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "Variables.h"
+#include "HttpServ.h"
+#include "BString.h"
+
+Variables::Variables(int nb) : Vars(nb), nbvars(nb) { }
+
+Variables::Variables(const Variables & v) : nbvars(v.nbvars) {
+ for (int i = 0; i < nbvars; i++) {
+ Vars.push_back(v.Vars[i]);
+ }
+}
+
+Variables::~Variables() { }
+
+void Variables::SetTo(int i, const String & s) {
+ Vars[i] = s;
+}
+
+String Variables::operator[](const String & name) {
+ int i;
+ String r;
+
+ for (i = 0; i < nbvars; i++) {
+ if (Vars[i].strstr(name) == 0) break;
+ }
+
+ if (i == nbvars) {
+ r = "";
+ } else {
+ r = Vars[i].extract(Vars[i].strchr('=') + 1);
+ }
+
+ return r;
+}
+
+String Variables::operator[](int i) {
+ return Vars[i];
+}
+
+int Variables::GetNb(void) {
+ return nbvars;
+}
+
+void Variables::Dump(Handle * h, const String & format) {
+ int i, eqp;
+ String Vn, Vv;
+
+ for (i = 0; i < nbvars; i++) {
+ eqp = Vars[i].strchr('=');
+ Vn = Vars[i].extract(0, eqp - 1);
+ Vv = Vars[i].extract(eqp + 1);
+ if (format == "") {
+ (*h) << "<INPUT TYPE=\"HIDDEN\" NAME=\"" << Vn << "\" VALUE=\"" << Vv << "\">" << endnl;
+ } else {
+ // Use format here...
+ // **FIXME**
+#warning FIXME
+ }
+ }
+}
+
+void Variables::Add(const String & s) {
+ nbvars++;
+ Vars.push_back(s);
+}
+
+void Variables::Del(int i) {
+ nbvars--;
+ Vars.erase(Vars.begin() + i, Vars.begin() + i);
+}
+
+void Variables::Del(const String & name) {
+ int i;
+
+ for (i = 0; i < nbvars; i++) {
+ if (Vars[i].strstr(name) == 0) break;
+ }
+
+ if (i != nbvars) {
+ Del(i);
+ }
+}
diff --git a/lib/checkargs.c b/lib/checkargs.c
index fcd84ed..4fee446 100644
--- a/lib/checkargs.c
+++ b/lib/checkargs.c
@@ -1,85 +1,85 @@
-/* datedif - calculates the difference in days between two dates
- * Copyright (C) 2000 Micael Widell contact: xeniac@linux.nu
- *
- * 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.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-int isDateArgument(char* dateString) {
-
- const int MONTHS[] = {31,0,31,30,31,30,31,31,30,31,30,31};
- int i, day, month, year;
- char buffer[5];
-
- /* 'today' is a valid date */
- if (strcmp(dateString, "today") == 0)
- return 1;
-
- /* Numeric dates must be eight characters long */
- if (8 != strlen(dateString))
- return 0;
-
- /* Check that the date is entirely formed of numbers */
- for (i = 0; i < 8; i++) {
- if (dateString[i] < '0' || dateString[i] > '9')
- return 0;
- }
-
- /* Check that the date exists */
- memset(buffer, 0, 5);
- strncpy(buffer, dateString + 6, 2);
- day = atoi(buffer);
- strncpy(buffer, dateString + 4, 2);
- month = atoi(buffer);
- month -= 1;
- strncpy(buffer, dateString, 4);
- year = atoi(buffer);
-
- /* Validate month */
- if (month < 0 || month > 11)
- return 0;
-
- /* Validating dates is simple when the date does not fall into February */
- if (1 != month) {
- if (day < 1 || day > MONTHS[month])
- return 0;
- } else {
- int feb = 28;
-
- /* Februarys are a bit tougher issue */
- if (0 == year % 4) {
- if (0 == year % 100) {
- if (0 == year % 400) {
- feb = 29;
- } else {
- feb = 28;
- }
- } else {
- feb = 29;
- }
- }
- if (day < 1 || day > feb)
- return 0;
- }
-
- /* Avoid user from using dates before 16000301, since those will result in
- incorrect output */
- if(16000301 > atoi(dateString))
- return 0;
-
- return 1;
-}
+/* datedif - calculates the difference in days between two dates
+ * Copyright (C) 2000 Micael Widell contact: xeniac@linux.nu
+ *
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+int isDateArgument(char* dateString) {
+
+ const int MONTHS[] = {31,0,31,30,31,30,31,31,30,31,30,31};
+ int i, day, month, year;
+ char buffer[5];
+
+ /* 'today' is a valid date */
+ if (strcmp(dateString, "today") == 0)
+ return 1;
+
+ /* Numeric dates must be eight characters long */
+ if (8 != strlen(dateString))
+ return 0;
+
+ /* Check that the date is entirely formed of numbers */
+ for (i = 0; i < 8; i++) {
+ if (dateString[i] < '0' || dateString[i] > '9')
+ return 0;
+ }
+
+ /* Check that the date exists */
+ memset(buffer, 0, 5);
+ strncpy(buffer, dateString + 6, 2);
+ day = atoi(buffer);
+ strncpy(buffer, dateString + 4, 2);
+ month = atoi(buffer);
+ month -= 1;
+ strncpy(buffer, dateString, 4);
+ year = atoi(buffer);
+
+ /* Validate month */
+ if (month < 0 || month > 11)
+ return 0;
+
+ /* Validating dates is simple when the date does not fall into February */
+ if (1 != month) {
+ if (day < 1 || day > MONTHS[month])
+ return 0;
+ } else {
+ int feb = 28;
+
+ /* Februarys are a bit tougher issue */
+ if (0 == year % 4) {
+ if (0 == year % 100) {
+ if (0 == year % 400) {
+ feb = 29;
+ } else {
+ feb = 28;
+ }
+ } else {
+ feb = 29;
+ }
+ }
+ if (day < 1 || day > feb)
+ return 0;
+ }
+
+ /* Avoid user from using dates before 16000301, since those will result in
+ incorrect output */
+ if(16000301 > atoi(dateString))
+ return 0;
+
+ return 1;
+}
diff --git a/lib/datecalc.c b/lib/datecalc.c
index 8cf2539..ad6684a 100644
--- a/lib/datecalc.c
+++ b/lib/datecalc.c
@@ -1,78 +1,78 @@
-/* datedif - calculates the difference in days between two dates
- * Copyright (C) 2000 Micael Widell contact: xeniac@linux.nu
- *
- * 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.
- */
-
-#include <time.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-/* Gaus's formula - days since 1.3.1600 (Gregorian calendar) */
-int days(register int n, register int m, register int y)
-{
- register int cy;
- if((m -= 2) <= 0){
- m += 12; y--;
- }
- y -= 1600; cy = y/100;
- return 365*y+y/4-cy+cy/4+367*m/12+n-31;
-}
-
-
-double dateCalc(char date1[], char date2[]){
-
- /* Declare the needed variables */
- char* date[2] = { date1, date2 };
- struct tm *date_tm[2];
- time_t date_time_t[2];
- double dateDifference;
- int isToday[2] = { 0, 0 };
- char buffer[5];
- int day[2], month[2], year[2], i;
-
-
- /* If any of the arguments are "today", then include today's date in the
- right variables */
- for(i = 0; i < 2; i++){
- if(!strcmp(date[i], "today")){
- time(&date_time_t[i]);
- date_tm[i] = localtime(&date_time_t[i]);
- day[i] = (*date_tm[i]).tm_mday;
- month[i] = (*date_tm[i]).tm_mon + 1;
- year[i] = (*date_tm[i]).tm_year + 1900;
- isToday[i] = 1;
- }
- }
-
- /* Cut out the year, month and day from 8-digit datestrings */
- for (i = 0; i < 2; i++){
- if(!isToday[i]){
- memset(buffer, 0, 5);
- strncpy(buffer, &date[i][6], 2);
- day[i] = atoi(buffer);
- strncpy(buffer, &date[i][4], 2);
- month[i] = atoi(buffer);
- strncpy(buffer, date[i], 4);
- year[i] = atoi(buffer);
- }
- }
-
- /* Calculate the difference */
- dateDifference = days(day[1], month[1], year[1]) - days(day[0], month[0], year[0]);
-
- return dateDifference;
-}
+/* datedif - calculates the difference in days between two dates
+ * Copyright (C) 2000 Micael Widell contact: xeniac@linux.nu
+ *
+ * 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.
+ */
+
+#include <time.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* Gaus's formula - days since 1.3.1600 (Gregorian calendar) */
+int days(register int n, register int m, register int y)
+{
+ register int cy;
+ if((m -= 2) <= 0){
+ m += 12; y--;
+ }
+ y -= 1600; cy = y/100;
+ return 365*y+y/4-cy+cy/4+367*m/12+n-31;
+}
+
+
+double dateCalc(char date1[], char date2[]){
+
+ /* Declare the needed variables */
+ char* date[2] = { date1, date2 };
+ struct tm *date_tm[2];
+ time_t date_time_t[2];
+ double dateDifference;
+ int isToday[2] = { 0, 0 };
+ char buffer[5];
+ int day[2], month[2], year[2], i;
+
+
+ /* If any of the arguments are "today", then include today's date in the
+ right variables */
+ for(i = 0; i < 2; i++){
+ if(!strcmp(date[i], "today")){
+ time(&date_time_t[i]);
+ date_tm[i] = localtime(&date_time_t[i]);
+ day[i] = (*date_tm[i]).tm_mday;
+ month[i] = (*date_tm[i]).tm_mon + 1;
+ year[i] = (*date_tm[i]).tm_year + 1900;
+ isToday[i] = 1;
+ }
+ }
+
+ /* Cut out the year, month and day from 8-digit datestrings */
+ for (i = 0; i < 2; i++){
+ if(!isToday[i]){
+ memset(buffer, 0, 5);
+ strncpy(buffer, &date[i][6], 2);
+ day[i] = atoi(buffer);
+ strncpy(buffer, &date[i][4], 2);
+ month[i] = atoi(buffer);
+ strncpy(buffer, date[i], 4);
+ year[i] = atoi(buffer);
+ }
+ }
+
+ /* Calculate the difference */
+ dateDifference = days(day[1], month[1], year[1]) - days(day[0], month[0], year[0]);
+
+ return dateDifference;
+}
diff --git a/lib/fileutils.cc b/lib/fileutils.cc
index 79ae576..b637546 100644
--- a/lib/fileutils.cc
+++ b/lib/fileutils.cc
@@ -1,81 +1,81 @@
-/*
- * PSX-Tools Bundle Pack
- * Copyright (C) 2002 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-#include "generic.h"
-
-unsigned long filesize(int f_iso)
-{
- long curpos, length;
-
- curpos = lseek(f_iso, 0, SEEK_CUR);
- length = lseek(f_iso, 0, SEEK_END);
- lseek(f_iso, curpos, SEEK_SET);
- return length;
-}
-
-void copy(int s, int d, long size) {
- long i;
- unsigned char c;
- long r;
-
- for (i = 0; (i < size) || (size < 0); i++) {
- r = read(s, &c, 1);
- if (r == 0) {
- break;
- }
- write(d, &c, 1);
- }
-}
-
-unsigned long filesize(FILE * f_iso)
-{
- long curpos, length;
-
- curpos = ftell(f_iso);
- fseek(f_iso, 0, SEEK_END);
- length = ftell(f_iso);
- fseek(f_iso, curpos, SEEK_SET);
- return length;
-}
-
-void copy(FILE * s, FILE * d, long size) {
- long i;
- unsigned char c;
- long r;
-
- for (i = 0; (i < size) || (size < 0); i++) {
- r = fread(&c, 1, 1, s);
- if (r == 0) {
- break;
- }
- fwrite(&c, 1, 1, d);
- }
-}
+/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+#include "generic.h"
+
+unsigned long filesize(int f_iso)
+{
+ long curpos, length;
+
+ curpos = lseek(f_iso, 0, SEEK_CUR);
+ length = lseek(f_iso, 0, SEEK_END);
+ lseek(f_iso, curpos, SEEK_SET);
+ return length;
+}
+
+void copy(int s, int d, long size) {
+ long i;
+ unsigned char c;
+ long r;
+
+ for (i = 0; (i < size) || (size < 0); i++) {
+ r = read(s, &c, 1);
+ if (r == 0) {
+ break;
+ }
+ write(d, &c, 1);
+ }
+}
+
+unsigned long filesize(FILE * f_iso)
+{
+ long curpos, length;
+
+ curpos = ftell(f_iso);
+ fseek(f_iso, 0, SEEK_END);
+ length = ftell(f_iso);
+ fseek(f_iso, curpos, SEEK_SET);
+ return length;
+}
+
+void copy(FILE * s, FILE * d, long size) {
+ long i;
+ unsigned char c;
+ long r;
+
+ for (i = 0; (i < size) || (size < 0); i++) {
+ r = fread(&c, 1, 1, s);
+ if (r == 0) {
+ break;
+ }
+ fwrite(&c, 1, 1, d);
+ }
+}
diff --git a/lib/generic.cc b/lib/generic.cc
index e641d55..dac827b 100644
--- a/lib/generic.cc
+++ b/lib/generic.cc
@@ -1,103 +1,103 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * 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
- */
-
-/* $Id: generic.cc,v 1.11 2004-11-27 21:35:19 pixel Exp $ */
-
-#include <stdio.h>
-#include <stdarg.h>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "BString.h"
-#ifdef HAVE_GMP
-#include <gmp.h>
-#endif
-
-char verbosity = 0;
-static char * heads[] = {"EE", "--", "WW", "II"};
-printer_t * printer = 0;
-locker_t * locker = 0;
-
-void Base::printm(int level, const ugly_string & m, ...) {
- va_list ap;
- bool display = true;
-
- if (verbosity < level) {
- return;
- }
-
- va_start(ap, m);
-
- if (printer)
- display = printer->printm(level, m.p, ap);
-
- if (display) {
- if (level >= 0) {
- fprintf(stderr, "(%s) ", heads[level]);
- }
-
-#ifdef HAVE_GMP
- gmp_vfprintf(stderr, m.p, ap);
-#else
- vfprintf(stderr, m.p, ap);
-#endif
- }
- va_end(ap);
-}
-
-void Base::printm(int level, const char * m, ...) {
- va_list ap;
- bool display = true;
-
- if (verbosity < level) {
- return;
- }
-
- va_start(ap, m);
- if (printer)
- display = printer->printm(level, m, ap);
-
- if (display) {
- if (level >= 0) {
- fprintf(stderr, "(%s) ", heads[level]);
- }
-
-#ifdef HAVE_GMP
- gmp_vfprintf(stderr, m, ap);
-#else
- vfprintf(stderr, m, ap);
-#endif
- }
- va_end(ap);
-}
-
-char ** split(char * s, char t) {
- static char * p[100];
- int i;
-
- for (i = 1, p[0] = s; *s; s++) {
- if (*s == t) {
- *s = 0;
- p[i++] = s + 1;
- }
- }
- p[i] = 0;
-
- return p;
-}
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * 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
+ */
+
+/* $Id: generic.cc,v 1.12 2004-11-27 21:46:04 pixel Exp $ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "BString.h"
+#ifdef HAVE_GMP
+#include <gmp.h>
+#endif
+
+char verbosity = 0;
+static char * heads[] = {"EE", "--", "WW", "II"};
+printer_t * printer = 0;
+locker_t * locker = 0;
+
+void Base::printm(int level, const ugly_string & m, ...) {
+ va_list ap;
+ bool display = true;
+
+ if (verbosity < level) {
+ return;
+ }
+
+ va_start(ap, m);
+
+ if (printer)
+ display = printer->printm(level, m.p, ap);
+
+ if (display) {
+ if (level >= 0) {
+ fprintf(stderr, "(%s) ", heads[level]);
+ }
+
+#ifdef HAVE_GMP
+ gmp_vfprintf(stderr, m.p, ap);
+#else
+ vfprintf(stderr, m.p, ap);
+#endif
+ }
+ va_end(ap);
+}
+
+void Base::printm(int level, const char * m, ...) {
+ va_list ap;
+ bool display = true;
+
+ if (verbosity < level) {
+ return;
+ }
+
+ va_start(ap, m);
+ if (printer)
+ display = printer->printm(level, m, ap);
+
+ if (display) {
+ if (level >= 0) {
+ fprintf(stderr, "(%s) ", heads[level]);
+ }
+
+#ifdef HAVE_GMP
+ gmp_vfprintf(stderr, m, ap);
+#else
+ vfprintf(stderr, m, ap);
+#endif
+ }
+ va_end(ap);
+}
+
+char ** split(char * s, char t) {
+ static char * p[100];
+ int i;
+
+ for (i = 1, p[0] = s; *s; s++) {
+ if (*s == t) {
+ *s = 0;
+ p[i++] = s + 1;
+ }
+ }
+ p[i] = 0;
+
+ return p;
+}
diff --git a/lib/lua/include/lauxlib.h b/lib/lua/include/lauxlib.h
index dd4dd7b..18ba835 100644
--- a/lib/lua/include/lauxlib.h
+++ b/lib/lua/include/lauxlib.h
@@ -1,149 +1,149 @@
-/*
-** $Id: lauxlib.h,v 1.4 2004-11-27 21:43:49 pixel Exp $
-** Auxiliary functions for building Lua libraries
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lauxlib_h
-#define lauxlib_h
-
-
-#include <stddef.h>
-#include <stdio.h>
-
-#include "lua.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef LUALIB_API
-#define LUALIB_API LUA_API
-#endif
-
-typedef struct luaL_reg {
- const char *name;
- lua_CFunction func;
-} luaL_reg;
-
-
-LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
- const luaL_reg *l, int nup);
-LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *e);
-LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *e);
-LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname);
-LUALIB_API int luaL_argerror (lua_State *L, int numarg, const char *extramsg);
-LUALIB_API const char *luaL_checklstring (lua_State *L, int numArg, size_t *l);
-LUALIB_API const char *luaL_optlstring (lua_State *L, int numArg,
- const char *def, size_t *l);
-LUALIB_API lua_Number luaL_checknumber (lua_State *L, int numArg);
-LUALIB_API lua_Number luaL_optnumber (lua_State *L, int nArg, lua_Number def);
-
-LUALIB_API void luaL_checkstack (lua_State *L, int sz, const char *msg);
-LUALIB_API void luaL_checktype (lua_State *L, int narg, int t);
-LUALIB_API void luaL_checkany (lua_State *L, int narg);
-
-LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname);
-LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname);
-LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname);
-
-LUALIB_API void luaL_where (lua_State *L, int lvl);
-LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...);
-
-LUALIB_API int luaL_findstring (const char *st, const char *const lst[]);
-
-LUALIB_API int luaL_ref (lua_State *L, int t);
-LUALIB_API void luaL_unref (lua_State *L, int t, int ref);
-
-LUALIB_API int luaL_getn (lua_State *L, int t);
-LUALIB_API void luaL_setn (lua_State *L, int t, int n);
-
-LUALIB_API int luaL_loadfile (lua_State *L, const char *filename);
-LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz,
- const char *name);
-
-
-
-/*
-** ===============================================================
-** some useful macros
-** ===============================================================
-*/
-
-#define luaL_argcheck(L, cond,numarg,extramsg) if (!(cond)) \
- luaL_argerror(L, numarg,extramsg)
-#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
-#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
-#define luaL_checkint(L,n) ((int)luaL_checknumber(L, n))
-#define luaL_checklong(L,n) ((long)luaL_checknumber(L, n))
-#define luaL_optint(L,n,d) ((int)luaL_optnumber(L, n,(lua_Number)(d)))
-#define luaL_optlong(L,n,d) ((long)luaL_optnumber(L, n,(lua_Number)(d)))
-
-
-/*
-** {======================================================
-** Generic Buffer manipulation
-** =======================================================
-*/
-
-
-#ifndef LUAL_BUFFERSIZE
-#define LUAL_BUFFERSIZE BUFSIZ
-#endif
-
-
-typedef struct luaL_Buffer {
- char *p; /* current position in buffer */
- int lvl; /* number of strings in the stack (level) */
- lua_State *L;
- char buffer[LUAL_BUFFERSIZE];
-} luaL_Buffer;
-
-#define luaL_putchar(B,c) \
- ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
- (*(B)->p++ = (char)(c)))
-
-#define luaL_addsize(B,n) ((B)->p += (n))
-
-LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B);
-LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B);
-LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
-LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s);
-LUALIB_API void luaL_addvalue (luaL_Buffer *B);
-LUALIB_API void luaL_pushresult (luaL_Buffer *B);
-
-
-/* }====================================================== */
-
-
-
-/*
-** Compatibility macros and functions
-*/
-
-LUALIB_API int lua_dofile (lua_State *L, const char *filename);
-LUALIB_API int lua_dostring (lua_State *L, const char *str);
-LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t sz,
- const char *n);
-
-
-#define luaL_check_lstr luaL_checklstring
-#define luaL_opt_lstr luaL_optlstring
-#define luaL_check_number luaL_checknumber
-#define luaL_opt_number luaL_optnumber
-#define luaL_arg_check luaL_argcheck
-#define luaL_check_string luaL_checkstring
-#define luaL_opt_string luaL_optstring
-#define luaL_check_int luaL_checkint
-#define luaL_check_long luaL_checklong
-#define luaL_opt_int luaL_optint
-#define luaL_opt_long luaL_optlong
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-
+/*
+** $Id: lauxlib.h,v 1.5 2004-11-27 21:46:06 pixel Exp $
+** Auxiliary functions for building Lua libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lauxlib_h
+#define lauxlib_h
+
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include "lua.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef LUALIB_API
+#define LUALIB_API LUA_API
+#endif
+
+typedef struct luaL_reg {
+ const char *name;
+ lua_CFunction func;
+} luaL_reg;
+
+
+LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
+ const luaL_reg *l, int nup);
+LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *e);
+LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *e);
+LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname);
+LUALIB_API int luaL_argerror (lua_State *L, int numarg, const char *extramsg);
+LUALIB_API const char *luaL_checklstring (lua_State *L, int numArg, size_t *l);
+LUALIB_API const char *luaL_optlstring (lua_State *L, int numArg,
+ const char *def, size_t *l);
+LUALIB_API lua_Number luaL_checknumber (lua_State *L, int numArg);
+LUALIB_API lua_Number luaL_optnumber (lua_State *L, int nArg, lua_Number def);
+
+LUALIB_API void luaL_checkstack (lua_State *L, int sz, const char *msg);
+LUALIB_API void luaL_checktype (lua_State *L, int narg, int t);
+LUALIB_API void luaL_checkany (lua_State *L, int narg);
+
+LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname);
+LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname);
+LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname);
+
+LUALIB_API void luaL_where (lua_State *L, int lvl);
+LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...);
+
+LUALIB_API int luaL_findstring (const char *st, const char *const lst[]);
+
+LUALIB_API int luaL_ref (lua_State *L, int t);
+LUALIB_API void luaL_unref (lua_State *L, int t, int ref);
+
+LUALIB_API int luaL_getn (lua_State *L, int t);
+LUALIB_API void luaL_setn (lua_State *L, int t, int n);
+
+LUALIB_API int luaL_loadfile (lua_State *L, const char *filename);
+LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz,
+ const char *name);
+
+
+
+/*
+** ===============================================================
+** some useful macros
+** ===============================================================
+*/
+
+#define luaL_argcheck(L, cond,numarg,extramsg) if (!(cond)) \
+ luaL_argerror(L, numarg,extramsg)
+#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
+#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
+#define luaL_checkint(L,n) ((int)luaL_checknumber(L, n))
+#define luaL_checklong(L,n) ((long)luaL_checknumber(L, n))
+#define luaL_optint(L,n,d) ((int)luaL_optnumber(L, n,(lua_Number)(d)))
+#define luaL_optlong(L,n,d) ((long)luaL_optnumber(L, n,(lua_Number)(d)))
+
+
+/*
+** {======================================================
+** Generic Buffer manipulation
+** =======================================================
+*/
+
+
+#ifndef LUAL_BUFFERSIZE
+#define LUAL_BUFFERSIZE BUFSIZ
+#endif
+
+
+typedef struct luaL_Buffer {
+ char *p; /* current position in buffer */
+ int lvl; /* number of strings in the stack (level) */
+ lua_State *L;
+ char buffer[LUAL_BUFFERSIZE];
+} luaL_Buffer;
+
+#define luaL_putchar(B,c) \
+ ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
+ (*(B)->p++ = (char)(c)))
+
+#define luaL_addsize(B,n) ((B)->p += (n))
+
+LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B);
+LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B);
+LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
+LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s);
+LUALIB_API void luaL_addvalue (luaL_Buffer *B);
+LUALIB_API void luaL_pushresult (luaL_Buffer *B);
+
+
+/* }====================================================== */
+
+
+
+/*
+** Compatibility macros and functions
+*/
+
+LUALIB_API int lua_dofile (lua_State *L, const char *filename);
+LUALIB_API int lua_dostring (lua_State *L, const char *str);
+LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t sz,
+ const char *n);
+
+
+#define luaL_check_lstr luaL_checklstring
+#define luaL_opt_lstr luaL_optlstring
+#define luaL_check_number luaL_checknumber
+#define luaL_opt_number luaL_optnumber
+#define luaL_arg_check luaL_argcheck
+#define luaL_check_string luaL_checkstring
+#define luaL_opt_string luaL_optstring
+#define luaL_check_int luaL_checkint
+#define luaL_check_long luaL_checklong
+#define luaL_opt_int luaL_optint
+#define luaL_opt_long luaL_optlong
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/lua/include/lua.h b/lib/lua/include/lua.h
index 87e69af..a3def0e 100644
--- a/lib/lua/include/lua.h
+++ b/lib/lua/include/lua.h
@@ -1,400 +1,400 @@
-/*
-** $Id: lua.h,v 1.5 2004-11-27 21:43:49 pixel Exp $
-** Lua - An Extensible Extension Language
-** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
-** http://www.lua.org mailto:info@lua.org
-** See Copyright Notice at the end of this file
-*/
-
-
-#ifndef lua_h
-#define lua_h
-
-#include <stdarg.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LUA_VERSION "Lua 5.0"
-#define LUA_COPYRIGHT "Copyright (C) 1994-2003 Tecgraf, PUC-Rio"
-#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
-
-
-
-/* option for multiple returns in `lua_pcall' and `lua_call' */
-#define LUA_MULTRET (-1)
-
-
-/*
-** pseudo-indices
-*/
-#define LUA_REGISTRYINDEX (-10000)
-#define LUA_GLOBALSINDEX (-10001)
-#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
-
-
-/* error codes for `lua_load' and `lua_pcall' */
-#define LUA_ERRRUN 1
-#define LUA_ERRFILE 2
-#define LUA_ERRSYNTAX 3
-#define LUA_ERRMEM 4
-#define LUA_ERRERR 5
-
-
-typedef struct lua_State lua_State;
-
-typedef int (*lua_CFunction) (lua_State *L);
-
-
-/*
-** functions that read/write blocks when loading/dumping Lua chunks
-*/
-typedef const char * (*lua_Chunkreader) (lua_State *L, void *ud, size_t *sz);
-
-typedef int (*lua_Chunkwriter) (lua_State *L, const void* p,
- size_t sz, void* ud);
-
-
-/*
-** basic types
-*/
-#define LUA_TNONE (-1)
-
-#define LUA_TNIL 0
-#define LUA_TBOOLEAN 1
-#define LUA_TLIGHTUSERDATA 2
-#define LUA_TNUMBER 3
-#define LUA_TSTRING 4
-#define LUA_TTABLE 5
-#define LUA_TFUNCTION 6
-#define LUA_TUSERDATA 7
-#define LUA_TTHREAD 8
-
-
-/* minimum Lua stack available to a C function */
-#define LUA_MINSTACK 20
-
-
-/*
-** generic extra include file
-*/
-#ifdef LUA_USER_H
-#include LUA_USER_H
-#endif
-
-
-/* type of numbers in Lua */
-#ifndef LUA_NUMBER
-typedef double lua_Number;
-#else
-typedef LUA_NUMBER lua_Number;
-#endif
-
-
-/* mark for all API functions */
-#ifndef LUA_API
-#define LUA_API extern
-#endif
-
-
-/*
-** state manipulation
-*/
-LUA_API lua_State *lua_open (void);
-LUA_API void lua_close (lua_State *L);
-LUA_API lua_State *lua_newthread (lua_State *L);
-
-LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
-
-
-/*
-** basic stack manipulation
-*/
-LUA_API int lua_gettop (lua_State *L);
-LUA_API void lua_settop (lua_State *L, int idx);
-LUA_API void lua_pushvalue (lua_State *L, int idx);
-LUA_API void lua_remove (lua_State *L, int idx);
-LUA_API void lua_insert (lua_State *L, int idx);
-LUA_API void lua_replace (lua_State *L, int idx);
-LUA_API int lua_checkstack (lua_State *L, int sz);
-
-LUA_API void lua_xmove (lua_State *from, lua_State *to, int n);
-
-
-/*
-** access functions (stack -> C)
-*/
-
-LUA_API int lua_isnumber (lua_State *L, int idx);
-LUA_API int lua_isstring (lua_State *L, int idx);
-LUA_API int lua_iscfunction (lua_State *L, int idx);
-LUA_API int lua_isuserdata (lua_State *L, int idx);
-LUA_API int lua_type (lua_State *L, int idx);
-LUA_API const char *lua_typename (lua_State *L, int tp);
-
-LUA_API int lua_equal (lua_State *L, int idx1, int idx2);
-LUA_API int lua_rawequal (lua_State *L, int idx1, int idx2);
-LUA_API int lua_lessthan (lua_State *L, int idx1, int idx2);
-
-LUA_API lua_Number lua_tonumber (lua_State *L, int idx);
-LUA_API int lua_toboolean (lua_State *L, int idx);
-LUA_API const char *lua_tostring (lua_State *L, int idx);
-LUA_API size_t lua_strlen (lua_State *L, int idx);
-LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx);
-LUA_API void *lua_touserdata (lua_State *L, int idx);
-LUA_API lua_State *lua_tothread (lua_State *L, int idx);
-LUA_API const void *lua_topointer (lua_State *L, int idx);
-
-
-/*
-** push functions (C -> stack)
-*/
-LUA_API void lua_pushnil (lua_State *L);
-LUA_API void lua_pushnumber (lua_State *L, lua_Number n);
-LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t l);
-LUA_API void lua_pushstring (lua_State *L, const char *s);
-LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
- va_list argp);
-LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
-LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
-LUA_API void lua_pushboolean (lua_State *L, int b);
-LUA_API void lua_pushlightuserdata (lua_State *L, void *p);
-
-
-/*
-** get functions (Lua -> stack)
-*/
-LUA_API void lua_gettable (lua_State *L, int idx);
-LUA_API void lua_rawget (lua_State *L, int idx);
-LUA_API void lua_rawgeti (lua_State *L, int idx, int n);
-LUA_API void lua_newtable (lua_State *L);
-LUA_API void *lua_newuserdata (lua_State *L, size_t sz);
-LUA_API int lua_getmetatable (lua_State *L, int objindex);
-LUA_API void lua_getfenv (lua_State *L, int idx);
-
-
-/*
-** set functions (stack -> Lua)
-*/
-LUA_API void lua_settable (lua_State *L, int idx);
-LUA_API void lua_rawset (lua_State *L, int idx);
-LUA_API void lua_rawseti (lua_State *L, int idx, int n);
-LUA_API int lua_setmetatable (lua_State *L, int objindex);
-LUA_API int lua_setfenv (lua_State *L, int idx);
-
-
-/*
-** `load' and `call' functions (load and run Lua code)
-*/
-LUA_API void lua_call (lua_State *L, int nargs, int nresults);
-LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
-LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);
-LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *dt,
- const char *chunkname);
-
-LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data);
-
-
-/*
-** coroutine functions
-*/
-LUA_API int lua_yield (lua_State *L, int nresults);
-LUA_API int lua_resume (lua_State *L, int narg);
-
-/*
-** garbage-collection functions
-*/
-LUA_API int lua_getgcthreshold (lua_State *L);
-LUA_API int lua_getgccount (lua_State *L);
-LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold);
-
-/*
-** miscellaneous functions
-*/
-
-LUA_API const char *lua_version (void);
-
-LUA_API int lua_error (lua_State *L);
-
-LUA_API int lua_next (lua_State *L, int idx);
-
-LUA_API void lua_concat (lua_State *L, int n);
-
-LUA_API void lua_break (lua_State *L);
-
-
-
-/*
-** ===============================================================
-** some useful macros
-** ===============================================================
-*/
-
-#define lua_boxpointer(L,u) \
- (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u))
-
-#define lua_unboxpointer(L,i) (*(void **)(lua_touserdata(L, i)))
-
-#define lua_pop(L,n) lua_settop(L, -(n)-1)
-
-#define lua_register(L,n,f) \
- (lua_pushstring(L, n), \
- lua_pushcfunction(L, f), \
- lua_settable(L, LUA_GLOBALSINDEX))
-
-#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0)
-
-#define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION)
-#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE)
-#define lua_islightuserdata(L,n) (lua_type(L,n) == LUA_TLIGHTUSERDATA)
-#define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL)
-#define lua_isboolean(L,n) (lua_type(L,n) == LUA_TBOOLEAN)
-#define lua_isnone(L,n) (lua_type(L,n) == LUA_TNONE)
-#define lua_isnoneornil(L, n) (lua_type(L,n) <= 0)
-
-#define lua_pushliteral(L, s) \
- lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
-
-
-
-/*
-** compatibility macros and functions
-*/
-
-
-LUA_API int lua_pushupvalues (lua_State *L);
-
-#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
-#define lua_setglobal(L,s) \
- (lua_pushstring(L, s), lua_insert(L, -2), lua_settable(L, LUA_GLOBALSINDEX))
-
-#define lua_getglobal(L,s) \
- (lua_pushstring(L, s), lua_gettable(L, LUA_GLOBALSINDEX))
-
-
-/* compatibility with ref system */
-
-/* pre-defined references */
-#define LUA_NOREF (-2)
-#define LUA_REFNIL (-1)
-
-#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
- (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
-
-#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
-
-#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, ref)
-
-
-
-/*
-** {======================================================================
-** useful definitions for Lua kernel and libraries
-** =======================================================================
-*/
-
-/* formats for Lua numbers */
-#ifndef LUA_NUMBER_SCAN
-#define LUA_NUMBER_SCAN "%lf"
-#endif
-
-#ifndef LUA_NUMBER_FMT
-#define LUA_NUMBER_FMT "%.14g"
-#endif
-
-/* }====================================================================== */
-
-
-/*
-** {======================================================================
-** Debug API
-** =======================================================================
-*/
-
-
-/*
-** Event codes
-*/
-#define LUA_HOOKCALL 0
-#define LUA_HOOKRET 1
-#define LUA_HOOKLINE 2
-#define LUA_HOOKCOUNT 3
-#define LUA_HOOKTAILRET 4
-
-
-/*
-** Event masks
-*/
-#define LUA_MASKCALL (1 << LUA_HOOKCALL)
-#define LUA_MASKRET (1 << LUA_HOOKRET)
-#define LUA_MASKLINE (1 << LUA_HOOKLINE)
-#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
-
-typedef struct lua_Debug lua_Debug; /* activation record */
-
-typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
-
-
-LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
-LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
-LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
-LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
-LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
-LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
-
-LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
-LUA_API lua_Hook lua_gethook (lua_State *L);
-LUA_API int lua_gethookmask (lua_State *L);
-LUA_API int lua_gethookcount (lua_State *L);
-
-
-#define LUA_IDSIZE 60
-
-struct lua_Debug {
- int event;
- const char *name; /* (n) */
- const char *namewhat; /* (n) `global', `local', `field', `method' */
- const char *what; /* (S) `Lua', `C', `main', `tail' */
- const char *source; /* (S) */
- int currentline; /* (l) */
- int nups; /* (u) number of upvalues */
- int linedefined; /* (S) */
- char short_src[LUA_IDSIZE]; /* (S) */
- /* private part */
- int i_ci; /* active function */
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-/* }====================================================================== */
-
-
-/******************************************************************************
-* Copyright (C) 1994-2003 Tecgraf, PUC-Rio. All rights reserved.
-*
-* Permission is hereby granted, free of charge, to any person obtaining
-* a copy of this software and associated documentation files (the
-* "Software"), to deal in the Software without restriction, including
-* without limitation the rights to use, copy, modify, merge, publish,
-* distribute, sublicense, and/or sell copies of the Software, and to
-* permit persons to whom the Software is furnished to do so, subject to
-* the following conditions:
-*
-* The above copyright notice and this permission notice shall be
-* included in all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-******************************************************************************/
-
-
-#endif
+/*
+** $Id: lua.h,v 1.6 2004-11-27 21:46:06 pixel Exp $
+** Lua - An Extensible Extension Language
+** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
+** http://www.lua.org mailto:info@lua.org
+** See Copyright Notice at the end of this file
+*/
+
+
+#ifndef lua_h
+#define lua_h
+
+#include <stdarg.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LUA_VERSION "Lua 5.0"
+#define LUA_COPYRIGHT "Copyright (C) 1994-2003 Tecgraf, PUC-Rio"
+#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
+
+
+
+/* option for multiple returns in `lua_pcall' and `lua_call' */
+#define LUA_MULTRET (-1)
+
+
+/*
+** pseudo-indices
+*/
+#define LUA_REGISTRYINDEX (-10000)
+#define LUA_GLOBALSINDEX (-10001)
+#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
+
+
+/* error codes for `lua_load' and `lua_pcall' */
+#define LUA_ERRRUN 1
+#define LUA_ERRFILE 2
+#define LUA_ERRSYNTAX 3
+#define LUA_ERRMEM 4
+#define LUA_ERRERR 5
+
+
+typedef struct lua_State lua_State;
+
+typedef int (*lua_CFunction) (lua_State *L);
+
+
+/*
+** functions that read/write blocks when loading/dumping Lua chunks
+*/
+typedef const char * (*lua_Chunkreader) (lua_State *L, void *ud, size_t *sz);
+
+typedef int (*lua_Chunkwriter) (lua_State *L, const void* p,
+ size_t sz, void* ud);
+
+
+/*
+** basic types
+*/
+#define LUA_TNONE (-1)
+
+#define LUA_TNIL 0
+#define LUA_TBOOLEAN 1
+#define LUA_TLIGHTUSERDATA 2
+#define LUA_TNUMBER 3
+#define LUA_TSTRING 4
+#define LUA_TTABLE 5
+#define LUA_TFUNCTION 6
+#define LUA_TUSERDATA 7
+#define LUA_TTHREAD 8
+
+
+/* minimum Lua stack available to a C function */
+#define LUA_MINSTACK 20
+
+
+/*
+** generic extra include file
+*/
+#ifdef LUA_USER_H
+#include LUA_USER_H
+#endif
+
+
+/* type of numbers in Lua */
+#ifndef LUA_NUMBER
+typedef double lua_Number;
+#else
+typedef LUA_NUMBER lua_Number;
+#endif
+
+
+/* mark for all API functions */
+#ifndef LUA_API
+#define LUA_API extern
+#endif
+
+
+/*
+** state manipulation
+*/
+LUA_API lua_State *lua_open (void);
+LUA_API void lua_close (lua_State *L);
+LUA_API lua_State *lua_newthread (lua_State *L);
+
+LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
+
+
+/*
+** basic stack manipulation
+*/
+LUA_API int lua_gettop (lua_State *L);
+LUA_API void lua_settop (lua_State *L, int idx);
+LUA_API void lua_pushvalue (lua_State *L, int idx);
+LUA_API void lua_remove (lua_State *L, int idx);
+LUA_API void lua_insert (lua_State *L, int idx);
+LUA_API void lua_replace (lua_State *L, int idx);
+LUA_API int lua_checkstack (lua_State *L, int sz);
+
+LUA_API void lua_xmove (lua_State *from, lua_State *to, int n);
+
+
+/*
+** access functions (stack -> C)
+*/
+
+LUA_API int lua_isnumber (lua_State *L, int idx);
+LUA_API int lua_isstring (lua_State *L, int idx);
+LUA_API int lua_iscfunction (lua_State *L, int idx);
+LUA_API int lua_isuserdata (lua_State *L, int idx);
+LUA_API int lua_type (lua_State *L, int idx);
+LUA_API const char *lua_typename (lua_State *L, int tp);
+
+LUA_API int lua_equal (lua_State *L, int idx1, int idx2);
+LUA_API int lua_rawequal (lua_State *L, int idx1, int idx2);
+LUA_API int lua_lessthan (lua_State *L, int idx1, int idx2);
+
+LUA_API lua_Number lua_tonumber (lua_State *L, int idx);
+LUA_API int lua_toboolean (lua_State *L, int idx);
+LUA_API const char *lua_tostring (lua_State *L, int idx);
+LUA_API size_t lua_strlen (lua_State *L, int idx);
+LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx);
+LUA_API void *lua_touserdata (lua_State *L, int idx);
+LUA_API lua_State *lua_tothread (lua_State *L, int idx);
+LUA_API const void *lua_topointer (lua_State *L, int idx);
+
+
+/*
+** push functions (C -> stack)
+*/
+LUA_API void lua_pushnil (lua_State *L);
+LUA_API void lua_pushnumber (lua_State *L, lua_Number n);
+LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t l);
+LUA_API void lua_pushstring (lua_State *L, const char *s);
+LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
+ va_list argp);
+LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
+LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
+LUA_API void lua_pushboolean (lua_State *L, int b);
+LUA_API void lua_pushlightuserdata (lua_State *L, void *p);
+
+
+/*
+** get functions (Lua -> stack)
+*/
+LUA_API void lua_gettable (lua_State *L, int idx);
+LUA_API void lua_rawget (lua_State *L, int idx);
+LUA_API void lua_rawgeti (lua_State *L, int idx, int n);
+LUA_API void lua_newtable (lua_State *L);
+LUA_API void *lua_newuserdata (lua_State *L, size_t sz);
+LUA_API int lua_getmetatable (lua_State *L, int objindex);
+LUA_API void lua_getfenv (lua_State *L, int idx);
+
+
+/*
+** set functions (stack -> Lua)
+*/
+LUA_API void lua_settable (lua_State *L, int idx);
+LUA_API void lua_rawset (lua_State *L, int idx);
+LUA_API void lua_rawseti (lua_State *L, int idx, int n);
+LUA_API int lua_setmetatable (lua_State *L, int objindex);
+LUA_API int lua_setfenv (lua_State *L, int idx);
+
+
+/*
+** `load' and `call' functions (load and run Lua code)
+*/
+LUA_API void lua_call (lua_State *L, int nargs, int nresults);
+LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
+LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);
+LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *dt,
+ const char *chunkname);
+
+LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data);
+
+
+/*
+** coroutine functions
+*/
+LUA_API int lua_yield (lua_State *L, int nresults);
+LUA_API int lua_resume (lua_State *L, int narg);
+
+/*
+** garbage-collection functions
+*/
+LUA_API int lua_getgcthreshold (lua_State *L);
+LUA_API int lua_getgccount (lua_State *L);
+LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold);
+
+/*
+** miscellaneous functions
+*/
+
+LUA_API const char *lua_version (void);
+
+LUA_API int lua_error (lua_State *L);
+
+LUA_API int lua_next (lua_State *L, int idx);
+
+LUA_API void lua_concat (lua_State *L, int n);
+
+LUA_API void lua_break (lua_State *L);
+
+
+
+/*
+** ===============================================================
+** some useful macros
+** ===============================================================
+*/
+
+#define lua_boxpointer(L,u) \
+ (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u))
+
+#define lua_unboxpointer(L,i) (*(void **)(lua_touserdata(L, i)))
+
+#define lua_pop(L,n) lua_settop(L, -(n)-1)
+
+#define lua_register(L,n,f) \
+ (lua_pushstring(L, n), \
+ lua_pushcfunction(L, f), \
+ lua_settable(L, LUA_GLOBALSINDEX))
+
+#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0)
+
+#define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION)
+#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE)
+#define lua_islightuserdata(L,n) (lua_type(L,n) == LUA_TLIGHTUSERDATA)
+#define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL)
+#define lua_isboolean(L,n) (lua_type(L,n) == LUA_TBOOLEAN)
+#define lua_isnone(L,n) (lua_type(L,n) == LUA_TNONE)
+#define lua_isnoneornil(L, n) (lua_type(L,n) <= 0)
+
+#define lua_pushliteral(L, s) \
+ lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
+
+
+
+/*
+** compatibility macros and functions
+*/
+
+
+LUA_API int lua_pushupvalues (lua_State *L);
+
+#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
+#define lua_setglobal(L,s) \
+ (lua_pushstring(L, s), lua_insert(L, -2), lua_settable(L, LUA_GLOBALSINDEX))
+
+#define lua_getglobal(L,s) \
+ (lua_pushstring(L, s), lua_gettable(L, LUA_GLOBALSINDEX))
+
+
+/* compatibility with ref system */
+
+/* pre-defined references */
+#define LUA_NOREF (-2)
+#define LUA_REFNIL (-1)
+
+#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
+ (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
+
+#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
+
+#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, ref)
+
+
+
+/*
+** {======================================================================
+** useful definitions for Lua kernel and libraries
+** =======================================================================
+*/
+
+/* formats for Lua numbers */
+#ifndef LUA_NUMBER_SCAN
+#define LUA_NUMBER_SCAN "%lf"
+#endif
+
+#ifndef LUA_NUMBER_FMT
+#define LUA_NUMBER_FMT "%.14g"
+#endif
+
+/* }====================================================================== */
+
+
+/*
+** {======================================================================
+** Debug API
+** =======================================================================
+*/
+
+
+/*
+** Event codes
+*/
+#define LUA_HOOKCALL 0
+#define LUA_HOOKRET 1
+#define LUA_HOOKLINE 2
+#define LUA_HOOKCOUNT 3
+#define LUA_HOOKTAILRET 4
+
+
+/*
+** Event masks
+*/
+#define LUA_MASKCALL (1 << LUA_HOOKCALL)
+#define LUA_MASKRET (1 << LUA_HOOKRET)
+#define LUA_MASKLINE (1 << LUA_HOOKLINE)
+#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
+
+typedef struct lua_Debug lua_Debug; /* activation record */
+
+typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
+
+
+LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
+LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
+LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
+LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
+
+LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
+LUA_API lua_Hook lua_gethook (lua_State *L);
+LUA_API int lua_gethookmask (lua_State *L);
+LUA_API int lua_gethookcount (lua_State *L);
+
+
+#define LUA_IDSIZE 60
+
+struct lua_Debug {
+ int event;
+ const char *name; /* (n) */
+ const char *namewhat; /* (n) `global', `local', `field', `method' */
+ const char *what; /* (S) `Lua', `C', `main', `tail' */
+ const char *source; /* (S) */
+ int currentline; /* (l) */
+ int nups; /* (u) number of upvalues */
+ int linedefined; /* (S) */
+ char short_src[LUA_IDSIZE]; /* (S) */
+ /* private part */
+ int i_ci; /* active function */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+/* }====================================================================== */
+
+
+/******************************************************************************
+* Copyright (C) 1994-2003 Tecgraf, PUC-Rio. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+
+#endif
diff --git a/lib/lua/include/lualib.h b/lib/lua/include/lualib.h
index 7c7a7b5..753c7fb 100644
--- a/lib/lua/include/lualib.h
+++ b/lib/lua/include/lualib.h
@@ -1,66 +1,66 @@
-/*
-** $Id: lualib.h,v 1.5 2004-11-27 21:43:49 pixel Exp $
-** Lua standard libraries
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lualib_h
-#define lualib_h
-
-#include "lua.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef LUALIB_API
-#define LUALIB_API LUA_API
-#endif
-
-
-#define LUA_COLIBNAME "coroutine"
-LUALIB_API int luaopen_base (lua_State *L);
-
-#define LUA_TABLIBNAME "table"
-LUALIB_API int luaopen_table (lua_State *L);
-
-#define LUA_IOLIBNAME "io"
-#define LUA_OSLIBNAME "os"
-LUALIB_API int luaopen_io (lua_State *L);
-
-#define LUA_STRLIBNAME "string"
-LUALIB_API int luaopen_string (lua_State *L);
-
-#define LUA_MATHLIBNAME "math"
-LUALIB_API int luaopen_math (lua_State *L);
-
-#define LUA_DBLIBNAME "debug"
-LUALIB_API int luaopen_debug (lua_State *L);
-
-#define LUA_DIRLIBNAME "dir"
-LUALIB_API int luaopen_dir (lua_State *L);
-
-
-LUALIB_API int luaopen_loadlib (lua_State *L);
-
-
-/* to help testing the libraries */
-#ifndef lua_assert
-#define lua_assert(c) /* empty */
-#endif
-
-
-/* compatibility code */
-#define lua_baselibopen luaopen_base
-#define lua_tablibopen luaopen_table
-#define lua_iolibopen luaopen_io
-#define lua_strlibopen luaopen_string
-#define lua_mathlibopen luaopen_math
-#define lua_dblibopen luaopen_debug
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/*
+** $Id: lualib.h,v 1.6 2004-11-27 21:46:06 pixel Exp $
+** Lua standard libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lualib_h
+#define lualib_h
+
+#include "lua.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef LUALIB_API
+#define LUALIB_API LUA_API
+#endif
+
+
+#define LUA_COLIBNAME "coroutine"
+LUALIB_API int luaopen_base (lua_State *L);
+
+#define LUA_TABLIBNAME "table"
+LUALIB_API int luaopen_table (lua_State *L);
+
+#define LUA_IOLIBNAME "io"
+#define LUA_OSLIBNAME "os"
+LUALIB_API int luaopen_io (lua_State *L);
+
+#define LUA_STRLIBNAME "string"
+LUALIB_API int luaopen_string (lua_State *L);
+
+#define LUA_MATHLIBNAME "math"
+LUALIB_API int luaopen_math (lua_State *L);
+
+#define LUA_DBLIBNAME "debug"
+LUALIB_API int luaopen_debug (lua_State *L);
+
+#define LUA_DIRLIBNAME "dir"
+LUALIB_API int luaopen_dir (lua_State *L);
+
+
+LUALIB_API int luaopen_loadlib (lua_State *L);
+
+
+/* to help testing the libraries */
+#ifndef lua_assert
+#define lua_assert(c) /* empty */
+#endif
+
+
+/* compatibility code */
+#define lua_baselibopen luaopen_base
+#define lua_tablibopen luaopen_table
+#define lua_iolibopen luaopen_io
+#define lua_strlibopen luaopen_string
+#define lua_mathlibopen luaopen_math
+#define lua_dblibopen luaopen_debug
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/lua/includes/lapi.h b/lib/lua/includes/lapi.h
index 1e18867..44445f7 100644
--- a/lib/lua/includes/lapi.h
+++ b/lib/lua/includes/lapi.h
@@ -1,16 +1,16 @@
-/*
-** $Id: lapi.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Auxiliary functions from Lua API
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lapi_h
-#define lapi_h
-
-
-#include "lobject.h"
-
-
-void luaA_pushobject (lua_State *L, const TObject *o);
-
-#endif
+/*
+** $Id: lapi.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Auxiliary functions from Lua API
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lapi_h
+#define lapi_h
+
+
+#include "lobject.h"
+
+
+void luaA_pushobject (lua_State *L, const TObject *o);
+
+#endif
diff --git a/lib/lua/includes/lcode.h b/lib/lua/includes/lcode.h
index fdd7025..0ba20f6 100644
--- a/lib/lua/includes/lcode.h
+++ b/lib/lua/includes/lcode.h
@@ -1,74 +1,74 @@
-/*
-** $Id: lcode.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Code generator for Lua
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lcode_h
-#define lcode_h
-
-#include "llex.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lparser.h"
-
-
-/*
-** Marks the end of a patch list. It is an invalid value both as an absolute
-** address, and as a list link (would link an element to itself).
-*/
-#define NO_JUMP (-1)
-
-
-/*
-** grep "ORDER OPR" if you change these enums
-*/
-typedef enum BinOpr {
- OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_POW,
- OPR_CONCAT,
- OPR_NE, OPR_EQ,
- OPR_LT, OPR_LE, OPR_GT, OPR_GE,
- OPR_AND, OPR_OR,
- OPR_NOBINOPR
-} BinOpr;
-
-#define binopistest(op) ((op) >= OPR_NE)
-
-typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr;
-
-
-#define getcode(fs,e) ((fs)->f->code[(e)->info])
-
-#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
-
-int luaK_code (FuncState *fs, Instruction i, int line);
-int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
-int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
-void luaK_fixline (FuncState *fs, int line);
-void luaK_nil (FuncState *fs, int from, int n);
-void luaK_reserveregs (FuncState *fs, int n);
-void luaK_checkstack (FuncState *fs, int n);
-int luaK_stringK (FuncState *fs, TString *s);
-int luaK_numberK (FuncState *fs, lua_Number r);
-void luaK_dischargevars (FuncState *fs, expdesc *e);
-int luaK_exp2anyreg (FuncState *fs, expdesc *e);
-void luaK_exp2nextreg (FuncState *fs, expdesc *e);
-void luaK_exp2val (FuncState *fs, expdesc *e);
-int luaK_exp2RK (FuncState *fs, expdesc *e);
-void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
-void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
-void luaK_goiftrue (FuncState *fs, expdesc *e);
-void luaK_goiffalse (FuncState *fs, expdesc *e);
-void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
-void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults);
-int luaK_jump (FuncState *fs);
-void luaK_patchlist (FuncState *fs, int list, int target);
-void luaK_patchtohere (FuncState *fs, int list);
-void luaK_concat (FuncState *fs, int *l1, int l2);
-int luaK_getlabel (FuncState *fs);
-void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
-void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
-void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
-
-
-#endif
+/*
+** $Id: lcode.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Code generator for Lua
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lcode_h
+#define lcode_h
+
+#include "llex.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lparser.h"
+
+
+/*
+** Marks the end of a patch list. It is an invalid value both as an absolute
+** address, and as a list link (would link an element to itself).
+*/
+#define NO_JUMP (-1)
+
+
+/*
+** grep "ORDER OPR" if you change these enums
+*/
+typedef enum BinOpr {
+ OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_POW,
+ OPR_CONCAT,
+ OPR_NE, OPR_EQ,
+ OPR_LT, OPR_LE, OPR_GT, OPR_GE,
+ OPR_AND, OPR_OR,
+ OPR_NOBINOPR
+} BinOpr;
+
+#define binopistest(op) ((op) >= OPR_NE)
+
+typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr;
+
+
+#define getcode(fs,e) ((fs)->f->code[(e)->info])
+
+#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
+
+int luaK_code (FuncState *fs, Instruction i, int line);
+int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
+int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
+void luaK_fixline (FuncState *fs, int line);
+void luaK_nil (FuncState *fs, int from, int n);
+void luaK_reserveregs (FuncState *fs, int n);
+void luaK_checkstack (FuncState *fs, int n);
+int luaK_stringK (FuncState *fs, TString *s);
+int luaK_numberK (FuncState *fs, lua_Number r);
+void luaK_dischargevars (FuncState *fs, expdesc *e);
+int luaK_exp2anyreg (FuncState *fs, expdesc *e);
+void luaK_exp2nextreg (FuncState *fs, expdesc *e);
+void luaK_exp2val (FuncState *fs, expdesc *e);
+int luaK_exp2RK (FuncState *fs, expdesc *e);
+void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
+void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
+void luaK_goiftrue (FuncState *fs, expdesc *e);
+void luaK_goiffalse (FuncState *fs, expdesc *e);
+void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
+void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults);
+int luaK_jump (FuncState *fs);
+void luaK_patchlist (FuncState *fs, int list, int target);
+void luaK_patchtohere (FuncState *fs, int list);
+void luaK_concat (FuncState *fs, int *l1, int l2);
+int luaK_getlabel (FuncState *fs);
+void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
+void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
+void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
+
+
+#endif
diff --git a/lib/lua/includes/ldebug.h b/lib/lua/includes/ldebug.h
index 2494575..9efa287 100644
--- a/lib/lua/includes/ldebug.h
+++ b/lib/lua/includes/ldebug.h
@@ -1,31 +1,31 @@
-/*
-** $Id: ldebug.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Auxiliary functions from Debug Interface module
-** See Copyright Notice in lua.h
-*/
-
-#ifndef ldebug_h
-#define ldebug_h
-
-
-#include "lstate.h"
-
-
-#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
-
-#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
-
-#define resethookcount(L) (L->hookcount = L->basehookcount)
-
-
-void luaG_inithooks (lua_State *L);
-void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
-void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
-void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2);
-int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2);
-void luaG_runerror (lua_State *L, const char *fmt, ...);
-void luaG_errormsg (lua_State *L);
-int luaG_checkcode (const Proto *pt);
-
-
-#endif
+/*
+** $Id: ldebug.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Auxiliary functions from Debug Interface module
+** See Copyright Notice in lua.h
+*/
+
+#ifndef ldebug_h
+#define ldebug_h
+
+
+#include "lstate.h"
+
+
+#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
+
+#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
+
+#define resethookcount(L) (L->hookcount = L->basehookcount)
+
+
+void luaG_inithooks (lua_State *L);
+void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
+void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
+void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2);
+int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2);
+void luaG_runerror (lua_State *L, const char *fmt, ...);
+void luaG_errormsg (lua_State *L);
+int luaG_checkcode (const Proto *pt);
+
+
+#endif
diff --git a/lib/lua/includes/ldo.h b/lib/lua/includes/ldo.h
index e7b24d8..415da8c 100644
--- a/lib/lua/includes/ldo.h
+++ b/lib/lua/includes/ldo.h
@@ -1,60 +1,60 @@
-/*
-** $Id: ldo.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Stack and Call structure of Lua
-** See Copyright Notice in lua.h
-*/
-
-#ifndef ldo_h
-#define ldo_h
-
-
-#include "lobject.h"
-#include "lstate.h"
-#include "lzio.h"
-
-
-/*
-** macro to control inclusion of some hard tests on stack reallocation
-*/
-#ifndef HARDSTACKTESTS
-#define condhardstacktests(x) { /* empty */ }
-#else
-#define condhardstacktests(x) x
-#endif
-
-
-#define luaD_checkstack(L,n) \
- if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TObject)) \
- luaD_growstack(L, n); \
- else condhardstacktests(luaD_reallocstack(L, L->stacksize));
-
-
-#define incr_top(L) {luaD_checkstack(L,1); L->top++;}
-
-#define savestack(L,p) ((char *)(p) - (char *)L->stack)
-#define restorestack(L,n) ((TObject *)((char *)L->stack + (n)))
-
-#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
-#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
-
-
-/* type of protected functions, to be ran by `runprotected' */
-typedef void (*Pfunc) (lua_State *L, void *ud);
-
-void luaD_resetprotection (lua_State *L);
-int luaD_protectedparser (lua_State *L, ZIO *z, int bin);
-void luaD_callhook (lua_State *L, int event, int line);
-StkId luaD_precall (lua_State *L, StkId func);
-void luaD_call (lua_State *L, StkId func, int nResults);
-int luaD_pcall (lua_State *L, Pfunc func, void *u,
- ptrdiff_t oldtop, ptrdiff_t ef);
-void luaD_poscall (lua_State *L, int wanted, StkId firstResult);
-void luaD_reallocCI (lua_State *L, int newsize);
-void luaD_reallocstack (lua_State *L, int newsize);
-void luaD_growstack (lua_State *L, int n);
-
-void luaD_throw (lua_State *L, int errcode);
-int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
-
-
-#endif
+/*
+** $Id: ldo.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Stack and Call structure of Lua
+** See Copyright Notice in lua.h
+*/
+
+#ifndef ldo_h
+#define ldo_h
+
+
+#include "lobject.h"
+#include "lstate.h"
+#include "lzio.h"
+
+
+/*
+** macro to control inclusion of some hard tests on stack reallocation
+*/
+#ifndef HARDSTACKTESTS
+#define condhardstacktests(x) { /* empty */ }
+#else
+#define condhardstacktests(x) x
+#endif
+
+
+#define luaD_checkstack(L,n) \
+ if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TObject)) \
+ luaD_growstack(L, n); \
+ else condhardstacktests(luaD_reallocstack(L, L->stacksize));
+
+
+#define incr_top(L) {luaD_checkstack(L,1); L->top++;}
+
+#define savestack(L,p) ((char *)(p) - (char *)L->stack)
+#define restorestack(L,n) ((TObject *)((char *)L->stack + (n)))
+
+#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
+#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
+
+
+/* type of protected functions, to be ran by `runprotected' */
+typedef void (*Pfunc) (lua_State *L, void *ud);
+
+void luaD_resetprotection (lua_State *L);
+int luaD_protectedparser (lua_State *L, ZIO *z, int bin);
+void luaD_callhook (lua_State *L, int event, int line);
+StkId luaD_precall (lua_State *L, StkId func);
+void luaD_call (lua_State *L, StkId func, int nResults);
+int luaD_pcall (lua_State *L, Pfunc func, void *u,
+ ptrdiff_t oldtop, ptrdiff_t ef);
+void luaD_poscall (lua_State *L, int wanted, StkId firstResult);
+void luaD_reallocCI (lua_State *L, int newsize);
+void luaD_reallocstack (lua_State *L, int newsize);
+void luaD_growstack (lua_State *L, int n);
+
+void luaD_throw (lua_State *L, int errcode);
+int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
+
+
+#endif
diff --git a/lib/lua/includes/lfunc.h b/lib/lua/includes/lfunc.h
index 68c129b..6af41b7 100644
--- a/lib/lua/includes/lfunc.h
+++ b/lib/lua/includes/lfunc.h
@@ -1,25 +1,25 @@
-/*
-** $Id: lfunc.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Auxiliary functions to manipulate prototypes and closures
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lfunc_h
-#define lfunc_h
-
-
-#include "lobject.h"
-
-
-Proto *luaF_newproto (lua_State *L);
-Closure *luaF_newCclosure (lua_State *L, int nelems);
-Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e);
-UpVal *luaF_findupval (lua_State *L, StkId level);
-void luaF_close (lua_State *L, StkId level);
-void luaF_freeproto (lua_State *L, Proto *f);
-void luaF_freeclosure (lua_State *L, Closure *c);
-
-const char *luaF_getlocalname (const Proto *func, int local_number, int pc);
-
-
-#endif
+/*
+** $Id: lfunc.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Auxiliary functions to manipulate prototypes and closures
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lfunc_h
+#define lfunc_h
+
+
+#include "lobject.h"
+
+
+Proto *luaF_newproto (lua_State *L);
+Closure *luaF_newCclosure (lua_State *L, int nelems);
+Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e);
+UpVal *luaF_findupval (lua_State *L, StkId level);
+void luaF_close (lua_State *L, StkId level);
+void luaF_freeproto (lua_State *L, Proto *f);
+void luaF_freeclosure (lua_State *L, Closure *c);
+
+const char *luaF_getlocalname (const Proto *func, int local_number, int pc);
+
+
+#endif
diff --git a/lib/lua/includes/lgc.h b/lib/lua/includes/lgc.h
index 52e0c58..43ae521 100644
--- a/lib/lua/includes/lgc.h
+++ b/lib/lua/includes/lgc.h
@@ -1,25 +1,25 @@
-/*
-** $Id: lgc.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Garbage Collector
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lgc_h
-#define lgc_h
-
-
-#include "lobject.h"
-
-
-#define luaC_checkGC(L) { lua_assert(!(L->ci->state & CI_CALLING)); \
- if (G(L)->nblocks >= G(L)->GCthreshold) luaC_collectgarbage(L); }
-
-
-void luaC_separateudata (lua_State *L);
-void luaC_callGCTM (lua_State *L);
-void luaC_sweep (lua_State *L, int all);
-void luaC_collectgarbage (lua_State *L);
-void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
-
-
-#endif
+/*
+** $Id: lgc.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Garbage Collector
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lgc_h
+#define lgc_h
+
+
+#include "lobject.h"
+
+
+#define luaC_checkGC(L) { lua_assert(!(L->ci->state & CI_CALLING)); \
+ if (G(L)->nblocks >= G(L)->GCthreshold) luaC_collectgarbage(L); }
+
+
+void luaC_separateudata (lua_State *L);
+void luaC_callGCTM (lua_State *L);
+void luaC_sweep (lua_State *L, int all);
+void luaC_collectgarbage (lua_State *L);
+void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
+
+
+#endif
diff --git a/lib/lua/includes/llex.h b/lib/lua/includes/llex.h
index 94f0b8f..805abc5 100644
--- a/lib/lua/includes/llex.h
+++ b/lib/lua/includes/llex.h
@@ -1,75 +1,75 @@
-/*
-** $Id: llex.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Lexical Analyzer
-** See Copyright Notice in lua.h
-*/
-
-#ifndef llex_h
-#define llex_h
-
-#include "lobject.h"
-#include "lzio.h"
-
-
-#define FIRST_RESERVED 257
-
-/* maximum length of a reserved word */
-#define TOKEN_LEN (sizeof("function")/sizeof(char))
-
-
-/*
-* WARNING: if you change the order of this enumeration,
-* grep "ORDER RESERVED"
-*/
-enum RESERVED {
- /* terminal symbols denoted by reserved words */
- TK_AND = FIRST_RESERVED, TK_BREAK,
- TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
- TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
- TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
- /* other terminal symbols */
- TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
- TK_STRING, TK_EOS
-};
-
-/* number of reserved words */
-#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
-
-
-typedef union {
- lua_Number r;
- TString *ts;
-} SemInfo; /* semantics information */
-
-
-typedef struct Token {
- int token;
- SemInfo seminfo;
-} Token;
-
-
-typedef struct LexState {
- int current; /* current character (charint) */
- int linenumber; /* input line counter */
- int lastline; /* line of last token `consumed' */
- Token t; /* current token */
- Token lookahead; /* look ahead token */
- struct FuncState *fs; /* `FuncState' is private to the parser */
- struct lua_State *L;
- ZIO *z; /* input stream */
- Mbuffer *buff; /* buffer for tokens */
- TString *source; /* current source name */
- int nestlevel; /* level of nested non-terminals */
-} LexState;
-
-
-void luaX_init (lua_State *L);
-void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source);
-int luaX_lex (LexState *LS, SemInfo *seminfo);
-void luaX_checklimit (LexState *ls, int val, int limit, const char *msg);
-void luaX_syntaxerror (LexState *ls, const char *s);
-void luaX_errorline (LexState *ls, const char *s, const char *token, int line);
-const char *luaX_token2str (LexState *ls, int token);
-
-
-#endif
+/*
+** $Id: llex.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Lexical Analyzer
+** See Copyright Notice in lua.h
+*/
+
+#ifndef llex_h
+#define llex_h
+
+#include "lobject.h"
+#include "lzio.h"
+
+
+#define FIRST_RESERVED 257
+
+/* maximum length of a reserved word */
+#define TOKEN_LEN (sizeof("function")/sizeof(char))
+
+
+/*
+* WARNING: if you change the order of this enumeration,
+* grep "ORDER RESERVED"
+*/
+enum RESERVED {
+ /* terminal symbols denoted by reserved words */
+ TK_AND = FIRST_RESERVED, TK_BREAK,
+ TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
+ TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
+ TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
+ /* other terminal symbols */
+ TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
+ TK_STRING, TK_EOS
+};
+
+/* number of reserved words */
+#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
+
+
+typedef union {
+ lua_Number r;
+ TString *ts;
+} SemInfo; /* semantics information */
+
+
+typedef struct Token {
+ int token;
+ SemInfo seminfo;
+} Token;
+
+
+typedef struct LexState {
+ int current; /* current character (charint) */
+ int linenumber; /* input line counter */
+ int lastline; /* line of last token `consumed' */
+ Token t; /* current token */
+ Token lookahead; /* look ahead token */
+ struct FuncState *fs; /* `FuncState' is private to the parser */
+ struct lua_State *L;
+ ZIO *z; /* input stream */
+ Mbuffer *buff; /* buffer for tokens */
+ TString *source; /* current source name */
+ int nestlevel; /* level of nested non-terminals */
+} LexState;
+
+
+void luaX_init (lua_State *L);
+void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source);
+int luaX_lex (LexState *LS, SemInfo *seminfo);
+void luaX_checklimit (LexState *ls, int val, int limit, const char *msg);
+void luaX_syntaxerror (LexState *ls, const char *s);
+void luaX_errorline (LexState *ls, const char *s, const char *token, int line);
+const char *luaX_token2str (LexState *ls, int token);
+
+
+#endif
diff --git a/lib/lua/includes/llimits.h b/lib/lua/includes/llimits.h
index 0b4a084..e5f18a9 100644
--- a/lib/lua/includes/llimits.h
+++ b/lib/lua/includes/llimits.h
@@ -1,185 +1,185 @@
-/*
-** $Id: llimits.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Limits, basic types, and some other `installation-dependent' definitions
-** See Copyright Notice in lua.h
-*/
-
-#ifndef llimits_h
-#define llimits_h
-
-
-#include <limits.h>
-#include <stddef.h>
-
-
-#include "lua.h"
-
-
-/*
-** try to find number of bits in an integer
-*/
-#ifndef BITS_INT
-/* avoid overflows in comparison */
-#if INT_MAX-20 < 32760
-#define BITS_INT 16
-#else
-#if INT_MAX > 2147483640L
-/* machine has at least 32 bits */
-#define BITS_INT 32
-#else
-#error "you must define BITS_INT with number of bits in an integer"
-#endif
-#endif
-#endif
-
-
-/*
-** the following types define integer types for values that may not
-** fit in a `small int' (16 bits), but may waste space in a
-** `large long' (64 bits). The current definitions should work in
-** any machine, but may not be optimal.
-*/
-
-/* an unsigned integer to hold hash values */
-typedef unsigned int lu_hash;
-/* its signed equivalent */
-typedef int ls_hash;
-
-/* an unsigned integer big enough to count the total memory used by Lua; */
-/* it should be at least as large as size_t */
-typedef unsigned long lu_mem;
-
-#define MAX_LUMEM ULONG_MAX
-
-
-/* an integer big enough to count the number of strings in use */
-typedef long ls_nstr;
-
-/* chars used as small naturals (so that `char' is reserved for characters) */
-typedef unsigned char lu_byte;
-
-
-#define MAX_SIZET ((size_t)(~(size_t)0)-2)
-
-
-#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
-
-/*
-** conversion of pointer to integer
-** this is for hashing only; there is no problem if the integer
-** cannot hold the whole pointer value
-*/
-#define IntPoint(p) ((lu_hash)(p))
-
-
-
-/* type to ensure maximum alignment */
-#ifndef LUSER_ALIGNMENT_T
-typedef union { double u; void *s; long l; } L_Umaxalign;
-#else
-typedef LUSER_ALIGNMENT_T L_Umaxalign;
-#endif
-
-
-/* result of `usual argument conversion' over lua_Number */
-#ifndef LUA_UACNUMBER
-typedef double l_uacNumber;
-#else
-typedef LUA_UACNUMBER l_uacNumber;
-#endif
-
-
-#ifndef lua_assert
-#define lua_assert(c) /* empty */
-#endif
-
-
-#ifndef check_exp
-#define check_exp(c,e) (e)
-#endif
-
-
-#ifndef UNUSED
-#define UNUSED(x) ((void)(x)) /* to avoid warnings */
-#endif
-
-
-#ifndef cast
-#define cast(t, exp) ((t)(exp))
-#endif
-
-
-
-/*
-** type for virtual-machine instructions
-** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
-*/
-typedef unsigned long Instruction;
-
-
-/* maximum depth for calls (unsigned short) */
-#ifndef LUA_MAXCALLS
-#define LUA_MAXCALLS 4096
-#endif
-
-
-/*
-** maximum depth for C calls (unsigned short): Not too big, or may
-** overflow the C stack...
-*/
-
-#ifndef LUA_MAXCCALLS
-#define LUA_MAXCCALLS 200
-#endif
-
-
-/* maximum size for the C stack */
-#ifndef LUA_MAXCSTACK
-#define LUA_MAXCSTACK 2048
-#endif
-
-
-/* maximum stack for a Lua function */
-#define MAXSTACK 250
-
-
-/* maximum number of variables declared in a function */
-#ifndef MAXVARS
-#define MAXVARS 200 /* arbitrary limit (<MAXSTACK) */
-#endif
-
-
-/* maximum number of upvalues per function */
-#ifndef MAXUPVALUES
-#define MAXUPVALUES 32
-#endif
-
-
-/* maximum number of parameters in a function */
-#ifndef MAXPARAMS
-#define MAXPARAMS 100 /* arbitrary limit (<MAXLOCALS) */
-#endif
-
-
-/* minimum size for the string table (must be power of 2) */
-#ifndef MINSTRTABSIZE
-#define MINSTRTABSIZE 32
-#endif
-
-
-/* minimum size for string buffer */
-#ifndef LUA_MINBUFFER
-#define LUA_MINBUFFER 32
-#endif
-
-
-/*
-** maximum number of syntactical nested non-terminals: Not too big,
-** or may overflow the C stack...
-*/
-#ifndef LUA_MAXPARSERLEVEL
-#define LUA_MAXPARSERLEVEL 200
-#endif
-
-
-#endif
+/*
+** $Id: llimits.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Limits, basic types, and some other `installation-dependent' definitions
+** See Copyright Notice in lua.h
+*/
+
+#ifndef llimits_h
+#define llimits_h
+
+
+#include <limits.h>
+#include <stddef.h>
+
+
+#include "lua.h"
+
+
+/*
+** try to find number of bits in an integer
+*/
+#ifndef BITS_INT
+/* avoid overflows in comparison */
+#if INT_MAX-20 < 32760
+#define BITS_INT 16
+#else
+#if INT_MAX > 2147483640L
+/* machine has at least 32 bits */
+#define BITS_INT 32
+#else
+#error "you must define BITS_INT with number of bits in an integer"
+#endif
+#endif
+#endif
+
+
+/*
+** the following types define integer types for values that may not
+** fit in a `small int' (16 bits), but may waste space in a
+** `large long' (64 bits). The current definitions should work in
+** any machine, but may not be optimal.
+*/
+
+/* an unsigned integer to hold hash values */
+typedef unsigned int lu_hash;
+/* its signed equivalent */
+typedef int ls_hash;
+
+/* an unsigned integer big enough to count the total memory used by Lua; */
+/* it should be at least as large as size_t */
+typedef unsigned long lu_mem;
+
+#define MAX_LUMEM ULONG_MAX
+
+
+/* an integer big enough to count the number of strings in use */
+typedef long ls_nstr;
+
+/* chars used as small naturals (so that `char' is reserved for characters) */
+typedef unsigned char lu_byte;
+
+
+#define MAX_SIZET ((size_t)(~(size_t)0)-2)
+
+
+#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
+
+/*
+** conversion of pointer to integer
+** this is for hashing only; there is no problem if the integer
+** cannot hold the whole pointer value
+*/
+#define IntPoint(p) ((lu_hash)(p))
+
+
+
+/* type to ensure maximum alignment */
+#ifndef LUSER_ALIGNMENT_T
+typedef union { double u; void *s; long l; } L_Umaxalign;
+#else
+typedef LUSER_ALIGNMENT_T L_Umaxalign;
+#endif
+
+
+/* result of `usual argument conversion' over lua_Number */
+#ifndef LUA_UACNUMBER
+typedef double l_uacNumber;
+#else
+typedef LUA_UACNUMBER l_uacNumber;
+#endif
+
+
+#ifndef lua_assert
+#define lua_assert(c) /* empty */
+#endif
+
+
+#ifndef check_exp
+#define check_exp(c,e) (e)
+#endif
+
+
+#ifndef UNUSED
+#define UNUSED(x) ((void)(x)) /* to avoid warnings */
+#endif
+
+
+#ifndef cast
+#define cast(t, exp) ((t)(exp))
+#endif
+
+
+
+/*
+** type for virtual-machine instructions
+** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
+*/
+typedef unsigned long Instruction;
+
+
+/* maximum depth for calls (unsigned short) */
+#ifndef LUA_MAXCALLS
+#define LUA_MAXCALLS 4096
+#endif
+
+
+/*
+** maximum depth for C calls (unsigned short): Not too big, or may
+** overflow the C stack...
+*/
+
+#ifndef LUA_MAXCCALLS
+#define LUA_MAXCCALLS 200
+#endif
+
+
+/* maximum size for the C stack */
+#ifndef LUA_MAXCSTACK
+#define LUA_MAXCSTACK 2048
+#endif
+
+
+/* maximum stack for a Lua function */
+#define MAXSTACK 250
+
+
+/* maximum number of variables declared in a function */
+#ifndef MAXVARS
+#define MAXVARS 200 /* arbitrary limit (<MAXSTACK) */
+#endif
+
+
+/* maximum number of upvalues per function */
+#ifndef MAXUPVALUES
+#define MAXUPVALUES 32
+#endif
+
+
+/* maximum number of parameters in a function */
+#ifndef MAXPARAMS
+#define MAXPARAMS 100 /* arbitrary limit (<MAXLOCALS) */
+#endif
+
+
+/* minimum size for the string table (must be power of 2) */
+#ifndef MINSTRTABSIZE
+#define MINSTRTABSIZE 32
+#endif
+
+
+/* minimum size for string buffer */
+#ifndef LUA_MINBUFFER
+#define LUA_MINBUFFER 32
+#endif
+
+
+/*
+** maximum number of syntactical nested non-terminals: Not too big,
+** or may overflow the C stack...
+*/
+#ifndef LUA_MAXPARSERLEVEL
+#define LUA_MAXPARSERLEVEL 200
+#endif
+
+
+#endif
diff --git a/lib/lua/includes/lmem.h b/lib/lua/includes/lmem.h
index 3211713..20bc584 100644
--- a/lib/lua/includes/lmem.h
+++ b/lib/lua/includes/lmem.h
@@ -1,44 +1,44 @@
-/*
-** $Id: lmem.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Interface to Memory Manager
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lmem_h
-#define lmem_h
-
-
-#include <stddef.h>
-
-#include "llimits.h"
-#include "lua.h"
-
-#define MEMERRMSG "not enough memory"
-
-
-void *luaM_realloc (lua_State *L, void *oldblock, lu_mem oldsize, lu_mem size);
-
-void *luaM_growaux (lua_State *L, void *block, int *size, int size_elem,
- int limit, const char *errormsg);
-
-#define luaM_free(L, b, s) luaM_realloc(L, (b), (s), 0)
-#define luaM_freelem(L, b) luaM_realloc(L, (b), sizeof(*(b)), 0)
-#define luaM_freearray(L, b, n, t) luaM_realloc(L, (b), \
- cast(lu_mem, n)*cast(lu_mem, sizeof(t)), 0)
-
-#define luaM_malloc(L, t) luaM_realloc(L, NULL, 0, (t))
-#define luaM_new(L, t) cast(t *, luaM_malloc(L, sizeof(t)))
-#define luaM_newvector(L, n,t) cast(t *, luaM_malloc(L, \
- cast(lu_mem, n)*cast(lu_mem, sizeof(t))))
-
-#define luaM_growvector(L,v,nelems,size,t,limit,e) \
- if (((nelems)+1) > (size)) \
- ((v)=cast(t *, luaM_growaux(L,v,&(size),sizeof(t),limit,e)))
-
-#define luaM_reallocvector(L, v,oldn,n,t) \
- ((v)=cast(t *, luaM_realloc(L, v,cast(lu_mem, oldn)*cast(lu_mem, sizeof(t)), \
- cast(lu_mem, n)*cast(lu_mem, sizeof(t)))))
-
-
-#endif
-
+/*
+** $Id: lmem.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Interface to Memory Manager
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lmem_h
+#define lmem_h
+
+
+#include <stddef.h>
+
+#include "llimits.h"
+#include "lua.h"
+
+#define MEMERRMSG "not enough memory"
+
+
+void *luaM_realloc (lua_State *L, void *oldblock, lu_mem oldsize, lu_mem size);
+
+void *luaM_growaux (lua_State *L, void *block, int *size, int size_elem,
+ int limit, const char *errormsg);
+
+#define luaM_free(L, b, s) luaM_realloc(L, (b), (s), 0)
+#define luaM_freelem(L, b) luaM_realloc(L, (b), sizeof(*(b)), 0)
+#define luaM_freearray(L, b, n, t) luaM_realloc(L, (b), \
+ cast(lu_mem, n)*cast(lu_mem, sizeof(t)), 0)
+
+#define luaM_malloc(L, t) luaM_realloc(L, NULL, 0, (t))
+#define luaM_new(L, t) cast(t *, luaM_malloc(L, sizeof(t)))
+#define luaM_newvector(L, n,t) cast(t *, luaM_malloc(L, \
+ cast(lu_mem, n)*cast(lu_mem, sizeof(t))))
+
+#define luaM_growvector(L,v,nelems,size,t,limit,e) \
+ if (((nelems)+1) > (size)) \
+ ((v)=cast(t *, luaM_growaux(L,v,&(size),sizeof(t),limit,e)))
+
+#define luaM_reallocvector(L, v,oldn,n,t) \
+ ((v)=cast(t *, luaM_realloc(L, v,cast(lu_mem, oldn)*cast(lu_mem, sizeof(t)), \
+ cast(lu_mem, n)*cast(lu_mem, sizeof(t)))))
+
+
+#endif
+
diff --git a/lib/lua/includes/lobject.h b/lib/lua/includes/lobject.h
index 02f3d80..5bd6917 100644
--- a/lib/lua/includes/lobject.h
+++ b/lib/lua/includes/lobject.h
@@ -1,336 +1,336 @@
-/*
-** $Id: lobject.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Type definitions for Lua objects
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lobject_h
-#define lobject_h
-
-
-#include "llimits.h"
-#include "lua.h"
-
-
-/* tags for values visible from Lua */
-#define NUM_TAGS LUA_TTHREAD
-
-
-/*
-** Extra tags for non-values
-*/
-#define LUA_TPROTO (NUM_TAGS+1)
-#define LUA_TUPVAL (NUM_TAGS+2)
-
-
-/*
-** Union of all collectable objects
-*/
-typedef union GCObject GCObject;
-
-
-/*
-** Common Header for all collectable objects (in macro form, to be
-** included in other objects)
-*/
-#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
-
-
-/*
-** Common header in struct form
-*/
-typedef struct GCheader {
- CommonHeader;
-} GCheader;
-
-
-
-
-/*
-** Union of all Lua values
-*/
-typedef union {
- GCObject *gc;
- void *p;
- lua_Number n;
- int b;
-} Value;
-
-
-/*
-** Lua values (or `tagged objects')
-*/
-typedef struct lua_TObject {
- int tt;
- Value value;
-} TObject;
-
-
-/* Macros to test type */
-#define ttisnil(o) (ttype(o) == LUA_TNIL)
-#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
-#define ttisstring(o) (ttype(o) == LUA_TSTRING)
-#define ttistable(o) (ttype(o) == LUA_TTABLE)
-#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
-#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
-#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
-#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
-#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
-
-/* Macros to access values */
-#define ttype(o) ((o)->tt)
-#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
-#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
-#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
-#define tsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
-#define uvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
-#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
-#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
-#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
-#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
-
-#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
-
-/* Macros to set values */
-#define setnvalue(obj,x) \
- { TObject *i_o=(obj); i_o->tt=LUA_TNUMBER; i_o->value.n=(x); }
-
-#define chgnvalue(obj,x) \
- check_exp(ttype(obj)==LUA_TNUMBER, (obj)->value.n=(x))
-
-#define setpvalue(obj,x) \
- { TObject *i_o=(obj); i_o->tt=LUA_TLIGHTUSERDATA; i_o->value.p=(x); }
-
-#define setbvalue(obj,x) \
- { TObject *i_o=(obj); i_o->tt=LUA_TBOOLEAN; i_o->value.b=(x); }
-
-#define setsvalue(obj,x) \
- { TObject *i_o=(obj); i_o->tt=LUA_TSTRING; \
- i_o->value.gc=cast(GCObject *, (x)); \
- lua_assert(i_o->value.gc->gch.tt == LUA_TSTRING); }
-
-#define setuvalue(obj,x) \
- { TObject *i_o=(obj); i_o->tt=LUA_TUSERDATA; \
- i_o->value.gc=cast(GCObject *, (x)); \
- lua_assert(i_o->value.gc->gch.tt == LUA_TUSERDATA); }
-
-#define setthvalue(obj,x) \
- { TObject *i_o=(obj); i_o->tt=LUA_TTHREAD; \
- i_o->value.gc=cast(GCObject *, (x)); \
- lua_assert(i_o->value.gc->gch.tt == LUA_TTHREAD); }
-
-#define setclvalue(obj,x) \
- { TObject *i_o=(obj); i_o->tt=LUA_TFUNCTION; \
- i_o->value.gc=cast(GCObject *, (x)); \
- lua_assert(i_o->value.gc->gch.tt == LUA_TFUNCTION); }
-
-#define sethvalue(obj,x) \
- { TObject *i_o=(obj); i_o->tt=LUA_TTABLE; \
- i_o->value.gc=cast(GCObject *, (x)); \
- lua_assert(i_o->value.gc->gch.tt == LUA_TTABLE); }
-
-#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
-
-
-
-/*
-** for internal debug only
-*/
-#define checkconsistency(obj) \
- lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
-
-
-#define setobj(obj1,obj2) \
- { const TObject *o2=(obj2); TObject *o1=(obj1); \
- checkconsistency(o2); \
- o1->tt=o2->tt; o1->value = o2->value; }
-
-
-/*
-** different types of sets, according to destination
-*/
-
-/* from stack to (same) stack */
-#define setobjs2s setobj
-/* to stack (not from same stack) */
-#define setobj2s setobj
-#define setsvalue2s setsvalue
-/* from table to same table */
-#define setobjt2t setobj
-/* to table */
-#define setobj2t setobj
-/* to new object */
-#define setobj2n setobj
-#define setsvalue2n setsvalue
-
-#define setttype(obj, tt) (ttype(obj) = (tt))
-
-
-#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
-
-
-
-typedef TObject *StkId; /* index to stack elements */
-
-
-/*
-** String headers for string table
-*/
-typedef union TString {
- L_Umaxalign dummy; /* ensures maximum alignment for strings */
- struct {
- CommonHeader;
- lu_byte reserved;
- lu_hash hash;
- size_t len;
- } tsv;
-} TString;
-
-
-#define getstr(ts) cast(const char *, (ts) + 1)
-#define svalue(o) getstr(tsvalue(o))
-
-
-
-typedef union Udata {
- L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
- struct {
- CommonHeader;
- struct Table *metatable;
- size_t len;
- } uv;
-} Udata;
-
-
-
-
-/*
-** Function Prototypes
-*/
-typedef struct Proto {
- CommonHeader;
- TObject *k; /* constants used by the function */
- Instruction *code;
- struct Proto **p; /* functions defined inside the function */
- int *lineinfo; /* map from opcodes to source lines */
- struct LocVar *locvars; /* information about local variables */
- TString **upvalues; /* upvalue names */
- TString *source;
- int sizeupvalues;
- int sizek; /* size of `k' */
- int sizecode;
- int sizelineinfo;
- int sizep; /* size of `p' */
- int sizelocvars;
- int lineDefined;
- GCObject *gclist;
- lu_byte nups; /* number of upvalues */
- lu_byte numparams;
- lu_byte is_vararg;
- lu_byte maxstacksize;
-} Proto;
-
-
-typedef struct LocVar {
- TString *varname;
- int startpc; /* first point where variable is active */
- int endpc; /* first point where variable is dead */
-} LocVar;
-
-
-
-/*
-** Upvalues
-*/
-
-typedef struct UpVal {
- CommonHeader;
- TObject *v; /* points to stack or to its own value */
- TObject value; /* the value (when closed) */
-} UpVal;
-
-
-/*
-** Closures
-*/
-
-#define ClosureHeader \
- CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist
-
-typedef struct CClosure {
- ClosureHeader;
- lua_CFunction f;
- TObject upvalue[1];
-} CClosure;
-
-
-typedef struct LClosure {
- ClosureHeader;
- struct Proto *p;
- TObject g; /* global table for this closure */
- UpVal *upvals[1];
-} LClosure;
-
-
-typedef union Closure {
- CClosure c;
- LClosure l;
-} Closure;
-
-
-#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
-#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
-
-
-/*
-** Tables
-*/
-
-typedef struct Node {
- TObject i_key;
- TObject i_val;
- struct Node *next; /* for chaining */
-} Node;
-
-
-typedef struct Table {
- CommonHeader;
- lu_byte flags; /* 1<<p means tagmethod(p) is not present */
- lu_byte lsizenode; /* log2 of size of `node' array */
- struct Table *metatable;
- TObject *array; /* array part */
- Node *node;
- Node *firstfree; /* this position is free; all positions after it are full */
- GCObject *gclist;
- int sizearray; /* size of `array' array */
-} Table;
-
-
-
-/*
-** `module' operation for hashing (size is always a power of 2)
-*/
-#define lmod(s,size) \
- check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1))))
-
-
-#define twoto(x) (1<<(x))
-#define sizenode(t) (twoto((t)->lsizenode))
-
-
-
-extern const TObject luaO_nilobject;
-
-int luaO_log2 (unsigned int x);
-int luaO_int2fb (unsigned int x);
-#define fb2int(x) (((x) & 7) << ((x) >> 3))
-
-int luaO_rawequalObj (const TObject *t1, const TObject *t2);
-int luaO_str2d (const char *s, lua_Number *result);
-
-const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp);
-const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
-void luaO_chunkid (char *out, const char *source, int len);
-
-
-#endif
+/*
+** $Id: lobject.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Type definitions for Lua objects
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lobject_h
+#define lobject_h
+
+
+#include "llimits.h"
+#include "lua.h"
+
+
+/* tags for values visible from Lua */
+#define NUM_TAGS LUA_TTHREAD
+
+
+/*
+** Extra tags for non-values
+*/
+#define LUA_TPROTO (NUM_TAGS+1)
+#define LUA_TUPVAL (NUM_TAGS+2)
+
+
+/*
+** Union of all collectable objects
+*/
+typedef union GCObject GCObject;
+
+
+/*
+** Common Header for all collectable objects (in macro form, to be
+** included in other objects)
+*/
+#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
+
+
+/*
+** Common header in struct form
+*/
+typedef struct GCheader {
+ CommonHeader;
+} GCheader;
+
+
+
+
+/*
+** Union of all Lua values
+*/
+typedef union {
+ GCObject *gc;
+ void *p;
+ lua_Number n;
+ int b;
+} Value;
+
+
+/*
+** Lua values (or `tagged objects')
+*/
+typedef struct lua_TObject {
+ int tt;
+ Value value;
+} TObject;
+
+
+/* Macros to test type */
+#define ttisnil(o) (ttype(o) == LUA_TNIL)
+#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
+#define ttisstring(o) (ttype(o) == LUA_TSTRING)
+#define ttistable(o) (ttype(o) == LUA_TTABLE)
+#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
+#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
+#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
+#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
+#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
+
+/* Macros to access values */
+#define ttype(o) ((o)->tt)
+#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
+#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
+#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
+#define tsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
+#define uvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
+#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
+#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
+#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
+#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
+
+#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
+
+/* Macros to set values */
+#define setnvalue(obj,x) \
+ { TObject *i_o=(obj); i_o->tt=LUA_TNUMBER; i_o->value.n=(x); }
+
+#define chgnvalue(obj,x) \
+ check_exp(ttype(obj)==LUA_TNUMBER, (obj)->value.n=(x))
+
+#define setpvalue(obj,x) \
+ { TObject *i_o=(obj); i_o->tt=LUA_TLIGHTUSERDATA; i_o->value.p=(x); }
+
+#define setbvalue(obj,x) \
+ { TObject *i_o=(obj); i_o->tt=LUA_TBOOLEAN; i_o->value.b=(x); }
+
+#define setsvalue(obj,x) \
+ { TObject *i_o=(obj); i_o->tt=LUA_TSTRING; \
+ i_o->value.gc=cast(GCObject *, (x)); \
+ lua_assert(i_o->value.gc->gch.tt == LUA_TSTRING); }
+
+#define setuvalue(obj,x) \
+ { TObject *i_o=(obj); i_o->tt=LUA_TUSERDATA; \
+ i_o->value.gc=cast(GCObject *, (x)); \
+ lua_assert(i_o->value.gc->gch.tt == LUA_TUSERDATA); }
+
+#define setthvalue(obj,x) \
+ { TObject *i_o=(obj); i_o->tt=LUA_TTHREAD; \
+ i_o->value.gc=cast(GCObject *, (x)); \
+ lua_assert(i_o->value.gc->gch.tt == LUA_TTHREAD); }
+
+#define setclvalue(obj,x) \
+ { TObject *i_o=(obj); i_o->tt=LUA_TFUNCTION; \
+ i_o->value.gc=cast(GCObject *, (x)); \
+ lua_assert(i_o->value.gc->gch.tt == LUA_TFUNCTION); }
+
+#define sethvalue(obj,x) \
+ { TObject *i_o=(obj); i_o->tt=LUA_TTABLE; \
+ i_o->value.gc=cast(GCObject *, (x)); \
+ lua_assert(i_o->value.gc->gch.tt == LUA_TTABLE); }
+
+#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
+
+
+
+/*
+** for internal debug only
+*/
+#define checkconsistency(obj) \
+ lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
+
+
+#define setobj(obj1,obj2) \
+ { const TObject *o2=(obj2); TObject *o1=(obj1); \
+ checkconsistency(o2); \
+ o1->tt=o2->tt; o1->value = o2->value; }
+
+
+/*
+** different types of sets, according to destination
+*/
+
+/* from stack to (same) stack */
+#define setobjs2s setobj
+/* to stack (not from same stack) */
+#define setobj2s setobj
+#define setsvalue2s setsvalue
+/* from table to same table */
+#define setobjt2t setobj
+/* to table */
+#define setobj2t setobj
+/* to new object */
+#define setobj2n setobj
+#define setsvalue2n setsvalue
+
+#define setttype(obj, tt) (ttype(obj) = (tt))
+
+
+#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
+
+
+
+typedef TObject *StkId; /* index to stack elements */
+
+
+/*
+** String headers for string table
+*/
+typedef union TString {
+ L_Umaxalign dummy; /* ensures maximum alignment for strings */
+ struct {
+ CommonHeader;
+ lu_byte reserved;
+ lu_hash hash;
+ size_t len;
+ } tsv;
+} TString;
+
+
+#define getstr(ts) cast(const char *, (ts) + 1)
+#define svalue(o) getstr(tsvalue(o))
+
+
+
+typedef union Udata {
+ L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
+ struct {
+ CommonHeader;
+ struct Table *metatable;
+ size_t len;
+ } uv;
+} Udata;
+
+
+
+
+/*
+** Function Prototypes
+*/
+typedef struct Proto {
+ CommonHeader;
+ TObject *k; /* constants used by the function */
+ Instruction *code;
+ struct Proto **p; /* functions defined inside the function */
+ int *lineinfo; /* map from opcodes to source lines */
+ struct LocVar *locvars; /* information about local variables */
+ TString **upvalues; /* upvalue names */
+ TString *source;
+ int sizeupvalues;
+ int sizek; /* size of `k' */
+ int sizecode;
+ int sizelineinfo;
+ int sizep; /* size of `p' */
+ int sizelocvars;
+ int lineDefined;
+ GCObject *gclist;
+ lu_byte nups; /* number of upvalues */
+ lu_byte numparams;
+ lu_byte is_vararg;
+ lu_byte maxstacksize;
+} Proto;
+
+
+typedef struct LocVar {
+ TString *varname;
+ int startpc; /* first point where variable is active */
+ int endpc; /* first point where variable is dead */
+} LocVar;
+
+
+
+/*
+** Upvalues
+*/
+
+typedef struct UpVal {
+ CommonHeader;
+ TObject *v; /* points to stack or to its own value */
+ TObject value; /* the value (when closed) */
+} UpVal;
+
+
+/*
+** Closures
+*/
+
+#define ClosureHeader \
+ CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist
+
+typedef struct CClosure {
+ ClosureHeader;
+ lua_CFunction f;
+ TObject upvalue[1];
+} CClosure;
+
+
+typedef struct LClosure {
+ ClosureHeader;
+ struct Proto *p;
+ TObject g; /* global table for this closure */
+ UpVal *upvals[1];
+} LClosure;
+
+
+typedef union Closure {
+ CClosure c;
+ LClosure l;
+} Closure;
+
+
+#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
+#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
+
+
+/*
+** Tables
+*/
+
+typedef struct Node {
+ TObject i_key;
+ TObject i_val;
+ struct Node *next; /* for chaining */
+} Node;
+
+
+typedef struct Table {
+ CommonHeader;
+ lu_byte flags; /* 1<<p means tagmethod(p) is not present */
+ lu_byte lsizenode; /* log2 of size of `node' array */
+ struct Table *metatable;
+ TObject *array; /* array part */
+ Node *node;
+ Node *firstfree; /* this position is free; all positions after it are full */
+ GCObject *gclist;
+ int sizearray; /* size of `array' array */
+} Table;
+
+
+
+/*
+** `module' operation for hashing (size is always a power of 2)
+*/
+#define lmod(s,size) \
+ check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1))))
+
+
+#define twoto(x) (1<<(x))
+#define sizenode(t) (twoto((t)->lsizenode))
+
+
+
+extern const TObject luaO_nilobject;
+
+int luaO_log2 (unsigned int x);
+int luaO_int2fb (unsigned int x);
+#define fb2int(x) (((x) & 7) << ((x) >> 3))
+
+int luaO_rawequalObj (const TObject *t1, const TObject *t2);
+int luaO_str2d (const char *s, lua_Number *result);
+
+const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp);
+const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
+void luaO_chunkid (char *out, const char *source, int len);
+
+
+#endif
diff --git a/lib/lua/includes/lopcodes.h b/lib/lua/includes/lopcodes.h
index 0418593..c3da5b2 100644
--- a/lib/lua/includes/lopcodes.h
+++ b/lib/lua/includes/lopcodes.h
@@ -1,238 +1,238 @@
-/*
-** $Id: lopcodes.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Opcodes for Lua virtual machine
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lopcodes_h
-#define lopcodes_h
-
-#include "llimits.h"
-
-
-/*===========================================================================
- We assume that instructions are unsigned numbers.
- All instructions have an opcode in the first 6 bits.
- Instructions can have the following fields:
- `A' : 8 bits
- `B' : 9 bits
- `C' : 9 bits
- `Bx' : 18 bits (`B' and `C' together)
- `sBx' : signed Bx
-
- A signed argument is represented in excess K; that is, the number
- value is the unsigned value minus K. K is exactly the maximum value
- for that argument (so that -max is represented by 0, and +max is
- represented by 2*max), which is half the maximum for the corresponding
- unsigned argument.
-===========================================================================*/
-
-
-enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
-
-
-/*
-** size and position of opcode arguments.
-*/
-#define SIZE_C 9
-#define SIZE_B 9
-#define SIZE_Bx (SIZE_C + SIZE_B)
-#define SIZE_A 8
-
-#define SIZE_OP 6
-
-#define POS_C SIZE_OP
-#define POS_B (POS_C + SIZE_C)
-#define POS_Bx POS_C
-#define POS_A (POS_B + SIZE_B)
-
-
-/*
-** limits for opcode arguments.
-** we use (signed) int to manipulate most arguments,
-** so they must fit in BITS_INT-1 bits (-1 for sign)
-*/
-#if SIZE_Bx < BITS_INT-1
-#define MAXARG_Bx ((1<<SIZE_Bx)-1)
-#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
-#else
-#define MAXARG_Bx MAX_INT
-#define MAXARG_sBx MAX_INT
-#endif
-
-
-#define MAXARG_A ((1<<SIZE_A)-1)
-#define MAXARG_B ((1<<SIZE_B)-1)
-#define MAXARG_C ((1<<SIZE_C)-1)
-
-
-/* creates a mask with `n' 1 bits at position `p' */
-#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p)
-
-/* creates a mask with `n' 0 bits at position `p' */
-#define MASK0(n,p) (~MASK1(n,p))
-
-/*
-** the following macros help to manipulate instructions
-*/
-
-#define GET_OPCODE(i) (cast(OpCode, (i)&MASK1(SIZE_OP,0)))
-#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | cast(Instruction, o)))
-
-#define GETARG_A(i) (cast(int, (i)>>POS_A))
-#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
- ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
-
-#define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
-#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
- ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
-
-#define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
-#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
- ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
-
-#define GETARG_Bx(i) (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
-#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
- ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
-
-#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
-#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
-
-
-#define CREATE_ABC(o,a,b,c) (cast(Instruction, o) \
- | (cast(Instruction, a)<<POS_A) \
- | (cast(Instruction, b)<<POS_B) \
- | (cast(Instruction, c)<<POS_C))
-
-#define CREATE_ABx(o,a,bc) (cast(Instruction, o) \
- | (cast(Instruction, a)<<POS_A) \
- | (cast(Instruction, bc)<<POS_Bx))
-
-
-
-
-/*
-** invalid register that fits in 8 bits
-*/
-#define NO_REG MAXARG_A
-
-
-/*
-** R(x) - register
-** Kst(x) - constant (in constant table)
-** RK(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK)
-*/
-
-
-/*
-** grep "ORDER OP" if you change these enums
-*/
-
-typedef enum {
-/*----------------------------------------------------------------------
-name args description
-------------------------------------------------------------------------*/
-OP_MOVE,/* A B R(A) := R(B) */
-OP_LOADK,/* A Bx R(A) := Kst(Bx) */
-OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) PC++ */
-OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
-OP_GETUPVAL,/* A B R(A) := UpValue[B] */
-
-OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
-OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
-
-OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
-OP_SETUPVAL,/* A B UpValue[B] := R(A) */
-OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
-
-OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
-
-OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
-
-OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
-OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
-OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
-OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
-OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
-OP_UNM,/* A B R(A) := -R(B) */
-OP_NOT,/* A B R(A) := not R(B) */
-
-OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
-
-OP_JMP,/* sBx PC += sBx */
-
-OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
-OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
-OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
-
-OP_TEST,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
-
-OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
-OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
-OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
-
-OP_FORLOOP,/* A sBx R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBx */
-
-OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
- if R(A+2) ~= nil then pc++ */
-OP_TFORPREP,/* A sBx if type(R(A)) == table then R(A+1):=R(A), R(A):=next;
- PC += sBx */
-
-OP_SETLIST,/* A Bx R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1 */
-OP_SETLISTO,/* A Bx */
-
-OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
-OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
-} OpCode;
-
-
-#define NUM_OPCODES (cast(int, OP_CLOSURE+1))
-
-
-
-/*===========================================================================
- Notes:
- (1) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
- and can be 0: OP_CALL then sets `top' to last_result+1, so
- next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
-
- (2) In OP_RETURN, if (B == 0) then return up to `top'
-
- (3) For comparisons, B specifies what conditions the test should accept.
-
- (4) All `skips' (pc++) assume that next instruction is a jump
-===========================================================================*/
-
-
-/*
-** masks for instruction properties
-*/
-enum OpModeMask {
- OpModeBreg = 2, /* B is a register */
- OpModeBrk, /* B is a register/constant */
- OpModeCrk, /* C is a register/constant */
- OpModesetA, /* instruction set register A */
- OpModeK, /* Bx is a constant */
- OpModeT /* operator is a test */
-
-};
-
-
-extern const lu_byte luaP_opmodes[NUM_OPCODES];
-
-#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
-#define testOpMode(m, b) (luaP_opmodes[m] & (1 << (b)))
-
-
-#ifdef LUA_OPNAMES
-extern const char *const luaP_opnames[]; /* opcode names */
-#endif
-
-
-
-/* number of list items to accumulate before a SETLIST instruction */
-/* (must be a power of 2) */
-#define LFIELDS_PER_FLUSH 32
-
-
-#endif
+/*
+** $Id: lopcodes.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Opcodes for Lua virtual machine
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lopcodes_h
+#define lopcodes_h
+
+#include "llimits.h"
+
+
+/*===========================================================================
+ We assume that instructions are unsigned numbers.
+ All instructions have an opcode in the first 6 bits.
+ Instructions can have the following fields:
+ `A' : 8 bits
+ `B' : 9 bits
+ `C' : 9 bits
+ `Bx' : 18 bits (`B' and `C' together)
+ `sBx' : signed Bx
+
+ A signed argument is represented in excess K; that is, the number
+ value is the unsigned value minus K. K is exactly the maximum value
+ for that argument (so that -max is represented by 0, and +max is
+ represented by 2*max), which is half the maximum for the corresponding
+ unsigned argument.
+===========================================================================*/
+
+
+enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
+
+
+/*
+** size and position of opcode arguments.
+*/
+#define SIZE_C 9
+#define SIZE_B 9
+#define SIZE_Bx (SIZE_C + SIZE_B)
+#define SIZE_A 8
+
+#define SIZE_OP 6
+
+#define POS_C SIZE_OP
+#define POS_B (POS_C + SIZE_C)
+#define POS_Bx POS_C
+#define POS_A (POS_B + SIZE_B)
+
+
+/*
+** limits for opcode arguments.
+** we use (signed) int to manipulate most arguments,
+** so they must fit in BITS_INT-1 bits (-1 for sign)
+*/
+#if SIZE_Bx < BITS_INT-1
+#define MAXARG_Bx ((1<<SIZE_Bx)-1)
+#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
+#else
+#define MAXARG_Bx MAX_INT
+#define MAXARG_sBx MAX_INT
+#endif
+
+
+#define MAXARG_A ((1<<SIZE_A)-1)
+#define MAXARG_B ((1<<SIZE_B)-1)
+#define MAXARG_C ((1<<SIZE_C)-1)
+
+
+/* creates a mask with `n' 1 bits at position `p' */
+#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p)
+
+/* creates a mask with `n' 0 bits at position `p' */
+#define MASK0(n,p) (~MASK1(n,p))
+
+/*
+** the following macros help to manipulate instructions
+*/
+
+#define GET_OPCODE(i) (cast(OpCode, (i)&MASK1(SIZE_OP,0)))
+#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,0)) | cast(Instruction, o)))
+
+#define GETARG_A(i) (cast(int, (i)>>POS_A))
+#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
+ ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
+
+#define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
+#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
+ ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
+
+#define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
+#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
+ ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
+
+#define GETARG_Bx(i) (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
+#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
+ ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
+
+#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
+#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
+
+
+#define CREATE_ABC(o,a,b,c) (cast(Instruction, o) \
+ | (cast(Instruction, a)<<POS_A) \
+ | (cast(Instruction, b)<<POS_B) \
+ | (cast(Instruction, c)<<POS_C))
+
+#define CREATE_ABx(o,a,bc) (cast(Instruction, o) \
+ | (cast(Instruction, a)<<POS_A) \
+ | (cast(Instruction, bc)<<POS_Bx))
+
+
+
+
+/*
+** invalid register that fits in 8 bits
+*/
+#define NO_REG MAXARG_A
+
+
+/*
+** R(x) - register
+** Kst(x) - constant (in constant table)
+** RK(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK)
+*/
+
+
+/*
+** grep "ORDER OP" if you change these enums
+*/
+
+typedef enum {
+/*----------------------------------------------------------------------
+name args description
+------------------------------------------------------------------------*/
+OP_MOVE,/* A B R(A) := R(B) */
+OP_LOADK,/* A Bx R(A) := Kst(Bx) */
+OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) PC++ */
+OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
+OP_GETUPVAL,/* A B R(A) := UpValue[B] */
+
+OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
+OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
+
+OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
+OP_SETUPVAL,/* A B UpValue[B] := R(A) */
+OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
+
+OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
+
+OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
+
+OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
+OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
+OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
+OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
+OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
+OP_UNM,/* A B R(A) := -R(B) */
+OP_NOT,/* A B R(A) := not R(B) */
+
+OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
+
+OP_JMP,/* sBx PC += sBx */
+
+OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
+OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
+OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
+
+OP_TEST,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
+
+OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
+OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
+OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
+
+OP_FORLOOP,/* A sBx R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBx */
+
+OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
+ if R(A+2) ~= nil then pc++ */
+OP_TFORPREP,/* A sBx if type(R(A)) == table then R(A+1):=R(A), R(A):=next;
+ PC += sBx */
+
+OP_SETLIST,/* A Bx R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1 */
+OP_SETLISTO,/* A Bx */
+
+OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
+OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
+} OpCode;
+
+
+#define NUM_OPCODES (cast(int, OP_CLOSURE+1))
+
+
+
+/*===========================================================================
+ Notes:
+ (1) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
+ and can be 0: OP_CALL then sets `top' to last_result+1, so
+ next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
+
+ (2) In OP_RETURN, if (B == 0) then return up to `top'
+
+ (3) For comparisons, B specifies what conditions the test should accept.
+
+ (4) All `skips' (pc++) assume that next instruction is a jump
+===========================================================================*/
+
+
+/*
+** masks for instruction properties
+*/
+enum OpModeMask {
+ OpModeBreg = 2, /* B is a register */
+ OpModeBrk, /* B is a register/constant */
+ OpModeCrk, /* C is a register/constant */
+ OpModesetA, /* instruction set register A */
+ OpModeK, /* Bx is a constant */
+ OpModeT /* operator is a test */
+
+};
+
+
+extern const lu_byte luaP_opmodes[NUM_OPCODES];
+
+#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
+#define testOpMode(m, b) (luaP_opmodes[m] & (1 << (b)))
+
+
+#ifdef LUA_OPNAMES
+extern const char *const luaP_opnames[]; /* opcode names */
+#endif
+
+
+
+/* number of list items to accumulate before a SETLIST instruction */
+/* (must be a power of 2) */
+#define LFIELDS_PER_FLUSH 32
+
+
+#endif
diff --git a/lib/lua/includes/lparser.h b/lib/lua/includes/lparser.h
index 7055a9e..acbda7f 100644
--- a/lib/lua/includes/lparser.h
+++ b/lib/lua/includes/lparser.h
@@ -1,71 +1,71 @@
-/*
-** $Id: lparser.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Lua Parser
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lparser_h
-#define lparser_h
-
-#include "llimits.h"
-#include "lobject.h"
-#include "ltable.h"
-#include "lzio.h"
-
-
-/*
-** Expression descriptor
-*/
-
-typedef enum {
- VVOID, /* no value */
- VNIL,
- VTRUE,
- VFALSE,
- VK, /* info = index of constant in `k' */
- VLOCAL, /* info = local register */
- VUPVAL, /* info = index of upvalue in `upvalues' */
- VGLOBAL, /* info = index of table; aux = index of global name in `k' */
- VINDEXED, /* info = table register; aux = index register (or `k') */
- VJMP, /* info = instruction pc */
- VRELOCABLE, /* info = instruction pc */
- VNONRELOC, /* info = result register */
- VCALL /* info = result register */
-} expkind;
-
-typedef struct expdesc {
- expkind k;
- int info, aux;
- int t; /* patch list of `exit when true' */
- int f; /* patch list of `exit when false' */
-} expdesc;
-
-
-struct BlockCnt; /* defined in lparser.c */
-
-
-/* state needed to generate code for a given function */
-typedef struct FuncState {
- Proto *f; /* current function header */
- Table *h; /* table to find (and reuse) elements in `k' */
- struct FuncState *prev; /* enclosing function */
- struct LexState *ls; /* lexical state */
- struct lua_State *L; /* copy of the Lua state */
- struct BlockCnt *bl; /* chain of current blocks */
- int pc; /* next position to code (equivalent to `ncode') */
- int lasttarget; /* `pc' of last `jump target' */
- int jpc; /* list of pending jumps to `pc' */
- int freereg; /* first free register */
- int nk; /* number of elements in `k' */
- int np; /* number of elements in `p' */
- int nlocvars; /* number of elements in `locvars' */
- int nactvar; /* number of active local variables */
- expdesc upvalues[MAXUPVALUES]; /* upvalues */
- int actvar[MAXVARS]; /* declared-variable stack */
-} FuncState;
-
-
-Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff);
-
-
-#endif
+/*
+** $Id: lparser.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Lua Parser
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lparser_h
+#define lparser_h
+
+#include "llimits.h"
+#include "lobject.h"
+#include "ltable.h"
+#include "lzio.h"
+
+
+/*
+** Expression descriptor
+*/
+
+typedef enum {
+ VVOID, /* no value */
+ VNIL,
+ VTRUE,
+ VFALSE,
+ VK, /* info = index of constant in `k' */
+ VLOCAL, /* info = local register */
+ VUPVAL, /* info = index of upvalue in `upvalues' */
+ VGLOBAL, /* info = index of table; aux = index of global name in `k' */
+ VINDEXED, /* info = table register; aux = index register (or `k') */
+ VJMP, /* info = instruction pc */
+ VRELOCABLE, /* info = instruction pc */
+ VNONRELOC, /* info = result register */
+ VCALL /* info = result register */
+} expkind;
+
+typedef struct expdesc {
+ expkind k;
+ int info, aux;
+ int t; /* patch list of `exit when true' */
+ int f; /* patch list of `exit when false' */
+} expdesc;
+
+
+struct BlockCnt; /* defined in lparser.c */
+
+
+/* state needed to generate code for a given function */
+typedef struct FuncState {
+ Proto *f; /* current function header */
+ Table *h; /* table to find (and reuse) elements in `k' */
+ struct FuncState *prev; /* enclosing function */
+ struct LexState *ls; /* lexical state */
+ struct lua_State *L; /* copy of the Lua state */
+ struct BlockCnt *bl; /* chain of current blocks */
+ int pc; /* next position to code (equivalent to `ncode') */
+ int lasttarget; /* `pc' of last `jump target' */
+ int jpc; /* list of pending jumps to `pc' */
+ int freereg; /* first free register */
+ int nk; /* number of elements in `k' */
+ int np; /* number of elements in `p' */
+ int nlocvars; /* number of elements in `locvars' */
+ int nactvar; /* number of active local variables */
+ expdesc upvalues[MAXUPVALUES]; /* upvalues */
+ int actvar[MAXVARS]; /* declared-variable stack */
+} FuncState;
+
+
+Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff);
+
+
+#endif
diff --git a/lib/lua/includes/lstate.h b/lib/lua/includes/lstate.h
index 93cec30..dec40f5 100644
--- a/lib/lua/includes/lstate.h
+++ b/lib/lua/includes/lstate.h
@@ -1,200 +1,200 @@
-/*
-** $Id: lstate.h,v 1.4 2004-11-27 21:43:50 pixel Exp $
-** Global State
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lstate_h
-#define lstate_h
-
-#include "lua.h"
-
-#include "lobject.h"
-#include "ltm.h"
-#include "lzio.h"
-
-
-/*
-** macros for thread synchronization inside Lua core machine:
-** all accesses to the global state and to global objects are synchronized.
-** Because threads can read the stack of other threads
-** (when running garbage collection),
-** a thread must also synchronize any write-access to its own stack.
-** Unsynchronized accesses are allowed only when reading its own stack,
-** or when reading immutable fields from global objects
-** (such as string values and udata values).
-*/
-
-void do_lua_lock(lua_State *);
-void do_lua_unlock(lua_State *);
-
-#ifndef lua_lock
-#define lua_lock(L) do_lua_lock(L)
-#endif
-
-#ifndef lua_unlock
-#define lua_unlock(L) do_lua_unlock(L)
-#endif
-
-
-#ifndef lua_userstateopen
-#define lua_userstateopen(l)
-#endif
-
-
-
-struct lua_longjmp; /* defined in ldo.c */
-
-
-/* default meta table (both for tables and udata) */
-#define defaultmeta(L) (&G(L)->_defaultmeta)
-
-/* table of globals */
-#define gt(L) (&L->_gt)
-
-/* registry */
-#define registry(L) (&G(L)->_registry)
-
-
-/* extra stack space to handle TM calls and some other extras */
-#define EXTRA_STACK 5
-
-
-#define BASIC_CI_SIZE 8
-
-#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
-
-
-
-typedef struct stringtable {
- GCObject **hash;
- ls_nstr nuse; /* number of elements */
- int size;
-} stringtable;
-
-
-/*
-** informations about a call
-*/
-typedef struct CallInfo {
- StkId base; /* base for called function */
- StkId top; /* top for this function */
- int state; /* bit fields; see below */
- union {
- struct { /* for Lua functions */
- const Instruction *savedpc;
- const Instruction **pc; /* points to `pc' variable in `luaV_execute' */
- int tailcalls; /* number of tail calls lost under this entry */
- } l;
- struct { /* for C functions */
- int dummy; /* just to avoid an empty struct */
- } c;
- } u;
-} CallInfo;
-
-
-/*
-** bit fields for `CallInfo.state'
-*/
-#define CI_C (1<<0) /* 1 if function is a C function */
-/* 1 if (Lua) function has an active `luaV_execute' running it */
-#define CI_HASFRAME (1<<1)
-/* 1 if Lua function is calling another Lua function (and therefore its
- `pc' is being used by the other, and therefore CI_SAVEDPC is 1 too) */
-#define CI_CALLING (1<<2)
-#define CI_SAVEDPC (1<<3) /* 1 if `savedpc' is updated */
-#define CI_YIELD (1<<4) /* 1 if thread is suspended */
-#define CI_BREAK (1<<5) /* 1 if user break */
-
-
-#define ci_func(ci) (clvalue((ci)->base - 1))
-
-
-/*
-** `global state', shared by all threads of this state
-*/
-typedef struct global_State {
- stringtable strt; /* hash table for strings */
- GCObject *rootgc; /* list of (almost) all collectable objects */
- GCObject *rootudata; /* (separated) list of all userdata */
- GCObject *tmudata; /* list of userdata to be GC */
- Mbuffer buff; /* temporary buffer for string concatentation */
- lu_mem GCthreshold;
- lu_mem nblocks; /* number of `bytes' currently allocated */
- lua_CFunction panic; /* to be called in unprotected errors */
- TObject _registry;
- TObject _defaultmeta;
- struct lua_State *mainthread;
- Node dummynode[1]; /* common node array for all empty tables */
- TString *tmname[TM_N]; /* array with tag-method names */
-} global_State;
-
-
-/*
-** `per thread' state
-*/
-struct lua_State {
- CommonHeader;
- StkId top; /* first free slot in the stack */
- StkId base; /* base of current function */
- global_State *l_G;
- CallInfo *ci; /* call info for current function */
- StkId stack_last; /* last free slot in the stack */
- StkId stack; /* stack base */
- int stacksize;
- CallInfo *end_ci; /* points after end of ci array*/
- CallInfo *base_ci; /* array of CallInfo's */
- unsigned short size_ci; /* size of array `base_ci' */
- unsigned short nCcalls; /* number of nested C calls */
- lu_byte hookmask;
- lu_byte allowhook;
- lu_byte hookinit;
- int basehookcount;
- int hookcount;
- lua_Hook hook;
- TObject _gt; /* table of globals */
- GCObject *openupval; /* list of open upvalues in this stack */
- GCObject *gclist;
- struct lua_longjmp *errorJmp; /* current error recover point */
- ptrdiff_t errfunc; /* current error handling function (stack index) */
-};
-
-
-#define G(L) (L->l_G)
-
-
-/*
-** Union of all collectable objects
-*/
-union GCObject {
- GCheader gch;
- union TString ts;
- union Udata u;
- union Closure cl;
- struct Table h;
- struct Proto p;
- struct UpVal uv;
- struct lua_State th; /* thread */
-};
-
-
-/* macros to convert a GCObject into a specific value */
-#define gcotots(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
-#define gcotou(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
-#define gcotocl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
-#define gcotoh(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
-#define gcotop(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
-#define gcotouv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
-#define ngcotouv(o) \
- check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
-#define gcototh(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
-
-/* macro to convert any value into a GCObject */
-#define valtogco(v) (cast(GCObject *, (v)))
-
-
-lua_State *luaE_newthread (lua_State *L);
-void luaE_freethread (lua_State *L, lua_State *L1);
-
-#endif
-
+/*
+** $Id: lstate.h,v 1.5 2004-11-27 21:46:06 pixel Exp $
+** Global State
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lstate_h
+#define lstate_h
+
+#include "lua.h"
+
+#include "lobject.h"
+#include "ltm.h"
+#include "lzio.h"
+
+
+/*
+** macros for thread synchronization inside Lua core machine:
+** all accesses to the global state and to global objects are synchronized.
+** Because threads can read the stack of other threads
+** (when running garbage collection),
+** a thread must also synchronize any write-access to its own stack.
+** Unsynchronized accesses are allowed only when reading its own stack,
+** or when reading immutable fields from global objects
+** (such as string values and udata values).
+*/
+
+void do_lua_lock(lua_State *);
+void do_lua_unlock(lua_State *);
+
+#ifndef lua_lock
+#define lua_lock(L) do_lua_lock(L)
+#endif
+
+#ifndef lua_unlock
+#define lua_unlock(L) do_lua_unlock(L)
+#endif
+
+
+#ifndef lua_userstateopen
+#define lua_userstateopen(l)
+#endif
+
+
+
+struct lua_longjmp; /* defined in ldo.c */
+
+
+/* default meta table (both for tables and udata) */
+#define defaultmeta(L) (&G(L)->_defaultmeta)
+
+/* table of globals */
+#define gt(L) (&L->_gt)
+
+/* registry */
+#define registry(L) (&G(L)->_registry)
+
+
+/* extra stack space to handle TM calls and some other extras */
+#define EXTRA_STACK 5
+
+
+#define BASIC_CI_SIZE 8
+
+#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
+
+
+
+typedef struct stringtable {
+ GCObject **hash;
+ ls_nstr nuse; /* number of elements */
+ int size;
+} stringtable;
+
+
+/*
+** informations about a call
+*/
+typedef struct CallInfo {
+ StkId base; /* base for called function */
+ StkId top; /* top for this function */
+ int state; /* bit fields; see below */
+ union {
+ struct { /* for Lua functions */
+ const Instruction *savedpc;
+ const Instruction **pc; /* points to `pc' variable in `luaV_execute' */
+ int tailcalls; /* number of tail calls lost under this entry */
+ } l;
+ struct { /* for C functions */
+ int dummy; /* just to avoid an empty struct */
+ } c;
+ } u;
+} CallInfo;
+
+
+/*
+** bit fields for `CallInfo.state'
+*/
+#define CI_C (1<<0) /* 1 if function is a C function */
+/* 1 if (Lua) function has an active `luaV_execute' running it */
+#define CI_HASFRAME (1<<1)
+/* 1 if Lua function is calling another Lua function (and therefore its
+ `pc' is being used by the other, and therefore CI_SAVEDPC is 1 too) */
+#define CI_CALLING (1<<2)
+#define CI_SAVEDPC (1<<3) /* 1 if `savedpc' is updated */
+#define CI_YIELD (1<<4) /* 1 if thread is suspended */
+#define CI_BREAK (1<<5) /* 1 if user break */
+
+
+#define ci_func(ci) (clvalue((ci)->base - 1))
+
+
+/*
+** `global state', shared by all threads of this state
+*/
+typedef struct global_State {
+ stringtable strt; /* hash table for strings */
+ GCObject *rootgc; /* list of (almost) all collectable objects */
+ GCObject *rootudata; /* (separated) list of all userdata */
+ GCObject *tmudata; /* list of userdata to be GC */
+ Mbuffer buff; /* temporary buffer for string concatentation */
+ lu_mem GCthreshold;
+ lu_mem nblocks; /* number of `bytes' currently allocated */
+ lua_CFunction panic; /* to be called in unprotected errors */
+ TObject _registry;
+ TObject _defaultmeta;
+ struct lua_State *mainthread;
+ Node dummynode[1]; /* common node array for all empty tables */
+ TString *tmname[TM_N]; /* array with tag-method names */
+} global_State;
+
+
+/*
+** `per thread' state
+*/
+struct lua_State {
+ CommonHeader;
+ StkId top; /* first free slot in the stack */
+ StkId base; /* base of current function */
+ global_State *l_G;
+ CallInfo *ci; /* call info for current function */
+ StkId stack_last; /* last free slot in the stack */
+ StkId stack; /* stack base */
+ int stacksize;
+ CallInfo *end_ci; /* points after end of ci array*/
+ CallInfo *base_ci; /* array of CallInfo's */
+ unsigned short size_ci; /* size of array `base_ci' */
+ unsigned short nCcalls; /* number of nested C calls */
+ lu_byte hookmask;
+ lu_byte allowhook;
+ lu_byte hookinit;
+ int basehookcount;
+ int hookcount;
+ lua_Hook hook;
+ TObject _gt; /* table of globals */
+ GCObject *openupval; /* list of open upvalues in this stack */
+ GCObject *gclist;
+ struct lua_longjmp *errorJmp; /* current error recover point */
+ ptrdiff_t errfunc; /* current error handling function (stack index) */
+};
+
+
+#define G(L) (L->l_G)
+
+
+/*
+** Union of all collectable objects
+*/
+union GCObject {
+ GCheader gch;
+ union TString ts;
+ union Udata u;
+ union Closure cl;
+ struct Table h;
+ struct Proto p;
+ struct UpVal uv;
+ struct lua_State th; /* thread */
+};
+
+
+/* macros to convert a GCObject into a specific value */
+#define gcotots(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
+#define gcotou(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
+#define gcotocl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
+#define gcotoh(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
+#define gcotop(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
+#define gcotouv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
+#define ngcotouv(o) \
+ check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
+#define gcototh(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
+
+/* macro to convert any value into a GCObject */
+#define valtogco(v) (cast(GCObject *, (v)))
+
+
+lua_State *luaE_newthread (lua_State *L);
+void luaE_freethread (lua_State *L, lua_State *L1);
+
+#endif
+
diff --git a/lib/lua/includes/lstring.h b/lib/lua/includes/lstring.h
index 11791f0..15745f5 100644
--- a/lib/lua/includes/lstring.h
+++ b/lib/lua/includes/lstring.h
@@ -1,33 +1,33 @@
-/*
-** $Id: lstring.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** String table (keep all strings handled by Lua)
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lstring_h
-#define lstring_h
-
-
-#include "lobject.h"
-#include "lstate.h"
-
-
-
-#define sizestring(l) (cast(lu_mem, sizeof(union TString))+ \
- (cast(lu_mem, l)+1)*sizeof(char))
-
-#define sizeudata(l) (cast(lu_mem, sizeof(union Udata))+(l))
-
-#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
-#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
- (sizeof(s)/sizeof(char))-1))
-
-#define luaS_fix(s) ((s)->tsv.marked |= (1<<4))
-
-void luaS_resize (lua_State *L, int newsize);
-Udata *luaS_newudata (lua_State *L, size_t s);
-void luaS_freeall (lua_State *L);
-TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
-
-
-#endif
+/*
+** $Id: lstring.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** String table (keep all strings handled by Lua)
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lstring_h
+#define lstring_h
+
+
+#include "lobject.h"
+#include "lstate.h"
+
+
+
+#define sizestring(l) (cast(lu_mem, sizeof(union TString))+ \
+ (cast(lu_mem, l)+1)*sizeof(char))
+
+#define sizeudata(l) (cast(lu_mem, sizeof(union Udata))+(l))
+
+#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
+#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
+ (sizeof(s)/sizeof(char))-1))
+
+#define luaS_fix(s) ((s)->tsv.marked |= (1<<4))
+
+void luaS_resize (lua_State *L, int newsize);
+Udata *luaS_newudata (lua_State *L, size_t s);
+void luaS_freeall (lua_State *L);
+TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
+
+
+#endif
diff --git a/lib/lua/includes/ltable.h b/lib/lua/includes/ltable.h
index 97695d0..56920ee 100644
--- a/lib/lua/includes/ltable.h
+++ b/lib/lua/includes/ltable.h
@@ -1,31 +1,31 @@
-/*
-** $Id: ltable.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Lua tables (hash)
-** See Copyright Notice in lua.h
-*/
-
-#ifndef ltable_h
-#define ltable_h
-
-#include "lobject.h"
-
-
-#define gnode(t,i) (&(t)->node[i])
-#define gkey(n) (&(n)->i_key)
-#define gval(n) (&(n)->i_val)
-
-
-const TObject *luaH_getnum (Table *t, int key);
-TObject *luaH_setnum (lua_State *L, Table *t, int key);
-const TObject *luaH_getstr (Table *t, TString *key);
-const TObject *luaH_get (Table *t, const TObject *key);
-TObject *luaH_set (lua_State *L, Table *t, const TObject *key);
-Table *luaH_new (lua_State *L, int narray, int lnhash);
-void luaH_free (lua_State *L, Table *t);
-int luaH_next (lua_State *L, Table *t, StkId key);
-
-/* exported only for debugging */
-Node *luaH_mainposition (const Table *t, const TObject *key);
-
-
-#endif
+/*
+** $Id: ltable.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Lua tables (hash)
+** See Copyright Notice in lua.h
+*/
+
+#ifndef ltable_h
+#define ltable_h
+
+#include "lobject.h"
+
+
+#define gnode(t,i) (&(t)->node[i])
+#define gkey(n) (&(n)->i_key)
+#define gval(n) (&(n)->i_val)
+
+
+const TObject *luaH_getnum (Table *t, int key);
+TObject *luaH_setnum (lua_State *L, Table *t, int key);
+const TObject *luaH_getstr (Table *t, TString *key);
+const TObject *luaH_get (Table *t, const TObject *key);
+TObject *luaH_set (lua_State *L, Table *t, const TObject *key);
+Table *luaH_new (lua_State *L, int narray, int lnhash);
+void luaH_free (lua_State *L, Table *t);
+int luaH_next (lua_State *L, Table *t, StkId key);
+
+/* exported only for debugging */
+Node *luaH_mainposition (const Table *t, const TObject *key);
+
+
+#endif
diff --git a/lib/lua/includes/ltm.h b/lib/lua/includes/ltm.h
index 7652e4d..73625c2 100644
--- a/lib/lua/includes/ltm.h
+++ b/lib/lua/includes/ltm.h
@@ -1,51 +1,51 @@
-/*
-** $Id: ltm.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Tag methods
-** See Copyright Notice in lua.h
-*/
-
-#ifndef ltm_h
-#define ltm_h
-
-
-#include "lobject.h"
-
-
-/*
-* WARNING: if you change the order of this enumeration,
-* grep "ORDER TM"
-*/
-typedef enum {
- TM_INDEX,
- TM_NEWINDEX,
- TM_GC,
- TM_MODE,
- TM_EQ, /* last tag method with `fast' access */
- TM_ADD,
- TM_SUB,
- TM_MUL,
- TM_DIV,
- TM_POW,
- TM_UNM,
- TM_LT,
- TM_LE,
- TM_CONCAT,
- TM_CALL,
- TM_N /* number of elements in the enum */
-} TMS;
-
-
-
-#define gfasttm(g,et,e) \
- (((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
-
-#define fasttm(l,et,e) gfasttm(G(l), et, e)
-
-
-const TObject *luaT_gettm (Table *events, TMS event, TString *ename);
-const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event);
-void luaT_init (lua_State *L);
-
-extern const char *const luaT_typenames[];
-
-#endif
+/*
+** $Id: ltm.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Tag methods
+** See Copyright Notice in lua.h
+*/
+
+#ifndef ltm_h
+#define ltm_h
+
+
+#include "lobject.h"
+
+
+/*
+* WARNING: if you change the order of this enumeration,
+* grep "ORDER TM"
+*/
+typedef enum {
+ TM_INDEX,
+ TM_NEWINDEX,
+ TM_GC,
+ TM_MODE,
+ TM_EQ, /* last tag method with `fast' access */
+ TM_ADD,
+ TM_SUB,
+ TM_MUL,
+ TM_DIV,
+ TM_POW,
+ TM_UNM,
+ TM_LT,
+ TM_LE,
+ TM_CONCAT,
+ TM_CALL,
+ TM_N /* number of elements in the enum */
+} TMS;
+
+
+
+#define gfasttm(g,et,e) \
+ (((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
+
+#define fasttm(l,et,e) gfasttm(G(l), et, e)
+
+
+const TObject *luaT_gettm (Table *events, TMS event, TString *ename);
+const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event);
+void luaT_init (lua_State *L);
+
+extern const char *const luaT_typenames[];
+
+#endif
diff --git a/lib/lua/includes/lundump.h b/lib/lua/includes/lundump.h
index adcb85c..7f33793 100644
--- a/lib/lua/includes/lundump.h
+++ b/lib/lua/includes/lundump.h
@@ -1,34 +1,34 @@
-/*
-** $Id: lundump.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** load pre-compiled Lua chunks
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lundump_h
-#define lundump_h
-
-#include "lobject.h"
-#include "lzio.h"
-
-/* load one chunk; from lundump.c */
-Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff);
-
-/* find byte order; from lundump.c */
-int luaU_endianness (void);
-
-/* dump one chunk; from ldump.c */
-void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data);
-
-/* print one chunk; from print.c */
-void luaU_print (const Proto* Main);
-
-/* definitions for headers of binary files */
-#define LUA_SIGNATURE "\033Lua" /* binary files start with "<esc>Lua" */
-#define VERSION 0x50 /* last format change was in 5.0 */
-#define VERSION0 0x50 /* last major change was in 5.0 */
-
-/* a multiple of PI for testing native format */
-/* multiplying by 1E7 gives non-trivial integer values */
-#define TEST_NUMBER ((lua_Number)3.14159265358979323846E7)
-
-#endif
+/*
+** $Id: lundump.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** load pre-compiled Lua chunks
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lundump_h
+#define lundump_h
+
+#include "lobject.h"
+#include "lzio.h"
+
+/* load one chunk; from lundump.c */
+Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff);
+
+/* find byte order; from lundump.c */
+int luaU_endianness (void);
+
+/* dump one chunk; from ldump.c */
+void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data);
+
+/* print one chunk; from print.c */
+void luaU_print (const Proto* Main);
+
+/* definitions for headers of binary files */
+#define LUA_SIGNATURE "\033Lua" /* binary files start with "<esc>Lua" */
+#define VERSION 0x50 /* last format change was in 5.0 */
+#define VERSION0 0x50 /* last major change was in 5.0 */
+
+/* a multiple of PI for testing native format */
+/* multiplying by 1E7 gives non-trivial integer values */
+#define TEST_NUMBER ((lua_Number)3.14159265358979323846E7)
+
+#endif
diff --git a/lib/lua/includes/lvm.h b/lib/lua/includes/lvm.h
index 56f6415..20b75de 100644
--- a/lib/lua/includes/lvm.h
+++ b/lib/lua/includes/lvm.h
@@ -1,35 +1,35 @@
-/*
-** $Id: lvm.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Lua virtual machine
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lvm_h
-#define lvm_h
-
-
-#include "ldo.h"
-#include "lobject.h"
-#include "ltm.h"
-
-
-#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
-
-#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
- (((o) = luaV_tonumber(o,n)) != NULL))
-
-#define equalobj(L,o1,o2) \
- (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
-
-
-int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
-int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2);
-const TObject *luaV_tonumber (const TObject *obj, TObject *n);
-int luaV_tostring (lua_State *L, StkId obj);
-const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key,
- int loop);
-void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val);
-StkId luaV_execute (lua_State *L);
-void luaV_concat (lua_State *L, int total, int last);
-
-#endif
+/*
+** $Id: lvm.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Lua virtual machine
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lvm_h
+#define lvm_h
+
+
+#include "ldo.h"
+#include "lobject.h"
+#include "ltm.h"
+
+
+#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
+
+#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
+ (((o) = luaV_tonumber(o,n)) != NULL))
+
+#define equalobj(L,o1,o2) \
+ (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
+
+
+int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
+int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2);
+const TObject *luaV_tonumber (const TObject *obj, TObject *n);
+int luaV_tostring (lua_State *L, StkId obj);
+const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key,
+ int loop);
+void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val);
+StkId luaV_execute (lua_State *L);
+void luaV_concat (lua_State *L, int total, int last);
+
+#endif
diff --git a/lib/lua/includes/lzio.h b/lib/lua/includes/lzio.h
index 6fff60d..7d41fbd 100644
--- a/lib/lua/includes/lzio.h
+++ b/lib/lua/includes/lzio.h
@@ -1,64 +1,64 @@
-/*
-** $Id: lzio.h,v 1.3 2004-11-27 21:43:50 pixel Exp $
-** Buffered streams
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lzio_h
-#define lzio_h
-
-#include "lua.h"
-
-
-#define EOZ (-1) /* end of stream */
-
-typedef struct Zio ZIO;
-
-
-#define char2int(c) cast(int, cast(unsigned char, (c)))
-
-#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
-
-#define zname(z) ((z)->name)
-
-void luaZ_init (ZIO *z, lua_Chunkreader reader, void *data, const char *name);
-size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
-int luaZ_lookahead (ZIO *z);
-
-
-
-typedef struct Mbuffer {
- char *buffer;
- size_t buffsize;
-} Mbuffer;
-
-
-char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
-
-#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
-
-#define luaZ_sizebuffer(buff) ((buff)->buffsize)
-#define luaZ_buffer(buff) ((buff)->buffer)
-
-#define luaZ_resizebuffer(L, buff, size) \
- (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
- (buff)->buffsize = size)
-
-#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
-
-
-/* --------- Private Part ------------------ */
-
-struct Zio {
- size_t n; /* bytes still unread */
- const char *p; /* current position in buffer */
- lua_Chunkreader reader;
- void* data; /* additional data */
- const char *name;
-};
-
-
-int luaZ_fill (ZIO *z);
-
-#endif
+/*
+** $Id: lzio.h,v 1.4 2004-11-27 21:46:06 pixel Exp $
+** Buffered streams
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lzio_h
+#define lzio_h
+
+#include "lua.h"
+
+
+#define EOZ (-1) /* end of stream */
+
+typedef struct Zio ZIO;
+
+
+#define char2int(c) cast(int, cast(unsigned char, (c)))
+
+#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
+
+#define zname(z) ((z)->name)
+
+void luaZ_init (ZIO *z, lua_Chunkreader reader, void *data, const char *name);
+size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
+int luaZ_lookahead (ZIO *z);
+
+
+
+typedef struct Mbuffer {
+ char *buffer;
+ size_t buffsize;
+} Mbuffer;
+
+
+char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
+
+#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
+
+#define luaZ_sizebuffer(buff) ((buff)->buffsize)
+#define luaZ_buffer(buff) ((buff)->buffer)
+
+#define luaZ_resizebuffer(L, buff, size) \
+ (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
+ (buff)->buffsize = size)
+
+#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
+
+
+/* --------- Private Part ------------------ */
+
+struct Zio {
+ size_t n; /* bytes still unread */
+ const char *p; /* current position in buffer */
+ lua_Chunkreader reader;
+ void* data; /* additional data */
+ const char *name;
+};
+
+
+int luaZ_fill (ZIO *z);
+
+#endif
diff --git a/lib/lua/src/LuaLib/lauxlib.c b/lib/lua/src/LuaLib/lauxlib.c
index c4b24a7..2088b9e 100644
--- a/lib/lua/src/LuaLib/lauxlib.c
+++ b/lib/lua/src/LuaLib/lauxlib.c
@@ -1,591 +1,591 @@
-/*
-** $Id: lauxlib.c,v 1.3 2004-11-27 21:35:21 pixel Exp $
-** Auxiliary functions for building Lua libraries
-** See Copyright Notice in lua.h
-*/
-
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-
-/* This file uses only the official API of Lua.
-** Any function declared here could be written as an application function.
-*/
-
-#define lauxlib_c
-
-#include "lua.h"
-
-#include "lauxlib.h"
-
-
-/* number of prereserved references (for internal use) */
-#define RESERVED_REFS 2
-
-/* reserved references */
-#define FREELIST_REF 1 /* free list of references */
-#define ARRAYSIZE_REF 2 /* array sizes */
-
-
-/* convert a stack index to positive */
-#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
- lua_gettop(L) + (i) + 1)
-
-
-/*
-** {======================================================
-** Error-report functions
-** =======================================================
-*/
-
-
-LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
- lua_Debug ar;
- lua_getstack(L, 0, &ar);
- lua_getinfo(L, "n", &ar);
- if (strcmp(ar.namewhat, "method") == 0) {
- narg--; /* do not count `self' */
- if (narg == 0) /* error is in the self argument itself? */
- return luaL_error(L, "calling `%s' on bad self (%s)", ar.name, extramsg);
- }
- if (ar.name == NULL)
- ar.name = "?";
- return luaL_error(L, "bad argument #%d to `%s' (%s)",
- narg, ar.name, extramsg);
-}
-
-
-LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
- const char *msg = lua_pushfstring(L, "%s expected, got %s",
- tname, lua_typename(L, lua_type(L,narg)));
- return luaL_argerror(L, narg, msg);
-}
-
-
-static void tag_error (lua_State *L, int narg, int tag) {
- luaL_typerror(L, narg, lua_typename(L, tag));
-}
-
-
-LUALIB_API void luaL_where (lua_State *L, int level) {
- lua_Debug ar;
- if (lua_getstack(L, level, &ar)) { /* check function at level */
- lua_getinfo(L, "Snl", &ar); /* get info about it */
- if (ar.currentline > 0) { /* is there info? */
- lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
- return;
- }
- }
- lua_pushliteral(L, ""); /* else, no information available... */
-}
-
-
-LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
- va_list argp;
- va_start(argp, fmt);
- luaL_where(L, 1);
- lua_pushvfstring(L, fmt, argp);
- va_end(argp);
- lua_concat(L, 2);
- return lua_error(L);
-}
-
-/* }====================================================== */
-
-
-LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
- int i;
- for (i=0; list[i]; i++)
- if (strcmp(list[i], name) == 0)
- return i;
- return -1; /* name not found */
-}
-
-
-LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
- lua_pushstring(L, tname);
- lua_rawget(L, LUA_REGISTRYINDEX); /* get registry.name */
- if (!lua_isnil(L, -1)) /* name already in use? */
- return 0; /* leave previous value on top, but return 0 */
- lua_pop(L, 1);
- lua_newtable(L); /* create metatable */
- lua_pushstring(L, tname);
- lua_pushvalue(L, -2);
- lua_rawset(L, LUA_REGISTRYINDEX); /* registry.name = metatable */
- lua_pushvalue(L, -1);
- lua_pushstring(L, tname);
- lua_rawset(L, LUA_REGISTRYINDEX); /* registry[metatable] = name */
- return 1;
-}
-
-
-LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname) {
- lua_pushstring(L, tname);
- lua_rawget(L, LUA_REGISTRYINDEX);
-}
-
-
-LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
- const char *tn;
- if (!lua_getmetatable(L, ud)) return NULL; /* no metatable? */
- lua_rawget(L, LUA_REGISTRYINDEX); /* get registry[metatable] */
- tn = lua_tostring(L, -1);
- if (tn && (strcmp(tn, tname) == 0)) {
- lua_pop(L, 1);
- return lua_touserdata(L, ud);
- }
- else {
- lua_pop(L, 1);
- return NULL;
- }
-}
-
-
-LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
- if (!lua_checkstack(L, space))
- luaL_error(L, "stack overflow (%s)", mes);
-}
-
-
-LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
- if (lua_type(L, narg) != t)
- tag_error(L, narg, t);
-}
-
-
-LUALIB_API void luaL_checkany (lua_State *L, int narg) {
- if (lua_type(L, narg) == LUA_TNONE)
- luaL_argerror(L, narg, "value expected");
-}
-
-
-LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
- const char *s = lua_tostring(L, narg);
- if (!s) tag_error(L, narg, LUA_TSTRING);
- if (len) *len = lua_strlen(L, narg);
- return s;
-}
-
-
-LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
- const char *def, size_t *len) {
- if (lua_isnoneornil(L, narg)) {
- if (len)
- *len = (def ? strlen(def) : 0);
- return def;
- }
- else return luaL_checklstring(L, narg, len);
-}
-
-
-LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
- lua_Number d = lua_tonumber(L, narg);
- if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
- tag_error(L, narg, LUA_TNUMBER);
- return d;
-}
-
-
-LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
- if (lua_isnoneornil(L, narg)) return def;
- else return luaL_checknumber(L, narg);
-}
-
-
-LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
- if (!lua_getmetatable(L, obj)) /* no metatable? */
- return 0;
- lua_pushstring(L, event);
- lua_rawget(L, -2);
- if (lua_isnil(L, -1)) {
- lua_pop(L, 2); /* remove metatable and metafield */
- return 0;
- }
- else {
- lua_remove(L, -2); /* remove only metatable */
- return 1;
- }
-}
-
-
-LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
- obj = abs_index(L, obj);
- if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
- return 0;
- lua_pushvalue(L, obj);
- lua_call(L, 1, 1);
- return 1;
-}
-
-
-LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
- const luaL_reg *l, int nup) {
- if (libname) {
- lua_pushstring(L, libname);
- lua_gettable(L, LUA_GLOBALSINDEX); /* check whether lib already exists */
- if (lua_isnil(L, -1)) { /* no? */
- lua_pop(L, 1);
- lua_newtable(L); /* create it */
- lua_pushstring(L, libname);
- lua_pushvalue(L, -2);
- lua_settable(L, LUA_GLOBALSINDEX); /* register it with given name */
- }
- lua_insert(L, -(nup+1)); /* move library table to below upvalues */
- }
- for (; l->name; l++) {
- int i;
- lua_pushstring(L, l->name);
- for (i=0; i<nup; i++) /* copy upvalues to the top */
- lua_pushvalue(L, -(nup+1));
- lua_pushcclosure(L, l->func, nup);
- lua_settable(L, -(nup+3));
- }
- lua_pop(L, nup); /* remove upvalues */
-}
-
-
-
-/*
-** {======================================================
-** getn-setn: size for arrays
-** =======================================================
-*/
-
-static int checkint (lua_State *L, int topop) {
- int n = (int)lua_tonumber(L, -1);
- if (n == 0 && !lua_isnumber(L, -1)) n = -1;
- lua_pop(L, topop);
- return n;
-}
-
-
-static void getsizes (lua_State *L) {
- lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF);
- if (lua_isnil(L, -1)) { /* no `size' table? */
- lua_pop(L, 1); /* remove nil */
- lua_newtable(L); /* create it */
- lua_pushvalue(L, -1); /* `size' will be its own metatable */
- lua_setmetatable(L, -2);
- lua_pushliteral(L, "__mode");
- lua_pushliteral(L, "k");
- lua_rawset(L, -3); /* metatable(N).__mode = "k" */
- lua_pushvalue(L, -1);
- lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */
- }
-}
-
-
-void luaL_setn (lua_State *L, int t, int n) {
- t = abs_index(L, t);
- lua_pushliteral(L, "n");
- lua_rawget(L, t);
- if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
- lua_pushliteral(L, "n"); /* use it */
- lua_pushnumber(L, (lua_Number)n);
- lua_rawset(L, t);
- }
- else { /* use `sizes' */
- getsizes(L);
- lua_pushvalue(L, t);
- lua_pushnumber(L, (lua_Number)n);
- lua_rawset(L, -3); /* sizes[t] = n */
- lua_pop(L, 1); /* remove `sizes' */
- }
-}
-
-
-int luaL_getn (lua_State *L, int t) {
- int n;
- t = abs_index(L, t);
- lua_pushliteral(L, "n"); /* try t.n */
- lua_rawget(L, t);
- if ((n = checkint(L, 1)) >= 0) return n;
- getsizes(L); /* else try sizes[t] */
- lua_pushvalue(L, t);
- lua_rawget(L, -2);
- if ((n = checkint(L, 2)) >= 0) return n;
- for (n = 1; ; n++) { /* else must count elements */
- lua_rawgeti(L, t, n);
- if (lua_isnil(L, -1)) break;
- lua_pop(L, 1);
- }
- lua_pop(L, 1);
- return n - 1;
-}
-
-/* }====================================================== */
-
-
-
-/*
-** {======================================================
-** Generic Buffer manipulation
-** =======================================================
-*/
-
-
-#define bufflen(B) ((B)->p - (B)->buffer)
-#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
-
-#define LIMIT (LUA_MINSTACK/2)
-
-
-static int emptybuffer (luaL_Buffer *B) {
- size_t l = bufflen(B);
- if (l == 0) return 0; /* put nothing on stack */
- else {
- lua_pushlstring(B->L, B->buffer, l);
- B->p = B->buffer;
- B->lvl++;
- return 1;
- }
-}
-
-
-static void adjuststack (luaL_Buffer *B) {
- if (B->lvl > 1) {
- lua_State *L = B->L;
- int toget = 1; /* number of levels to concat */
- size_t toplen = lua_strlen(L, -1);
- do {
- size_t l = lua_strlen(L, -(toget+1));
- if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
- toplen += l;
- toget++;
- }
- else break;
- } while (toget < B->lvl);
- lua_concat(L, toget);
- B->lvl = B->lvl - toget + 1;
- }
-}
-
-
-LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
- if (emptybuffer(B))
- adjuststack(B);
- return B->buffer;
-}
-
-
-LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
- while (l--)
- luaL_putchar(B, *s++);
-}
-
-
-LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
- luaL_addlstring(B, s, strlen(s));
-}
-
-
-LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
- emptybuffer(B);
- lua_concat(B->L, B->lvl);
- B->lvl = 1;
-}
-
-
-LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
- lua_State *L = B->L;
- size_t vl = lua_strlen(L, -1);
- if (vl <= bufffree(B)) { /* fit into buffer? */
- memcpy(B->p, lua_tostring(L, -1), vl); /* put it there */
- B->p += vl;
- lua_pop(L, 1); /* remove from stack */
- }
- else {
- if (emptybuffer(B))
- lua_insert(L, -2); /* put buffer before new value */
- B->lvl++; /* add new value into B stack */
- adjuststack(B);
- }
-}
-
-
-LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
- B->L = L;
- B->p = B->buffer;
- B->lvl = 0;
-}
-
-/* }====================================================== */
-
-
-LUALIB_API int luaL_ref (lua_State *L, int t) {
- int ref;
- t = abs_index(L, t);
- if (lua_isnil(L, -1)) {
- lua_pop(L, 1); /* remove from stack */
- return LUA_REFNIL; /* `nil' has a unique fixed reference */
- }
- lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
- ref = (int)lua_tonumber(L, -1); /* ref = t[FREELIST_REF] */
- lua_pop(L, 1); /* remove it from stack */
- if (ref != 0) { /* any free element? */
- lua_rawgeti(L, t, ref); /* remove it from list */
- lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
- }
- else { /* no free elements */
- ref = luaL_getn(L, t);
- if (ref < RESERVED_REFS)
- ref = RESERVED_REFS; /* skip reserved references */
- ref++; /* create new reference */
- luaL_setn(L, t, ref);
- }
- lua_rawseti(L, t, ref);
- return ref;
-}
-
-
-LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
- if (ref >= 0) {
- t = abs_index(L, t);
- lua_rawgeti(L, t, FREELIST_REF);
- lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
- lua_pushnumber(L, (lua_Number)ref);
- lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
- }
-}
-
-
-
-/*
-** {======================================================
-** Load functions
-** =======================================================
-*/
-
-typedef struct LoadF {
- FILE *f;
- char buff[LUAL_BUFFERSIZE];
-} LoadF;
-
-
-static const char *getF (lua_State *L, void *ud, size_t *size) {
- LoadF *lf = (LoadF *)ud;
- (void)L;
- if (feof(lf->f)) return NULL;
- *size = fread(lf->buff, 1, LUAL_BUFFERSIZE, lf->f);
- return (*size > 0) ? lf->buff : NULL;
-}
-
-
-static int errfile (lua_State *L, int fnameindex) {
- const char *filename = lua_tostring(L, fnameindex) + 1;
- lua_pushfstring(L, "cannot read %s: %s", filename, strerror(errno));
- lua_remove(L, fnameindex);
- return LUA_ERRFILE;
-}
-
-
-LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
- LoadF lf;
- int status, readstatus;
- int c;
- int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
- if (filename == NULL) {
- lua_pushliteral(L, "=stdin");
- lf.f = stdin;
- }
- else {
- lua_pushfstring(L, "@%s", filename);
- lf.f = fopen(filename, "r");
- }
- if (lf.f == NULL) return errfile(L, fnameindex); /* unable to open file */
- c = ungetc(getc(lf.f), lf.f);
- if (!(isspace(c) || isprint(c)) && lf.f != stdin) { /* binary file? */
- fclose(lf.f);
- lf.f = fopen(filename, "rb"); /* reopen in binary mode */
- if (lf.f == NULL) return errfile(L, fnameindex); /* unable to reopen file */
- }
- status = lua_load(L, getF, &lf, lua_tostring(L, -1));
- readstatus = ferror(lf.f);
- if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */
- if (readstatus) {
- lua_settop(L, fnameindex); /* ignore results from `lua_load' */
- return errfile(L, fnameindex);
- }
- lua_remove(L, fnameindex);
- return status;
-}
-
-
-typedef struct LoadS {
- const char *s;
- size_t size;
-} LoadS;
-
-
-static const char *getS (lua_State *L, void *ud, size_t *size) {
- LoadS *ls = (LoadS *)ud;
- (void)L;
- if (ls->size == 0) return NULL;
- *size = ls->size;
- ls->size = 0;
- return ls->s;
-}
-
-
-LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
- const char *name) {
- LoadS ls;
- ls.s = buff;
- ls.size = size;
- return lua_load(L, getS, &ls, name);
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** compatibility code
-** =======================================================
-*/
-
-
-static void callalert (lua_State *L, int status) {
- if (status != 0) {
- lua_getglobal(L, "_ALERT");
- if (lua_isfunction(L, -1)) {
- lua_insert(L, -2);
- lua_call(L, 1, 0);
- }
- else { /* no _ALERT function; print it on stderr */
- fprintf(stderr, "%s\n", lua_tostring(L, -2));
- lua_pop(L, 2); /* remove error message and _ALERT */
- }
- }
-}
-
-
-static int aux_do (lua_State *L, int status) {
- if (status == 0) { /* parse OK? */
- status = lua_pcall(L, 0, LUA_MULTRET, 0); /* call main */
- }
- callalert(L, status);
- return status;
-}
-
-
-LUALIB_API int lua_dofile (lua_State *L, const char *filename) {
- return aux_do(L, luaL_loadfile(L, filename));
-}
-
-
-LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t size,
- const char *name) {
- return aux_do(L, luaL_loadbuffer(L, buff, size, name));
-}
-
-
-LUALIB_API int lua_dostring (lua_State *L, const char *str) {
- return lua_dobuffer(L, str, strlen(str), str);
-}
-
-/* }====================================================== */
+/*
+** $Id: lauxlib.c,v 1.4 2004-11-27 21:46:10 pixel Exp $
+** Auxiliary functions for building Lua libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* This file uses only the official API of Lua.
+** Any function declared here could be written as an application function.
+*/
+
+#define lauxlib_c
+
+#include "lua.h"
+
+#include "lauxlib.h"
+
+
+/* number of prereserved references (for internal use) */
+#define RESERVED_REFS 2
+
+/* reserved references */
+#define FREELIST_REF 1 /* free list of references */
+#define ARRAYSIZE_REF 2 /* array sizes */
+
+
+/* convert a stack index to positive */
+#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
+ lua_gettop(L) + (i) + 1)
+
+
+/*
+** {======================================================
+** Error-report functions
+** =======================================================
+*/
+
+
+LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
+ lua_Debug ar;
+ lua_getstack(L, 0, &ar);
+ lua_getinfo(L, "n", &ar);
+ if (strcmp(ar.namewhat, "method") == 0) {
+ narg--; /* do not count `self' */
+ if (narg == 0) /* error is in the self argument itself? */
+ return luaL_error(L, "calling `%s' on bad self (%s)", ar.name, extramsg);
+ }
+ if (ar.name == NULL)
+ ar.name = "?";
+ return luaL_error(L, "bad argument #%d to `%s' (%s)",
+ narg, ar.name, extramsg);
+}
+
+
+LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
+ const char *msg = lua_pushfstring(L, "%s expected, got %s",
+ tname, lua_typename(L, lua_type(L,narg)));
+ return luaL_argerror(L, narg, msg);
+}
+
+
+static void tag_error (lua_State *L, int narg, int tag) {
+ luaL_typerror(L, narg, lua_typename(L, tag));
+}
+
+
+LUALIB_API void luaL_where (lua_State *L, int level) {
+ lua_Debug ar;
+ if (lua_getstack(L, level, &ar)) { /* check function at level */
+ lua_getinfo(L, "Snl", &ar); /* get info about it */
+ if (ar.currentline > 0) { /* is there info? */
+ lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
+ return;
+ }
+ }
+ lua_pushliteral(L, ""); /* else, no information available... */
+}
+
+
+LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
+ va_list argp;
+ va_start(argp, fmt);
+ luaL_where(L, 1);
+ lua_pushvfstring(L, fmt, argp);
+ va_end(argp);
+ lua_concat(L, 2);
+ return lua_error(L);
+}
+
+/* }====================================================== */
+
+
+LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
+ int i;
+ for (i=0; list[i]; i++)
+ if (strcmp(list[i], name) == 0)
+ return i;
+ return -1; /* name not found */
+}
+
+
+LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
+ lua_pushstring(L, tname);
+ lua_rawget(L, LUA_REGISTRYINDEX); /* get registry.name */
+ if (!lua_isnil(L, -1)) /* name already in use? */
+ return 0; /* leave previous value on top, but return 0 */
+ lua_pop(L, 1);
+ lua_newtable(L); /* create metatable */
+ lua_pushstring(L, tname);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, LUA_REGISTRYINDEX); /* registry.name = metatable */
+ lua_pushvalue(L, -1);
+ lua_pushstring(L, tname);
+ lua_rawset(L, LUA_REGISTRYINDEX); /* registry[metatable] = name */
+ return 1;
+}
+
+
+LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname) {
+ lua_pushstring(L, tname);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+}
+
+
+LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
+ const char *tn;
+ if (!lua_getmetatable(L, ud)) return NULL; /* no metatable? */
+ lua_rawget(L, LUA_REGISTRYINDEX); /* get registry[metatable] */
+ tn = lua_tostring(L, -1);
+ if (tn && (strcmp(tn, tname) == 0)) {
+ lua_pop(L, 1);
+ return lua_touserdata(L, ud);
+ }
+ else {
+ lua_pop(L, 1);
+ return NULL;
+ }
+}
+
+
+LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
+ if (!lua_checkstack(L, space))
+ luaL_error(L, "stack overflow (%s)", mes);
+}
+
+
+LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
+ if (lua_type(L, narg) != t)
+ tag_error(L, narg, t);
+}
+
+
+LUALIB_API void luaL_checkany (lua_State *L, int narg) {
+ if (lua_type(L, narg) == LUA_TNONE)
+ luaL_argerror(L, narg, "value expected");
+}
+
+
+LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
+ const char *s = lua_tostring(L, narg);
+ if (!s) tag_error(L, narg, LUA_TSTRING);
+ if (len) *len = lua_strlen(L, narg);
+ return s;
+}
+
+
+LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
+ const char *def, size_t *len) {
+ if (lua_isnoneornil(L, narg)) {
+ if (len)
+ *len = (def ? strlen(def) : 0);
+ return def;
+ }
+ else return luaL_checklstring(L, narg, len);
+}
+
+
+LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
+ lua_Number d = lua_tonumber(L, narg);
+ if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
+ tag_error(L, narg, LUA_TNUMBER);
+ return d;
+}
+
+
+LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
+ if (lua_isnoneornil(L, narg)) return def;
+ else return luaL_checknumber(L, narg);
+}
+
+
+LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
+ if (!lua_getmetatable(L, obj)) /* no metatable? */
+ return 0;
+ lua_pushstring(L, event);
+ lua_rawget(L, -2);
+ if (lua_isnil(L, -1)) {
+ lua_pop(L, 2); /* remove metatable and metafield */
+ return 0;
+ }
+ else {
+ lua_remove(L, -2); /* remove only metatable */
+ return 1;
+ }
+}
+
+
+LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
+ obj = abs_index(L, obj);
+ if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
+ return 0;
+ lua_pushvalue(L, obj);
+ lua_call(L, 1, 1);
+ return 1;
+}
+
+
+LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
+ const luaL_reg *l, int nup) {
+ if (libname) {
+ lua_pushstring(L, libname);
+ lua_gettable(L, LUA_GLOBALSINDEX); /* check whether lib already exists */
+ if (lua_isnil(L, -1)) { /* no? */
+ lua_pop(L, 1);
+ lua_newtable(L); /* create it */
+ lua_pushstring(L, libname);
+ lua_pushvalue(L, -2);
+ lua_settable(L, LUA_GLOBALSINDEX); /* register it with given name */
+ }
+ lua_insert(L, -(nup+1)); /* move library table to below upvalues */
+ }
+ for (; l->name; l++) {
+ int i;
+ lua_pushstring(L, l->name);
+ for (i=0; i<nup; i++) /* copy upvalues to the top */
+ lua_pushvalue(L, -(nup+1));
+ lua_pushcclosure(L, l->func, nup);
+ lua_settable(L, -(nup+3));
+ }
+ lua_pop(L, nup); /* remove upvalues */
+}
+
+
+
+/*
+** {======================================================
+** getn-setn: size for arrays
+** =======================================================
+*/
+
+static int checkint (lua_State *L, int topop) {
+ int n = (int)lua_tonumber(L, -1);
+ if (n == 0 && !lua_isnumber(L, -1)) n = -1;
+ lua_pop(L, topop);
+ return n;
+}
+
+
+static void getsizes (lua_State *L) {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF);
+ if (lua_isnil(L, -1)) { /* no `size' table? */
+ lua_pop(L, 1); /* remove nil */
+ lua_newtable(L); /* create it */
+ lua_pushvalue(L, -1); /* `size' will be its own metatable */
+ lua_setmetatable(L, -2);
+ lua_pushliteral(L, "__mode");
+ lua_pushliteral(L, "k");
+ lua_rawset(L, -3); /* metatable(N).__mode = "k" */
+ lua_pushvalue(L, -1);
+ lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */
+ }
+}
+
+
+void luaL_setn (lua_State *L, int t, int n) {
+ t = abs_index(L, t);
+ lua_pushliteral(L, "n");
+ lua_rawget(L, t);
+ if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
+ lua_pushliteral(L, "n"); /* use it */
+ lua_pushnumber(L, (lua_Number)n);
+ lua_rawset(L, t);
+ }
+ else { /* use `sizes' */
+ getsizes(L);
+ lua_pushvalue(L, t);
+ lua_pushnumber(L, (lua_Number)n);
+ lua_rawset(L, -3); /* sizes[t] = n */
+ lua_pop(L, 1); /* remove `sizes' */
+ }
+}
+
+
+int luaL_getn (lua_State *L, int t) {
+ int n;
+ t = abs_index(L, t);
+ lua_pushliteral(L, "n"); /* try t.n */
+ lua_rawget(L, t);
+ if ((n = checkint(L, 1)) >= 0) return n;
+ getsizes(L); /* else try sizes[t] */
+ lua_pushvalue(L, t);
+ lua_rawget(L, -2);
+ if ((n = checkint(L, 2)) >= 0) return n;
+ for (n = 1; ; n++) { /* else must count elements */
+ lua_rawgeti(L, t, n);
+ if (lua_isnil(L, -1)) break;
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 1);
+ return n - 1;
+}
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** Generic Buffer manipulation
+** =======================================================
+*/
+
+
+#define bufflen(B) ((B)->p - (B)->buffer)
+#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
+
+#define LIMIT (LUA_MINSTACK/2)
+
+
+static int emptybuffer (luaL_Buffer *B) {
+ size_t l = bufflen(B);
+ if (l == 0) return 0; /* put nothing on stack */
+ else {
+ lua_pushlstring(B->L, B->buffer, l);
+ B->p = B->buffer;
+ B->lvl++;
+ return 1;
+ }
+}
+
+
+static void adjuststack (luaL_Buffer *B) {
+ if (B->lvl > 1) {
+ lua_State *L = B->L;
+ int toget = 1; /* number of levels to concat */
+ size_t toplen = lua_strlen(L, -1);
+ do {
+ size_t l = lua_strlen(L, -(toget+1));
+ if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
+ toplen += l;
+ toget++;
+ }
+ else break;
+ } while (toget < B->lvl);
+ lua_concat(L, toget);
+ B->lvl = B->lvl - toget + 1;
+ }
+}
+
+
+LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
+ if (emptybuffer(B))
+ adjuststack(B);
+ return B->buffer;
+}
+
+
+LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
+ while (l--)
+ luaL_putchar(B, *s++);
+}
+
+
+LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
+ luaL_addlstring(B, s, strlen(s));
+}
+
+
+LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
+ emptybuffer(B);
+ lua_concat(B->L, B->lvl);
+ B->lvl = 1;
+}
+
+
+LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
+ lua_State *L = B->L;
+ size_t vl = lua_strlen(L, -1);
+ if (vl <= bufffree(B)) { /* fit into buffer? */
+ memcpy(B->p, lua_tostring(L, -1), vl); /* put it there */
+ B->p += vl;
+ lua_pop(L, 1); /* remove from stack */
+ }
+ else {
+ if (emptybuffer(B))
+ lua_insert(L, -2); /* put buffer before new value */
+ B->lvl++; /* add new value into B stack */
+ adjuststack(B);
+ }
+}
+
+
+LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
+ B->L = L;
+ B->p = B->buffer;
+ B->lvl = 0;
+}
+
+/* }====================================================== */
+
+
+LUALIB_API int luaL_ref (lua_State *L, int t) {
+ int ref;
+ t = abs_index(L, t);
+ if (lua_isnil(L, -1)) {
+ lua_pop(L, 1); /* remove from stack */
+ return LUA_REFNIL; /* `nil' has a unique fixed reference */
+ }
+ lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
+ ref = (int)lua_tonumber(L, -1); /* ref = t[FREELIST_REF] */
+ lua_pop(L, 1); /* remove it from stack */
+ if (ref != 0) { /* any free element? */
+ lua_rawgeti(L, t, ref); /* remove it from list */
+ lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
+ }
+ else { /* no free elements */
+ ref = luaL_getn(L, t);
+ if (ref < RESERVED_REFS)
+ ref = RESERVED_REFS; /* skip reserved references */
+ ref++; /* create new reference */
+ luaL_setn(L, t, ref);
+ }
+ lua_rawseti(L, t, ref);
+ return ref;
+}
+
+
+LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
+ if (ref >= 0) {
+ t = abs_index(L, t);
+ lua_rawgeti(L, t, FREELIST_REF);
+ lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
+ lua_pushnumber(L, (lua_Number)ref);
+ lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
+ }
+}
+
+
+
+/*
+** {======================================================
+** Load functions
+** =======================================================
+*/
+
+typedef struct LoadF {
+ FILE *f;
+ char buff[LUAL_BUFFERSIZE];
+} LoadF;
+
+
+static const char *getF (lua_State *L, void *ud, size_t *size) {
+ LoadF *lf = (LoadF *)ud;
+ (void)L;
+ if (feof(lf->f)) return NULL;
+ *size = fread(lf->buff, 1, LUAL_BUFFERSIZE, lf->f);
+ return (*size > 0) ? lf->buff : NULL;
+}
+
+
+static int errfile (lua_State *L, int fnameindex) {
+ const char *filename = lua_tostring(L, fnameindex) + 1;
+ lua_pushfstring(L, "cannot read %s: %s", filename, strerror(errno));
+ lua_remove(L, fnameindex);
+ return LUA_ERRFILE;
+}
+
+
+LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
+ LoadF lf;
+ int status, readstatus;
+ int c;
+ int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
+ if (filename == NULL) {
+ lua_pushliteral(L, "=stdin");
+ lf.f = stdin;
+ }
+ else {
+ lua_pushfstring(L, "@%s", filename);
+ lf.f = fopen(filename, "r");
+ }
+ if (lf.f == NULL) return errfile(L, fnameindex); /* unable to open file */
+ c = ungetc(getc(lf.f), lf.f);
+ if (!(isspace(c) || isprint(c)) && lf.f != stdin) { /* binary file? */
+ fclose(lf.f);
+ lf.f = fopen(filename, "rb"); /* reopen in binary mode */
+ if (lf.f == NULL) return errfile(L, fnameindex); /* unable to reopen file */
+ }
+ status = lua_load(L, getF, &lf, lua_tostring(L, -1));
+ readstatus = ferror(lf.f);
+ if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */
+ if (readstatus) {
+ lua_settop(L, fnameindex); /* ignore results from `lua_load' */
+ return errfile(L, fnameindex);
+ }
+ lua_remove(L, fnameindex);
+ return status;
+}
+
+
+typedef struct LoadS {
+ const char *s;
+ size_t size;
+} LoadS;
+
+
+static const char *getS (lua_State *L, void *ud, size_t *size) {
+ LoadS *ls = (LoadS *)ud;
+ (void)L;
+ if (ls->size == 0) return NULL;
+ *size = ls->size;
+ ls->size = 0;
+ return ls->s;
+}
+
+
+LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
+ const char *name) {
+ LoadS ls;
+ ls.s = buff;
+ ls.size = size;
+ return lua_load(L, getS, &ls, name);
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** compatibility code
+** =======================================================
+*/
+
+
+static void callalert (lua_State *L, int status) {
+ if (status != 0) {
+ lua_getglobal(L, "_ALERT");
+ if (lua_isfunction(L, -1)) {
+ lua_insert(L, -2);
+ lua_call(L, 1, 0);
+ }
+ else { /* no _ALERT function; print it on stderr */
+ fprintf(stderr, "%s\n", lua_tostring(L, -2));
+ lua_pop(L, 2); /* remove error message and _ALERT */
+ }
+ }
+}
+
+
+static int aux_do (lua_State *L, int status) {
+ if (status == 0) { /* parse OK? */
+ status = lua_pcall(L, 0, LUA_MULTRET, 0); /* call main */
+ }
+ callalert(L, status);
+ return status;
+}
+
+
+LUALIB_API int lua_dofile (lua_State *L, const char *filename) {
+ return aux_do(L, luaL_loadfile(L, filename));
+}
+
+
+LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t size,
+ const char *name) {
+ return aux_do(L, luaL_loadbuffer(L, buff, size, name));
+}
+
+
+LUALIB_API int lua_dostring (lua_State *L, const char *str) {
+ return lua_dobuffer(L, str, strlen(str), str);
+}
+
+/* }====================================================== */
diff --git a/lib/lua/src/LuaLib/lbaselib.c b/lib/lua/src/LuaLib/lbaselib.c
index 6c928b5..11e5504 100644
--- a/lib/lua/src/LuaLib/lbaselib.c
+++ b/lib/lua/src/LuaLib/lbaselib.c
@@ -1,674 +1,674 @@
-/*
-** $Id: lbaselib.c,v 1.3 2004-11-27 21:35:21 pixel Exp $
-** Basic library
-** See Copyright Notice in lua.h
-*/
-
-
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define lbaselib_c
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-
-
-/*
-** If your system does not support `stdout', you can just remove this function.
-** If you need, you can define your own `print' function, following this
-** model but changing `fputs' to put the strings at a proper place
-** (a console window or a log file, for instance).
-*/
-static int luaB_print (lua_State *L) {
- int n = lua_gettop(L); /* number of arguments */
- int i;
- lua_getglobal(L, "tostring");
- for (i=1; i<=n; i++) {
- const char *s;
- lua_pushvalue(L, -1); /* function to be called */
- lua_pushvalue(L, i); /* value to print */
- lua_call(L, 1, 1);
- s = lua_tostring(L, -1); /* get result */
- if (s == NULL)
- return luaL_error(L, "`tostring' must return a string to `print'");
- if (i>1) fputs("\t", stdout);
- fputs(s, stdout);
- lua_pop(L, 1); /* pop result */
- }
- fputs("\n", stdout);
- return 0;
-}
-
-
-static int luaB_tonumber (lua_State *L) {
- int base = luaL_optint(L, 2, 10);
- if (base == 10) { /* standard conversion */
- luaL_checkany(L, 1);
- if (lua_isnumber(L, 1)) {
- lua_pushnumber(L, lua_tonumber(L, 1));
- return 1;
- }
- }
- else {
- const char *s1 = luaL_checkstring(L, 1);
- char *s2;
- unsigned long n;
- luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
- n = strtoul(s1, &s2, base);
- if (s1 != s2) { /* at least one valid digit? */
- while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
- if (*s2 == '\0') { /* no invalid trailing characters? */
- lua_pushnumber(L, (lua_Number)n);
- return 1;
- }
- }
- }
- lua_pushnil(L); /* else not a number */
- return 1;
-}
-
-
-static int luaB_error (lua_State *L) {
- int level = luaL_optint(L, 2, 1);
- luaL_checkany(L, 1);
- if (!lua_isstring(L, 1) || level == 0)
- lua_pushvalue(L, 1); /* propagate error message without changes */
- else { /* add extra information */
- luaL_where(L, level);
- lua_pushvalue(L, 1);
- lua_concat(L, 2);
- }
- return lua_error(L);
-}
-
-
-static int luaB_getmetatable (lua_State *L) {
- luaL_checkany(L, 1);
- if (!lua_getmetatable(L, 1)) {
- lua_pushnil(L);
- return 1; /* no metatable */
- }
- luaL_getmetafield(L, 1, "__metatable");
- return 1; /* returns either __metatable field (if present) or metatable */
-}
-
-
-static int luaB_setmetatable (lua_State *L) {
- int t = lua_type(L, 2);
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
- "nil or table expected");
- if (luaL_getmetafield(L, 1, "__metatable"))
- luaL_error(L, "cannot change a protected metatable");
- lua_settop(L, 2);
- lua_setmetatable(L, 1);
- return 1;
-}
-
-
-static void getfunc (lua_State *L) {
- if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
- else {
- lua_Debug ar;
- int level = luaL_optint(L, 1, 1);
- luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
- if (lua_getstack(L, level, &ar) == 0)
- luaL_argerror(L, 1, "invalid level");
- lua_getinfo(L, "f", &ar);
- if (lua_isnil(L, -1))
- luaL_error(L, "no function environment for tail call at level %d",
- level);
- }
-}
-
-
-static int aux_getfenv (lua_State *L) {
- lua_getfenv(L, -1);
- lua_pushliteral(L, "__fenv");
- lua_rawget(L, -2);
- return !lua_isnil(L, -1);
-}
-
-
-static int luaB_getfenv (lua_State *L) {
- getfunc(L);
- if (!aux_getfenv(L)) /* __fenv not defined? */
- lua_pop(L, 1); /* remove it, to return real environment */
- return 1;
-}
-
-
-static int luaB_setfenv (lua_State *L) {
- luaL_checktype(L, 2, LUA_TTABLE);
- getfunc(L);
- if (aux_getfenv(L)) /* __fenv defined? */
- luaL_error(L, "`setfenv' cannot change a protected environment");
- else
- lua_pop(L, 2); /* remove __fenv and real environment table */
- lua_pushvalue(L, 2);
- if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0)
- lua_replace(L, LUA_GLOBALSINDEX);
- else if (lua_setfenv(L, -2) == 0)
- luaL_error(L, "`setfenv' cannot change environment of given function");
- return 0;
-}
-
-
-static int luaB_rawequal (lua_State *L) {
- luaL_checkany(L, 1);
- luaL_checkany(L, 2);
- lua_pushboolean(L, lua_rawequal(L, 1, 2));
- return 1;
-}
-
-
-static int luaB_rawget (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_checkany(L, 2);
- lua_rawget(L, 1);
- return 1;
-}
-
-static int luaB_rawset (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_checkany(L, 2);
- luaL_checkany(L, 3);
- lua_rawset(L, 1);
- return 1;
-}
-
-
-static int luaB_gcinfo (lua_State *L) {
- lua_pushnumber(L, (lua_Number)lua_getgccount(L));
- lua_pushnumber(L, (lua_Number)lua_getgcthreshold(L));
- return 2;
-}
-
-
-static int luaB_collectgarbage (lua_State *L) {
- lua_setgcthreshold(L, luaL_optint(L, 1, 0));
- return 0;
-}
-
-
-static int luaB_type (lua_State *L) {
- luaL_checkany(L, 1);
- lua_pushstring(L, lua_typename(L, lua_type(L, 1)));
- return 1;
-}
-
-
-static int luaB_next (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- lua_settop(L, 2); /* create a 2nd argument if there isn't one */
- if (lua_next(L, 1))
- return 2;
- else {
- lua_pushnil(L);
- return 1;
- }
-}
-
-
-static int luaB_pairs (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- lua_pushliteral(L, "next");
- lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */
- lua_pushvalue(L, 1); /* state, */
- lua_pushnil(L); /* and initial value */
- return 3;
-}
-
-
-static int luaB_ipairs (lua_State *L) {
- lua_Number i = lua_tonumber(L, 2);
- luaL_checktype(L, 1, LUA_TTABLE);
- if (i == 0 && lua_isnone(L, 2)) { /* `for' start? */
- lua_pushliteral(L, "ipairs");
- lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */
- lua_pushvalue(L, 1); /* state, */
- lua_pushnumber(L, 0); /* and initial value */
- return 3;
- }
- else { /* `for' step */
- i++; /* next value */
- lua_pushnumber(L, i);
- lua_rawgeti(L, 1, (int)i);
- return (lua_isnil(L, -1)) ? 0 : 2;
- }
-}
-
-
-static int load_aux (lua_State *L, int status) {
- if (status == 0) /* OK? */
- return 1;
- else {
- lua_pushnil(L);
- lua_insert(L, -2); /* put before error message */
- return 2; /* return nil plus error message */
- }
-}
-
-
-static int luaB_loadstring (lua_State *L) {
- size_t l;
- const char *s = luaL_checklstring(L, 1, &l);
- const char *chunkname = luaL_optstring(L, 2, s);
- return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
-}
-
-
-static int luaB_loadfile (lua_State *L) {
- const char *fname = luaL_optstring(L, 1, NULL);
- return load_aux(L, luaL_loadfile(L, fname));
-}
-
-
-static int luaB_dofile (lua_State *L) {
- const char *fname = luaL_optstring(L, 1, NULL);
- int status = luaL_loadfile(L, fname);
- if (status != 0) lua_error(L);
- lua_call(L, 0, LUA_MULTRET);
- return lua_gettop(L) - 1;
-}
-
-
-static int luaB_assert (lua_State *L) {
- luaL_checkany(L, 1);
- if (!lua_toboolean(L, 1))
- return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
- lua_settop(L, 1);
- return 1;
-}
-
-
-static int luaB_unpack (lua_State *L) {
- int n, i;
- luaL_checktype(L, 1, LUA_TTABLE);
- n = luaL_getn(L, 1);
- luaL_checkstack(L, n, "table too big to unpack");
- for (i=1; i<=n; i++) /* push arg[1...n] */
- lua_rawgeti(L, 1, i);
- return n;
-}
-
-
-static int luaB_pcall (lua_State *L) {
- int status;
- luaL_checkany(L, 1);
- status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
- lua_pushboolean(L, (status == 0));
- lua_insert(L, 1);
- return lua_gettop(L); /* return status + all results */
-}
-
-
-static int luaB_xpcall (lua_State *L) {
- int status;
- luaL_checkany(L, 2);
- lua_settop(L, 2);
- lua_insert(L, 1); /* put error function under function to be called */
- status = lua_pcall(L, 0, LUA_MULTRET, 1);
- lua_pushboolean(L, (status == 0));
- lua_replace(L, 1);
- return lua_gettop(L); /* return status + all results */
-}
-
-
-static int luaB_tostring (lua_State *L) {
- char buff[64];
- luaL_checkany(L, 1);
- if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
- return 1; /* use its value */
- switch (lua_type(L, 1)) {
- case LUA_TNUMBER:
- lua_pushstring(L, lua_tostring(L, 1));
- return 1;
- case LUA_TSTRING:
- lua_pushvalue(L, 1);
- return 1;
- case LUA_TBOOLEAN:
- lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
- return 1;
- case LUA_TTABLE:
- sprintf(buff, "table: %p", lua_topointer(L, 1));
- break;
- case LUA_TFUNCTION:
- sprintf(buff, "function: %p", lua_topointer(L, 1));
- break;
- case LUA_TUSERDATA:
- case LUA_TLIGHTUSERDATA:
- sprintf(buff, "userdata: %p", lua_touserdata(L, 1));
- break;
- case LUA_TTHREAD:
- sprintf(buff, "thread: %p", (void *)lua_tothread(L, 1));
- break;
- case LUA_TNIL:
- lua_pushliteral(L, "nil");
- return 1;
- }
- lua_pushstring(L, buff);
- return 1;
-}
-
-
-static int luaB_newproxy (lua_State *L) {
- lua_settop(L, 1);
- lua_newuserdata(L, 0); /* create proxy */
- if (lua_toboolean(L, 1) == 0)
- return 1; /* no metatable */
- else if (lua_isboolean(L, 1)) {
- lua_newtable(L); /* create a new metatable `m' ... */
- lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
- lua_pushboolean(L, 1);
- lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
- }
- else {
- int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
- if (lua_getmetatable(L, 1)) {
- lua_rawget(L, lua_upvalueindex(1));
- validproxy = lua_toboolean(L, -1);
- lua_pop(L, 1); /* remove value */
- }
- luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
- lua_getmetatable(L, 1); /* metatable is valid; get it */
- }
- lua_setmetatable(L, 2);
- return 1;
-}
-
-
-/*
-** {======================================================
-** `require' function
-** =======================================================
-*/
-
-
-/* name of global that holds table with loaded packages */
-#define REQTAB "_LOADED"
-
-/* name of global that holds the search path for packages */
-#define LUA_PATH "LUA_PATH"
-
-#ifndef LUA_PATH_SEP
-#define LUA_PATH_SEP ';'
-#endif
-
-#ifndef LUA_PATH_MARK
-#define LUA_PATH_MARK '?'
-#endif
-
-#ifndef LUA_PATH_DEFAULT
-#define LUA_PATH_DEFAULT "?;?.lua"
-#endif
-
-
-static const char *getpath (lua_State *L) {
- const char *path;
- lua_getglobal(L, LUA_PATH); /* try global variable */
- path = lua_tostring(L, -1);
- lua_pop(L, 1);
- if (path) return path;
- path = getenv(LUA_PATH); /* else try environment variable */
- if (path) return path;
- return LUA_PATH_DEFAULT; /* else use default */
-}
-
-
-static const char *pushnextpath (lua_State *L, const char *path) {
- const char *l;
- if (*path == '\0') return NULL; /* no more paths */
- if (*path == LUA_PATH_SEP) path++; /* skip separator */
- l = strchr(path, LUA_PATH_SEP); /* find next separator */
- if (l == NULL) l = path+strlen(path);
- lua_pushlstring(L, path, l - path); /* directory name */
- return l;
-}
-
-
-static void pushcomposename (lua_State *L) {
- const char *path = lua_tostring(L, -1);
- const char *wild;
- int n = 1;
- while ((wild = strchr(path, LUA_PATH_MARK)) != NULL) {
- /* is there stack space for prefix, name, and eventual last sufix? */
- luaL_checkstack(L, 3, "too many marks in a path component");
- lua_pushlstring(L, path, wild - path); /* push prefix */
- lua_pushvalue(L, 1); /* push package name (in place of MARK) */
- path = wild + 1; /* continue after MARK */
- n += 2;
- }
- lua_pushstring(L, path); /* push last sufix (`n' already includes this) */
- lua_concat(L, n);
-}
-
-
-static int luaB_require (lua_State *L) {
- const char *path;
- int status = LUA_ERRFILE; /* not found (yet) */
- luaL_checkstring(L, 1);
- lua_settop(L, 1);
- lua_getglobal(L, REQTAB);
- if (!lua_istable(L, 2)) return luaL_error(L, "`" REQTAB "' is not a table");
- path = getpath(L);
- lua_pushvalue(L, 1); /* check package's name in book-keeping table */
- lua_rawget(L, 2);
- if (lua_toboolean(L, -1)) /* is it there? */
- return 1; /* package is already loaded; return its result */
- else { /* must load it */
- while (status == LUA_ERRFILE) {
- lua_settop(L, 3); /* reset stack position */
- if ((path = pushnextpath(L, path)) == NULL) break;
- pushcomposename(L);
- status = luaL_loadfile(L, lua_tostring(L, -1)); /* try to load it */
- }
- }
- switch (status) {
- case 0: {
- lua_getglobal(L, "_REQUIREDNAME"); /* save previous name */
- lua_insert(L, -2); /* put it below function */
- lua_pushvalue(L, 1);
- lua_setglobal(L, "_REQUIREDNAME"); /* set new name */
- lua_call(L, 0, 1); /* run loaded module */
- lua_insert(L, -2); /* put result below previous name */
- lua_setglobal(L, "_REQUIREDNAME"); /* reset to previous name */
- if (lua_isnil(L, -1)) { /* no/nil return? */
- lua_pushboolean(L, 1);
- lua_replace(L, -2); /* replace to true */
- }
- lua_pushvalue(L, 1);
- lua_pushvalue(L, -2);
- lua_rawset(L, 2); /* mark it as loaded */
- return 1; /* return value */
- }
- case LUA_ERRFILE: { /* file not found */
- return luaL_error(L, "could not load package `%s' from path `%s'",
- lua_tostring(L, 1), getpath(L));
- }
- default: {
- return luaL_error(L, "error loading package `%s' (%s)",
- lua_tostring(L, 1), lua_tostring(L, -1));
- }
- }
-}
-
-/* }====================================================== */
-
-
-static const luaL_reg base_funcs[] = {
- {"error", luaB_error},
- {"getmetatable", luaB_getmetatable},
- {"setmetatable", luaB_setmetatable},
- {"getfenv", luaB_getfenv},
- {"setfenv", luaB_setfenv},
- {"next", luaB_next},
- {"ipairs", luaB_ipairs},
- {"pairs", luaB_pairs},
- {"print", luaB_print},
- {"tonumber", luaB_tonumber},
- {"tostring", luaB_tostring},
- {"type", luaB_type},
- {"assert", luaB_assert},
- {"unpack", luaB_unpack},
- {"rawequal", luaB_rawequal},
- {"rawget", luaB_rawget},
- {"rawset", luaB_rawset},
- {"pcall", luaB_pcall},
- {"xpcall", luaB_xpcall},
- {"collectgarbage", luaB_collectgarbage},
- {"gcinfo", luaB_gcinfo},
- {"loadfile", luaB_loadfile},
- {"dofile", luaB_dofile},
- {"loadstring", luaB_loadstring},
- {"require", luaB_require},
- {NULL, NULL}
-};
-
-
-/*
-** {======================================================
-** Coroutine library
-** =======================================================
-*/
-
-static int auxresume (lua_State *L, lua_State *co, int narg) {
- int status;
- if (!lua_checkstack(co, narg))
- luaL_error(L, "too many arguments to resume");
- lua_xmove(L, co, narg);
- status = lua_resume(co, narg);
- if (status == 0) {
- int nres = lua_gettop(co);
- if (!lua_checkstack(L, nres))
- luaL_error(L, "too many results to resume");
- lua_xmove(co, L, nres); /* move yielded values */
- return nres;
- }
- else {
- lua_xmove(co, L, 1); /* move error message */
- return -1; /* error flag */
- }
-}
-
-
-static int luaB_coresume (lua_State *L) {
- lua_State *co = lua_tothread(L, 1);
- int r;
- luaL_argcheck(L, co, 1, "coroutine expected");
- r = auxresume(L, co, lua_gettop(L) - 1);
- if (r < 0) {
- lua_pushboolean(L, 0);
- lua_insert(L, -2);
- return 2; /* return false + error message */
- }
- else {
- lua_pushboolean(L, 1);
- lua_insert(L, -(r + 1));
- return r + 1; /* return true + `resume' returns */
- }
-}
-
-
-static int luaB_auxwrap (lua_State *L) {
- lua_State *co = lua_tothread(L, lua_upvalueindex(1));
- int r = auxresume(L, co, lua_gettop(L));
- if (r < 0) {
- if (lua_isstring(L, -1)) { /* error object is a string? */
- luaL_where(L, 1); /* add extra info */
- lua_insert(L, -2);
- lua_concat(L, 2);
- }
- lua_error(L); /* propagate error */
- }
- return r;
-}
-
-
-static int luaB_cocreate (lua_State *L) {
- lua_State *NL = lua_newthread(L);
- luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
- "Lua function expected");
- lua_pushvalue(L, 1); /* move function to top */
- lua_xmove(L, NL, 1); /* move function from L to NL */
- return 1;
-}
-
-
-static int luaB_cowrap (lua_State *L) {
- luaB_cocreate(L);
- lua_pushcclosure(L, luaB_auxwrap, 1);
- return 1;
-}
-
-
-static int luaB_yield (lua_State *L) {
- return lua_yield(L, lua_gettop(L));
-}
-
-
-static int luaB_costatus (lua_State *L) {
- lua_State *co = lua_tothread(L, 1);
- luaL_argcheck(L, co, 1, "coroutine expected");
- if (L == co) lua_pushliteral(L, "running");
- else {
- lua_Debug ar;
- if (lua_getstack(co, 0, &ar) == 0 && lua_gettop(co) == 0)
- lua_pushliteral(L, "dead");
- else
- lua_pushliteral(L, "suspended");
- }
- return 1;
-}
-
-
-static const luaL_reg co_funcs[] = {
- {"create", luaB_cocreate},
- {"wrap", luaB_cowrap},
- {"resume", luaB_coresume},
- {"yield", luaB_yield},
- {"status", luaB_costatus},
- {NULL, NULL}
-};
-
-/* }====================================================== */
-
-
-
-static void base_open (lua_State *L) {
- lua_pushliteral(L, "_G");
- lua_pushvalue(L, LUA_GLOBALSINDEX);
- luaL_openlib(L, NULL, base_funcs, 0); /* open lib into global table */
- lua_pushliteral(L, "_VERSION");
- lua_pushliteral(L, LUA_VERSION);
- lua_rawset(L, -3); /* set global _VERSION */
- /* `newproxy' needs a weaktable as upvalue */
- lua_pushliteral(L, "newproxy");
- lua_newtable(L); /* new table `w' */
- lua_pushvalue(L, -1); /* `w' will be its own metatable */
- lua_setmetatable(L, -2);
- lua_pushliteral(L, "__mode");
- lua_pushliteral(L, "k");
- lua_rawset(L, -3); /* metatable(w).__mode = "k" */
- lua_pushcclosure(L, luaB_newproxy, 1);
- lua_rawset(L, -3); /* set global `newproxy' */
- lua_rawset(L, -1); /* set global _G */
-}
-
-
-LUALIB_API int luaopen_base (lua_State *L) {
- base_open(L);
- luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0);
- lua_newtable(L);
- lua_setglobal(L, REQTAB);
- return 0;
-}
-
+/*
+** $Id: lbaselib.c,v 1.4 2004-11-27 21:46:10 pixel Exp $
+** Basic library
+** See Copyright Notice in lua.h
+*/
+
+
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lbaselib_c
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+
+
+/*
+** If your system does not support `stdout', you can just remove this function.
+** If you need, you can define your own `print' function, following this
+** model but changing `fputs' to put the strings at a proper place
+** (a console window or a log file, for instance).
+*/
+static int luaB_print (lua_State *L) {
+ int n = lua_gettop(L); /* number of arguments */
+ int i;
+ lua_getglobal(L, "tostring");
+ for (i=1; i<=n; i++) {
+ const char *s;
+ lua_pushvalue(L, -1); /* function to be called */
+ lua_pushvalue(L, i); /* value to print */
+ lua_call(L, 1, 1);
+ s = lua_tostring(L, -1); /* get result */
+ if (s == NULL)
+ return luaL_error(L, "`tostring' must return a string to `print'");
+ if (i>1) fputs("\t", stdout);
+ fputs(s, stdout);
+ lua_pop(L, 1); /* pop result */
+ }
+ fputs("\n", stdout);
+ return 0;
+}
+
+
+static int luaB_tonumber (lua_State *L) {
+ int base = luaL_optint(L, 2, 10);
+ if (base == 10) { /* standard conversion */
+ luaL_checkany(L, 1);
+ if (lua_isnumber(L, 1)) {
+ lua_pushnumber(L, lua_tonumber(L, 1));
+ return 1;
+ }
+ }
+ else {
+ const char *s1 = luaL_checkstring(L, 1);
+ char *s2;
+ unsigned long n;
+ luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
+ n = strtoul(s1, &s2, base);
+ if (s1 != s2) { /* at least one valid digit? */
+ while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
+ if (*s2 == '\0') { /* no invalid trailing characters? */
+ lua_pushnumber(L, (lua_Number)n);
+ return 1;
+ }
+ }
+ }
+ lua_pushnil(L); /* else not a number */
+ return 1;
+}
+
+
+static int luaB_error (lua_State *L) {
+ int level = luaL_optint(L, 2, 1);
+ luaL_checkany(L, 1);
+ if (!lua_isstring(L, 1) || level == 0)
+ lua_pushvalue(L, 1); /* propagate error message without changes */
+ else { /* add extra information */
+ luaL_where(L, level);
+ lua_pushvalue(L, 1);
+ lua_concat(L, 2);
+ }
+ return lua_error(L);
+}
+
+
+static int luaB_getmetatable (lua_State *L) {
+ luaL_checkany(L, 1);
+ if (!lua_getmetatable(L, 1)) {
+ lua_pushnil(L);
+ return 1; /* no metatable */
+ }
+ luaL_getmetafield(L, 1, "__metatable");
+ return 1; /* returns either __metatable field (if present) or metatable */
+}
+
+
+static int luaB_setmetatable (lua_State *L) {
+ int t = lua_type(L, 2);
+ luaL_checktype(L, 1, LUA_TTABLE);
+ luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
+ "nil or table expected");
+ if (luaL_getmetafield(L, 1, "__metatable"))
+ luaL_error(L, "cannot change a protected metatable");
+ lua_settop(L, 2);
+ lua_setmetatable(L, 1);
+ return 1;
+}
+
+
+static void getfunc (lua_State *L) {
+ if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
+ else {
+ lua_Debug ar;
+ int level = luaL_optint(L, 1, 1);
+ luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
+ if (lua_getstack(L, level, &ar) == 0)
+ luaL_argerror(L, 1, "invalid level");
+ lua_getinfo(L, "f", &ar);
+ if (lua_isnil(L, -1))
+ luaL_error(L, "no function environment for tail call at level %d",
+ level);
+ }
+}
+
+
+static int aux_getfenv (lua_State *L) {
+ lua_getfenv(L, -1);
+ lua_pushliteral(L, "__fenv");
+ lua_rawget(L, -2);
+ return !lua_isnil(L, -1);
+}
+
+
+static int luaB_getfenv (lua_State *L) {
+ getfunc(L);
+ if (!aux_getfenv(L)) /* __fenv not defined? */
+ lua_pop(L, 1); /* remove it, to return real environment */
+ return 1;
+}
+
+
+static int luaB_setfenv (lua_State *L) {
+ luaL_checktype(L, 2, LUA_TTABLE);
+ getfunc(L);
+ if (aux_getfenv(L)) /* __fenv defined? */
+ luaL_error(L, "`setfenv' cannot change a protected environment");
+ else
+ lua_pop(L, 2); /* remove __fenv and real environment table */
+ lua_pushvalue(L, 2);
+ if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0)
+ lua_replace(L, LUA_GLOBALSINDEX);
+ else if (lua_setfenv(L, -2) == 0)
+ luaL_error(L, "`setfenv' cannot change environment of given function");
+ return 0;
+}
+
+
+static int luaB_rawequal (lua_State *L) {
+ luaL_checkany(L, 1);
+ luaL_checkany(L, 2);
+ lua_pushboolean(L, lua_rawequal(L, 1, 2));
+ return 1;
+}
+
+
+static int luaB_rawget (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ luaL_checkany(L, 2);
+ lua_rawget(L, 1);
+ return 1;
+}
+
+static int luaB_rawset (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ luaL_checkany(L, 2);
+ luaL_checkany(L, 3);
+ lua_rawset(L, 1);
+ return 1;
+}
+
+
+static int luaB_gcinfo (lua_State *L) {
+ lua_pushnumber(L, (lua_Number)lua_getgccount(L));
+ lua_pushnumber(L, (lua_Number)lua_getgcthreshold(L));
+ return 2;
+}
+
+
+static int luaB_collectgarbage (lua_State *L) {
+ lua_setgcthreshold(L, luaL_optint(L, 1, 0));
+ return 0;
+}
+
+
+static int luaB_type (lua_State *L) {
+ luaL_checkany(L, 1);
+ lua_pushstring(L, lua_typename(L, lua_type(L, 1)));
+ return 1;
+}
+
+
+static int luaB_next (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ lua_settop(L, 2); /* create a 2nd argument if there isn't one */
+ if (lua_next(L, 1))
+ return 2;
+ else {
+ lua_pushnil(L);
+ return 1;
+ }
+}
+
+
+static int luaB_pairs (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ lua_pushliteral(L, "next");
+ lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */
+ lua_pushvalue(L, 1); /* state, */
+ lua_pushnil(L); /* and initial value */
+ return 3;
+}
+
+
+static int luaB_ipairs (lua_State *L) {
+ lua_Number i = lua_tonumber(L, 2);
+ luaL_checktype(L, 1, LUA_TTABLE);
+ if (i == 0 && lua_isnone(L, 2)) { /* `for' start? */
+ lua_pushliteral(L, "ipairs");
+ lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */
+ lua_pushvalue(L, 1); /* state, */
+ lua_pushnumber(L, 0); /* and initial value */
+ return 3;
+ }
+ else { /* `for' step */
+ i++; /* next value */
+ lua_pushnumber(L, i);
+ lua_rawgeti(L, 1, (int)i);
+ return (lua_isnil(L, -1)) ? 0 : 2;
+ }
+}
+
+
+static int load_aux (lua_State *L, int status) {
+ if (status == 0) /* OK? */
+ return 1;
+ else {
+ lua_pushnil(L);
+ lua_insert(L, -2); /* put before error message */
+ return 2; /* return nil plus error message */
+ }
+}
+
+
+static int luaB_loadstring (lua_State *L) {
+ size_t l;
+ const char *s = luaL_checklstring(L, 1, &l);
+ const char *chunkname = luaL_optstring(L, 2, s);
+ return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
+}
+
+
+static int luaB_loadfile (lua_State *L) {
+ const char *fname = luaL_optstring(L, 1, NULL);
+ return load_aux(L, luaL_loadfile(L, fname));
+}
+
+
+static int luaB_dofile (lua_State *L) {
+ const char *fname = luaL_optstring(L, 1, NULL);
+ int status = luaL_loadfile(L, fname);
+ if (status != 0) lua_error(L);
+ lua_call(L, 0, LUA_MULTRET);
+ return lua_gettop(L) - 1;
+}
+
+
+static int luaB_assert (lua_State *L) {
+ luaL_checkany(L, 1);
+ if (!lua_toboolean(L, 1))
+ return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
+ lua_settop(L, 1);
+ return 1;
+}
+
+
+static int luaB_unpack (lua_State *L) {
+ int n, i;
+ luaL_checktype(L, 1, LUA_TTABLE);
+ n = luaL_getn(L, 1);
+ luaL_checkstack(L, n, "table too big to unpack");
+ for (i=1; i<=n; i++) /* push arg[1...n] */
+ lua_rawgeti(L, 1, i);
+ return n;
+}
+
+
+static int luaB_pcall (lua_State *L) {
+ int status;
+ luaL_checkany(L, 1);
+ status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
+ lua_pushboolean(L, (status == 0));
+ lua_insert(L, 1);
+ return lua_gettop(L); /* return status + all results */
+}
+
+
+static int luaB_xpcall (lua_State *L) {
+ int status;
+ luaL_checkany(L, 2);
+ lua_settop(L, 2);
+ lua_insert(L, 1); /* put error function under function to be called */
+ status = lua_pcall(L, 0, LUA_MULTRET, 1);
+ lua_pushboolean(L, (status == 0));
+ lua_replace(L, 1);
+ return lua_gettop(L); /* return status + all results */
+}
+
+
+static int luaB_tostring (lua_State *L) {
+ char buff[64];
+ luaL_checkany(L, 1);
+ if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
+ return 1; /* use its value */
+ switch (lua_type(L, 1)) {
+ case LUA_TNUMBER:
+ lua_pushstring(L, lua_tostring(L, 1));
+ return 1;
+ case LUA_TSTRING:
+ lua_pushvalue(L, 1);
+ return 1;
+ case LUA_TBOOLEAN:
+ lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
+ return 1;
+ case LUA_TTABLE:
+ sprintf(buff, "table: %p", lua_topointer(L, 1));
+ break;
+ case LUA_TFUNCTION:
+ sprintf(buff, "function: %p", lua_topointer(L, 1));
+ break;
+ case LUA_TUSERDATA:
+ case LUA_TLIGHTUSERDATA:
+ sprintf(buff, "userdata: %p", lua_touserdata(L, 1));
+ break;
+ case LUA_TTHREAD:
+ sprintf(buff, "thread: %p", (void *)lua_tothread(L, 1));
+ break;
+ case LUA_TNIL:
+ lua_pushliteral(L, "nil");
+ return 1;
+ }
+ lua_pushstring(L, buff);
+ return 1;
+}
+
+
+static int luaB_newproxy (lua_State *L) {
+ lua_settop(L, 1);
+ lua_newuserdata(L, 0); /* create proxy */
+ if (lua_toboolean(L, 1) == 0)
+ return 1; /* no metatable */
+ else if (lua_isboolean(L, 1)) {
+ lua_newtable(L); /* create a new metatable `m' ... */
+ lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
+ lua_pushboolean(L, 1);
+ lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
+ }
+ else {
+ int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
+ if (lua_getmetatable(L, 1)) {
+ lua_rawget(L, lua_upvalueindex(1));
+ validproxy = lua_toboolean(L, -1);
+ lua_pop(L, 1); /* remove value */
+ }
+ luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
+ lua_getmetatable(L, 1); /* metatable is valid; get it */
+ }
+ lua_setmetatable(L, 2);
+ return 1;
+}
+
+
+/*
+** {======================================================
+** `require' function
+** =======================================================
+*/
+
+
+/* name of global that holds table with loaded packages */
+#define REQTAB "_LOADED"
+
+/* name of global that holds the search path for packages */
+#define LUA_PATH "LUA_PATH"
+
+#ifndef LUA_PATH_SEP
+#define LUA_PATH_SEP ';'
+#endif
+
+#ifndef LUA_PATH_MARK
+#define LUA_PATH_MARK '?'
+#endif
+
+#ifndef LUA_PATH_DEFAULT
+#define LUA_PATH_DEFAULT "?;?.lua"
+#endif
+
+
+static const char *getpath (lua_State *L) {
+ const char *path;
+ lua_getglobal(L, LUA_PATH); /* try global variable */
+ path = lua_tostring(L, -1);
+ lua_pop(L, 1);
+ if (path) return path;
+ path = getenv(LUA_PATH); /* else try environment variable */
+ if (path) return path;
+ return LUA_PATH_DEFAULT; /* else use default */
+}
+
+
+static const char *pushnextpath (lua_State *L, const char *path) {
+ const char *l;
+ if (*path == '\0') return NULL; /* no more paths */
+ if (*path == LUA_PATH_SEP) path++; /* skip separator */
+ l = strchr(path, LUA_PATH_SEP); /* find next separator */
+ if (l == NULL) l = path+strlen(path);
+ lua_pushlstring(L, path, l - path); /* directory name */
+ return l;
+}
+
+
+static void pushcomposename (lua_State *L) {
+ const char *path = lua_tostring(L, -1);
+ const char *wild;
+ int n = 1;
+ while ((wild = strchr(path, LUA_PATH_MARK)) != NULL) {
+ /* is there stack space for prefix, name, and eventual last sufix? */
+ luaL_checkstack(L, 3, "too many marks in a path component");
+ lua_pushlstring(L, path, wild - path); /* push prefix */
+ lua_pushvalue(L, 1); /* push package name (in place of MARK) */
+ path = wild + 1; /* continue after MARK */
+ n += 2;
+ }
+ lua_pushstring(L, path); /* push last sufix (`n' already includes this) */
+ lua_concat(L, n);
+}
+
+
+static int luaB_require (lua_State *L) {
+ const char *path;
+ int status = LUA_ERRFILE; /* not found (yet) */
+ luaL_checkstring(L, 1);
+ lua_settop(L, 1);
+ lua_getglobal(L, REQTAB);
+ if (!lua_istable(L, 2)) return luaL_error(L, "`" REQTAB "' is not a table");
+ path = getpath(L);
+ lua_pushvalue(L, 1); /* check package's name in book-keeping table */
+ lua_rawget(L, 2);
+ if (lua_toboolean(L, -1)) /* is it there? */
+ return 1; /* package is already loaded; return its result */
+ else { /* must load it */
+ while (status == LUA_ERRFILE) {
+ lua_settop(L, 3); /* reset stack position */
+ if ((path = pushnextpath(L, path)) == NULL) break;
+ pushcomposename(L);
+ status = luaL_loadfile(L, lua_tostring(L, -1)); /* try to load it */
+ }
+ }
+ switch (status) {
+ case 0: {
+ lua_getglobal(L, "_REQUIREDNAME"); /* save previous name */
+ lua_insert(L, -2); /* put it below function */
+ lua_pushvalue(L, 1);
+ lua_setglobal(L, "_REQUIREDNAME"); /* set new name */
+ lua_call(L, 0, 1); /* run loaded module */
+ lua_insert(L, -2); /* put result below previous name */
+ lua_setglobal(L, "_REQUIREDNAME"); /* reset to previous name */
+ if (lua_isnil(L, -1)) { /* no/nil return? */
+ lua_pushboolean(L, 1);
+ lua_replace(L, -2); /* replace to true */
+ }
+ lua_pushvalue(L, 1);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, 2); /* mark it as loaded */
+ return 1; /* return value */
+ }
+ case LUA_ERRFILE: { /* file not found */
+ return luaL_error(L, "could not load package `%s' from path `%s'",
+ lua_tostring(L, 1), getpath(L));
+ }
+ default: {
+ return luaL_error(L, "error loading package `%s' (%s)",
+ lua_tostring(L, 1), lua_tostring(L, -1));
+ }
+ }
+}
+
+/* }====================================================== */
+
+
+static const luaL_reg base_funcs[] = {
+ {"error", luaB_error},
+ {"getmetatable", luaB_getmetatable},
+ {"setmetatable", luaB_setmetatable},
+ {"getfenv", luaB_getfenv},
+ {"setfenv", luaB_setfenv},
+ {"next", luaB_next},
+ {"ipairs", luaB_ipairs},
+ {"pairs", luaB_pairs},
+ {"print", luaB_print},
+ {"tonumber", luaB_tonumber},
+ {"tostring", luaB_tostring},
+ {"type", luaB_type},
+ {"assert", luaB_assert},
+ {"unpack", luaB_unpack},
+ {"rawequal", luaB_rawequal},
+ {"rawget", luaB_rawget},
+ {"rawset", luaB_rawset},
+ {"pcall", luaB_pcall},
+ {"xpcall", luaB_xpcall},
+ {"collectgarbage", luaB_collectgarbage},
+ {"gcinfo", luaB_gcinfo},
+ {"loadfile", luaB_loadfile},
+ {"dofile", luaB_dofile},
+ {"loadstring", luaB_loadstring},
+ {"require", luaB_require},
+ {NULL, NULL}
+};
+
+
+/*
+** {======================================================
+** Coroutine library
+** =======================================================
+*/
+
+static int auxresume (lua_State *L, lua_State *co, int narg) {
+ int status;
+ if (!lua_checkstack(co, narg))
+ luaL_error(L, "too many arguments to resume");
+ lua_xmove(L, co, narg);
+ status = lua_resume(co, narg);
+ if (status == 0) {
+ int nres = lua_gettop(co);
+ if (!lua_checkstack(L, nres))
+ luaL_error(L, "too many results to resume");
+ lua_xmove(co, L, nres); /* move yielded values */
+ return nres;
+ }
+ else {
+ lua_xmove(co, L, 1); /* move error message */
+ return -1; /* error flag */
+ }
+}
+
+
+static int luaB_coresume (lua_State *L) {
+ lua_State *co = lua_tothread(L, 1);
+ int r;
+ luaL_argcheck(L, co, 1, "coroutine expected");
+ r = auxresume(L, co, lua_gettop(L) - 1);
+ if (r < 0) {
+ lua_pushboolean(L, 0);
+ lua_insert(L, -2);
+ return 2; /* return false + error message */
+ }
+ else {
+ lua_pushboolean(L, 1);
+ lua_insert(L, -(r + 1));
+ return r + 1; /* return true + `resume' returns */
+ }
+}
+
+
+static int luaB_auxwrap (lua_State *L) {
+ lua_State *co = lua_tothread(L, lua_upvalueindex(1));
+ int r = auxresume(L, co, lua_gettop(L));
+ if (r < 0) {
+ if (lua_isstring(L, -1)) { /* error object is a string? */
+ luaL_where(L, 1); /* add extra info */
+ lua_insert(L, -2);
+ lua_concat(L, 2);
+ }
+ lua_error(L); /* propagate error */
+ }
+ return r;
+}
+
+
+static int luaB_cocreate (lua_State *L) {
+ lua_State *NL = lua_newthread(L);
+ luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
+ "Lua function expected");
+ lua_pushvalue(L, 1); /* move function to top */
+ lua_xmove(L, NL, 1); /* move function from L to NL */
+ return 1;
+}
+
+
+static int luaB_cowrap (lua_State *L) {
+ luaB_cocreate(L);
+ lua_pushcclosure(L, luaB_auxwrap, 1);
+ return 1;
+}
+
+
+static int luaB_yield (lua_State *L) {
+ return lua_yield(L, lua_gettop(L));
+}
+
+
+static int luaB_costatus (lua_State *L) {
+ lua_State *co = lua_tothread(L, 1);
+ luaL_argcheck(L, co, 1, "coroutine expected");
+ if (L == co) lua_pushliteral(L, "running");
+ else {
+ lua_Debug ar;
+ if (lua_getstack(co, 0, &ar) == 0 && lua_gettop(co) == 0)
+ lua_pushliteral(L, "dead");
+ else
+ lua_pushliteral(L, "suspended");
+ }
+ return 1;
+}
+
+
+static const luaL_reg co_funcs[] = {
+ {"create", luaB_cocreate},
+ {"wrap", luaB_cowrap},
+ {"resume", luaB_coresume},
+ {"yield", luaB_yield},
+ {"status", luaB_costatus},
+ {NULL, NULL}
+};
+
+/* }====================================================== */
+
+
+
+static void base_open (lua_State *L) {
+ lua_pushliteral(L, "_G");
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ luaL_openlib(L, NULL, base_funcs, 0); /* open lib into global table */
+ lua_pushliteral(L, "_VERSION");
+ lua_pushliteral(L, LUA_VERSION);
+ lua_rawset(L, -3); /* set global _VERSION */
+ /* `newproxy' needs a weaktable as upvalue */
+ lua_pushliteral(L, "newproxy");
+ lua_newtable(L); /* new table `w' */
+ lua_pushvalue(L, -1); /* `w' will be its own metatable */
+ lua_setmetatable(L, -2);
+ lua_pushliteral(L, "__mode");
+ lua_pushliteral(L, "k");
+ lua_rawset(L, -3); /* metatable(w).__mode = "k" */
+ lua_pushcclosure(L, luaB_newproxy, 1);
+ lua_rawset(L, -3); /* set global `newproxy' */
+ lua_rawset(L, -1); /* set global _G */
+}
+
+
+LUALIB_API int luaopen_base (lua_State *L) {
+ base_open(L);
+ luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0);
+ lua_newtable(L);
+ lua_setglobal(L, REQTAB);
+ return 0;
+}
+
diff --git a/lib/lua/src/LuaLib/ldblib.c b/lib/lua/src/LuaLib/ldblib.c
index 455b89f..2449b90 100644
--- a/lib/lua/src/LuaLib/ldblib.c
+++ b/lib/lua/src/LuaLib/ldblib.c
@@ -1,299 +1,299 @@
-/*
-** $Id: ldblib.c,v 1.3 2004-11-27 21:35:21 pixel Exp $
-** Interface from Lua to its debug API
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define ldblib_c
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-
-static void settabss (lua_State *L, const char *i, const char *v) {
- lua_pushstring(L, i);
- lua_pushstring(L, v);
- lua_rawset(L, -3);
-}
-
-
-static void settabsi (lua_State *L, const char *i, int v) {
- lua_pushstring(L, i);
- lua_pushnumber(L, (lua_Number)v);
- lua_rawset(L, -3);
-}
-
-
-static int getinfo (lua_State *L) {
- lua_Debug ar;
- const char *options = luaL_optstring(L, 2, "flnSu");
- if (lua_isnumber(L, 1)) {
- if (!lua_getstack(L, (int)(lua_tonumber(L, 1)), &ar)) {
- lua_pushnil(L); /* level out of range */
- return 1;
- }
- }
- else if (lua_isfunction(L, 1)) {
- lua_pushfstring(L, ">%s", options);
- options = lua_tostring(L, -1);
- lua_pushvalue(L, 1);
- }
- else
- return luaL_argerror(L, 1, "function or level expected");
- if (!lua_getinfo(L, options, &ar))
- return luaL_argerror(L, 2, "invalid option");
- lua_newtable(L);
- for (; *options; options++) {
- switch (*options) {
- case 'S':
- settabss(L, "source", ar.source);
- settabss(L, "short_src", ar.short_src);
- settabsi(L, "linedefined", ar.linedefined);
- settabss(L, "what", ar.what);
- break;
- case 'l':
- settabsi(L, "currentline", ar.currentline);
- break;
- case 'u':
- settabsi(L, "nups", ar.nups);
- break;
- case 'n':
- settabss(L, "name", ar.name);
- settabss(L, "namewhat", ar.namewhat);
- break;
- case 'f':
- lua_pushliteral(L, "func");
- lua_pushvalue(L, -3);
- lua_rawset(L, -3);
- break;
- }
- }
- return 1; /* return table */
-}
-
-
-static int getlocal (lua_State *L) {
- lua_Debug ar;
- const char *name;
- if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */
- return luaL_argerror(L, 1, "level out of range");
- name = lua_getlocal(L, &ar, luaL_checkint(L, 2));
- if (name) {
- lua_pushstring(L, name);
- lua_pushvalue(L, -2);
- return 2;
- }
- else {
- lua_pushnil(L);
- return 1;
- }
-}
-
-
-static int setlocal (lua_State *L) {
- lua_Debug ar;
- if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */
- return luaL_argerror(L, 1, "level out of range");
- luaL_checkany(L, 3);
- lua_pushstring(L, lua_setlocal(L, &ar, luaL_checkint(L, 2)));
- return 1;
-}
-
-
-static int auxupvalue (lua_State *L, int get) {
- const char *name;
- int n = luaL_checkint(L, 2);
- luaL_checktype(L, 1, LUA_TFUNCTION);
- if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
- name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
- if (name == NULL) return 0;
- lua_pushstring(L, name);
- lua_insert(L, -(get+1));
- return get + 1;
-}
-
-
-static int getupvalue (lua_State *L) {
- return auxupvalue(L, 1);
-}
-
-
-static int setupvalue (lua_State *L) {
- luaL_checkany(L, 3);
- return auxupvalue(L, 0);
-}
-
-
-
-static const char KEY_HOOK = 'h';
-
-
-static void hookf (lua_State *L, lua_Debug *ar) {
- static const char *const hooknames[] =
- {"call", "return", "line", "count", "tail return"};
- lua_pushlightuserdata(L, (void *)&KEY_HOOK);
- lua_rawget(L, LUA_REGISTRYINDEX);
- if (lua_isfunction(L, -1)) {
- lua_pushstring(L, hooknames[(int)ar->event]);
- if (ar->currentline >= 0)
- lua_pushnumber(L, (lua_Number)ar->currentline);
- else lua_pushnil(L);
- lua_assert(lua_getinfo(L, "lS", ar));
- lua_call(L, 2, 0);
- }
- else
- lua_pop(L, 1); /* pop result from gettable */
-}
-
-
-static int makemask (const char *smask, int count) {
- int mask = 0;
- if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
- if (strchr(smask, 'r')) mask |= LUA_MASKRET;
- if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
- if (count > 0) mask |= LUA_MASKCOUNT;
- return mask;
-}
-
-
-static char *unmakemask (int mask, char *smask) {
- int i = 0;
- if (mask & LUA_MASKCALL) smask[i++] = 'c';
- if (mask & LUA_MASKRET) smask[i++] = 'r';
- if (mask & LUA_MASKLINE) smask[i++] = 'l';
- smask[i] = '\0';
- return smask;
-}
-
-
-static int sethook (lua_State *L) {
- if (lua_isnoneornil(L, 1)) {
- lua_settop(L, 1);
- lua_sethook(L, NULL, 0, 0); /* turn off hooks */
- }
- else {
- const char *smask = luaL_checkstring(L, 2);
- int count = luaL_optint(L, 3, 0);
- luaL_checktype(L, 1, LUA_TFUNCTION);
- lua_sethook(L, hookf, makemask(smask, count), count);
- }
- lua_pushlightuserdata(L, (void *)&KEY_HOOK);
- lua_pushvalue(L, 1);
- lua_rawset(L, LUA_REGISTRYINDEX); /* set new hook */
- return 0;
-}
-
-
-static int gethook (lua_State *L) {
- char buff[5];
- int mask = lua_gethookmask(L);
- lua_Hook hook = lua_gethook(L);
- if (hook != NULL && hook != hookf) /* external hook? */
- lua_pushliteral(L, "external hook");
- else {
- lua_pushlightuserdata(L, (void *)&KEY_HOOK);
- lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */
- }
- lua_pushstring(L, unmakemask(mask, buff));
- lua_pushnumber(L, (lua_Number)lua_gethookcount(L));
- return 3;
-}
-
-
-static int debug (lua_State *L) {
- for (;;) {
- char buffer[250];
- fputs("lua_debug> ", stderr);
- if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
- strcmp(buffer, "cont\n") == 0)
- return 0;
- lua_dostring(L, buffer);
- lua_settop(L, 0); /* remove eventual returns */
- }
-}
-
-
-#define LEVELS1 12 /* size of the first part of the stack */
-#define LEVELS2 10 /* size of the second part of the stack */
-
-static int errorfb (lua_State *L) {
- int level = 1; /* skip level 0 (it's this function) */
- int firstpart = 1; /* still before eventual `...' */
- lua_Debug ar;
- if (lua_gettop(L) == 0)
- lua_pushliteral(L, "");
- else if (!lua_isstring(L, 1)) return 1; /* no string message */
- else lua_pushliteral(L, "\n");
- lua_pushliteral(L, "stack traceback:");
- while (lua_getstack(L, level++, &ar)) {
- if (level > LEVELS1 && firstpart) {
- /* no more than `LEVELS2' more levels? */
- if (!lua_getstack(L, level+LEVELS2, &ar))
- level--; /* keep going */
- else {
- lua_pushliteral(L, "\n\t..."); /* too many levels */
- while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */
- level++;
- }
- firstpart = 0;
- continue;
- }
- lua_pushliteral(L, "\n\t");
- lua_getinfo(L, "Snl", &ar);
- lua_pushfstring(L, "%s:", ar.short_src);
- if (ar.currentline > 0)
- lua_pushfstring(L, "%d:", ar.currentline);
- switch (*ar.namewhat) {
- case 'g': /* global */
- case 'l': /* local */
- case 'f': /* field */
- case 'm': /* method */
- lua_pushfstring(L, " in function `%s'", ar.name);
- break;
- default: {
- if (*ar.what == 'm') /* main? */
- lua_pushfstring(L, " in main chunk");
- else if (*ar.what == 'C' || *ar.what == 't')
- lua_pushliteral(L, " ?"); /* C function or tail call */
- else
- lua_pushfstring(L, " in function <%s:%d>",
- ar.short_src, ar.linedefined);
- }
- }
- lua_concat(L, lua_gettop(L));
- }
- lua_concat(L, lua_gettop(L));
- return 1;
-}
-
-
-static const luaL_reg dblib[] = {
- {"getlocal", getlocal},
- {"getinfo", getinfo},
- {"gethook", gethook},
- {"getupvalue", getupvalue},
- {"sethook", sethook},
- {"setlocal", setlocal},
- {"setupvalue", setupvalue},
- {"debug", debug},
- {"traceback", errorfb},
- {NULL, NULL}
-};
-
-
-LUALIB_API int luaopen_debug (lua_State *L) {
- luaL_openlib(L, LUA_DBLIBNAME, dblib, 0);
- lua_pushliteral(L, "_TRACEBACK");
- lua_pushcfunction(L, errorfb);
- lua_settable(L, LUA_GLOBALSINDEX);
- return 1;
-}
-
+/*
+** $Id: ldblib.c,v 1.4 2004-11-27 21:46:10 pixel Exp $
+** Interface from Lua to its debug API
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ldblib_c
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+
+static void settabss (lua_State *L, const char *i, const char *v) {
+ lua_pushstring(L, i);
+ lua_pushstring(L, v);
+ lua_rawset(L, -3);
+}
+
+
+static void settabsi (lua_State *L, const char *i, int v) {
+ lua_pushstring(L, i);
+ lua_pushnumber(L, (lua_Number)v);
+ lua_rawset(L, -3);
+}
+
+
+static int getinfo (lua_State *L) {
+ lua_Debug ar;
+ const char *options = luaL_optstring(L, 2, "flnSu");
+ if (lua_isnumber(L, 1)) {
+ if (!lua_getstack(L, (int)(lua_tonumber(L, 1)), &ar)) {
+ lua_pushnil(L); /* level out of range */
+ return 1;
+ }
+ }
+ else if (lua_isfunction(L, 1)) {
+ lua_pushfstring(L, ">%s", options);
+ options = lua_tostring(L, -1);
+ lua_pushvalue(L, 1);
+ }
+ else
+ return luaL_argerror(L, 1, "function or level expected");
+ if (!lua_getinfo(L, options, &ar))
+ return luaL_argerror(L, 2, "invalid option");
+ lua_newtable(L);
+ for (; *options; options++) {
+ switch (*options) {
+ case 'S':
+ settabss(L, "source", ar.source);
+ settabss(L, "short_src", ar.short_src);
+ settabsi(L, "linedefined", ar.linedefined);
+ settabss(L, "what", ar.what);
+ break;
+ case 'l':
+ settabsi(L, "currentline", ar.currentline);
+ break;
+ case 'u':
+ settabsi(L, "nups", ar.nups);
+ break;
+ case 'n':
+ settabss(L, "name", ar.name);
+ settabss(L, "namewhat", ar.namewhat);
+ break;
+ case 'f':
+ lua_pushliteral(L, "func");
+ lua_pushvalue(L, -3);
+ lua_rawset(L, -3);
+ break;
+ }
+ }
+ return 1; /* return table */
+}
+
+
+static int getlocal (lua_State *L) {
+ lua_Debug ar;
+ const char *name;
+ if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */
+ return luaL_argerror(L, 1, "level out of range");
+ name = lua_getlocal(L, &ar, luaL_checkint(L, 2));
+ if (name) {
+ lua_pushstring(L, name);
+ lua_pushvalue(L, -2);
+ return 2;
+ }
+ else {
+ lua_pushnil(L);
+ return 1;
+ }
+}
+
+
+static int setlocal (lua_State *L) {
+ lua_Debug ar;
+ if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */
+ return luaL_argerror(L, 1, "level out of range");
+ luaL_checkany(L, 3);
+ lua_pushstring(L, lua_setlocal(L, &ar, luaL_checkint(L, 2)));
+ return 1;
+}
+
+
+static int auxupvalue (lua_State *L, int get) {
+ const char *name;
+ int n = luaL_checkint(L, 2);
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+ if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
+ name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
+ if (name == NULL) return 0;
+ lua_pushstring(L, name);
+ lua_insert(L, -(get+1));
+ return get + 1;
+}
+
+
+static int getupvalue (lua_State *L) {
+ return auxupvalue(L, 1);
+}
+
+
+static int setupvalue (lua_State *L) {
+ luaL_checkany(L, 3);
+ return auxupvalue(L, 0);
+}
+
+
+
+static const char KEY_HOOK = 'h';
+
+
+static void hookf (lua_State *L, lua_Debug *ar) {
+ static const char *const hooknames[] =
+ {"call", "return", "line", "count", "tail return"};
+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ if (lua_isfunction(L, -1)) {
+ lua_pushstring(L, hooknames[(int)ar->event]);
+ if (ar->currentline >= 0)
+ lua_pushnumber(L, (lua_Number)ar->currentline);
+ else lua_pushnil(L);
+ lua_assert(lua_getinfo(L, "lS", ar));
+ lua_call(L, 2, 0);
+ }
+ else
+ lua_pop(L, 1); /* pop result from gettable */
+}
+
+
+static int makemask (const char *smask, int count) {
+ int mask = 0;
+ if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
+ if (strchr(smask, 'r')) mask |= LUA_MASKRET;
+ if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
+ if (count > 0) mask |= LUA_MASKCOUNT;
+ return mask;
+}
+
+
+static char *unmakemask (int mask, char *smask) {
+ int i = 0;
+ if (mask & LUA_MASKCALL) smask[i++] = 'c';
+ if (mask & LUA_MASKRET) smask[i++] = 'r';
+ if (mask & LUA_MASKLINE) smask[i++] = 'l';
+ smask[i] = '\0';
+ return smask;
+}
+
+
+static int sethook (lua_State *L) {
+ if (lua_isnoneornil(L, 1)) {
+ lua_settop(L, 1);
+ lua_sethook(L, NULL, 0, 0); /* turn off hooks */
+ }
+ else {
+ const char *smask = luaL_checkstring(L, 2);
+ int count = luaL_optint(L, 3, 0);
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+ lua_sethook(L, hookf, makemask(smask, count), count);
+ }
+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
+ lua_pushvalue(L, 1);
+ lua_rawset(L, LUA_REGISTRYINDEX); /* set new hook */
+ return 0;
+}
+
+
+static int gethook (lua_State *L) {
+ char buff[5];
+ int mask = lua_gethookmask(L);
+ lua_Hook hook = lua_gethook(L);
+ if (hook != NULL && hook != hookf) /* external hook? */
+ lua_pushliteral(L, "external hook");
+ else {
+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
+ lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */
+ }
+ lua_pushstring(L, unmakemask(mask, buff));
+ lua_pushnumber(L, (lua_Number)lua_gethookcount(L));
+ return 3;
+}
+
+
+static int debug (lua_State *L) {
+ for (;;) {
+ char buffer[250];
+ fputs("lua_debug> ", stderr);
+ if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
+ strcmp(buffer, "cont\n") == 0)
+ return 0;
+ lua_dostring(L, buffer);
+ lua_settop(L, 0); /* remove eventual returns */
+ }
+}
+
+
+#define LEVELS1 12 /* size of the first part of the stack */
+#define LEVELS2 10 /* size of the second part of the stack */
+
+static int errorfb (lua_State *L) {
+ int level = 1; /* skip level 0 (it's this function) */
+ int firstpart = 1; /* still before eventual `...' */
+ lua_Debug ar;
+ if (lua_gettop(L) == 0)
+ lua_pushliteral(L, "");
+ else if (!lua_isstring(L, 1)) return 1; /* no string message */
+ else lua_pushliteral(L, "\n");
+ lua_pushliteral(L, "stack traceback:");
+ while (lua_getstack(L, level++, &ar)) {
+ if (level > LEVELS1 && firstpart) {
+ /* no more than `LEVELS2' more levels? */
+ if (!lua_getstack(L, level+LEVELS2, &ar))
+ level--; /* keep going */
+ else {
+ lua_pushliteral(L, "\n\t..."); /* too many levels */
+ while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */
+ level++;
+ }
+ firstpart = 0;
+ continue;
+ }
+ lua_pushliteral(L, "\n\t");
+ lua_getinfo(L, "Snl", &ar);
+ lua_pushfstring(L, "%s:", ar.short_src);
+ if (ar.currentline > 0)
+ lua_pushfstring(L, "%d:", ar.currentline);
+ switch (*ar.namewhat) {
+ case 'g': /* global */
+ case 'l': /* local */
+ case 'f': /* field */
+ case 'm': /* method */
+ lua_pushfstring(L, " in function `%s'", ar.name);
+ break;
+ default: {
+ if (*ar.what == 'm') /* main? */
+ lua_pushfstring(L, " in main chunk");
+ else if (*ar.what == 'C' || *ar.what == 't')
+ lua_pushliteral(L, " ?"); /* C function or tail call */
+ else
+ lua_pushfstring(L, " in function <%s:%d>",
+ ar.short_src, ar.linedefined);
+ }
+ }
+ lua_concat(L, lua_gettop(L));
+ }
+ lua_concat(L, lua_gettop(L));
+ return 1;
+}
+
+
+static const luaL_reg dblib[] = {
+ {"getlocal", getlocal},
+ {"getinfo", getinfo},
+ {"gethook", gethook},
+ {"getupvalue", getupvalue},
+ {"sethook", sethook},
+ {"setlocal", setlocal},
+ {"setupvalue", setupvalue},
+ {"debug", debug},
+ {"traceback", errorfb},
+ {NULL, NULL}
+};
+
+
+LUALIB_API int luaopen_debug (lua_State *L) {
+ luaL_openlib(L, LUA_DBLIBNAME, dblib, 0);
+ lua_pushliteral(L, "_TRACEBACK");
+ lua_pushcfunction(L, errorfb);
+ lua_settable(L, LUA_GLOBALSINDEX);
+ return 1;
+}
+
diff --git a/lib/lua/src/LuaLib/ldirlib.c b/lib/lua/src/LuaLib/ldirlib.c
index 4e221b4..9bf2090 100644
--- a/lib/lua/src/LuaLib/ldirlib.c
+++ b/lib/lua/src/LuaLib/ldirlib.c
@@ -1,96 +1,96 @@
-#include <stdlib.h>
-#include <dirent.h>
-#include <errno.h>
-#include <sys/stat.h>
-
-#define ldirlib_c
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-/* forward declaration for the iterator function */
-static int dir_iter (lua_State *L);
-
-static int l_dir (lua_State *L) {
- const char *path = luaL_checkstring(L, 1);
-
- /* create a userdatum to store a DIR address */
- DIR **d = (DIR **)lua_newuserdata(L, sizeof(DIR *));
-
- /* set its metatable */
- luaL_getmetatable(L, "LuaBook.dir");
- lua_setmetatable(L, -2);
-
- /* try to open the given directory */
- *d = opendir(path);
- if (*d == NULL) /* error opening the directory? */
- luaL_error(L, "cannot open %s: %s", path,
- strerror(errno));
-
- /* creates and returns the iterator function
- (its sole upvalue, the directory userdatum,
- is already on the stack top */
- lua_pushcclosure(L, dir_iter, 1);
- return 1;
-}
-
-static int dir_iter (lua_State *L) {
- DIR *d = *(DIR **)lua_touserdata(L, lua_upvalueindex(1));
- struct dirent *entry;
-#ifdef _WIN32
- struct _stat file_stat;
-#else
- struct stat file_stat;
-#endif
- if ((entry = readdir(d)) != NULL) {
- lua_newtable(L);
- lua_pushstring(L, "name");
- lua_pushstring(L, entry->d_name);
- lua_settable(L, -3);
-#ifdef _WIN32
- _stat(entry->d_name, &file_stat);
-#else
- stat(entry->d_name, &file_stat);
-#endif
- lua_pushstring(L, "type");
- lua_pushnumber(L, (S_IFREG & file_stat.st_mode) ? 2 : ((S_IFDIR & file_stat.st_mode) ? 1 : 0));
- lua_settable(L, -3);
-
- return 1;
- }
- else return 0; /* no more values to return */
-}
-
-static int dir_gc (lua_State *L) {
- DIR *d = *(DIR **)lua_touserdata(L, 1);
- if (d) closedir(d);
- return 0;
-}
-
-static const luaL_reg dirlib[] = {
- {NULL, NULL}
-};
-
-int luaopen_dir (lua_State *L) {
- luaL_openlib(L, LUA_DIRLIBNAME, dirlib, 0);
- luaL_newmetatable(L, "LuaBook.dir");
-
- /* set its __gc field */
- lua_pushstring(L, "__gc");
- lua_pushcfunction(L, dir_gc);
- lua_settable(L, -3);
-
- /* register the `dir' function */
- lua_pushcfunction(L, l_dir);
- lua_setglobal(L, "dir");
-
- lua_pushnumber(L, 1);
- lua_setglobal(L, "FLAG_DIR");
-
- lua_pushnumber(L, 2);
- lua_setglobal(L, "FLAG_FILE");
-
- return 0;
-}
+#include <stdlib.h>
+#include <dirent.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#define ldirlib_c
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+/* forward declaration for the iterator function */
+static int dir_iter (lua_State *L);
+
+static int l_dir (lua_State *L) {
+ const char *path = luaL_checkstring(L, 1);
+
+ /* create a userdatum to store a DIR address */
+ DIR **d = (DIR **)lua_newuserdata(L, sizeof(DIR *));
+
+ /* set its metatable */
+ luaL_getmetatable(L, "LuaBook.dir");
+ lua_setmetatable(L, -2);
+
+ /* try to open the given directory */
+ *d = opendir(path);
+ if (*d == NULL) /* error opening the directory? */
+ luaL_error(L, "cannot open %s: %s", path,
+ strerror(errno));
+
+ /* creates and returns the iterator function
+ (its sole upvalue, the directory userdatum,
+ is already on the stack top */
+ lua_pushcclosure(L, dir_iter, 1);
+ return 1;
+}
+
+static int dir_iter (lua_State *L) {
+ DIR *d = *(DIR **)lua_touserdata(L, lua_upvalueindex(1));
+ struct dirent *entry;
+#ifdef _WIN32
+ struct _stat file_stat;
+#else
+ struct stat file_stat;
+#endif
+ if ((entry = readdir(d)) != NULL) {
+ lua_newtable(L);
+ lua_pushstring(L, "name");
+ lua_pushstring(L, entry->d_name);
+ lua_settable(L, -3);
+#ifdef _WIN32
+ _stat(entry->d_name, &file_stat);
+#else
+ stat(entry->d_name, &file_stat);
+#endif
+ lua_pushstring(L, "type");
+ lua_pushnumber(L, (S_IFREG & file_stat.st_mode) ? 2 : ((S_IFDIR & file_stat.st_mode) ? 1 : 0));
+ lua_settable(L, -3);
+
+ return 1;
+ }
+ else return 0; /* no more values to return */
+}
+
+static int dir_gc (lua_State *L) {
+ DIR *d = *(DIR **)lua_touserdata(L, 1);
+ if (d) closedir(d);
+ return 0;
+}
+
+static const luaL_reg dirlib[] = {
+ {NULL, NULL}
+};
+
+int luaopen_dir (lua_State *L) {
+ luaL_openlib(L, LUA_DIRLIBNAME, dirlib, 0);
+ luaL_newmetatable(L, "LuaBook.dir");
+
+ /* set its __gc field */
+ lua_pushstring(L, "__gc");
+ lua_pushcfunction(L, dir_gc);
+ lua_settable(L, -3);
+
+ /* register the `dir' function */
+ lua_pushcfunction(L, l_dir);
+ lua_setglobal(L, "dir");
+
+ lua_pushnumber(L, 1);
+ lua_setglobal(L, "FLAG_DIR");
+
+ lua_pushnumber(L, 2);
+ lua_setglobal(L, "FLAG_FILE");
+
+ return 0;
+}
diff --git a/lib/lua/src/LuaLib/liolib.c b/lib/lua/src/LuaLib/liolib.c
index 3eeb05f..69e0a19 100644
--- a/lib/lua/src/LuaLib/liolib.c
+++ b/lib/lua/src/LuaLib/liolib.c
@@ -1,750 +1,750 @@
-/*
-** $Id: liolib.c,v 1.3 2004-11-27 21:35:21 pixel Exp $
-** Standard I/O (and system) library
-** See Copyright Notice in lua.h
-*/
-
-
-#include <errno.h>
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#define liolib_c
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-
-/*
-** by default, gcc does not get `tmpname'
-*/
-#ifndef USE_TMPNAME
-#ifdef __GNUC__
-#define USE_TMPNAME 0
-#else
-#define USE_TMPNAME 1
-#endif
-#endif
-
-
-/*
-** by default, posix systems get `popen'
-*/
-#ifndef USE_POPEN
-#ifdef _POSIX_C_SOURCE
-#if _POSIX_C_SOURCE >= 2
-#define USE_POPEN 1
-#endif
-#endif
-#endif
-
-#ifndef USE_POPEN
-#define USE_POPEN 0
-#endif
-
-
-
-
-/*
-** {======================================================
-** FILE Operations
-** =======================================================
-*/
-
-
-#if !USE_POPEN
-#define pclose(f) (-1)
-#endif
-
-
-#define FILEHANDLE "FILE*"
-
-#define IO_INPUT "_input"
-#define IO_OUTPUT "_output"
-
-
-static int pushresult (lua_State *L, int i, const char *filename) {
- if (i) {
- lua_pushboolean(L, 1);
- return 1;
- }
- else {
- lua_pushnil(L);
- if (filename)
- lua_pushfstring(L, "%s: %s", filename, strerror(errno));
- else
- lua_pushfstring(L, "%s", strerror(errno));
- lua_pushnumber(L, errno);
- return 3;
- }
-}
-
-
-static FILE **topfile (lua_State *L, int findex) {
- FILE **f = (FILE **)luaL_checkudata(L, findex, FILEHANDLE);
- if (f == NULL) luaL_argerror(L, findex, "bad file");
- return f;
-}
-
-
-static int io_type (lua_State *L) {
- FILE **f = (FILE **)luaL_checkudata(L, 1, FILEHANDLE);
- if (f == NULL) lua_pushnil(L);
- else if (*f == NULL)
- lua_pushliteral(L, "closed file");
- else
- lua_pushliteral(L, "file");
- return 1;
-}
-
-
-static FILE *tofile (lua_State *L, int findex) {
- FILE **f = topfile(L, findex);
- if (*f == NULL)
- luaL_error(L, "attempt to use a closed file");
- return *f;
-}
-
-
-
-/*
-** When creating file handles, always creates a `closed' file handle
-** before opening the actual file; so, if there is a memory error, the
-** file is not left opened.
-*/
-static FILE **newfile (lua_State *L) {
- FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
- *pf = NULL; /* file handle is currently `closed' */
- luaL_getmetatable(L, FILEHANDLE);
- lua_setmetatable(L, -2);
- return pf;
-}
-
-
-/*
-** assumes that top of the stack is the `io' library, and next is
-** the `io' metatable
-*/
-static void registerfile (lua_State *L, FILE *f, const char *name,
- const char *impname) {
- lua_pushstring(L, name);
- *newfile(L) = f;
- if (impname) {
- lua_pushstring(L, impname);
- lua_pushvalue(L, -2);
- lua_settable(L, -6); /* metatable[impname] = file */
- }
- lua_settable(L, -3); /* io[name] = file */
-}
-
-
-static int aux_close (lua_State *L) {
- FILE *f = tofile(L, 1);
- if (f == stdin || f == stdout || f == stderr)
- return 0; /* file cannot be closed */
- else {
- int ok = (pclose(f) != -1) || (fclose(f) == 0);
- if (ok)
- *(FILE **)lua_touserdata(L, 1) = NULL; /* mark file as closed */
- return ok;
- }
-}
-
-
-static int io_close (lua_State *L) {
- if (lua_isnone(L, 1)) {
- lua_pushstring(L, IO_OUTPUT);
- lua_rawget(L, lua_upvalueindex(1));
- }
- return pushresult(L, aux_close(L), NULL);
-}
-
-
-static int io_gc (lua_State *L) {
- FILE **f = topfile(L, 1);
- if (*f != NULL) /* ignore closed files */
- aux_close(L);
- return 0;
-}
-
-
-static int io_tostring (lua_State *L) {
- char buff[32];
- FILE **f = topfile(L, 1);
- if (*f == NULL)
- strcpy(buff, "closed");
- else
- sprintf(buff, "%p", lua_touserdata(L, 1));
- lua_pushfstring(L, "file (%s)", buff);
- return 1;
-}
-
-
-static int io_open (lua_State *L) {
- const char *filename = luaL_checkstring(L, 1);
- const char *mode = luaL_optstring(L, 2, "r");
- FILE **pf = newfile(L);
- *pf = fopen(filename, mode);
- return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
-}
-
-
-static int io_popen (lua_State *L) {
-#if !USE_POPEN
- luaL_error(L, "`popen' not supported");
- return 0;
-#else
- const char *filename = luaL_checkstring(L, 1);
- const char *mode = luaL_optstring(L, 2, "r");
- FILE **pf = newfile(L);
- *pf = popen(filename, mode);
- return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
-#endif
-}
-
-
-static int io_tmpfile (lua_State *L) {
- FILE **pf = newfile(L);
- *pf = tmpfile();
- return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
-}
-
-
-static FILE *getiofile (lua_State *L, const char *name) {
- lua_pushstring(L, name);
- lua_rawget(L, lua_upvalueindex(1));
- return tofile(L, -1);
-}
-
-
-static int g_iofile (lua_State *L, const char *name, const char *mode) {
- if (!lua_isnoneornil(L, 1)) {
- const char *filename = lua_tostring(L, 1);
- lua_pushstring(L, name);
- if (filename) {
- FILE **pf = newfile(L);
- *pf = fopen(filename, mode);
- if (*pf == NULL) {
- lua_pushfstring(L, "%s: %s", filename, strerror(errno));
- luaL_argerror(L, 1, lua_tostring(L, -1));
- }
- }
- else {
- tofile(L, 1); /* check that it's a valid file handle */
- lua_pushvalue(L, 1);
- }
- lua_rawset(L, lua_upvalueindex(1));
- }
- /* return current value */
- lua_pushstring(L, name);
- lua_rawget(L, lua_upvalueindex(1));
- return 1;
-}
-
-
-static int io_input (lua_State *L) {
- return g_iofile(L, IO_INPUT, "r");
-}
-
-
-static int io_output (lua_State *L) {
- return g_iofile(L, IO_OUTPUT, "w");
-}
-
-
-static int io_readline (lua_State *L);
-
-
-static void aux_lines (lua_State *L, int idx, int close) {
- lua_pushliteral(L, FILEHANDLE);
- lua_rawget(L, LUA_REGISTRYINDEX);
- lua_pushvalue(L, idx);
- lua_pushboolean(L, close); /* close/not close file when finished */
- lua_pushcclosure(L, io_readline, 3);
-}
-
-
-static int f_lines (lua_State *L) {
- tofile(L, 1); /* check that it's a valid file handle */
- aux_lines(L, 1, 0);
- return 1;
-}
-
-
-static int io_lines (lua_State *L) {
- if (lua_isnoneornil(L, 1)) { /* no arguments? */
- lua_pushstring(L, IO_INPUT);
- lua_rawget(L, lua_upvalueindex(1)); /* will iterate over default input */
- return f_lines(L);
- }
- else {
- const char *filename = luaL_checkstring(L, 1);
- FILE **pf = newfile(L);
- *pf = fopen(filename, "r");
- luaL_argcheck(L, *pf, 1, strerror(errno));
- aux_lines(L, lua_gettop(L), 1);
- return 1;
- }
-}
-
-
-/*
-** {======================================================
-** READ
-** =======================================================
-*/
-
-
-static int read_number (lua_State *L, FILE *f) {
- lua_Number d;
- if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
- lua_pushnumber(L, d);
- return 1;
- }
- else return 0; /* read fails */
-}
-
-
-static int test_eof (lua_State *L, FILE *f) {
- int c = getc(f);
- ungetc(c, f);
- lua_pushlstring(L, NULL, 0);
- return (c != EOF);
-}
-
-
-static int read_line (lua_State *L, FILE *f) {
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- for (;;) {
- size_t l;
- char *p = luaL_prepbuffer(&b);
- if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
- luaL_pushresult(&b); /* close buffer */
- return (lua_strlen(L, -1) > 0); /* check whether read something */
- }
- l = strlen(p);
- if (p[l-1] != '\n')
- luaL_addsize(&b, l);
- else {
- luaL_addsize(&b, l - 1); /* do not include `eol' */
- luaL_pushresult(&b); /* close buffer */
- return 1; /* read at least an `eol' */
- }
- }
-}
-
-
-static int read_chars (lua_State *L, FILE *f, size_t n) {
- size_t rlen; /* how much to read */
- size_t nr; /* number of chars actually read */
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
- do {
- char *p = luaL_prepbuffer(&b);
- if (rlen > n) rlen = n; /* cannot read more than asked */
- nr = fread(p, sizeof(char), rlen, f);
- luaL_addsize(&b, nr);
- n -= nr; /* still have to read `n' chars */
- } while (n > 0 && nr == rlen); /* until end of count or eof */
- luaL_pushresult(&b); /* close buffer */
- return (n == 0 || lua_strlen(L, -1) > 0);
-}
-
-
-static int g_read (lua_State *L, FILE *f, int first) {
- int nargs = lua_gettop(L) - 1;
- int success;
- int n;
- if (nargs == 0) { /* no arguments? */
- success = read_line(L, f);
- n = first+1; /* to return 1 result */
- }
- else { /* ensure stack space for all results and for auxlib's buffer */
- luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
- success = 1;
- for (n = first; nargs-- && success; n++) {
- if (lua_type(L, n) == LUA_TNUMBER) {
- size_t l = (size_t)lua_tonumber(L, n);
- success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
- }
- else {
- const char *p = lua_tostring(L, n);
- luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
- switch (p[1]) {
- case 'n': /* number */
- success = read_number(L, f);
- break;
- case 'l': /* line */
- success = read_line(L, f);
- break;
- case 'a': /* file */
- read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
- success = 1; /* always success */
- break;
- case 'w': /* word */
- return luaL_error(L, "obsolete option `*w' to `read'");
- default:
- return luaL_argerror(L, n, "invalid format");
- }
- }
- }
- }
- if (!success) {
- lua_pop(L, 1); /* remove last result */
- lua_pushnil(L); /* push nil instead */
- }
- return n - first;
-}
-
-
-static int io_read (lua_State *L) {
- return g_read(L, getiofile(L, IO_INPUT), 1);
-}
-
-
-static int f_read (lua_State *L) {
- return g_read(L, tofile(L, 1), 2);
-}
-
-
-static int io_readline (lua_State *L) {
- FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(2));
- if (f == NULL) /* file is already closed? */
- luaL_error(L, "file is already closed");
- if (read_line(L, f)) return 1;
- else { /* EOF */
- if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
- lua_settop(L, 0);
- lua_pushvalue(L, lua_upvalueindex(2));
- aux_close(L); /* close it */
- }
- return 0;
- }
-}
-
-/* }====================================================== */
-
-
-static int g_write (lua_State *L, FILE *f, int arg) {
- int nargs = lua_gettop(L) - 1;
- int status = 1;
- for (; nargs--; arg++) {
- if (lua_type(L, arg) == LUA_TNUMBER) {
- /* optimization: could be done exactly as for strings */
- status = status &&
- fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
- }
- else {
- size_t l;
- const char *s = luaL_checklstring(L, arg, &l);
- status = status && (fwrite(s, sizeof(char), l, f) == l);
- }
- }
- return pushresult(L, status, NULL);
-}
-
-
-static int io_write (lua_State *L) {
- return g_write(L, getiofile(L, IO_OUTPUT), 1);
-}
-
-
-static int f_write (lua_State *L) {
- return g_write(L, tofile(L, 1), 2);
-}
-
-
-static int f_seek (lua_State *L) {
- static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
- static const char *const modenames[] = {"set", "cur", "end", NULL};
- FILE *f = tofile(L, 1);
- int op = luaL_findstring(luaL_optstring(L, 2, "cur"), modenames);
- long offset = luaL_optlong(L, 3, 0);
- luaL_argcheck(L, op != -1, 2, "invalid mode");
- op = fseek(f, offset, mode[op]);
- if (op)
- return pushresult(L, 0, NULL); /* error */
- else {
- lua_pushnumber(L, ftell(f));
- return 1;
- }
-}
-
-
-static int io_flush (lua_State *L) {
- return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
-}
-
-
-static int f_flush (lua_State *L) {
- return pushresult(L, fflush(tofile(L, 1)) == 0, NULL);
-}
-
-
-static const luaL_reg iolib[] = {
- {"input", io_input},
- {"output", io_output},
- {"lines", io_lines},
- {"close", io_close},
- {"flush", io_flush},
- {"open", io_open},
- {"popen", io_popen},
- {"read", io_read},
- {"tmpfile", io_tmpfile},
- {"type", io_type},
- {"write", io_write},
- {NULL, NULL}
-};
-
-
-static const luaL_reg flib[] = {
- {"flush", f_flush},
- {"read", f_read},
- {"lines", f_lines},
- {"seek", f_seek},
- {"write", f_write},
- {"close", io_close},
- {"__gc", io_gc},
- {"__tostring", io_tostring},
- {NULL, NULL}
-};
-
-
-static void createmeta (lua_State *L) {
- luaL_newmetatable(L, FILEHANDLE); /* create new metatable for file handles */
- /* file methods */
- lua_pushliteral(L, "__index");
- lua_pushvalue(L, -2); /* push metatable */
- lua_rawset(L, -3); /* metatable.__index = metatable */
- luaL_openlib(L, NULL, flib, 0);
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Other O.S. Operations
-** =======================================================
-*/
-
-static int io_execute (lua_State *L) {
- lua_pushnumber(L, system(luaL_checkstring(L, 1)));
- return 1;
-}
-
-
-static int io_remove (lua_State *L) {
- const char *filename = luaL_checkstring(L, 1);
- return pushresult(L, remove(filename) == 0, filename);
-}
-
-
-static int io_rename (lua_State *L) {
- const char *fromname = luaL_checkstring(L, 1);
- const char *toname = luaL_checkstring(L, 2);
- return pushresult(L, rename(fromname, toname) == 0, fromname);
-}
-
-
-static int io_tmpname (lua_State *L) {
-#if !USE_TMPNAME
- luaL_error(L, "`tmpname' not supported");
- return 0;
-#else
- char buff[L_tmpnam];
- if (tmpnam(buff) != buff)
- return luaL_error(L, "unable to generate a unique filename in `tmpname'");
- lua_pushstring(L, buff);
- return 1;
-#endif
-}
-
-
-static int io_getenv (lua_State *L) {
- lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
- return 1;
-}
-
-
-static int io_clock (lua_State *L) {
- lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
- return 1;
-}
-
-
-/*
-** {======================================================
-** Time/Date operations
-** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
-** wday=%w+1, yday=%j, isdst=? }
-** =======================================================
-*/
-
-static void setfield (lua_State *L, const char *key, int value) {
- lua_pushstring(L, key);
- lua_pushnumber(L, value);
- lua_rawset(L, -3);
-}
-
-static void setboolfield (lua_State *L, const char *key, int value) {
- lua_pushstring(L, key);
- lua_pushboolean(L, value);
- lua_rawset(L, -3);
-}
-
-static int getboolfield (lua_State *L, const char *key) {
- int res;
- lua_pushstring(L, key);
- lua_gettable(L, -2);
- res = lua_toboolean(L, -1);
- lua_pop(L, 1);
- return res;
-}
-
-
-static int getfield (lua_State *L, const char *key, int d) {
- int res;
- lua_pushstring(L, key);
- lua_gettable(L, -2);
- if (lua_isnumber(L, -1))
- res = (int)(lua_tonumber(L, -1));
- else {
- if (d == -2)
- return luaL_error(L, "field `%s' missing in date table", key);
- res = d;
- }
- lua_pop(L, 1);
- return res;
-}
-
-
-static int io_date (lua_State *L) {
- const char *s = luaL_optstring(L, 1, "%c");
- time_t t = (time_t)(luaL_optnumber(L, 2, -1));
- struct tm *stm;
- if (t == (time_t)(-1)) /* no time given? */
- t = time(NULL); /* use current time */
- if (*s == '!') { /* UTC? */
- stm = gmtime(&t);
- s++; /* skip `!' */
- }
- else
- stm = localtime(&t);
- if (stm == NULL) /* invalid date? */
- lua_pushnil(L);
- else if (strcmp(s, "*t") == 0) {
- lua_newtable(L);
- setfield(L, "sec", stm->tm_sec);
- setfield(L, "min", stm->tm_min);
- setfield(L, "hour", stm->tm_hour);
- setfield(L, "day", stm->tm_mday);
- setfield(L, "month", stm->tm_mon+1);
- setfield(L, "year", stm->tm_year+1900);
- setfield(L, "wday", stm->tm_wday+1);
- setfield(L, "yday", stm->tm_yday+1);
- setboolfield(L, "isdst", stm->tm_isdst);
- }
- else {
- char b[256];
- if (strftime(b, sizeof(b), s, stm))
- lua_pushstring(L, b);
- else
- return luaL_error(L, "`date' format too long");
- }
- return 1;
-}
-
-
-static int io_time (lua_State *L) {
- if (lua_isnoneornil(L, 1)) /* called without args? */
- lua_pushnumber(L, time(NULL)); /* return current time */
- else {
- time_t t;
- struct tm ts;
- luaL_checktype(L, 1, LUA_TTABLE);
- lua_settop(L, 1); /* make sure table is at the top */
- ts.tm_sec = getfield(L, "sec", 0);
- ts.tm_min = getfield(L, "min", 0);
- ts.tm_hour = getfield(L, "hour", 12);
- ts.tm_mday = getfield(L, "day", -2);
- ts.tm_mon = getfield(L, "month", -2) - 1;
- ts.tm_year = getfield(L, "year", -2) - 1900;
- ts.tm_isdst = getboolfield(L, "isdst");
- t = mktime(&ts);
- if (t == (time_t)(-1))
- lua_pushnil(L);
- else
- lua_pushnumber(L, t);
- }
- return 1;
-}
-
-
-static int io_difftime (lua_State *L) {
- lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
- (time_t)(luaL_optnumber(L, 2, 0))));
- return 1;
-}
-
-/* }====================================================== */
-
-
-static int io_setloc (lua_State *L) {
- static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
- LC_NUMERIC, LC_TIME};
- static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
- "numeric", "time", NULL};
- const char *l = lua_tostring(L, 1);
- int op = luaL_findstring(luaL_optstring(L, 2, "all"), catnames);
- luaL_argcheck(L, l || lua_isnoneornil(L, 1), 1, "string expected");
- luaL_argcheck(L, op != -1, 2, "invalid option");
- lua_pushstring(L, setlocale(cat[op], l));
- return 1;
-}
-
-
-static int io_exit (lua_State *L) {
- exit(luaL_optint(L, 1, EXIT_SUCCESS));
- return 0; /* to avoid warnings */
-}
-
-static const luaL_reg syslib[] = {
- {"clock", io_clock},
- {"date", io_date},
- {"difftime", io_difftime},
- {"execute", io_execute},
- {"exit", io_exit},
- {"getenv", io_getenv},
- {"remove", io_remove},
- {"rename", io_rename},
- {"setlocale", io_setloc},
- {"time", io_time},
- {"tmpname", io_tmpname},
- {NULL, NULL}
-};
-
-/* }====================================================== */
-
-
-
-LUALIB_API int luaopen_io (lua_State *L) {
- luaL_openlib(L, LUA_OSLIBNAME, syslib, 0);
- createmeta(L);
- lua_pushvalue(L, -1);
- luaL_openlib(L, LUA_IOLIBNAME, iolib, 1);
- /* put predefined file handles into `io' table */
- registerfile(L, stdin, "stdin", IO_INPUT);
- registerfile(L, stdout, "stdout", IO_OUTPUT);
- registerfile(L, stderr, "stderr", NULL);
- return 1;
-}
-
+/*
+** $Id: liolib.c,v 1.4 2004-11-27 21:46:10 pixel Exp $
+** Standard I/O (and system) library
+** See Copyright Notice in lua.h
+*/
+
+
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#define liolib_c
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+
+/*
+** by default, gcc does not get `tmpname'
+*/
+#ifndef USE_TMPNAME
+#ifdef __GNUC__
+#define USE_TMPNAME 0
+#else
+#define USE_TMPNAME 1
+#endif
+#endif
+
+
+/*
+** by default, posix systems get `popen'
+*/
+#ifndef USE_POPEN
+#ifdef _POSIX_C_SOURCE
+#if _POSIX_C_SOURCE >= 2
+#define USE_POPEN 1
+#endif
+#endif
+#endif
+
+#ifndef USE_POPEN
+#define USE_POPEN 0
+#endif
+
+
+
+
+/*
+** {======================================================
+** FILE Operations
+** =======================================================
+*/
+
+
+#if !USE_POPEN
+#define pclose(f) (-1)
+#endif
+
+
+#define FILEHANDLE "FILE*"
+
+#define IO_INPUT "_input"
+#define IO_OUTPUT "_output"
+
+
+static int pushresult (lua_State *L, int i, const char *filename) {
+ if (i) {
+ lua_pushboolean(L, 1);
+ return 1;
+ }
+ else {
+ lua_pushnil(L);
+ if (filename)
+ lua_pushfstring(L, "%s: %s", filename, strerror(errno));
+ else
+ lua_pushfstring(L, "%s", strerror(errno));
+ lua_pushnumber(L, errno);
+ return 3;
+ }
+}
+
+
+static FILE **topfile (lua_State *L, int findex) {
+ FILE **f = (FILE **)luaL_checkudata(L, findex, FILEHANDLE);
+ if (f == NULL) luaL_argerror(L, findex, "bad file");
+ return f;
+}
+
+
+static int io_type (lua_State *L) {
+ FILE **f = (FILE **)luaL_checkudata(L, 1, FILEHANDLE);
+ if (f == NULL) lua_pushnil(L);
+ else if (*f == NULL)
+ lua_pushliteral(L, "closed file");
+ else
+ lua_pushliteral(L, "file");
+ return 1;
+}
+
+
+static FILE *tofile (lua_State *L, int findex) {
+ FILE **f = topfile(L, findex);
+ if (*f == NULL)
+ luaL_error(L, "attempt to use a closed file");
+ return *f;
+}
+
+
+
+/*
+** When creating file handles, always creates a `closed' file handle
+** before opening the actual file; so, if there is a memory error, the
+** file is not left opened.
+*/
+static FILE **newfile (lua_State *L) {
+ FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
+ *pf = NULL; /* file handle is currently `closed' */
+ luaL_getmetatable(L, FILEHANDLE);
+ lua_setmetatable(L, -2);
+ return pf;
+}
+
+
+/*
+** assumes that top of the stack is the `io' library, and next is
+** the `io' metatable
+*/
+static void registerfile (lua_State *L, FILE *f, const char *name,
+ const char *impname) {
+ lua_pushstring(L, name);
+ *newfile(L) = f;
+ if (impname) {
+ lua_pushstring(L, impname);
+ lua_pushvalue(L, -2);
+ lua_settable(L, -6); /* metatable[impname] = file */
+ }
+ lua_settable(L, -3); /* io[name] = file */
+}
+
+
+static int aux_close (lua_State *L) {
+ FILE *f = tofile(L, 1);
+ if (f == stdin || f == stdout || f == stderr)
+ return 0; /* file cannot be closed */
+ else {
+ int ok = (pclose(f) != -1) || (fclose(f) == 0);
+ if (ok)
+ *(FILE **)lua_touserdata(L, 1) = NULL; /* mark file as closed */
+ return ok;
+ }
+}
+
+
+static int io_close (lua_State *L) {
+ if (lua_isnone(L, 1)) {
+ lua_pushstring(L, IO_OUTPUT);
+ lua_rawget(L, lua_upvalueindex(1));
+ }
+ return pushresult(L, aux_close(L), NULL);
+}
+
+
+static int io_gc (lua_State *L) {
+ FILE **f = topfile(L, 1);
+ if (*f != NULL) /* ignore closed files */
+ aux_close(L);
+ return 0;
+}
+
+
+static int io_tostring (lua_State *L) {
+ char buff[32];
+ FILE **f = topfile(L, 1);
+ if (*f == NULL)
+ strcpy(buff, "closed");
+ else
+ sprintf(buff, "%p", lua_touserdata(L, 1));
+ lua_pushfstring(L, "file (%s)", buff);
+ return 1;
+}
+
+
+static int io_open (lua_State *L) {
+ const char *filename = luaL_checkstring(L, 1);
+ const char *mode = luaL_optstring(L, 2, "r");
+ FILE **pf = newfile(L);
+ *pf = fopen(filename, mode);
+ return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
+}
+
+
+static int io_popen (lua_State *L) {
+#if !USE_POPEN
+ luaL_error(L, "`popen' not supported");
+ return 0;
+#else
+ const char *filename = luaL_checkstring(L, 1);
+ const char *mode = luaL_optstring(L, 2, "r");
+ FILE **pf = newfile(L);
+ *pf = popen(filename, mode);
+ return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
+#endif
+}
+
+
+static int io_tmpfile (lua_State *L) {
+ FILE **pf = newfile(L);
+ *pf = tmpfile();
+ return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
+}
+
+
+static FILE *getiofile (lua_State *L, const char *name) {
+ lua_pushstring(L, name);
+ lua_rawget(L, lua_upvalueindex(1));
+ return tofile(L, -1);
+}
+
+
+static int g_iofile (lua_State *L, const char *name, const char *mode) {
+ if (!lua_isnoneornil(L, 1)) {
+ const char *filename = lua_tostring(L, 1);
+ lua_pushstring(L, name);
+ if (filename) {
+ FILE **pf = newfile(L);
+ *pf = fopen(filename, mode);
+ if (*pf == NULL) {
+ lua_pushfstring(L, "%s: %s", filename, strerror(errno));
+ luaL_argerror(L, 1, lua_tostring(L, -1));
+ }
+ }
+ else {
+ tofile(L, 1); /* check that it's a valid file handle */
+ lua_pushvalue(L, 1);
+ }
+ lua_rawset(L, lua_upvalueindex(1));
+ }
+ /* return current value */
+ lua_pushstring(L, name);
+ lua_rawget(L, lua_upvalueindex(1));
+ return 1;
+}
+
+
+static int io_input (lua_State *L) {
+ return g_iofile(L, IO_INPUT, "r");
+}
+
+
+static int io_output (lua_State *L) {
+ return g_iofile(L, IO_OUTPUT, "w");
+}
+
+
+static int io_readline (lua_State *L);
+
+
+static void aux_lines (lua_State *L, int idx, int close) {
+ lua_pushliteral(L, FILEHANDLE);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ lua_pushvalue(L, idx);
+ lua_pushboolean(L, close); /* close/not close file when finished */
+ lua_pushcclosure(L, io_readline, 3);
+}
+
+
+static int f_lines (lua_State *L) {
+ tofile(L, 1); /* check that it's a valid file handle */
+ aux_lines(L, 1, 0);
+ return 1;
+}
+
+
+static int io_lines (lua_State *L) {
+ if (lua_isnoneornil(L, 1)) { /* no arguments? */
+ lua_pushstring(L, IO_INPUT);
+ lua_rawget(L, lua_upvalueindex(1)); /* will iterate over default input */
+ return f_lines(L);
+ }
+ else {
+ const char *filename = luaL_checkstring(L, 1);
+ FILE **pf = newfile(L);
+ *pf = fopen(filename, "r");
+ luaL_argcheck(L, *pf, 1, strerror(errno));
+ aux_lines(L, lua_gettop(L), 1);
+ return 1;
+ }
+}
+
+
+/*
+** {======================================================
+** READ
+** =======================================================
+*/
+
+
+static int read_number (lua_State *L, FILE *f) {
+ lua_Number d;
+ if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
+ lua_pushnumber(L, d);
+ return 1;
+ }
+ else return 0; /* read fails */
+}
+
+
+static int test_eof (lua_State *L, FILE *f) {
+ int c = getc(f);
+ ungetc(c, f);
+ lua_pushlstring(L, NULL, 0);
+ return (c != EOF);
+}
+
+
+static int read_line (lua_State *L, FILE *f) {
+ luaL_Buffer b;
+ luaL_buffinit(L, &b);
+ for (;;) {
+ size_t l;
+ char *p = luaL_prepbuffer(&b);
+ if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
+ luaL_pushresult(&b); /* close buffer */
+ return (lua_strlen(L, -1) > 0); /* check whether read something */
+ }
+ l = strlen(p);
+ if (p[l-1] != '\n')
+ luaL_addsize(&b, l);
+ else {
+ luaL_addsize(&b, l - 1); /* do not include `eol' */
+ luaL_pushresult(&b); /* close buffer */
+ return 1; /* read at least an `eol' */
+ }
+ }
+}
+
+
+static int read_chars (lua_State *L, FILE *f, size_t n) {
+ size_t rlen; /* how much to read */
+ size_t nr; /* number of chars actually read */
+ luaL_Buffer b;
+ luaL_buffinit(L, &b);
+ rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
+ do {
+ char *p = luaL_prepbuffer(&b);
+ if (rlen > n) rlen = n; /* cannot read more than asked */
+ nr = fread(p, sizeof(char), rlen, f);
+ luaL_addsize(&b, nr);
+ n -= nr; /* still have to read `n' chars */
+ } while (n > 0 && nr == rlen); /* until end of count or eof */
+ luaL_pushresult(&b); /* close buffer */
+ return (n == 0 || lua_strlen(L, -1) > 0);
+}
+
+
+static int g_read (lua_State *L, FILE *f, int first) {
+ int nargs = lua_gettop(L) - 1;
+ int success;
+ int n;
+ if (nargs == 0) { /* no arguments? */
+ success = read_line(L, f);
+ n = first+1; /* to return 1 result */
+ }
+ else { /* ensure stack space for all results and for auxlib's buffer */
+ luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
+ success = 1;
+ for (n = first; nargs-- && success; n++) {
+ if (lua_type(L, n) == LUA_TNUMBER) {
+ size_t l = (size_t)lua_tonumber(L, n);
+ success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
+ }
+ else {
+ const char *p = lua_tostring(L, n);
+ luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
+ switch (p[1]) {
+ case 'n': /* number */
+ success = read_number(L, f);
+ break;
+ case 'l': /* line */
+ success = read_line(L, f);
+ break;
+ case 'a': /* file */
+ read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
+ success = 1; /* always success */
+ break;
+ case 'w': /* word */
+ return luaL_error(L, "obsolete option `*w' to `read'");
+ default:
+ return luaL_argerror(L, n, "invalid format");
+ }
+ }
+ }
+ }
+ if (!success) {
+ lua_pop(L, 1); /* remove last result */
+ lua_pushnil(L); /* push nil instead */
+ }
+ return n - first;
+}
+
+
+static int io_read (lua_State *L) {
+ return g_read(L, getiofile(L, IO_INPUT), 1);
+}
+
+
+static int f_read (lua_State *L) {
+ return g_read(L, tofile(L, 1), 2);
+}
+
+
+static int io_readline (lua_State *L) {
+ FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(2));
+ if (f == NULL) /* file is already closed? */
+ luaL_error(L, "file is already closed");
+ if (read_line(L, f)) return 1;
+ else { /* EOF */
+ if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
+ lua_settop(L, 0);
+ lua_pushvalue(L, lua_upvalueindex(2));
+ aux_close(L); /* close it */
+ }
+ return 0;
+ }
+}
+
+/* }====================================================== */
+
+
+static int g_write (lua_State *L, FILE *f, int arg) {
+ int nargs = lua_gettop(L) - 1;
+ int status = 1;
+ for (; nargs--; arg++) {
+ if (lua_type(L, arg) == LUA_TNUMBER) {
+ /* optimization: could be done exactly as for strings */
+ status = status &&
+ fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
+ }
+ else {
+ size_t l;
+ const char *s = luaL_checklstring(L, arg, &l);
+ status = status && (fwrite(s, sizeof(char), l, f) == l);
+ }
+ }
+ return pushresult(L, status, NULL);
+}
+
+
+static int io_write (lua_State *L) {
+ return g_write(L, getiofile(L, IO_OUTPUT), 1);
+}
+
+
+static int f_write (lua_State *L) {
+ return g_write(L, tofile(L, 1), 2);
+}
+
+
+static int f_seek (lua_State *L) {
+ static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
+ static const char *const modenames[] = {"set", "cur", "end", NULL};
+ FILE *f = tofile(L, 1);
+ int op = luaL_findstring(luaL_optstring(L, 2, "cur"), modenames);
+ long offset = luaL_optlong(L, 3, 0);
+ luaL_argcheck(L, op != -1, 2, "invalid mode");
+ op = fseek(f, offset, mode[op]);
+ if (op)
+ return pushresult(L, 0, NULL); /* error */
+ else {
+ lua_pushnumber(L, ftell(f));
+ return 1;
+ }
+}
+
+
+static int io_flush (lua_State *L) {
+ return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
+}
+
+
+static int f_flush (lua_State *L) {
+ return pushresult(L, fflush(tofile(L, 1)) == 0, NULL);
+}
+
+
+static const luaL_reg iolib[] = {
+ {"input", io_input},
+ {"output", io_output},
+ {"lines", io_lines},
+ {"close", io_close},
+ {"flush", io_flush},
+ {"open", io_open},
+ {"popen", io_popen},
+ {"read", io_read},
+ {"tmpfile", io_tmpfile},
+ {"type", io_type},
+ {"write", io_write},
+ {NULL, NULL}
+};
+
+
+static const luaL_reg flib[] = {
+ {"flush", f_flush},
+ {"read", f_read},
+ {"lines", f_lines},
+ {"seek", f_seek},
+ {"write", f_write},
+ {"close", io_close},
+ {"__gc", io_gc},
+ {"__tostring", io_tostring},
+ {NULL, NULL}
+};
+
+
+static void createmeta (lua_State *L) {
+ luaL_newmetatable(L, FILEHANDLE); /* create new metatable for file handles */
+ /* file methods */
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, -2); /* push metatable */
+ lua_rawset(L, -3); /* metatable.__index = metatable */
+ luaL_openlib(L, NULL, flib, 0);
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** Other O.S. Operations
+** =======================================================
+*/
+
+static int io_execute (lua_State *L) {
+ lua_pushnumber(L, system(luaL_checkstring(L, 1)));
+ return 1;
+}
+
+
+static int io_remove (lua_State *L) {
+ const char *filename = luaL_checkstring(L, 1);
+ return pushresult(L, remove(filename) == 0, filename);
+}
+
+
+static int io_rename (lua_State *L) {
+ const char *fromname = luaL_checkstring(L, 1);
+ const char *toname = luaL_checkstring(L, 2);
+ return pushresult(L, rename(fromname, toname) == 0, fromname);
+}
+
+
+static int io_tmpname (lua_State *L) {
+#if !USE_TMPNAME
+ luaL_error(L, "`tmpname' not supported");
+ return 0;
+#else
+ char buff[L_tmpnam];
+ if (tmpnam(buff) != buff)
+ return luaL_error(L, "unable to generate a unique filename in `tmpname'");
+ lua_pushstring(L, buff);
+ return 1;
+#endif
+}
+
+
+static int io_getenv (lua_State *L) {
+ lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
+ return 1;
+}
+
+
+static int io_clock (lua_State *L) {
+ lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
+ return 1;
+}
+
+
+/*
+** {======================================================
+** Time/Date operations
+** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
+** wday=%w+1, yday=%j, isdst=? }
+** =======================================================
+*/
+
+static void setfield (lua_State *L, const char *key, int value) {
+ lua_pushstring(L, key);
+ lua_pushnumber(L, value);
+ lua_rawset(L, -3);
+}
+
+static void setboolfield (lua_State *L, const char *key, int value) {
+ lua_pushstring(L, key);
+ lua_pushboolean(L, value);
+ lua_rawset(L, -3);
+}
+
+static int getboolfield (lua_State *L, const char *key) {
+ int res;
+ lua_pushstring(L, key);
+ lua_gettable(L, -2);
+ res = lua_toboolean(L, -1);
+ lua_pop(L, 1);
+ return res;
+}
+
+
+static int getfield (lua_State *L, const char *key, int d) {
+ int res;
+ lua_pushstring(L, key);
+ lua_gettable(L, -2);
+ if (lua_isnumber(L, -1))
+ res = (int)(lua_tonumber(L, -1));
+ else {
+ if (d == -2)
+ return luaL_error(L, "field `%s' missing in date table", key);
+ res = d;
+ }
+ lua_pop(L, 1);
+ return res;
+}
+
+
+static int io_date (lua_State *L) {
+ const char *s = luaL_optstring(L, 1, "%c");
+ time_t t = (time_t)(luaL_optnumber(L, 2, -1));
+ struct tm *stm;
+ if (t == (time_t)(-1)) /* no time given? */
+ t = time(NULL); /* use current time */
+ if (*s == '!') { /* UTC? */
+ stm = gmtime(&t);
+ s++; /* skip `!' */
+ }
+ else
+ stm = localtime(&t);
+ if (stm == NULL) /* invalid date? */
+ lua_pushnil(L);
+ else if (strcmp(s, "*t") == 0) {
+ lua_newtable(L);
+ setfield(L, "sec", stm->tm_sec);
+ setfield(L, "min", stm->tm_min);
+ setfield(L, "hour", stm->tm_hour);
+ setfield(L, "day", stm->tm_mday);
+ setfield(L, "month", stm->tm_mon+1);
+ setfield(L, "year", stm->tm_year+1900);
+ setfield(L, "wday", stm->tm_wday+1);
+ setfield(L, "yday", stm->tm_yday+1);
+ setboolfield(L, "isdst", stm->tm_isdst);
+ }
+ else {
+ char b[256];
+ if (strftime(b, sizeof(b), s, stm))
+ lua_pushstring(L, b);
+ else
+ return luaL_error(L, "`date' format too long");
+ }
+ return 1;
+}
+
+
+static int io_time (lua_State *L) {
+ if (lua_isnoneornil(L, 1)) /* called without args? */
+ lua_pushnumber(L, time(NULL)); /* return current time */
+ else {
+ time_t t;
+ struct tm ts;
+ luaL_checktype(L, 1, LUA_TTABLE);
+ lua_settop(L, 1); /* make sure table is at the top */
+ ts.tm_sec = getfield(L, "sec", 0);
+ ts.tm_min = getfield(L, "min", 0);
+ ts.tm_hour = getfield(L, "hour", 12);
+ ts.tm_mday = getfield(L, "day", -2);
+ ts.tm_mon = getfield(L, "month", -2) - 1;
+ ts.tm_year = getfield(L, "year", -2) - 1900;
+ ts.tm_isdst = getboolfield(L, "isdst");
+ t = mktime(&ts);
+ if (t == (time_t)(-1))
+ lua_pushnil(L);
+ else
+ lua_pushnumber(L, t);
+ }
+ return 1;
+}
+
+
+static int io_difftime (lua_State *L) {
+ lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
+ (time_t)(luaL_optnumber(L, 2, 0))));
+ return 1;
+}
+
+/* }====================================================== */
+
+
+static int io_setloc (lua_State *L) {
+ static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
+ LC_NUMERIC, LC_TIME};
+ static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
+ "numeric", "time", NULL};
+ const char *l = lua_tostring(L, 1);
+ int op = luaL_findstring(luaL_optstring(L, 2, "all"), catnames);
+ luaL_argcheck(L, l || lua_isnoneornil(L, 1), 1, "string expected");
+ luaL_argcheck(L, op != -1, 2, "invalid option");
+ lua_pushstring(L, setlocale(cat[op], l));
+ return 1;
+}
+
+
+static int io_exit (lua_State *L) {
+ exit(luaL_optint(L, 1, EXIT_SUCCESS));
+ return 0; /* to avoid warnings */
+}
+
+static const luaL_reg syslib[] = {
+ {"clock", io_clock},
+ {"date", io_date},
+ {"difftime", io_difftime},
+ {"execute", io_execute},
+ {"exit", io_exit},
+ {"getenv", io_getenv},
+ {"remove", io_remove},
+ {"rename", io_rename},
+ {"setlocale", io_setloc},
+ {"time", io_time},
+ {"tmpname", io_tmpname},
+ {NULL, NULL}
+};
+
+/* }====================================================== */
+
+
+
+LUALIB_API int luaopen_io (lua_State *L) {
+ luaL_openlib(L, LUA_OSLIBNAME, syslib, 0);
+ createmeta(L);
+ lua_pushvalue(L, -1);
+ luaL_openlib(L, LUA_IOLIBNAME, iolib, 1);
+ /* put predefined file handles into `io' table */
+ registerfile(L, stdin, "stdin", IO_INPUT);
+ registerfile(L, stdout, "stdout", IO_OUTPUT);
+ registerfile(L, stderr, "stderr", NULL);
+ return 1;
+}
+
diff --git a/lib/lua/src/LuaLib/lmathlib.c b/lib/lua/src/LuaLib/lmathlib.c
index 2352fca..998c46c 100644
--- a/lib/lua/src/LuaLib/lmathlib.c
+++ b/lib/lua/src/LuaLib/lmathlib.c
@@ -1,246 +1,246 @@
-/*
-** $Id: lmathlib.c,v 1.3 2004-11-27 21:35:21 pixel Exp $
-** Standard mathematical library
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stdlib.h>
-#include <math.h>
-
-#define lmathlib_c
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-#undef PI
-#define PI (3.14159265358979323846)
-#define RADIANS_PER_DEGREE (PI/180.0)
-
-
-
-/*
-** If you want Lua to operate in degrees (instead of radians),
-** define USE_DEGREES
-*/
-#ifdef USE_DEGREES
-#define FROMRAD(a) ((a)/RADIANS_PER_DEGREE)
-#define TORAD(a) ((a)*RADIANS_PER_DEGREE)
-#else
-#define FROMRAD(a) (a)
-#define TORAD(a) (a)
-#endif
-
-
-static int math_abs (lua_State *L) {
- lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_sin (lua_State *L) {
- lua_pushnumber(L, sin(TORAD(luaL_checknumber(L, 1))));
- return 1;
-}
-
-static int math_cos (lua_State *L) {
- lua_pushnumber(L, cos(TORAD(luaL_checknumber(L, 1))));
- return 1;
-}
-
-static int math_tan (lua_State *L) {
- lua_pushnumber(L, tan(TORAD(luaL_checknumber(L, 1))));
- return 1;
-}
-
-static int math_asin (lua_State *L) {
- lua_pushnumber(L, FROMRAD(asin(luaL_checknumber(L, 1))));
- return 1;
-}
-
-static int math_acos (lua_State *L) {
- lua_pushnumber(L, FROMRAD(acos(luaL_checknumber(L, 1))));
- return 1;
-}
-
-static int math_atan (lua_State *L) {
- lua_pushnumber(L, FROMRAD(atan(luaL_checknumber(L, 1))));
- return 1;
-}
-
-static int math_atan2 (lua_State *L) {
- lua_pushnumber(L, FROMRAD(atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))));
- return 1;
-}
-
-static int math_ceil (lua_State *L) {
- lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_floor (lua_State *L) {
- lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_mod (lua_State *L) {
- lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
- return 1;
-}
-
-static int math_sqrt (lua_State *L) {
- lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_pow (lua_State *L) {
- lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
- return 1;
-}
-
-static int math_log (lua_State *L) {
- lua_pushnumber(L, log(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_log10 (lua_State *L) {
- lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_exp (lua_State *L) {
- lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_deg (lua_State *L) {
- lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
- return 1;
-}
-
-static int math_rad (lua_State *L) {
- lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
- return 1;
-}
-
-static int math_frexp (lua_State *L) {
- int e;
- lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
- lua_pushnumber(L, e);
- return 2;
-}
-
-static int math_ldexp (lua_State *L) {
- lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
- return 1;
-}
-
-
-
-static int math_min (lua_State *L) {
- int n = lua_gettop(L); /* number of arguments */
- lua_Number dmin = luaL_checknumber(L, 1);
- int i;
- for (i=2; i<=n; i++) {
- lua_Number d = luaL_checknumber(L, i);
- if (d < dmin)
- dmin = d;
- }
- lua_pushnumber(L, dmin);
- return 1;
-}
-
-
-static int math_max (lua_State *L) {
- int n = lua_gettop(L); /* number of arguments */
- lua_Number dmax = luaL_checknumber(L, 1);
- int i;
- for (i=2; i<=n; i++) {
- lua_Number d = luaL_checknumber(L, i);
- if (d > dmax)
- dmax = d;
- }
- lua_pushnumber(L, dmax);
- return 1;
-}
-
-
-static int math_random (lua_State *L) {
- /* the `%' avoids the (rare) case of r==1, and is needed also because on
- some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
- lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
- switch (lua_gettop(L)) { /* check number of arguments */
- case 0: { /* no arguments */
- lua_pushnumber(L, r); /* Number between 0 and 1 */
- break;
- }
- case 1: { /* only upper limit */
- int u = luaL_checkint(L, 1);
- luaL_argcheck(L, 1<=u, 1, "interval is empty");
- lua_pushnumber(L, (int)floor(r*u)+1); /* int between 1 and `u' */
- break;
- }
- case 2: { /* lower and upper limits */
- int l = luaL_checkint(L, 1);
- int u = luaL_checkint(L, 2);
- luaL_argcheck(L, l<=u, 2, "interval is empty");
- lua_pushnumber(L, (int)floor(r*(u-l+1))+l); /* int between `l' and `u' */
- break;
- }
- default: return luaL_error(L, "wrong number of arguments");
- }
- return 1;
-}
-
-
-static int math_randomseed (lua_State *L) {
- srand(luaL_checkint(L, 1));
- return 0;
-}
-
-
-static const luaL_reg mathlib[] = {
- {"abs", math_abs},
- {"sin", math_sin},
- {"cos", math_cos},
- {"tan", math_tan},
- {"asin", math_asin},
- {"acos", math_acos},
- {"atan", math_atan},
- {"atan2", math_atan2},
- {"ceil", math_ceil},
- {"floor", math_floor},
- {"mod", math_mod},
- {"frexp", math_frexp},
- {"ldexp", math_ldexp},
- {"sqrt", math_sqrt},
- {"min", math_min},
- {"max", math_max},
- {"log", math_log},
- {"log10", math_log10},
- {"exp", math_exp},
- {"deg", math_deg},
- {"pow", math_pow},
- {"rad", math_rad},
- {"random", math_random},
- {"randomseed", math_randomseed},
- {NULL, NULL}
-};
-
-
-/*
-** Open math library
-*/
-LUALIB_API int luaopen_math (lua_State *L) {
- luaL_openlib(L, LUA_MATHLIBNAME, mathlib, 0);
- lua_pushliteral(L, "pi");
- lua_pushnumber(L, PI);
- lua_settable(L, -3);
- lua_pushliteral(L, "__pow");
- lua_pushcfunction(L, math_pow);
- lua_settable(L, LUA_GLOBALSINDEX);
- return 1;
-}
-
+/*
+** $Id: lmathlib.c,v 1.4 2004-11-27 21:46:10 pixel Exp $
+** Standard mathematical library
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdlib.h>
+#include <math.h>
+
+#define lmathlib_c
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+#undef PI
+#define PI (3.14159265358979323846)
+#define RADIANS_PER_DEGREE (PI/180.0)
+
+
+
+/*
+** If you want Lua to operate in degrees (instead of radians),
+** define USE_DEGREES
+*/
+#ifdef USE_DEGREES
+#define FROMRAD(a) ((a)/RADIANS_PER_DEGREE)
+#define TORAD(a) ((a)*RADIANS_PER_DEGREE)
+#else
+#define FROMRAD(a) (a)
+#define TORAD(a) (a)
+#endif
+
+
+static int math_abs (lua_State *L) {
+ lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_sin (lua_State *L) {
+ lua_pushnumber(L, sin(TORAD(luaL_checknumber(L, 1))));
+ return 1;
+}
+
+static int math_cos (lua_State *L) {
+ lua_pushnumber(L, cos(TORAD(luaL_checknumber(L, 1))));
+ return 1;
+}
+
+static int math_tan (lua_State *L) {
+ lua_pushnumber(L, tan(TORAD(luaL_checknumber(L, 1))));
+ return 1;
+}
+
+static int math_asin (lua_State *L) {
+ lua_pushnumber(L, FROMRAD(asin(luaL_checknumber(L, 1))));
+ return 1;
+}
+
+static int math_acos (lua_State *L) {
+ lua_pushnumber(L, FROMRAD(acos(luaL_checknumber(L, 1))));
+ return 1;
+}
+
+static int math_atan (lua_State *L) {
+ lua_pushnumber(L, FROMRAD(atan(luaL_checknumber(L, 1))));
+ return 1;
+}
+
+static int math_atan2 (lua_State *L) {
+ lua_pushnumber(L, FROMRAD(atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))));
+ return 1;
+}
+
+static int math_ceil (lua_State *L) {
+ lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_floor (lua_State *L) {
+ lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_mod (lua_State *L) {
+ lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
+ return 1;
+}
+
+static int math_sqrt (lua_State *L) {
+ lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_pow (lua_State *L) {
+ lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
+ return 1;
+}
+
+static int math_log (lua_State *L) {
+ lua_pushnumber(L, log(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_log10 (lua_State *L) {
+ lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_exp (lua_State *L) {
+ lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_deg (lua_State *L) {
+ lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
+ return 1;
+}
+
+static int math_rad (lua_State *L) {
+ lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
+ return 1;
+}
+
+static int math_frexp (lua_State *L) {
+ int e;
+ lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
+ lua_pushnumber(L, e);
+ return 2;
+}
+
+static int math_ldexp (lua_State *L) {
+ lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
+ return 1;
+}
+
+
+
+static int math_min (lua_State *L) {
+ int n = lua_gettop(L); /* number of arguments */
+ lua_Number dmin = luaL_checknumber(L, 1);
+ int i;
+ for (i=2; i<=n; i++) {
+ lua_Number d = luaL_checknumber(L, i);
+ if (d < dmin)
+ dmin = d;
+ }
+ lua_pushnumber(L, dmin);
+ return 1;
+}
+
+
+static int math_max (lua_State *L) {
+ int n = lua_gettop(L); /* number of arguments */
+ lua_Number dmax = luaL_checknumber(L, 1);
+ int i;
+ for (i=2; i<=n; i++) {
+ lua_Number d = luaL_checknumber(L, i);
+ if (d > dmax)
+ dmax = d;
+ }
+ lua_pushnumber(L, dmax);
+ return 1;
+}
+
+
+static int math_random (lua_State *L) {
+ /* the `%' avoids the (rare) case of r==1, and is needed also because on
+ some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
+ lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
+ switch (lua_gettop(L)) { /* check number of arguments */
+ case 0: { /* no arguments */
+ lua_pushnumber(L, r); /* Number between 0 and 1 */
+ break;
+ }
+ case 1: { /* only upper limit */
+ int u = luaL_checkint(L, 1);
+ luaL_argcheck(L, 1<=u, 1, "interval is empty");
+ lua_pushnumber(L, (int)floor(r*u)+1); /* int between 1 and `u' */
+ break;
+ }
+ case 2: { /* lower and upper limits */
+ int l = luaL_checkint(L, 1);
+ int u = luaL_checkint(L, 2);
+ luaL_argcheck(L, l<=u, 2, "interval is empty");
+ lua_pushnumber(L, (int)floor(r*(u-l+1))+l); /* int between `l' and `u' */
+ break;
+ }
+ default: return luaL_error(L, "wrong number of arguments");
+ }
+ return 1;
+}
+
+
+static int math_randomseed (lua_State *L) {
+ srand(luaL_checkint(L, 1));
+ return 0;
+}
+
+
+static const luaL_reg mathlib[] = {
+ {"abs", math_abs},
+ {"sin", math_sin},
+ {"cos", math_cos},
+ {"tan", math_tan},
+ {"asin", math_asin},
+ {"acos", math_acos},
+ {"atan", math_atan},
+ {"atan2", math_atan2},
+ {"ceil", math_ceil},
+ {"floor", math_floor},
+ {"mod", math_mod},
+ {"frexp", math_frexp},
+ {"ldexp", math_ldexp},
+ {"sqrt", math_sqrt},
+ {"min", math_min},
+ {"max", math_max},
+ {"log", math_log},
+ {"log10", math_log10},
+ {"exp", math_exp},
+ {"deg", math_deg},
+ {"pow", math_pow},
+ {"rad", math_rad},
+ {"random", math_random},
+ {"randomseed", math_randomseed},
+ {NULL, NULL}
+};
+
+
+/*
+** Open math library
+*/
+LUALIB_API int luaopen_math (lua_State *L) {
+ luaL_openlib(L, LUA_MATHLIBNAME, mathlib, 0);
+ lua_pushliteral(L, "pi");
+ lua_pushnumber(L, PI);
+ lua_settable(L, -3);
+ lua_pushliteral(L, "__pow");
+ lua_pushcfunction(L, math_pow);
+ lua_settable(L, LUA_GLOBALSINDEX);
+ return 1;
+}
+
diff --git a/lib/lua/src/LuaLib/loadlib.c b/lib/lua/src/LuaLib/loadlib.c
index dc83283..8756205 100644
--- a/lib/lua/src/LuaLib/loadlib.c
+++ b/lib/lua/src/LuaLib/loadlib.c
@@ -1,205 +1,205 @@
-/*
-** $Id: loadlib.c,v 1.3 2004-11-27 21:35:21 pixel Exp $
-** Dynamic library loader for Lua
-** See Copyright Notice in lua.h
-*
-* This Lua library exports a single function, called loadlib, which is
-* called from Lua as loadlib(lib,init), where lib is the full name of the
-* library to be loaded (including the complete path) and init is the name
-* of a function to be called after the library is loaded. Typically, this
-* function will register other functions, thus making the complete library
-* available to Lua. The init function is *not* automatically called by
-* loadlib. Instead, loadlib returns the init function as a Lua function
-* that the client can call when it thinks is appropriate. In the case of
-* errors, loadlib returns nil and two strings describing the error.
-* The first string is supplied by the operating system; it should be
-* informative and useful for error messages. The second string is "open",
-* "init", or "absent" to identify the error and is meant to be used for
-* making decisions without having to look into the first string (whose
-* format is system-dependent).
-*
-* This module contains an implementation of loadlib for Unix systems that
-* have dlfcn, an implementation for Windows, and a stub for other systems.
-* See the list at the end of this file for some links to available
-* implementations of dlfcn and interfaces to other native dynamic loaders
-* on top of which loadlib could be implemented.
-*
-*/
-
-#include "lua.h"
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-#undef LOADLIB
-
-
-#ifdef USE_DLOPEN
-#define LOADLIB
-/*
-* This is an implementation of loadlib based on the dlfcn interface.
-* The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
-* NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
-* as an emulation layer on top of native functions.
-*/
-
-#include <dlfcn.h>
-
-static int loadlib(lua_State *L)
-{
- const char *path=luaL_checkstring(L,1);
- const char *init=luaL_checkstring(L,2);
- void *lib=dlopen(path,RTLD_NOW);
- if (lib!=NULL)
- {
- lua_CFunction f=(lua_CFunction) dlsym(lib,init);
- if (f!=NULL)
- {
- lua_pushlightuserdata(L,lib);
- lua_pushcclosure(L,f,1);
- return 1;
- }
- }
- /* else return appropriate error messages */
- lua_pushnil(L);
- lua_pushstring(L,dlerror());
- lua_pushstring(L,(lib!=NULL) ? "init" : "open");
- if (lib!=NULL) dlclose(lib);
- return 3;
-}
-
-#endif
-
-
-
-/*
-** In Windows, default is to use dll; otherwise, default is not to use dll
-*/
-#ifndef USE_DLL
-#ifdef _WIN32
-#define USE_DLL 1
-#else
-#define USE_DLL 0
-#endif
-#endif
-
-
-#if USE_DLL
-#define LOADLIB
-/*
-* This is an implementation of loadlib for Windows using native functions.
-*/
-
-#include <windows.h>
-
-static void pusherror(lua_State *L)
-{
- int error=GetLastError();
- char buffer[128];
- if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
- 0, error, 0, buffer, sizeof(buffer), 0))
- lua_pushstring(L,buffer);
- else
- lua_pushfstring(L,"system error %d\n",error);
-}
-
-static int loadlib(lua_State *L)
-{
- const char *path=luaL_checkstring(L,1);
- const char *init=luaL_checkstring(L,2);
- HINSTANCE lib=LoadLibrary(path);
- if (lib!=NULL)
- {
- lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init);
- if (f!=NULL)
- {
- lua_pushlightuserdata(L,lib);
- lua_pushcclosure(L,f,1);
- return 1;
- }
- }
- lua_pushnil(L);
- pusherror(L);
- lua_pushstring(L,(lib!=NULL) ? "init" : "open");
- if (lib!=NULL) FreeLibrary(lib);
- return 3;
-}
-
-#endif
-
-
-
-#ifndef LOADLIB
-/* Fallback for other systems */
-
-/*
-** Those systems support dlopen, so they should have defined USE_DLOPEN.
-** The default (no)implementation gives them a special error message.
-*/
-#ifdef linux
-#define LOADLIB
-#endif
-
-#ifdef sun
-#define LOADLIB
-#endif
-
-#ifdef sgi
-#define LOADLIB
-#endif
-
-#ifdef BSD
-#define LOADLIB
-#endif
-
-#ifdef _WIN32
-#define LOADLIB
-#endif
-
-#ifdef LOADLIB
-#undef LOADLIB
-#define LOADLIB "`loadlib' not installed (check your Lua configuration)"
-#else
-#define LOADLIB "`loadlib' not supported"
-#endif
-
-static int loadlib(lua_State *L)
-{
- lua_pushnil(L);
- lua_pushliteral(L,LOADLIB);
- lua_pushliteral(L,"absent");
- return 3;
-}
-#endif
-
-LUALIB_API int luaopen_loadlib (lua_State *L)
-{
- lua_register(L,"loadlib",loadlib);
- return 0;
-}
-
-/*
-* Here are some links to available implementations of dlfcn and
-* interfaces to other native dynamic loaders on top of which loadlib
-* could be implemented. Please send contributions and corrections to us.
-*
-* AIX
-* Starting with AIX 4.2, dlfcn is included in the base OS.
-* There is also an emulation package available.
-* http://www.faqs.org/faqs/aix-faq/part4/section-21.html
-*
-* HPUX
-* HPUX 11 has dlfcn. For HPUX 10 use shl_*.
-* http://www.geda.seul.org/mailinglist/geda-dev37/msg00094.html
-* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
-*
-* Macintosh, Windows
-* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
-*
-* Mac OS X/Darwin
-* http://www.opendarwin.org/projects/dlcompat/
-*
-* GLIB has wrapper code for BeOS, OS2, Unix and Windows
-* http://cvs.gnome.org/lxr/source/glib/gmodule/
-*
-*/
+/*
+** $Id: loadlib.c,v 1.4 2004-11-27 21:46:10 pixel Exp $
+** Dynamic library loader for Lua
+** See Copyright Notice in lua.h
+*
+* This Lua library exports a single function, called loadlib, which is
+* called from Lua as loadlib(lib,init), where lib is the full name of the
+* library to be loaded (including the complete path) and init is the name
+* of a function to be called after the library is loaded. Typically, this
+* function will register other functions, thus making the complete library
+* available to Lua. The init function is *not* automatically called by
+* loadlib. Instead, loadlib returns the init function as a Lua function
+* that the client can call when it thinks is appropriate. In the case of
+* errors, loadlib returns nil and two strings describing the error.
+* The first string is supplied by the operating system; it should be
+* informative and useful for error messages. The second string is "open",
+* "init", or "absent" to identify the error and is meant to be used for
+* making decisions without having to look into the first string (whose
+* format is system-dependent).
+*
+* This module contains an implementation of loadlib for Unix systems that
+* have dlfcn, an implementation for Windows, and a stub for other systems.
+* See the list at the end of this file for some links to available
+* implementations of dlfcn and interfaces to other native dynamic loaders
+* on top of which loadlib could be implemented.
+*
+*/
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+#undef LOADLIB
+
+
+#ifdef USE_DLOPEN
+#define LOADLIB
+/*
+* This is an implementation of loadlib based on the dlfcn interface.
+* The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
+* NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
+* as an emulation layer on top of native functions.
+*/
+
+#include <dlfcn.h>
+
+static int loadlib(lua_State *L)
+{
+ const char *path=luaL_checkstring(L,1);
+ const char *init=luaL_checkstring(L,2);
+ void *lib=dlopen(path,RTLD_NOW);
+ if (lib!=NULL)
+ {
+ lua_CFunction f=(lua_CFunction) dlsym(lib,init);
+ if (f!=NULL)
+ {
+ lua_pushlightuserdata(L,lib);
+ lua_pushcclosure(L,f,1);
+ return 1;
+ }
+ }
+ /* else return appropriate error messages */
+ lua_pushnil(L);
+ lua_pushstring(L,dlerror());
+ lua_pushstring(L,(lib!=NULL) ? "init" : "open");
+ if (lib!=NULL) dlclose(lib);
+ return 3;
+}
+
+#endif
+
+
+
+/*
+** In Windows, default is to use dll; otherwise, default is not to use dll
+*/
+#ifndef USE_DLL
+#ifdef _WIN32
+#define USE_DLL 1
+#else
+#define USE_DLL 0
+#endif
+#endif
+
+
+#if USE_DLL
+#define LOADLIB
+/*
+* This is an implementation of loadlib for Windows using native functions.
+*/
+
+#include <windows.h>
+
+static void pusherror(lua_State *L)
+{
+ int error=GetLastError();
+ char buffer[128];
+ if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
+ 0, error, 0, buffer, sizeof(buffer), 0))
+ lua_pushstring(L,buffer);
+ else
+ lua_pushfstring(L,"system error %d\n",error);
+}
+
+static int loadlib(lua_State *L)
+{
+ const char *path=luaL_checkstring(L,1);
+ const char *init=luaL_checkstring(L,2);
+ HINSTANCE lib=LoadLibrary(path);
+ if (lib!=NULL)
+ {
+ lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init);
+ if (f!=NULL)
+ {
+ lua_pushlightuserdata(L,lib);
+ lua_pushcclosure(L,f,1);
+ return 1;
+ }
+ }
+ lua_pushnil(L);
+ pusherror(L);
+ lua_pushstring(L,(lib!=NULL) ? "init" : "open");
+ if (lib!=NULL) FreeLibrary(lib);
+ return 3;
+}
+
+#endif
+
+
+
+#ifndef LOADLIB
+/* Fallback for other systems */
+
+/*
+** Those systems support dlopen, so they should have defined USE_DLOPEN.
+** The default (no)implementation gives them a special error message.
+*/
+#ifdef linux
+#define LOADLIB
+#endif
+
+#ifdef sun
+#define LOADLIB
+#endif
+
+#ifdef sgi
+#define LOADLIB
+#endif
+
+#ifdef BSD
+#define LOADLIB
+#endif
+
+#ifdef _WIN32
+#define LOADLIB
+#endif
+
+#ifdef LOADLIB
+#undef LOADLIB
+#define LOADLIB "`loadlib' not installed (check your Lua configuration)"
+#else
+#define LOADLIB "`loadlib' not supported"
+#endif
+
+static int loadlib(lua_State *L)
+{
+ lua_pushnil(L);
+ lua_pushliteral(L,LOADLIB);
+ lua_pushliteral(L,"absent");
+ return 3;
+}
+#endif
+
+LUALIB_API int luaopen_loadlib (lua_State *L)
+{
+ lua_register(L,"loadlib",loadlib);
+ return 0;
+}
+
+/*
+* Here are some links to available implementations of dlfcn and
+* interfaces to other native dynamic loaders on top of which loadlib
+* could be implemented. Please send contributions and corrections to us.
+*
+* AIX
+* Starting with AIX 4.2, dlfcn is included in the base OS.
+* There is also an emulation package available.
+* http://www.faqs.org/faqs/aix-faq/part4/section-21.html
+*
+* HPUX
+* HPUX 11 has dlfcn. For HPUX 10 use shl_*.
+* http://www.geda.seul.org/mailinglist/geda-dev37/msg00094.html
+* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
+*
+* Macintosh, Windows
+* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
+*
+* Mac OS X/Darwin
+* http://www.opendarwin.org/projects/dlcompat/
+*
+* GLIB has wrapper code for BeOS, OS2, Unix and Windows
+* http://cvs.gnome.org/lxr/source/glib/gmodule/
+*
+*/
diff --git a/lib/lua/src/LuaLib/lstrlib.c b/lib/lua/src/LuaLib/lstrlib.c
index 9b5fe8a..2e5f26e 100644
--- a/lib/lua/src/LuaLib/lstrlib.c
+++ b/lib/lua/src/LuaLib/lstrlib.c
@@ -1,770 +1,770 @@
-/*
-** $Id: lstrlib.c,v 1.3 2004-11-27 21:35:21 pixel Exp $
-** Standard library for string operations and pattern-matching
-** See Copyright Notice in lua.h
-*/
-
-
-#include <ctype.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define lstrlib_c
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-/* macro to `unsign' a character */
-#ifndef uchar
-#define uchar(c) ((unsigned char)(c))
-#endif
-
-
-typedef long sint32; /* a signed version for size_t */
-
-
-static int str_len (lua_State *L) {
- size_t l;
- luaL_checklstring(L, 1, &l);
- lua_pushnumber(L, (lua_Number)l);
- return 1;
-}
-
-
-static sint32 posrelat (sint32 pos, size_t len) {
- /* relative string position: negative means back from end */
- return (pos>=0) ? pos : (sint32)len+pos+1;
-}
-
-
-static int str_sub (lua_State *L) {
- size_t l;
- const char *s = luaL_checklstring(L, 1, &l);
- sint32 start = posrelat(luaL_checklong(L, 2), l);
- sint32 end = posrelat(luaL_optlong(L, 3, -1), l);
- if (start < 1) start = 1;
- if (end > (sint32)l) end = (sint32)l;
- if (start <= end)
- lua_pushlstring(L, s+start-1, end-start+1);
- else lua_pushliteral(L, "");
- return 1;
-}
-
-
-static int str_lower (lua_State *L) {
- size_t l;
- size_t i;
- luaL_Buffer b;
- const char *s = luaL_checklstring(L, 1, &l);
- luaL_buffinit(L, &b);
- for (i=0; i<l; i++)
- luaL_putchar(&b, tolower(uchar(s[i])));
- luaL_pushresult(&b);
- return 1;
-}
-
-
-static int str_upper (lua_State *L) {
- size_t l;
- size_t i;
- luaL_Buffer b;
- const char *s = luaL_checklstring(L, 1, &l);
- luaL_buffinit(L, &b);
- for (i=0; i<l; i++)
- luaL_putchar(&b, toupper(uchar(s[i])));
- luaL_pushresult(&b);
- return 1;
-}
-
-static int str_rep (lua_State *L) {
- size_t l;
- luaL_Buffer b;
- const char *s = luaL_checklstring(L, 1, &l);
- int n = luaL_checkint(L, 2);
- luaL_buffinit(L, &b);
- while (n-- > 0)
- luaL_addlstring(&b, s, l);
- luaL_pushresult(&b);
- return 1;
-}
-
-
-static int str_byte (lua_State *L) {
- size_t l;
- const char *s = luaL_checklstring(L, 1, &l);
- sint32 pos = posrelat(luaL_optlong(L, 2, 1), l);
- if (pos <= 0 || (size_t)(pos) > l) /* index out of range? */
- return 0; /* no answer */
- lua_pushnumber(L, uchar(s[pos-1]));
- return 1;
-}
-
-
-static int str_char (lua_State *L) {
- int n = lua_gettop(L); /* number of arguments */
- int i;
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- for (i=1; i<=n; i++) {
- int c = luaL_checkint(L, i);
- luaL_argcheck(L, uchar(c) == c, i, "invalid value");
- luaL_putchar(&b, uchar(c));
- }
- luaL_pushresult(&b);
- return 1;
-}
-
-
-static int writer (lua_State *L, const void* b, size_t size, void* B) {
- (void)L;
- luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
- return 1;
-}
-
-
-static int str_dump (lua_State *L) {
- luaL_Buffer b;
- luaL_checktype(L, 1, LUA_TFUNCTION);
- luaL_buffinit(L,&b);
- if (!lua_dump(L, writer, &b))
- luaL_error(L, "unable to dump given function");
- luaL_pushresult(&b);
- return 1;
-}
-
-
-
-/*
-** {======================================================
-** PATTERN MATCHING
-** =======================================================
-*/
-
-#ifndef MAX_CAPTURES
-#define MAX_CAPTURES 32 /* arbitrary limit */
-#endif
-
-
-#define CAP_UNFINISHED (-1)
-#define CAP_POSITION (-2)
-
-typedef struct MatchState {
- const char *src_init; /* init of source string */
- const char *src_end; /* end (`\0') of source string */
- lua_State *L;
- int level; /* total number of captures (finished or unfinished) */
- struct {
- const char *init;
- sint32 len;
- } capture[MAX_CAPTURES];
-} MatchState;
-
-
-#define ESC '%'
-#define SPECIALS "^$*+?.([%-"
-
-
-static int check_capture (MatchState *ms, int l) {
- l -= '1';
- if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
- return luaL_error(ms->L, "invalid capture index");
- return l;
-}
-
-
-static int capture_to_close (MatchState *ms) {
- int level = ms->level;
- for (level--; level>=0; level--)
- if (ms->capture[level].len == CAP_UNFINISHED) return level;
- return luaL_error(ms->L, "invalid pattern capture");
-}
-
-
-static const char *luaI_classend (MatchState *ms, const char *p) {
- switch (*p++) {
- case ESC: {
- if (*p == '\0')
- luaL_error(ms->L, "malformed pattern (ends with `%')");
- return p+1;
- }
- case '[': {
- if (*p == '^') p++;
- do { /* look for a `]' */
- if (*p == '\0')
- luaL_error(ms->L, "malformed pattern (missing `]')");
- if (*(p++) == ESC && *p != '\0')
- p++; /* skip escapes (e.g. `%]') */
- } while (*p != ']');
- return p+1;
- }
- default: {
- return p;
- }
- }
-}
-
-
-static int match_class (int c, int cl) {
- int res;
- switch (tolower(cl)) {
- case 'a' : res = isalpha(c); break;
- case 'c' : res = iscntrl(c); break;
- case 'd' : res = isdigit(c); break;
- case 'l' : res = islower(c); break;
- case 'p' : res = ispunct(c); break;
- case 's' : res = isspace(c); break;
- case 'u' : res = isupper(c); break;
- case 'w' : res = isalnum(c); break;
- case 'x' : res = isxdigit(c); break;
- case 'z' : res = (c == 0); break;
- default: return (cl == c);
- }
- return (islower(cl) ? res : !res);
-}
-
-
-static int matchbracketclass (int c, const char *p, const char *ec) {
- int sig = 1;
- if (*(p+1) == '^') {
- sig = 0;
- p++; /* skip the `^' */
- }
- while (++p < ec) {
- if (*p == ESC) {
- p++;
- if (match_class(c, *p))
- return sig;
- }
- else if ((*(p+1) == '-') && (p+2 < ec)) {
- p+=2;
- if (uchar(*(p-2)) <= c && c <= uchar(*p))
- return sig;
- }
- else if (uchar(*p) == c) return sig;
- }
- return !sig;
-}
-
-
-static int luaI_singlematch (int c, const char *p, const char *ep) {
- switch (*p) {
- case '.': return 1; /* matches any char */
- case ESC: return match_class(c, *(p+1));
- case '[': return matchbracketclass(c, p, ep-1);
- default: return (uchar(*p) == c);
- }
-}
-
-
-static const char *match (MatchState *ms, const char *s, const char *p);
-
-
-static const char *matchbalance (MatchState *ms, const char *s,
- const char *p) {
- if (*p == 0 || *(p+1) == 0)
- luaL_error(ms->L, "unbalanced pattern");
- if (*s != *p) return NULL;
- else {
- int b = *p;
- int e = *(p+1);
- int cont = 1;
- while (++s < ms->src_end) {
- if (*s == e) {
- if (--cont == 0) return s+1;
- }
- else if (*s == b) cont++;
- }
- }
- return NULL; /* string ends out of balance */
-}
-
-
-static const char *max_expand (MatchState *ms, const char *s,
- const char *p, const char *ep) {
- sint32 i = 0; /* counts maximum expand for item */
- while ((s+i)<ms->src_end && luaI_singlematch(uchar(*(s+i)), p, ep))
- i++;
- /* keeps trying to match with the maximum repetitions */
- while (i>=0) {
- const char *res = match(ms, (s+i), ep+1);
- if (res) return res;
- i--; /* else didn't match; reduce 1 repetition to try again */
- }
- return NULL;
-}
-
-
-static const char *min_expand (MatchState *ms, const char *s,
- const char *p, const char *ep) {
- for (;;) {
- const char *res = match(ms, s, ep+1);
- if (res != NULL)
- return res;
- else if (s<ms->src_end && luaI_singlematch(uchar(*s), p, ep))
- s++; /* try with one more repetition */
- else return NULL;
- }
-}
-
-
-static const char *start_capture (MatchState *ms, const char *s,
- const char *p, int what) {
- const char *res;
- int level = ms->level;
- if (level >= MAX_CAPTURES) luaL_error(ms->L, "too many captures");
- ms->capture[level].init = s;
- ms->capture[level].len = what;
- ms->level = level+1;
- if ((res=match(ms, s, p)) == NULL) /* match failed? */
- ms->level--; /* undo capture */
- return res;
-}
-
-
-static const char *end_capture (MatchState *ms, const char *s,
- const char *p) {
- int l = capture_to_close(ms);
- const char *res;
- ms->capture[l].len = s - ms->capture[l].init; /* close capture */
- if ((res = match(ms, s, p)) == NULL) /* match failed? */
- ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
- return res;
-}
-
-
-static const char *match_capture (MatchState *ms, const char *s, int l) {
- size_t len;
- l = check_capture(ms, l);
- len = ms->capture[l].len;
- if ((size_t)(ms->src_end-s) >= len &&
- memcmp(ms->capture[l].init, s, len) == 0)
- return s+len;
- else return NULL;
-}
-
-
-static const char *match (MatchState *ms, const char *s, const char *p) {
- init: /* using goto's to optimize tail recursion */
- switch (*p) {
- case '(': { /* start capture */
- if (*(p+1) == ')') /* position capture? */
- return start_capture(ms, s, p+2, CAP_POSITION);
- else
- return start_capture(ms, s, p+1, CAP_UNFINISHED);
- }
- case ')': { /* end capture */
- return end_capture(ms, s, p+1);
- }
- case ESC: {
- switch (*(p+1)) {
- case 'b': { /* balanced string? */
- s = matchbalance(ms, s, p+2);
- if (s == NULL) return NULL;
- p+=4; goto init; /* else return match(ms, s, p+4); */
- }
- case 'f': { /* frontier? */
- const char *ep; char previous;
- p += 2;
- if (*p != '[')
- luaL_error(ms->L, "missing `[' after `%%f' in pattern");
- ep = luaI_classend(ms, p); /* points to what is next */
- previous = (s == ms->src_init) ? '\0' : *(s-1);
- if (matchbracketclass(uchar(previous), p, ep-1) ||
- !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
- p=ep; goto init; /* else return match(ms, s, ep); */
- }
- default: {
- if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
- s = match_capture(ms, s, *(p+1));
- if (s == NULL) return NULL;
- p+=2; goto init; /* else return match(ms, s, p+2) */
- }
- goto dflt; /* case default */
- }
- }
- }
- case '\0': { /* end of pattern */
- return s; /* match succeeded */
- }
- case '$': {
- if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
- return (s == ms->src_end) ? s : NULL; /* check end of string */
- else goto dflt;
- }
- default: dflt: { /* it is a pattern item */
- const char *ep = luaI_classend(ms, p); /* points to what is next */
- int m = s<ms->src_end && luaI_singlematch(uchar(*s), p, ep);
- switch (*ep) {
- case '?': { /* optional */
- const char *res;
- if (m && ((res=match(ms, s+1, ep+1)) != NULL))
- return res;
- p=ep+1; goto init; /* else return match(ms, s, ep+1); */
- }
- case '*': { /* 0 or more repetitions */
- return max_expand(ms, s, p, ep);
- }
- case '+': { /* 1 or more repetitions */
- return (m ? max_expand(ms, s+1, p, ep) : NULL);
- }
- case '-': { /* 0 or more repetitions (minimum) */
- return min_expand(ms, s, p, ep);
- }
- default: {
- if (!m) return NULL;
- s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
- }
- }
- }
- }
-}
-
-
-
-static const char *lmemfind (const char *s1, size_t l1,
- const char *s2, size_t l2) {
- if (l2 == 0) return s1; /* empty strings are everywhere */
- else if (l2 > l1) return NULL; /* avoids a negative `l1' */
- else {
- const char *init; /* to search for a `*s2' inside `s1' */
- l2--; /* 1st char will be checked by `memchr' */
- l1 = l1-l2; /* `s2' cannot be found after that */
- while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
- init++; /* 1st char is already checked */
- if (memcmp(init, s2+1, l2) == 0)
- return init-1;
- else { /* correct `l1' and `s1' to try again */
- l1 -= init-s1;
- s1 = init;
- }
- }
- return NULL; /* not found */
- }
-}
-
-
-static void push_onecapture (MatchState *ms, int i) {
- int l = ms->capture[i].len;
- if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
- if (l == CAP_POSITION)
- lua_pushnumber(ms->L, (lua_Number)(ms->capture[i].init - ms->src_init + 1));
- else
- lua_pushlstring(ms->L, ms->capture[i].init, l);
-}
-
-
-static int push_captures (MatchState *ms, const char *s, const char *e) {
- int i;
- luaL_checkstack(ms->L, ms->level, "too many captures");
- if (ms->level == 0 && s) { /* no explicit captures? */
- lua_pushlstring(ms->L, s, e-s); /* return whole match */
- return 1;
- }
- else { /* return all captures */
- for (i=0; i<ms->level; i++)
- push_onecapture(ms, i);
- return ms->level; /* number of strings pushed */
- }
-}
-
-
-static int str_find (lua_State *L) {
- size_t l1, l2;
- const char *s = luaL_checklstring(L, 1, &l1);
- const char *p = luaL_checklstring(L, 2, &l2);
- sint32 init = posrelat(luaL_optlong(L, 3, 1), l1) - 1;
- if (init < 0) init = 0;
- else if ((size_t)(init) > l1) init = (sint32)l1;
- if (lua_toboolean(L, 4) || /* explicit request? */
- strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */
- /* do a plain search */
- const char *s2 = lmemfind(s+init, l1-init, p, l2);
- if (s2) {
- lua_pushnumber(L, (lua_Number)(s2-s+1));
- lua_pushnumber(L, (lua_Number)(s2-s+l2));
- return 2;
- }
- }
- else {
- MatchState ms;
- int anchor = (*p == '^') ? (p++, 1) : 0;
- const char *s1=s+init;
- ms.L = L;
- ms.src_init = s;
- ms.src_end = s+l1;
- do {
- const char *res;
- ms.level = 0;
- if ((res=match(&ms, s1, p)) != NULL) {
- lua_pushnumber(L, (lua_Number)(s1-s+1)); /* start */
- lua_pushnumber(L, (lua_Number)(res-s)); /* end */
- return push_captures(&ms, NULL, 0) + 2;
- }
- } while (s1++<ms.src_end && !anchor);
- }
- lua_pushnil(L); /* not found */
- return 1;
-}
-
-
-static int gfind_aux (lua_State *L) {
- MatchState ms;
- const char *s = lua_tostring(L, lua_upvalueindex(1));
- size_t ls = lua_strlen(L, lua_upvalueindex(1));
- const char *p = lua_tostring(L, lua_upvalueindex(2));
- const char *src;
- ms.L = L;
- ms.src_init = s;
- ms.src_end = s+ls;
- for (src = s + (size_t)lua_tonumber(L, lua_upvalueindex(3));
- src <= ms.src_end;
- src++) {
- const char *e;
- ms.level = 0;
- if ((e = match(&ms, src, p)) != NULL) {
- int newstart = e-s;
- if (e == src) newstart++; /* empty match? go at least one position */
- lua_pushnumber(L, (lua_Number)newstart);
- lua_replace(L, lua_upvalueindex(3));
- return push_captures(&ms, src, e);
- }
- }
- return 0; /* not found */
-}
-
-
-static int gfind (lua_State *L) {
- luaL_checkstring(L, 1);
- luaL_checkstring(L, 2);
- lua_settop(L, 2);
- lua_pushnumber(L, 0);
- lua_pushcclosure(L, gfind_aux, 3);
- return 1;
-}
-
-
-static void add_s (MatchState *ms, luaL_Buffer *b,
- const char *s, const char *e) {
- lua_State *L = ms->L;
- if (lua_isstring(L, 3)) {
- const char *news = lua_tostring(L, 3);
- size_t l = lua_strlen(L, 3);
- size_t i;
- for (i=0; i<l; i++) {
- if (news[i] != ESC)
- luaL_putchar(b, news[i]);
- else {
- i++; /* skip ESC */
- if (!isdigit(uchar(news[i])))
- luaL_putchar(b, news[i]);
- else {
- int level = check_capture(ms, news[i]);
- push_onecapture(ms, level);
- luaL_addvalue(b); /* add capture to accumulated result */
- }
- }
- }
- }
- else { /* is a function */
- int n;
- lua_pushvalue(L, 3);
- n = push_captures(ms, s, e);
- lua_call(L, n, 1);
- if (lua_isstring(L, -1))
- luaL_addvalue(b); /* add return to accumulated result */
- else
- lua_pop(L, 1); /* function result is not a string: pop it */
- }
-}
-
-
-static int str_gsub (lua_State *L) {
- size_t srcl;
- const char *src = luaL_checklstring(L, 1, &srcl);
- const char *p = luaL_checkstring(L, 2);
- int max_s = luaL_optint(L, 4, srcl+1);
- int anchor = (*p == '^') ? (p++, 1) : 0;
- int n = 0;
- MatchState ms;
- luaL_Buffer b;
- luaL_argcheck(L,
- lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
- 3, "string or function expected");
- luaL_buffinit(L, &b);
- ms.L = L;
- ms.src_init = src;
- ms.src_end = src+srcl;
- while (n < max_s) {
- const char *e;
- ms.level = 0;
- e = match(&ms, src, p);
- if (e) {
- n++;
- add_s(&ms, &b, src, e);
- }
- if (e && e>src) /* non empty match? */
- src = e; /* skip it */
- else if (src < ms.src_end)
- luaL_putchar(&b, *src++);
- else break;
- if (anchor) break;
- }
- luaL_addlstring(&b, src, ms.src_end-src);
- luaL_pushresult(&b);
- lua_pushnumber(L, (lua_Number)n); /* number of substitutions */
- return 2;
-}
-
-/* }====================================================== */
-
-
-/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
-#define MAX_ITEM 512
-/* maximum size of each format specification (such as '%-099.99d') */
-#define MAX_FORMAT 20
-
-
-static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) {
- size_t l;
- const char *s = luaL_checklstring(L, arg, &l);
- luaL_putchar(b, '"');
- while (l--) {
- switch (*s) {
- case '"': case '\\': case '\n': {
- luaL_putchar(b, '\\');
- luaL_putchar(b, *s);
- break;
- }
- case '\0': {
- luaL_addlstring(b, "\\000", 4);
- break;
- }
- default: {
- luaL_putchar(b, *s);
- break;
- }
- }
- s++;
- }
- luaL_putchar(b, '"');
-}
-
-
-static const char *scanformat (lua_State *L, const char *strfrmt,
- char *form, int *hasprecision) {
- const char *p = strfrmt;
- while (strchr("-+ #0", *p)) p++; /* skip flags */
- if (isdigit(uchar(*p))) p++; /* skip width */
- if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
- if (*p == '.') {
- p++;
- *hasprecision = 1;
- if (isdigit(uchar(*p))) p++; /* skip precision */
- if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
- }
- if (isdigit(uchar(*p)))
- luaL_error(L, "invalid format (width or precision too long)");
- if (p-strfrmt+2 > MAX_FORMAT) /* +2 to include `%' and the specifier */
- luaL_error(L, "invalid format (too long)");
- form[0] = '%';
- strncpy(form+1, strfrmt, p-strfrmt+1);
- form[p-strfrmt+2] = 0;
- return p;
-}
-
-
-static int str_format (lua_State *L) {
- int arg = 1;
- size_t sfl;
- const char *strfrmt = luaL_checklstring(L, arg, &sfl);
- const char *strfrmt_end = strfrmt+sfl;
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- while (strfrmt < strfrmt_end) {
- if (*strfrmt != '%')
- luaL_putchar(&b, *strfrmt++);
- else if (*++strfrmt == '%')
- luaL_putchar(&b, *strfrmt++); /* %% */
- else { /* format item */
- char form[MAX_FORMAT]; /* to store the format (`%...') */
- char buff[MAX_ITEM]; /* to store the formatted item */
- int hasprecision = 0;
- if (isdigit(uchar(*strfrmt)) && *(strfrmt+1) == '$')
- return luaL_error(L, "obsolete option (d$) to `format'");
- arg++;
- strfrmt = scanformat(L, strfrmt, form, &hasprecision);
- switch (*strfrmt++) {
- case 'c': case 'd': case 'i': {
- sprintf(buff, form, luaL_checkint(L, arg));
- break;
- }
- case 'o': case 'u': case 'x': case 'X': {
- sprintf(buff, form, (unsigned int)(luaL_checknumber(L, arg)));
- break;
- }
- case 'e': case 'E': case 'f':
- case 'g': case 'G': {
- sprintf(buff, form, luaL_checknumber(L, arg));
- break;
- }
- case 'q': {
- luaI_addquoted(L, &b, arg);
- continue; /* skip the `addsize' at the end */
- }
- case 's': {
- size_t l;
- const char *s = luaL_checklstring(L, arg, &l);
- if (!hasprecision && l >= 100) {
- /* no precision and string is too long to be formatted;
- keep original string */
- lua_pushvalue(L, arg);
- luaL_addvalue(&b);
- continue; /* skip the `addsize' at the end */
- }
- else {
- sprintf(buff, form, s);
- break;
- }
- }
- default: { /* also treat cases `pnLlh' */
- return luaL_error(L, "invalid option to `format'");
- }
- }
- luaL_addlstring(&b, buff, strlen(buff));
- }
- }
- luaL_pushresult(&b);
- return 1;
-}
-
-
-static const luaL_reg strlib[] = {
- {"len", str_len},
- {"sub", str_sub},
- {"lower", str_lower},
- {"upper", str_upper},
- {"char", str_char},
- {"rep", str_rep},
- {"byte", str_byte},
- {"format", str_format},
- {"dump", str_dump},
- {"find", str_find},
- {"gfind", gfind},
- {"gsub", str_gsub},
- {NULL, NULL}
-};
-
-
-/*
-** Open string library
-*/
-LUALIB_API int luaopen_string (lua_State *L) {
- luaL_openlib(L, LUA_STRLIBNAME, strlib, 0);
- return 1;
-}
-
+/*
+** $Id: lstrlib.c,v 1.4 2004-11-27 21:46:10 pixel Exp $
+** Standard library for string operations and pattern-matching
+** See Copyright Notice in lua.h
+*/
+
+
+#include <ctype.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lstrlib_c
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+/* macro to `unsign' a character */
+#ifndef uchar
+#define uchar(c) ((unsigned char)(c))
+#endif
+
+
+typedef long sint32; /* a signed version for size_t */
+
+
+static int str_len (lua_State *L) {
+ size_t l;
+ luaL_checklstring(L, 1, &l);
+ lua_pushnumber(L, (lua_Number)l);
+ return 1;
+}
+
+
+static sint32 posrelat (sint32 pos, size_t len) {
+ /* relative string position: negative means back from end */
+ return (pos>=0) ? pos : (sint32)len+pos+1;
+}
+
+
+static int str_sub (lua_State *L) {
+ size_t l;
+ const char *s = luaL_checklstring(L, 1, &l);
+ sint32 start = posrelat(luaL_checklong(L, 2), l);
+ sint32 end = posrelat(luaL_optlong(L, 3, -1), l);
+ if (start < 1) start = 1;
+ if (end > (sint32)l) end = (sint32)l;
+ if (start <= end)
+ lua_pushlstring(L, s+start-1, end-start+1);
+ else lua_pushliteral(L, "");
+ return 1;
+}
+
+
+static int str_lower (lua_State *L) {
+ size_t l;
+ size_t i;
+ luaL_Buffer b;
+ const char *s = luaL_checklstring(L, 1, &l);
+ luaL_buffinit(L, &b);
+ for (i=0; i<l; i++)
+ luaL_putchar(&b, tolower(uchar(s[i])));
+ luaL_pushresult(&b);
+ return 1;
+}
+
+
+static int str_upper (lua_State *L) {
+ size_t l;
+ size_t i;
+ luaL_Buffer b;
+ const char *s = luaL_checklstring(L, 1, &l);
+ luaL_buffinit(L, &b);
+ for (i=0; i<l; i++)
+ luaL_putchar(&b, toupper(uchar(s[i])));
+ luaL_pushresult(&b);
+ return 1;
+}
+
+static int str_rep (lua_State *L) {
+ size_t l;
+ luaL_Buffer b;
+ const char *s = luaL_checklstring(L, 1, &l);
+ int n = luaL_checkint(L, 2);
+ luaL_buffinit(L, &b);
+ while (n-- > 0)
+ luaL_addlstring(&b, s, l);
+ luaL_pushresult(&b);
+ return 1;
+}
+
+
+static int str_byte (lua_State *L) {
+ size_t l;
+ const char *s = luaL_checklstring(L, 1, &l);
+ sint32 pos = posrelat(luaL_optlong(L, 2, 1), l);
+ if (pos <= 0 || (size_t)(pos) > l) /* index out of range? */
+ return 0; /* no answer */
+ lua_pushnumber(L, uchar(s[pos-1]));
+ return 1;
+}
+
+
+static int str_char (lua_State *L) {
+ int n = lua_gettop(L); /* number of arguments */
+ int i;
+ luaL_Buffer b;
+ luaL_buffinit(L, &b);
+ for (i=1; i<=n; i++) {
+ int c = luaL_checkint(L, i);
+ luaL_argcheck(L, uchar(c) == c, i, "invalid value");
+ luaL_putchar(&b, uchar(c));
+ }
+ luaL_pushresult(&b);
+ return 1;
+}
+
+
+static int writer (lua_State *L, const void* b, size_t size, void* B) {
+ (void)L;
+ luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
+ return 1;
+}
+
+
+static int str_dump (lua_State *L) {
+ luaL_Buffer b;
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+ luaL_buffinit(L,&b);
+ if (!lua_dump(L, writer, &b))
+ luaL_error(L, "unable to dump given function");
+ luaL_pushresult(&b);
+ return 1;
+}
+
+
+
+/*
+** {======================================================
+** PATTERN MATCHING
+** =======================================================
+*/
+
+#ifndef MAX_CAPTURES
+#define MAX_CAPTURES 32 /* arbitrary limit */
+#endif
+
+
+#define CAP_UNFINISHED (-1)
+#define CAP_POSITION (-2)
+
+typedef struct MatchState {
+ const char *src_init; /* init of source string */
+ const char *src_end; /* end (`\0') of source string */
+ lua_State *L;
+ int level; /* total number of captures (finished or unfinished) */
+ struct {
+ const char *init;
+ sint32 len;
+ } capture[MAX_CAPTURES];
+} MatchState;
+
+
+#define ESC '%'
+#define SPECIALS "^$*+?.([%-"
+
+
+static int check_capture (MatchState *ms, int l) {
+ l -= '1';
+ if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
+ return luaL_error(ms->L, "invalid capture index");
+ return l;
+}
+
+
+static int capture_to_close (MatchState *ms) {
+ int level = ms->level;
+ for (level--; level>=0; level--)
+ if (ms->capture[level].len == CAP_UNFINISHED) return level;
+ return luaL_error(ms->L, "invalid pattern capture");
+}
+
+
+static const char *luaI_classend (MatchState *ms, const char *p) {
+ switch (*p++) {
+ case ESC: {
+ if (*p == '\0')
+ luaL_error(ms->L, "malformed pattern (ends with `%')");
+ return p+1;
+ }
+ case '[': {
+ if (*p == '^') p++;
+ do { /* look for a `]' */
+ if (*p == '\0')
+ luaL_error(ms->L, "malformed pattern (missing `]')");
+ if (*(p++) == ESC && *p != '\0')
+ p++; /* skip escapes (e.g. `%]') */
+ } while (*p != ']');
+ return p+1;
+ }
+ default: {
+ return p;
+ }
+ }
+}
+
+
+static int match_class (int c, int cl) {
+ int res;
+ switch (tolower(cl)) {
+ case 'a' : res = isalpha(c); break;
+ case 'c' : res = iscntrl(c); break;
+ case 'd' : res = isdigit(c); break;
+ case 'l' : res = islower(c); break;
+ case 'p' : res = ispunct(c); break;
+ case 's' : res = isspace(c); break;
+ case 'u' : res = isupper(c); break;
+ case 'w' : res = isalnum(c); break;
+ case 'x' : res = isxdigit(c); break;
+ case 'z' : res = (c == 0); break;
+ default: return (cl == c);
+ }
+ return (islower(cl) ? res : !res);
+}
+
+
+static int matchbracketclass (int c, const char *p, const char *ec) {
+ int sig = 1;
+ if (*(p+1) == '^') {
+ sig = 0;
+ p++; /* skip the `^' */
+ }
+ while (++p < ec) {
+ if (*p == ESC) {
+ p++;
+ if (match_class(c, *p))
+ return sig;
+ }
+ else if ((*(p+1) == '-') && (p+2 < ec)) {
+ p+=2;
+ if (uchar(*(p-2)) <= c && c <= uchar(*p))
+ return sig;
+ }
+ else if (uchar(*p) == c) return sig;
+ }
+ return !sig;
+}
+
+
+static int luaI_singlematch (int c, const char *p, const char *ep) {
+ switch (*p) {
+ case '.': return 1; /* matches any char */
+ case ESC: return match_class(c, *(p+1));
+ case '[': return matchbracketclass(c, p, ep-1);
+ default: return (uchar(*p) == c);
+ }
+}
+
+
+static const char *match (MatchState *ms, const char *s, const char *p);
+
+
+static const char *matchbalance (MatchState *ms, const char *s,
+ const char *p) {
+ if (*p == 0 || *(p+1) == 0)
+ luaL_error(ms->L, "unbalanced pattern");
+ if (*s != *p) return NULL;
+ else {
+ int b = *p;
+ int e = *(p+1);
+ int cont = 1;
+ while (++s < ms->src_end) {
+ if (*s == e) {
+ if (--cont == 0) return s+1;
+ }
+ else if (*s == b) cont++;
+ }
+ }
+ return NULL; /* string ends out of balance */
+}
+
+
+static const char *max_expand (MatchState *ms, const char *s,
+ const char *p, const char *ep) {
+ sint32 i = 0; /* counts maximum expand for item */
+ while ((s+i)<ms->src_end && luaI_singlematch(uchar(*(s+i)), p, ep))
+ i++;
+ /* keeps trying to match with the maximum repetitions */
+ while (i>=0) {
+ const char *res = match(ms, (s+i), ep+1);
+ if (res) return res;
+ i--; /* else didn't match; reduce 1 repetition to try again */
+ }
+ return NULL;
+}
+
+
+static const char *min_expand (MatchState *ms, const char *s,
+ const char *p, const char *ep) {
+ for (;;) {
+ const char *res = match(ms, s, ep+1);
+ if (res != NULL)
+ return res;
+ else if (s<ms->src_end && luaI_singlematch(uchar(*s), p, ep))
+ s++; /* try with one more repetition */
+ else return NULL;
+ }
+}
+
+
+static const char *start_capture (MatchState *ms, const char *s,
+ const char *p, int what) {
+ const char *res;
+ int level = ms->level;
+ if (level >= MAX_CAPTURES) luaL_error(ms->L, "too many captures");
+ ms->capture[level].init = s;
+ ms->capture[level].len = what;
+ ms->level = level+1;
+ if ((res=match(ms, s, p)) == NULL) /* match failed? */
+ ms->level--; /* undo capture */
+ return res;
+}
+
+
+static const char *end_capture (MatchState *ms, const char *s,
+ const char *p) {
+ int l = capture_to_close(ms);
+ const char *res;
+ ms->capture[l].len = s - ms->capture[l].init; /* close capture */
+ if ((res = match(ms, s, p)) == NULL) /* match failed? */
+ ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
+ return res;
+}
+
+
+static const char *match_capture (MatchState *ms, const char *s, int l) {
+ size_t len;
+ l = check_capture(ms, l);
+ len = ms->capture[l].len;
+ if ((size_t)(ms->src_end-s) >= len &&
+ memcmp(ms->capture[l].init, s, len) == 0)
+ return s+len;
+ else return NULL;
+}
+
+
+static const char *match (MatchState *ms, const char *s, const char *p) {
+ init: /* using goto's to optimize tail recursion */
+ switch (*p) {
+ case '(': { /* start capture */
+ if (*(p+1) == ')') /* position capture? */
+ return start_capture(ms, s, p+2, CAP_POSITION);
+ else
+ return start_capture(ms, s, p+1, CAP_UNFINISHED);
+ }
+ case ')': { /* end capture */
+ return end_capture(ms, s, p+1);
+ }
+ case ESC: {
+ switch (*(p+1)) {
+ case 'b': { /* balanced string? */
+ s = matchbalance(ms, s, p+2);
+ if (s == NULL) return NULL;
+ p+=4; goto init; /* else return match(ms, s, p+4); */
+ }
+ case 'f': { /* frontier? */
+ const char *ep; char previous;
+ p += 2;
+ if (*p != '[')
+ luaL_error(ms->L, "missing `[' after `%%f' in pattern");
+ ep = luaI_classend(ms, p); /* points to what is next */
+ previous = (s == ms->src_init) ? '\0' : *(s-1);
+ if (matchbracketclass(uchar(previous), p, ep-1) ||
+ !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
+ p=ep; goto init; /* else return match(ms, s, ep); */
+ }
+ default: {
+ if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
+ s = match_capture(ms, s, *(p+1));
+ if (s == NULL) return NULL;
+ p+=2; goto init; /* else return match(ms, s, p+2) */
+ }
+ goto dflt; /* case default */
+ }
+ }
+ }
+ case '\0': { /* end of pattern */
+ return s; /* match succeeded */
+ }
+ case '$': {
+ if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
+ return (s == ms->src_end) ? s : NULL; /* check end of string */
+ else goto dflt;
+ }
+ default: dflt: { /* it is a pattern item */
+ const char *ep = luaI_classend(ms, p); /* points to what is next */
+ int m = s<ms->src_end && luaI_singlematch(uchar(*s), p, ep);
+ switch (*ep) {
+ case '?': { /* optional */
+ const char *res;
+ if (m && ((res=match(ms, s+1, ep+1)) != NULL))
+ return res;
+ p=ep+1; goto init; /* else return match(ms, s, ep+1); */
+ }
+ case '*': { /* 0 or more repetitions */
+ return max_expand(ms, s, p, ep);
+ }
+ case '+': { /* 1 or more repetitions */
+ return (m ? max_expand(ms, s+1, p, ep) : NULL);
+ }
+ case '-': { /* 0 or more repetitions (minimum) */
+ return min_expand(ms, s, p, ep);
+ }
+ default: {
+ if (!m) return NULL;
+ s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
+ }
+ }
+ }
+ }
+}
+
+
+
+static const char *lmemfind (const char *s1, size_t l1,
+ const char *s2, size_t l2) {
+ if (l2 == 0) return s1; /* empty strings are everywhere */
+ else if (l2 > l1) return NULL; /* avoids a negative `l1' */
+ else {
+ const char *init; /* to search for a `*s2' inside `s1' */
+ l2--; /* 1st char will be checked by `memchr' */
+ l1 = l1-l2; /* `s2' cannot be found after that */
+ while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
+ init++; /* 1st char is already checked */
+ if (memcmp(init, s2+1, l2) == 0)
+ return init-1;
+ else { /* correct `l1' and `s1' to try again */
+ l1 -= init-s1;
+ s1 = init;
+ }
+ }
+ return NULL; /* not found */
+ }
+}
+
+
+static void push_onecapture (MatchState *ms, int i) {
+ int l = ms->capture[i].len;
+ if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
+ if (l == CAP_POSITION)
+ lua_pushnumber(ms->L, (lua_Number)(ms->capture[i].init - ms->src_init + 1));
+ else
+ lua_pushlstring(ms->L, ms->capture[i].init, l);
+}
+
+
+static int push_captures (MatchState *ms, const char *s, const char *e) {
+ int i;
+ luaL_checkstack(ms->L, ms->level, "too many captures");
+ if (ms->level == 0 && s) { /* no explicit captures? */
+ lua_pushlstring(ms->L, s, e-s); /* return whole match */
+ return 1;
+ }
+ else { /* return all captures */
+ for (i=0; i<ms->level; i++)
+ push_onecapture(ms, i);
+ return ms->level; /* number of strings pushed */
+ }
+}
+
+
+static int str_find (lua_State *L) {
+ size_t l1, l2;
+ const char *s = luaL_checklstring(L, 1, &l1);
+ const char *p = luaL_checklstring(L, 2, &l2);
+ sint32 init = posrelat(luaL_optlong(L, 3, 1), l1) - 1;
+ if (init < 0) init = 0;
+ else if ((size_t)(init) > l1) init = (sint32)l1;
+ if (lua_toboolean(L, 4) || /* explicit request? */
+ strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */
+ /* do a plain search */
+ const char *s2 = lmemfind(s+init, l1-init, p, l2);
+ if (s2) {
+ lua_pushnumber(L, (lua_Number)(s2-s+1));
+ lua_pushnumber(L, (lua_Number)(s2-s+l2));
+ return 2;
+ }
+ }
+ else {
+ MatchState ms;
+ int anchor = (*p == '^') ? (p++, 1) : 0;
+ const char *s1=s+init;
+ ms.L = L;
+ ms.src_init = s;
+ ms.src_end = s+l1;
+ do {
+ const char *res;
+ ms.level = 0;
+ if ((res=match(&ms, s1, p)) != NULL) {
+ lua_pushnumber(L, (lua_Number)(s1-s+1)); /* start */
+ lua_pushnumber(L, (lua_Number)(res-s)); /* end */
+ return push_captures(&ms, NULL, 0) + 2;
+ }
+ } while (s1++<ms.src_end && !anchor);
+ }
+ lua_pushnil(L); /* not found */
+ return 1;
+}
+
+
+static int gfind_aux (lua_State *L) {
+ MatchState ms;
+ const char *s = lua_tostring(L, lua_upvalueindex(1));
+ size_t ls = lua_strlen(L, lua_upvalueindex(1));
+ const char *p = lua_tostring(L, lua_upvalueindex(2));
+ const char *src;
+ ms.L = L;
+ ms.src_init = s;
+ ms.src_end = s+ls;
+ for (src = s + (size_t)lua_tonumber(L, lua_upvalueindex(3));
+ src <= ms.src_end;
+ src++) {
+ const char *e;
+ ms.level = 0;
+ if ((e = match(&ms, src, p)) != NULL) {
+ int newstart = e-s;
+ if (e == src) newstart++; /* empty match? go at least one position */
+ lua_pushnumber(L, (lua_Number)newstart);
+ lua_replace(L, lua_upvalueindex(3));
+ return push_captures(&ms, src, e);
+ }
+ }
+ return 0; /* not found */
+}
+
+
+static int gfind (lua_State *L) {
+ luaL_checkstring(L, 1);
+ luaL_checkstring(L, 2);
+ lua_settop(L, 2);
+ lua_pushnumber(L, 0);
+ lua_pushcclosure(L, gfind_aux, 3);
+ return 1;
+}
+
+
+static void add_s (MatchState *ms, luaL_Buffer *b,
+ const char *s, const char *e) {
+ lua_State *L = ms->L;
+ if (lua_isstring(L, 3)) {
+ const char *news = lua_tostring(L, 3);
+ size_t l = lua_strlen(L, 3);
+ size_t i;
+ for (i=0; i<l; i++) {
+ if (news[i] != ESC)
+ luaL_putchar(b, news[i]);
+ else {
+ i++; /* skip ESC */
+ if (!isdigit(uchar(news[i])))
+ luaL_putchar(b, news[i]);
+ else {
+ int level = check_capture(ms, news[i]);
+ push_onecapture(ms, level);
+ luaL_addvalue(b); /* add capture to accumulated result */
+ }
+ }
+ }
+ }
+ else { /* is a function */
+ int n;
+ lua_pushvalue(L, 3);
+ n = push_captures(ms, s, e);
+ lua_call(L, n, 1);
+ if (lua_isstring(L, -1))
+ luaL_addvalue(b); /* add return to accumulated result */
+ else
+ lua_pop(L, 1); /* function result is not a string: pop it */
+ }
+}
+
+
+static int str_gsub (lua_State *L) {
+ size_t srcl;
+ const char *src = luaL_checklstring(L, 1, &srcl);
+ const char *p = luaL_checkstring(L, 2);
+ int max_s = luaL_optint(L, 4, srcl+1);
+ int anchor = (*p == '^') ? (p++, 1) : 0;
+ int n = 0;
+ MatchState ms;
+ luaL_Buffer b;
+ luaL_argcheck(L,
+ lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
+ 3, "string or function expected");
+ luaL_buffinit(L, &b);
+ ms.L = L;
+ ms.src_init = src;
+ ms.src_end = src+srcl;
+ while (n < max_s) {
+ const char *e;
+ ms.level = 0;
+ e = match(&ms, src, p);
+ if (e) {
+ n++;
+ add_s(&ms, &b, src, e);
+ }
+ if (e && e>src) /* non empty match? */
+ src = e; /* skip it */
+ else if (src < ms.src_end)
+ luaL_putchar(&b, *src++);
+ else break;
+ if (anchor) break;
+ }
+ luaL_addlstring(&b, src, ms.src_end-src);
+ luaL_pushresult(&b);
+ lua_pushnumber(L, (lua_Number)n); /* number of substitutions */
+ return 2;
+}
+
+/* }====================================================== */
+
+
+/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
+#define MAX_ITEM 512
+/* maximum size of each format specification (such as '%-099.99d') */
+#define MAX_FORMAT 20
+
+
+static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) {
+ size_t l;
+ const char *s = luaL_checklstring(L, arg, &l);
+ luaL_putchar(b, '"');
+ while (l--) {
+ switch (*s) {
+ case '"': case '\\': case '\n': {
+ luaL_putchar(b, '\\');
+ luaL_putchar(b, *s);
+ break;
+ }
+ case '\0': {
+ luaL_addlstring(b, "\\000", 4);
+ break;
+ }
+ default: {
+ luaL_putchar(b, *s);
+ break;
+ }
+ }
+ s++;
+ }
+ luaL_putchar(b, '"');
+}
+
+
+static const char *scanformat (lua_State *L, const char *strfrmt,
+ char *form, int *hasprecision) {
+ const char *p = strfrmt;
+ while (strchr("-+ #0", *p)) p++; /* skip flags */
+ if (isdigit(uchar(*p))) p++; /* skip width */
+ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
+ if (*p == '.') {
+ p++;
+ *hasprecision = 1;
+ if (isdigit(uchar(*p))) p++; /* skip precision */
+ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
+ }
+ if (isdigit(uchar(*p)))
+ luaL_error(L, "invalid format (width or precision too long)");
+ if (p-strfrmt+2 > MAX_FORMAT) /* +2 to include `%' and the specifier */
+ luaL_error(L, "invalid format (too long)");
+ form[0] = '%';
+ strncpy(form+1, strfrmt, p-strfrmt+1);
+ form[p-strfrmt+2] = 0;
+ return p;
+}
+
+
+static int str_format (lua_State *L) {
+ int arg = 1;
+ size_t sfl;
+ const char *strfrmt = luaL_checklstring(L, arg, &sfl);
+ const char *strfrmt_end = strfrmt+sfl;
+ luaL_Buffer b;
+ luaL_buffinit(L, &b);
+ while (strfrmt < strfrmt_end) {
+ if (*strfrmt != '%')
+ luaL_putchar(&b, *strfrmt++);
+ else if (*++strfrmt == '%')
+ luaL_putchar(&b, *strfrmt++); /* %% */
+ else { /* format item */
+ char form[MAX_FORMAT]; /* to store the format (`%...') */
+ char buff[MAX_ITEM]; /* to store the formatted item */
+ int hasprecision = 0;
+ if (isdigit(uchar(*strfrmt)) && *(strfrmt+1) == '$')
+ return luaL_error(L, "obsolete option (d$) to `format'");
+ arg++;
+ strfrmt = scanformat(L, strfrmt, form, &hasprecision);
+ switch (*strfrmt++) {
+ case 'c': case 'd': case 'i': {
+ sprintf(buff, form, luaL_checkint(L, arg));
+ break;
+ }
+ case 'o': case 'u': case 'x': case 'X': {
+ sprintf(buff, form, (unsigned int)(luaL_checknumber(L, arg)));
+ break;
+ }
+ case 'e': case 'E': case 'f':
+ case 'g': case 'G': {
+ sprintf(buff, form, luaL_checknumber(L, arg));
+ break;
+ }
+ case 'q': {
+ luaI_addquoted(L, &b, arg);
+ continue; /* skip the `addsize' at the end */
+ }
+ case 's': {
+ size_t l;
+ const char *s = luaL_checklstring(L, arg, &l);
+ if (!hasprecision && l >= 100) {
+ /* no precision and string is too long to be formatted;
+ keep original string */
+ lua_pushvalue(L, arg);
+ luaL_addvalue(&b);
+ continue; /* skip the `addsize' at the end */
+ }
+ else {
+ sprintf(buff, form, s);
+ break;
+ }
+ }
+ default: { /* also treat cases `pnLlh' */
+ return luaL_error(L, "invalid option to `format'");
+ }
+ }
+ luaL_addlstring(&b, buff, strlen(buff));
+ }
+ }
+ luaL_pushresult(&b);
+ return 1;
+}
+
+
+static const luaL_reg strlib[] = {
+ {"len", str_len},
+ {"sub", str_sub},
+ {"lower", str_lower},
+ {"upper", str_upper},
+ {"char", str_char},
+ {"rep", str_rep},
+ {"byte", str_byte},
+ {"format", str_format},
+ {"dump", str_dump},
+ {"find", str_find},
+ {"gfind", gfind},
+ {"gsub", str_gsub},
+ {NULL, NULL}
+};
+
+
+/*
+** Open string library
+*/
+LUALIB_API int luaopen_string (lua_State *L) {
+ luaL_openlib(L, LUA_STRLIBNAME, strlib, 0);
+ return 1;
+}
+
diff --git a/lib/lua/src/LuaLib/ltablib.c b/lib/lua/src/LuaLib/ltablib.c
index fc6c380..71f3afa 100644
--- a/lib/lua/src/LuaLib/ltablib.c
+++ b/lib/lua/src/LuaLib/ltablib.c
@@ -1,250 +1,250 @@
-/*
-** $Id: ltablib.c,v 1.3 2004-11-27 21:35:21 pixel Exp $
-** Library for Table Manipulation
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stddef.h>
-
-#define ltablib_c
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
-
-
-static int luaB_foreachi (lua_State *L) {
- int i;
- int n = aux_getn(L, 1);
- luaL_checktype(L, 2, LUA_TFUNCTION);
- for (i=1; i<=n; i++) {
- lua_pushvalue(L, 2); /* function */
- lua_pushnumber(L, (lua_Number)i); /* 1st argument */
- lua_rawgeti(L, 1, i); /* 2nd argument */
- lua_call(L, 2, 1);
- if (!lua_isnil(L, -1))
- return 1;
- lua_pop(L, 1); /* remove nil result */
- }
- return 0;
-}
-
-
-static int luaB_foreach (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_checktype(L, 2, LUA_TFUNCTION);
- lua_pushnil(L); /* first key */
- for (;;) {
- if (lua_next(L, 1) == 0)
- return 0;
- lua_pushvalue(L, 2); /* function */
- lua_pushvalue(L, -3); /* key */
- lua_pushvalue(L, -3); /* value */
- lua_call(L, 2, 1);
- if (!lua_isnil(L, -1))
- return 1;
- lua_pop(L, 2); /* remove value and result */
- }
-}
-
-
-static int luaB_getn (lua_State *L) {
- lua_pushnumber(L, (lua_Number)aux_getn(L, 1));
- return 1;
-}
-
-
-static int luaB_setn (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_setn(L, 1, luaL_checkint(L, 2));
- return 0;
-}
-
-
-static int luaB_tinsert (lua_State *L) {
- int v = lua_gettop(L); /* number of arguments */
- int n = aux_getn(L, 1) + 1;
- int pos; /* where to insert new element */
- if (v == 2) /* called with only 2 arguments */
- pos = n; /* insert new element at the end */
- else {
- pos = luaL_checkint(L, 2); /* 2nd argument is the position */
- if (pos > n) n = pos; /* `grow' array if necessary */
- v = 3; /* function may be called with more than 3 args */
- }
- luaL_setn(L, 1, n); /* new size */
- while (--n >= pos) { /* move up elements */
- lua_rawgeti(L, 1, n);
- lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */
- }
- lua_pushvalue(L, v);
- lua_rawseti(L, 1, pos); /* t[pos] = v */
- return 0;
-}
-
-
-static int luaB_tremove (lua_State *L) {
- int n = aux_getn(L, 1);
- int pos = luaL_optint(L, 2, n);
- if (n <= 0) return 0; /* table is `empty' */
- luaL_setn(L, 1, n-1); /* t.n = n-1 */
- lua_rawgeti(L, 1, pos); /* result = t[pos] */
- for ( ;pos<n; pos++) {
- lua_rawgeti(L, 1, pos+1);
- lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
- }
- lua_pushnil(L);
- lua_rawseti(L, 1, n); /* t[n] = nil */
- return 1;
-}
-
-
-static int str_concat (lua_State *L) {
- luaL_Buffer b;
- size_t lsep;
- const char *sep = luaL_optlstring(L, 2, "", &lsep);
- int i = luaL_optint(L, 3, 1);
- int n = luaL_optint(L, 4, 0);
- luaL_checktype(L, 1, LUA_TTABLE);
- if (n == 0) n = luaL_getn(L, 1);
- luaL_buffinit(L, &b);
- for (; i <= n; i++) {
- lua_rawgeti(L, 1, i);
- luaL_argcheck(L, lua_isstring(L, -1), 1, "table contains non-strings");
- luaL_addvalue(&b);
- if (i != n)
- luaL_addlstring(&b, sep, lsep);
- }
- luaL_pushresult(&b);
- return 1;
-}
-
-
-
-/*
-** {======================================================
-** Quicksort
-** (based on `Algorithms in MODULA-3', Robert Sedgewick;
-** Addison-Wesley, 1993.)
-*/
-
-
-static void set2 (lua_State *L, int i, int j) {
- lua_rawseti(L, 1, i);
- lua_rawseti(L, 1, j);
-}
-
-static int sort_comp (lua_State *L, int a, int b) {
- if (!lua_isnil(L, 2)) { /* function? */
- int res;
- lua_pushvalue(L, 2);
- lua_pushvalue(L, a-1); /* -1 to compensate function */
- lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
- lua_call(L, 2, 1);
- res = lua_toboolean(L, -1);
- lua_pop(L, 1);
- return res;
- }
- else /* a < b? */
- return lua_lessthan(L, a, b);
-}
-
-static void auxsort (lua_State *L, int l, int u) {
- while (l < u) { /* for tail recursion */
- int i, j;
- /* sort elements a[l], a[(l+u)/2] and a[u] */
- lua_rawgeti(L, 1, l);
- lua_rawgeti(L, 1, u);
- if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
- set2(L, l, u); /* swap a[l] - a[u] */
- else
- lua_pop(L, 2);
- if (u-l == 1) break; /* only 2 elements */
- i = (l+u)/2;
- lua_rawgeti(L, 1, i);
- lua_rawgeti(L, 1, l);
- if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
- set2(L, i, l);
- else {
- lua_pop(L, 1); /* remove a[l] */
- lua_rawgeti(L, 1, u);
- if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
- set2(L, i, u);
- else
- lua_pop(L, 2);
- }
- if (u-l == 2) break; /* only 3 elements */
- lua_rawgeti(L, 1, i); /* Pivot */
- lua_pushvalue(L, -1);
- lua_rawgeti(L, 1, u-1);
- set2(L, i, u-1);
- /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
- i = l; j = u-1;
- for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
- /* repeat ++i until a[i] >= P */
- while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
- if (i>u) luaL_error(L, "invalid order function for sorting");
- lua_pop(L, 1); /* remove a[i] */
- }
- /* repeat --j until a[j] <= P */
- while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
- if (j<l) luaL_error(L, "invalid order function for sorting");
- lua_pop(L, 1); /* remove a[j] */
- }
- if (j<i) {
- lua_pop(L, 3); /* pop pivot, a[i], a[j] */
- break;
- }
- set2(L, i, j);
- }
- lua_rawgeti(L, 1, u-1);
- lua_rawgeti(L, 1, i);
- set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
- /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
- /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
- if (i-l < u-i) {
- j=l; i=i-1; l=i+2;
- }
- else {
- j=i+1; i=u; u=j-2;
- }
- auxsort(L, j, i); /* call recursively the smaller one */
- } /* repeat the routine for the larger one */
-}
-
-static int luaB_sort (lua_State *L) {
- int n = aux_getn(L, 1);
- luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
- if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
- luaL_checktype(L, 2, LUA_TFUNCTION);
- lua_settop(L, 2); /* make sure there is two arguments */
- auxsort(L, 1, n);
- return 0;
-}
-
-/* }====================================================== */
-
-
-static const luaL_reg tab_funcs[] = {
- {"concat", str_concat},
- {"foreach", luaB_foreach},
- {"foreachi", luaB_foreachi},
- {"getn", luaB_getn},
- {"setn", luaB_setn},
- {"sort", luaB_sort},
- {"insert", luaB_tinsert},
- {"remove", luaB_tremove},
- {NULL, NULL}
-};
-
-
-LUALIB_API int luaopen_table (lua_State *L) {
- luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 0);
- return 1;
-}
-
+/*
+** $Id: ltablib.c,v 1.4 2004-11-27 21:46:10 pixel Exp $
+** Library for Table Manipulation
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stddef.h>
+
+#define ltablib_c
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
+
+
+static int luaB_foreachi (lua_State *L) {
+ int i;
+ int n = aux_getn(L, 1);
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ for (i=1; i<=n; i++) {
+ lua_pushvalue(L, 2); /* function */
+ lua_pushnumber(L, (lua_Number)i); /* 1st argument */
+ lua_rawgeti(L, 1, i); /* 2nd argument */
+ lua_call(L, 2, 1);
+ if (!lua_isnil(L, -1))
+ return 1;
+ lua_pop(L, 1); /* remove nil result */
+ }
+ return 0;
+}
+
+
+static int luaB_foreach (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ lua_pushnil(L); /* first key */
+ for (;;) {
+ if (lua_next(L, 1) == 0)
+ return 0;
+ lua_pushvalue(L, 2); /* function */
+ lua_pushvalue(L, -3); /* key */
+ lua_pushvalue(L, -3); /* value */
+ lua_call(L, 2, 1);
+ if (!lua_isnil(L, -1))
+ return 1;
+ lua_pop(L, 2); /* remove value and result */
+ }
+}
+
+
+static int luaB_getn (lua_State *L) {
+ lua_pushnumber(L, (lua_Number)aux_getn(L, 1));
+ return 1;
+}
+
+
+static int luaB_setn (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ luaL_setn(L, 1, luaL_checkint(L, 2));
+ return 0;
+}
+
+
+static int luaB_tinsert (lua_State *L) {
+ int v = lua_gettop(L); /* number of arguments */
+ int n = aux_getn(L, 1) + 1;
+ int pos; /* where to insert new element */
+ if (v == 2) /* called with only 2 arguments */
+ pos = n; /* insert new element at the end */
+ else {
+ pos = luaL_checkint(L, 2); /* 2nd argument is the position */
+ if (pos > n) n = pos; /* `grow' array if necessary */
+ v = 3; /* function may be called with more than 3 args */
+ }
+ luaL_setn(L, 1, n); /* new size */
+ while (--n >= pos) { /* move up elements */
+ lua_rawgeti(L, 1, n);
+ lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */
+ }
+ lua_pushvalue(L, v);
+ lua_rawseti(L, 1, pos); /* t[pos] = v */
+ return 0;
+}
+
+
+static int luaB_tremove (lua_State *L) {
+ int n = aux_getn(L, 1);
+ int pos = luaL_optint(L, 2, n);
+ if (n <= 0) return 0; /* table is `empty' */
+ luaL_setn(L, 1, n-1); /* t.n = n-1 */
+ lua_rawgeti(L, 1, pos); /* result = t[pos] */
+ for ( ;pos<n; pos++) {
+ lua_rawgeti(L, 1, pos+1);
+ lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
+ }
+ lua_pushnil(L);
+ lua_rawseti(L, 1, n); /* t[n] = nil */
+ return 1;
+}
+
+
+static int str_concat (lua_State *L) {
+ luaL_Buffer b;
+ size_t lsep;
+ const char *sep = luaL_optlstring(L, 2, "", &lsep);
+ int i = luaL_optint(L, 3, 1);
+ int n = luaL_optint(L, 4, 0);
+ luaL_checktype(L, 1, LUA_TTABLE);
+ if (n == 0) n = luaL_getn(L, 1);
+ luaL_buffinit(L, &b);
+ for (; i <= n; i++) {
+ lua_rawgeti(L, 1, i);
+ luaL_argcheck(L, lua_isstring(L, -1), 1, "table contains non-strings");
+ luaL_addvalue(&b);
+ if (i != n)
+ luaL_addlstring(&b, sep, lsep);
+ }
+ luaL_pushresult(&b);
+ return 1;
+}
+
+
+
+/*
+** {======================================================
+** Quicksort
+** (based on `Algorithms in MODULA-3', Robert Sedgewick;
+** Addison-Wesley, 1993.)
+*/
+
+
+static void set2 (lua_State *L, int i, int j) {
+ lua_rawseti(L, 1, i);
+ lua_rawseti(L, 1, j);
+}
+
+static int sort_comp (lua_State *L, int a, int b) {
+ if (!lua_isnil(L, 2)) { /* function? */
+ int res;
+ lua_pushvalue(L, 2);
+ lua_pushvalue(L, a-1); /* -1 to compensate function */
+ lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
+ lua_call(L, 2, 1);
+ res = lua_toboolean(L, -1);
+ lua_pop(L, 1);
+ return res;
+ }
+ else /* a < b? */
+ return lua_lessthan(L, a, b);
+}
+
+static void auxsort (lua_State *L, int l, int u) {
+ while (l < u) { /* for tail recursion */
+ int i, j;
+ /* sort elements a[l], a[(l+u)/2] and a[u] */
+ lua_rawgeti(L, 1, l);
+ lua_rawgeti(L, 1, u);
+ if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
+ set2(L, l, u); /* swap a[l] - a[u] */
+ else
+ lua_pop(L, 2);
+ if (u-l == 1) break; /* only 2 elements */
+ i = (l+u)/2;
+ lua_rawgeti(L, 1, i);
+ lua_rawgeti(L, 1, l);
+ if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
+ set2(L, i, l);
+ else {
+ lua_pop(L, 1); /* remove a[l] */
+ lua_rawgeti(L, 1, u);
+ if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
+ set2(L, i, u);
+ else
+ lua_pop(L, 2);
+ }
+ if (u-l == 2) break; /* only 3 elements */
+ lua_rawgeti(L, 1, i); /* Pivot */
+ lua_pushvalue(L, -1);
+ lua_rawgeti(L, 1, u-1);
+ set2(L, i, u-1);
+ /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
+ i = l; j = u-1;
+ for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
+ /* repeat ++i until a[i] >= P */
+ while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
+ if (i>u) luaL_error(L, "invalid order function for sorting");
+ lua_pop(L, 1); /* remove a[i] */
+ }
+ /* repeat --j until a[j] <= P */
+ while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
+ if (j<l) luaL_error(L, "invalid order function for sorting");
+ lua_pop(L, 1); /* remove a[j] */
+ }
+ if (j<i) {
+ lua_pop(L, 3); /* pop pivot, a[i], a[j] */
+ break;
+ }
+ set2(L, i, j);
+ }
+ lua_rawgeti(L, 1, u-1);
+ lua_rawgeti(L, 1, i);
+ set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
+ /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
+ /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
+ if (i-l < u-i) {
+ j=l; i=i-1; l=i+2;
+ }
+ else {
+ j=i+1; i=u; u=j-2;
+ }
+ auxsort(L, j, i); /* call recursively the smaller one */
+ } /* repeat the routine for the larger one */
+}
+
+static int luaB_sort (lua_State *L) {
+ int n = aux_getn(L, 1);
+ luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
+ if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ lua_settop(L, 2); /* make sure there is two arguments */
+ auxsort(L, 1, n);
+ return 0;
+}
+
+/* }====================================================== */
+
+
+static const luaL_reg tab_funcs[] = {
+ {"concat", str_concat},
+ {"foreach", luaB_foreach},
+ {"foreachi", luaB_foreachi},
+ {"getn", luaB_getn},
+ {"setn", luaB_setn},
+ {"sort", luaB_sort},
+ {"insert", luaB_tinsert},
+ {"remove", luaB_tremove},
+ {NULL, NULL}
+};
+
+
+LUALIB_API int luaopen_table (lua_State *L) {
+ luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 0);
+ return 1;
+}
+
diff --git a/lib/lua/src/lapi.c b/lib/lua/src/lapi.c
index 48646b9..038d5bf 100644
--- a/lib/lua/src/lapi.c
+++ b/lib/lua/src/lapi.c
@@ -1,922 +1,922 @@
-/*
-** $Id: lapi.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** Lua API
-** See Copyright Notice in lua.h
-*/
-
-
-#include <assert.h>
-#include <string.h>
-
-#define lapi_c
-
-#include "lua.h"
-
-#include "lapi.h"
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-#include "lundump.h"
-#include "lvm.h"
-
-
-const char lua_ident[] =
- "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
- "$Authors: " LUA_AUTHORS " $\n"
- "$URL: www.lua.org $\n";
-
-
-
-#ifndef api_check
-#define api_check(L, o) /*{ assert(o); }*/
-#endif
-
-#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
-
-#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
-
-
-
-
-static TObject *negindex (lua_State *L, int idx) {
- if (idx > LUA_REGISTRYINDEX) {
- api_check(L, idx != 0 && -idx <= L->top - L->base);
- return L->top+idx;
- }
- else switch (idx) { /* pseudo-indices */
- case LUA_REGISTRYINDEX: return registry(L);
- case LUA_GLOBALSINDEX: return gt(L);
- default: {
- TObject *func = (L->base - 1);
- idx = LUA_GLOBALSINDEX - idx;
- lua_assert(iscfunction(func));
- return (idx <= clvalue(func)->c.nupvalues)
- ? &clvalue(func)->c.upvalue[idx-1]
- : NULL;
- }
- }
-}
-
-
-static TObject *luaA_index (lua_State *L, int idx) {
- if (idx > 0) {
- api_check(L, idx <= L->top - L->base);
- return L->base + idx - 1;
- }
- else {
- TObject *o = negindex(L, idx);
- api_check(L, o != NULL);
- return o;
- }
-}
-
-
-static TObject *luaA_indexAcceptable (lua_State *L, int idx) {
- if (idx > 0) {
- TObject *o = L->base+(idx-1);
- api_check(L, idx <= L->stack_last - L->base);
- if (o >= L->top) return NULL;
- else return o;
- }
- else
- return negindex(L, idx);
-}
-
-
-void luaA_pushobject (lua_State *L, const TObject *o) {
- setobj2s(L->top, o);
- incr_top(L);
-}
-
-
-LUA_API int lua_checkstack (lua_State *L, int size) {
- int res;
- lua_lock(L);
- if ((L->top - L->base + size) > LUA_MAXCSTACK)
- res = 0; /* stack overflow */
- else {
- luaD_checkstack(L, size);
- if (L->ci->top < L->top + size)
- L->ci->top = L->top + size;
- res = 1;
- }
- lua_unlock(L);
- return res;
-}
-
-
-LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
- int i;
- lua_lock(to);
- api_checknelems(from, n);
- from->top -= n;
- for (i = 0; i < n; i++) {
- setobj2s(to->top, from->top + i);
- api_incr_top(to);
- }
- lua_unlock(to);
-}
-
-
-LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
- lua_CFunction old;
- lua_lock(L);
- old = G(L)->panic;
- G(L)->panic = panicf;
- lua_unlock(L);
- return old;
-}
-
-
-LUA_API lua_State *lua_newthread (lua_State *L) {
- lua_State *L1;
- lua_lock(L);
- luaC_checkGC(L);
- L1 = luaE_newthread(L);
- setthvalue(L->top, L1);
- api_incr_top(L);
- lua_unlock(L);
- lua_userstateopen(L1);
- return L1;
-}
-
-
-
-/*
-** basic stack manipulation
-*/
-
-
-LUA_API int lua_gettop (lua_State *L) {
- return (L->top - L->base);
-}
-
-
-LUA_API void lua_settop (lua_State *L, int idx) {
- lua_lock(L);
- if (idx >= 0) {
- api_check(L, idx <= L->stack_last - L->base);
- while (L->top < L->base + idx)
- setnilvalue(L->top++);
- L->top = L->base + idx;
- }
- else {
- api_check(L, -(idx+1) <= (L->top - L->base));
- L->top += idx+1; /* `subtract' index (index is negative) */
- }
- lua_unlock(L);
-}
-
-
-LUA_API void lua_remove (lua_State *L, int idx) {
- StkId p;
- lua_lock(L);
- p = luaA_index(L, idx);
- while (++p < L->top) setobjs2s(p-1, p);
- L->top--;
- lua_unlock(L);
-}
-
-
-LUA_API void lua_insert (lua_State *L, int idx) {
- StkId p;
- StkId q;
- lua_lock(L);
- p = luaA_index(L, idx);
- for (q = L->top; q>p; q--) setobjs2s(q, q-1);
- setobjs2s(p, L->top);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_replace (lua_State *L, int idx) {
- lua_lock(L);
- api_checknelems(L, 1);
- setobj(luaA_index(L, idx), L->top - 1); /* write barrier */
- L->top--;
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushvalue (lua_State *L, int idx) {
- lua_lock(L);
- setobj2s(L->top, luaA_index(L, idx));
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-
-/*
-** access functions (stack -> C)
-*/
-
-
-LUA_API int lua_type (lua_State *L, int idx) {
- StkId o = luaA_indexAcceptable(L, idx);
- return (o == NULL) ? LUA_TNONE : ttype(o);
-}
-
-
-LUA_API const char *lua_typename (lua_State *L, int t) {
- UNUSED(L);
- return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
-}
-
-
-LUA_API int lua_iscfunction (lua_State *L, int idx) {
- StkId o = luaA_indexAcceptable(L, idx);
- return (o == NULL) ? 0 : iscfunction(o);
-}
-
-
-LUA_API int lua_isnumber (lua_State *L, int idx) {
- TObject n;
- const TObject *o = luaA_indexAcceptable(L, idx);
- return (o != NULL && tonumber(o, &n));
-}
-
-
-LUA_API int lua_isstring (lua_State *L, int idx) {
- int t = lua_type(L, idx);
- return (t == LUA_TSTRING || t == LUA_TNUMBER);
-}
-
-
-LUA_API int lua_isuserdata (lua_State *L, int idx) {
- const TObject *o = luaA_indexAcceptable(L, idx);
- return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o)));
-}
-
-
-LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
- StkId o1 = luaA_indexAcceptable(L, index1);
- StkId o2 = luaA_indexAcceptable(L, index2);
- return (o1 == NULL || o2 == NULL) ? 0 /* index out of range */
- : luaO_rawequalObj(o1, o2);
-}
-
-
-LUA_API int lua_equal (lua_State *L, int index1, int index2) {
- StkId o1, o2;
- int i;
- lua_lock(L); /* may call tag method */
- o1 = luaA_indexAcceptable(L, index1);
- o2 = luaA_indexAcceptable(L, index2);
- i = (o1 == NULL || o2 == NULL) ? 0 /* index out of range */
- : equalobj(L, o1, o2);
- lua_unlock(L);
- return i;
-}
-
-
-LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
- StkId o1, o2;
- int i;
- lua_lock(L); /* may call tag method */
- o1 = luaA_indexAcceptable(L, index1);
- o2 = luaA_indexAcceptable(L, index2);
- i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */
- : luaV_lessthan(L, o1, o2);
- lua_unlock(L);
- return i;
-}
-
-
-
-LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
- TObject n;
- const TObject *o = luaA_indexAcceptable(L, idx);
- if (o != NULL && tonumber(o, &n))
- return nvalue(o);
- else
- return 0;
-}
-
-
-LUA_API int lua_toboolean (lua_State *L, int idx) {
- const TObject *o = luaA_indexAcceptable(L, idx);
- return (o != NULL) && !l_isfalse(o);
-}
-
-
-LUA_API const char *lua_tostring (lua_State *L, int idx) {
- StkId o = luaA_indexAcceptable(L, idx);
- if (o == NULL)
- return NULL;
- else if (ttisstring(o))
- return svalue(o);
- else {
- const char *s;
- lua_lock(L); /* `luaV_tostring' may create a new string */
- s = (luaV_tostring(L, o) ? svalue(o) : NULL);
- luaC_checkGC(L);
- lua_unlock(L);
- return s;
- }
-}
-
-
-LUA_API size_t lua_strlen (lua_State *L, int idx) {
- StkId o = luaA_indexAcceptable(L, idx);
- if (o == NULL)
- return 0;
- else if (ttisstring(o))
- return tsvalue(o)->tsv.len;
- else {
- size_t l;
- lua_lock(L); /* `luaV_tostring' may create a new string */
- l = (luaV_tostring(L, o) ? tsvalue(o)->tsv.len : 0);
- lua_unlock(L);
- return l;
- }
-}
-
-
-LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
- StkId o = luaA_indexAcceptable(L, idx);
- return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f;
-}
-
-
-LUA_API void *lua_touserdata (lua_State *L, int idx) {
- StkId o = luaA_indexAcceptable(L, idx);
- if (o == NULL) return NULL;
- switch (ttype(o)) {
- case LUA_TUSERDATA: return (uvalue(o) + 1);
- case LUA_TLIGHTUSERDATA: return pvalue(o);
- default: return NULL;
- }
-}
-
-
-LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
- StkId o = luaA_indexAcceptable(L, idx);
- return (o == NULL || !ttisthread(o)) ? NULL : thvalue(o);
-}
-
-
-LUA_API const void *lua_topointer (lua_State *L, int idx) {
- StkId o = luaA_indexAcceptable(L, idx);
- if (o == NULL) return NULL;
- else {
- switch (ttype(o)) {
- case LUA_TTABLE: return hvalue(o);
- case LUA_TFUNCTION: return clvalue(o);
- case LUA_TTHREAD: return thvalue(o);
- case LUA_TUSERDATA:
- case LUA_TLIGHTUSERDATA:
- return lua_touserdata(L, idx);
- default: return NULL;
- }
- }
-}
-
-
-
-/*
-** push functions (C -> stack)
-*/
-
-
-LUA_API void lua_pushnil (lua_State *L) {
- lua_lock(L);
- setnilvalue(L->top);
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
- lua_lock(L);
- setnvalue(L->top, n);
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
- lua_lock(L);
- luaC_checkGC(L);
- setsvalue2s(L->top, luaS_newlstr(L, s, len));
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushstring (lua_State *L, const char *s) {
- if (s == NULL)
- lua_pushnil(L);
- else
- lua_pushlstring(L, s, strlen(s));
-}
-
-
-LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
- va_list argp) {
- const char *ret;
- lua_lock(L);
- luaC_checkGC(L);
- ret = luaO_pushvfstring(L, fmt, argp);
- lua_unlock(L);
- return ret;
-}
-
-
-LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
- const char *ret;
- va_list argp;
- lua_lock(L);
- luaC_checkGC(L);
- va_start(argp, fmt);
- ret = luaO_pushvfstring(L, fmt, argp);
- va_end(argp);
- lua_unlock(L);
- return ret;
-}
-
-
-LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
- Closure *cl;
- lua_lock(L);
- luaC_checkGC(L);
- api_checknelems(L, n);
- cl = luaF_newCclosure(L, n);
- cl->c.f = fn;
- L->top -= n;
- while (n--)
- setobj2n(&cl->c.upvalue[n], L->top+n);
- setclvalue(L->top, cl);
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushboolean (lua_State *L, int b) {
- lua_lock(L);
- setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
- lua_lock(L);
- setpvalue(L->top, p);
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-
-/*
-** get functions (Lua -> stack)
-*/
-
-
-LUA_API void lua_gettable (lua_State *L, int idx) {
- StkId t;
- lua_lock(L);
- t = luaA_index(L, idx);
- setobj2s(L->top - 1, luaV_gettable(L, t, L->top - 1, 0));
- lua_unlock(L);
-}
-
-
-LUA_API void lua_rawget (lua_State *L, int idx) {
- StkId t;
- lua_lock(L);
- t = luaA_index(L, idx);
- api_check(L, ttistable(t));
- setobj2s(L->top - 1, luaH_get(hvalue(t), L->top - 1));
- lua_unlock(L);
-}
-
-
-LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
- StkId o;
- lua_lock(L);
- o = luaA_index(L, idx);
- api_check(L, ttistable(o));
- setobj2s(L->top, luaH_getnum(hvalue(o), n));
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_newtable (lua_State *L) {
- lua_lock(L);
- luaC_checkGC(L);
- sethvalue(L->top, luaH_new(L, 0, 0));
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API int lua_getmetatable (lua_State *L, int objindex) {
- const TObject *obj;
- Table *mt = NULL;
- int res;
- lua_lock(L);
- obj = luaA_indexAcceptable(L, objindex);
- if (obj != NULL) {
- switch (ttype(obj)) {
- case LUA_TTABLE:
- mt = hvalue(obj)->metatable;
- break;
- case LUA_TUSERDATA:
- mt = uvalue(obj)->uv.metatable;
- break;
- }
- }
- if (mt == NULL || mt == hvalue(defaultmeta(L)))
- res = 0;
- else {
- sethvalue(L->top, mt);
- api_incr_top(L);
- res = 1;
- }
- lua_unlock(L);
- return res;
-}
-
-
-LUA_API void lua_getfenv (lua_State *L, int idx) {
- StkId o;
- lua_lock(L);
- o = luaA_index(L, idx);
- setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L));
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-/*
-** set functions (stack -> Lua)
-*/
-
-
-LUA_API void lua_settable (lua_State *L, int idx) {
- StkId t;
- lua_lock(L);
- api_checknelems(L, 2);
- t = luaA_index(L, idx);
- luaV_settable(L, t, L->top - 2, L->top - 1);
- L->top -= 2; /* pop index and value */
- lua_unlock(L);
-}
-
-
-LUA_API void lua_rawset (lua_State *L, int idx) {
- StkId t;
- lua_lock(L);
- api_checknelems(L, 2);
- t = luaA_index(L, idx);
- api_check(L, ttistable(t));
- setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */
- L->top -= 2;
- lua_unlock(L);
-}
-
-
-LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
- StkId o;
- lua_lock(L);
- api_checknelems(L, 1);
- o = luaA_index(L, idx);
- api_check(L, ttistable(o));
- setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */
- L->top--;
- lua_unlock(L);
-}
-
-
-LUA_API int lua_setmetatable (lua_State *L, int objindex) {
- TObject *obj, *mt;
- int res = 1;
- lua_lock(L);
- api_checknelems(L, 1);
- obj = luaA_index(L, objindex);
- mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L);
- api_check(L, ttistable(mt));
- switch (ttype(obj)) {
- case LUA_TTABLE: {
- hvalue(obj)->metatable = hvalue(mt); /* write barrier */
- break;
- }
- case LUA_TUSERDATA: {
- uvalue(obj)->uv.metatable = hvalue(mt); /* write barrier */
- break;
- }
- default: {
- res = 0; /* cannot set */
- break;
- }
- }
- L->top--;
- lua_unlock(L);
- return res;
-}
-
-
-LUA_API int lua_setfenv (lua_State *L, int idx) {
- StkId o;
- int res = 0;
- lua_lock(L);
- api_checknelems(L, 1);
- o = luaA_index(L, idx);
- L->top--;
- api_check(L, ttistable(L->top));
- if (isLfunction(o)) {
- res = 1;
- clvalue(o)->l.g = *(L->top);
- }
- lua_unlock(L);
- return res;
-}
-
-
-/*
-** `load' and `call' functions (run Lua code)
-*/
-
-LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
- StkId func;
- lua_lock(L);
- api_checknelems(L, nargs+1);
- func = L->top - (nargs+1);
- luaD_call(L, func, nresults);
- lua_unlock(L);
-}
-
-
-
-/*
-** Execute a protected call.
-*/
-struct CallS { /* data to `f_call' */
- StkId func;
- int nresults;
-};
-
-
-static void f_call (lua_State *L, void *ud) {
- struct CallS *c = cast(struct CallS *, ud);
- luaD_call(L, c->func, c->nresults);
-}
-
-
-
-LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
- struct CallS c;
- int status;
- ptrdiff_t func;
- lua_lock(L);
- func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc));
- c.func = L->top - (nargs+1); /* function to be called */
- c.nresults = nresults;
- status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
- lua_unlock(L);
- return status;
-}
-
-
-/*
-** Execute a protected C call.
-*/
-struct CCallS { /* data to `f_Ccall' */
- lua_CFunction func;
- void *ud;
-};
-
-
-static void f_Ccall (lua_State *L, void *ud) {
- struct CCallS *c = cast(struct CCallS *, ud);
- Closure *cl;
- cl = luaF_newCclosure(L, 0);
- cl->c.f = c->func;
- setclvalue(L->top, cl); /* push function */
- incr_top(L);
- setpvalue(L->top, c->ud); /* push only argument */
- incr_top(L);
- luaD_call(L, L->top - 2, 0);
-}
-
-
-LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
- struct CCallS c;
- int status;
- lua_lock(L);
- c.func = func;
- c.ud = ud;
- status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
- lua_unlock(L);
- return status;
-}
-
-
-LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data,
- const char *chunkname) {
- ZIO z;
- int status;
- int c;
- lua_lock(L);
- if (!chunkname) chunkname = "?";
- luaZ_init(&z, reader, data, chunkname);
- c = luaZ_lookahead(&z);
- status = luaD_protectedparser(L, &z, (c == LUA_SIGNATURE[0]));
- lua_unlock(L);
- return status;
-}
-
-
-LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) {
- int status;
- TObject *o;
- lua_lock(L);
- api_checknelems(L, 1);
- o = L->top - 1;
- if (isLfunction(o) && clvalue(o)->l.nupvalues == 0) {
- luaU_dump(L, clvalue(o)->l.p, writer, data);
- status = 1;
- }
- else
- status = 0;
- lua_unlock(L);
- return status;
-}
-
-
-/*
-** Garbage-collection functions
-*/
-
-/* GC values are expressed in Kbytes: #bytes/2^10 */
-#define GCscalel(x) ((x)>>10)
-#define GCscale(x) (cast(int, GCscalel(x)))
-#define GCunscale(x) (cast(lu_mem, x)<<10)
-
-LUA_API int lua_getgcthreshold (lua_State *L) {
- int threshold;
- lua_lock(L);
- threshold = GCscale(G(L)->GCthreshold);
- lua_unlock(L);
- return threshold;
-}
-
-LUA_API int lua_getgccount (lua_State *L) {
- int count;
- lua_lock(L);
- count = GCscale(G(L)->nblocks);
- lua_unlock(L);
- return count;
-}
-
-LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
- lua_lock(L);
- if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM))
- G(L)->GCthreshold = MAX_LUMEM;
- else
- G(L)->GCthreshold = GCunscale(newthreshold);
- luaC_checkGC(L);
- lua_unlock(L);
-}
-
-
-/*
-** miscellaneous functions
-*/
-
-
-LUA_API const char *lua_version (void) {
- return LUA_VERSION;
-}
-
-
-LUA_API int lua_error (lua_State *L) {
- lua_lock(L);
- api_checknelems(L, 1);
- luaG_errormsg(L);
- lua_unlock(L);
- return 0; /* to avoid warnings */
-}
-
-
-LUA_API int lua_next (lua_State *L, int idx) {
- StkId t;
- int more;
- lua_lock(L);
- t = luaA_index(L, idx);
- api_check(L, ttistable(t));
- more = luaH_next(L, hvalue(t), L->top - 1);
- if (more) {
- api_incr_top(L);
- }
- else /* no more elements */
- L->top -= 1; /* remove key */
- lua_unlock(L);
- return more;
-}
-
-
-LUA_API void lua_concat (lua_State *L, int n) {
- lua_lock(L);
- luaC_checkGC(L);
- api_checknelems(L, n);
- if (n >= 2) {
- luaV_concat(L, n, L->top - L->base - 1);
- L->top -= (n-1);
- }
- else if (n == 0) { /* push empty string */
- setsvalue2s(L->top, luaS_newlstr(L, NULL, 0));
- api_incr_top(L);
- }
- /* else n == 1; nothing to do */
- lua_unlock(L);
-}
-
-
-LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
- Udata *u;
- lua_lock(L);
- luaC_checkGC(L);
- u = luaS_newudata(L, size);
- setuvalue(L->top, u);
- api_incr_top(L);
- lua_unlock(L);
- return u + 1;
-}
-
-
-LUA_API int lua_pushupvalues (lua_State *L) {
- Closure *func;
- int n, i;
- lua_lock(L);
- api_check(L, iscfunction(L->base - 1));
- func = clvalue(L->base - 1);
- n = func->c.nupvalues;
- luaD_checkstack(L, n + LUA_MINSTACK);
- for (i=0; i<n; i++) {
- setobj2s(L->top, &func->c.upvalue[i]);
- L->top++;
- }
- lua_unlock(L);
- return n;
-}
-
-
-static const char *aux_upvalue (lua_State *L, int funcindex, int n,
- TObject **val) {
- Closure *f;
- StkId fi = luaA_index(L, funcindex);
- if (!ttisfunction(fi)) return NULL;
- f = clvalue(fi);
- if (f->c.isC) {
- if (n > f->c.nupvalues) return NULL;
- *val = &f->c.upvalue[n-1];
- return "";
- }
- else {
- Proto *p = f->l.p;
- if (n > p->sizeupvalues) return NULL;
- *val = f->l.upvals[n-1]->v;
- return getstr(p->upvalues[n-1]);
- }
-}
-
-
-LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
- const char *name;
- TObject *val;
- lua_lock(L);
- name = aux_upvalue(L, funcindex, n, &val);
- if (name) {
- setobj2s(L->top, val);
- api_incr_top(L);
- }
- lua_unlock(L);
- return name;
-}
-
-
-LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
- const char *name;
- TObject *val;
- lua_lock(L);
- api_checknelems(L, 1);
- name = aux_upvalue(L, funcindex, n, &val);
- if (name) {
- L->top--;
- setobj(val, L->top); /* write barrier */
- }
- lua_unlock(L);
- return name;
-}
-
+/*
+** $Id: lapi.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** Lua API
+** See Copyright Notice in lua.h
+*/
+
+
+#include <assert.h>
+#include <string.h>
+
+#define lapi_c
+
+#include "lua.h"
+
+#include "lapi.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+#include "lundump.h"
+#include "lvm.h"
+
+
+const char lua_ident[] =
+ "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
+ "$Authors: " LUA_AUTHORS " $\n"
+ "$URL: www.lua.org $\n";
+
+
+
+#ifndef api_check
+#define api_check(L, o) /*{ assert(o); }*/
+#endif
+
+#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
+
+#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
+
+
+
+
+static TObject *negindex (lua_State *L, int idx) {
+ if (idx > LUA_REGISTRYINDEX) {
+ api_check(L, idx != 0 && -idx <= L->top - L->base);
+ return L->top+idx;
+ }
+ else switch (idx) { /* pseudo-indices */
+ case LUA_REGISTRYINDEX: return registry(L);
+ case LUA_GLOBALSINDEX: return gt(L);
+ default: {
+ TObject *func = (L->base - 1);
+ idx = LUA_GLOBALSINDEX - idx;
+ lua_assert(iscfunction(func));
+ return (idx <= clvalue(func)->c.nupvalues)
+ ? &clvalue(func)->c.upvalue[idx-1]
+ : NULL;
+ }
+ }
+}
+
+
+static TObject *luaA_index (lua_State *L, int idx) {
+ if (idx > 0) {
+ api_check(L, idx <= L->top - L->base);
+ return L->base + idx - 1;
+ }
+ else {
+ TObject *o = negindex(L, idx);
+ api_check(L, o != NULL);
+ return o;
+ }
+}
+
+
+static TObject *luaA_indexAcceptable (lua_State *L, int idx) {
+ if (idx > 0) {
+ TObject *o = L->base+(idx-1);
+ api_check(L, idx <= L->stack_last - L->base);
+ if (o >= L->top) return NULL;
+ else return o;
+ }
+ else
+ return negindex(L, idx);
+}
+
+
+void luaA_pushobject (lua_State *L, const TObject *o) {
+ setobj2s(L->top, o);
+ incr_top(L);
+}
+
+
+LUA_API int lua_checkstack (lua_State *L, int size) {
+ int res;
+ lua_lock(L);
+ if ((L->top - L->base + size) > LUA_MAXCSTACK)
+ res = 0; /* stack overflow */
+ else {
+ luaD_checkstack(L, size);
+ if (L->ci->top < L->top + size)
+ L->ci->top = L->top + size;
+ res = 1;
+ }
+ lua_unlock(L);
+ return res;
+}
+
+
+LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
+ int i;
+ lua_lock(to);
+ api_checknelems(from, n);
+ from->top -= n;
+ for (i = 0; i < n; i++) {
+ setobj2s(to->top, from->top + i);
+ api_incr_top(to);
+ }
+ lua_unlock(to);
+}
+
+
+LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
+ lua_CFunction old;
+ lua_lock(L);
+ old = G(L)->panic;
+ G(L)->panic = panicf;
+ lua_unlock(L);
+ return old;
+}
+
+
+LUA_API lua_State *lua_newthread (lua_State *L) {
+ lua_State *L1;
+ lua_lock(L);
+ luaC_checkGC(L);
+ L1 = luaE_newthread(L);
+ setthvalue(L->top, L1);
+ api_incr_top(L);
+ lua_unlock(L);
+ lua_userstateopen(L1);
+ return L1;
+}
+
+
+
+/*
+** basic stack manipulation
+*/
+
+
+LUA_API int lua_gettop (lua_State *L) {
+ return (L->top - L->base);
+}
+
+
+LUA_API void lua_settop (lua_State *L, int idx) {
+ lua_lock(L);
+ if (idx >= 0) {
+ api_check(L, idx <= L->stack_last - L->base);
+ while (L->top < L->base + idx)
+ setnilvalue(L->top++);
+ L->top = L->base + idx;
+ }
+ else {
+ api_check(L, -(idx+1) <= (L->top - L->base));
+ L->top += idx+1; /* `subtract' index (index is negative) */
+ }
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_remove (lua_State *L, int idx) {
+ StkId p;
+ lua_lock(L);
+ p = luaA_index(L, idx);
+ while (++p < L->top) setobjs2s(p-1, p);
+ L->top--;
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_insert (lua_State *L, int idx) {
+ StkId p;
+ StkId q;
+ lua_lock(L);
+ p = luaA_index(L, idx);
+ for (q = L->top; q>p; q--) setobjs2s(q, q-1);
+ setobjs2s(p, L->top);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_replace (lua_State *L, int idx) {
+ lua_lock(L);
+ api_checknelems(L, 1);
+ setobj(luaA_index(L, idx), L->top - 1); /* write barrier */
+ L->top--;
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_pushvalue (lua_State *L, int idx) {
+ lua_lock(L);
+ setobj2s(L->top, luaA_index(L, idx));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+
+/*
+** access functions (stack -> C)
+*/
+
+
+LUA_API int lua_type (lua_State *L, int idx) {
+ StkId o = luaA_indexAcceptable(L, idx);
+ return (o == NULL) ? LUA_TNONE : ttype(o);
+}
+
+
+LUA_API const char *lua_typename (lua_State *L, int t) {
+ UNUSED(L);
+ return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
+}
+
+
+LUA_API int lua_iscfunction (lua_State *L, int idx) {
+ StkId o = luaA_indexAcceptable(L, idx);
+ return (o == NULL) ? 0 : iscfunction(o);
+}
+
+
+LUA_API int lua_isnumber (lua_State *L, int idx) {
+ TObject n;
+ const TObject *o = luaA_indexAcceptable(L, idx);
+ return (o != NULL && tonumber(o, &n));
+}
+
+
+LUA_API int lua_isstring (lua_State *L, int idx) {
+ int t = lua_type(L, idx);
+ return (t == LUA_TSTRING || t == LUA_TNUMBER);
+}
+
+
+LUA_API int lua_isuserdata (lua_State *L, int idx) {
+ const TObject *o = luaA_indexAcceptable(L, idx);
+ return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o)));
+}
+
+
+LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
+ StkId o1 = luaA_indexAcceptable(L, index1);
+ StkId o2 = luaA_indexAcceptable(L, index2);
+ return (o1 == NULL || o2 == NULL) ? 0 /* index out of range */
+ : luaO_rawequalObj(o1, o2);
+}
+
+
+LUA_API int lua_equal (lua_State *L, int index1, int index2) {
+ StkId o1, o2;
+ int i;
+ lua_lock(L); /* may call tag method */
+ o1 = luaA_indexAcceptable(L, index1);
+ o2 = luaA_indexAcceptable(L, index2);
+ i = (o1 == NULL || o2 == NULL) ? 0 /* index out of range */
+ : equalobj(L, o1, o2);
+ lua_unlock(L);
+ return i;
+}
+
+
+LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
+ StkId o1, o2;
+ int i;
+ lua_lock(L); /* may call tag method */
+ o1 = luaA_indexAcceptable(L, index1);
+ o2 = luaA_indexAcceptable(L, index2);
+ i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */
+ : luaV_lessthan(L, o1, o2);
+ lua_unlock(L);
+ return i;
+}
+
+
+
+LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
+ TObject n;
+ const TObject *o = luaA_indexAcceptable(L, idx);
+ if (o != NULL && tonumber(o, &n))
+ return nvalue(o);
+ else
+ return 0;
+}
+
+
+LUA_API int lua_toboolean (lua_State *L, int idx) {
+ const TObject *o = luaA_indexAcceptable(L, idx);
+ return (o != NULL) && !l_isfalse(o);
+}
+
+
+LUA_API const char *lua_tostring (lua_State *L, int idx) {
+ StkId o = luaA_indexAcceptable(L, idx);
+ if (o == NULL)
+ return NULL;
+ else if (ttisstring(o))
+ return svalue(o);
+ else {
+ const char *s;
+ lua_lock(L); /* `luaV_tostring' may create a new string */
+ s = (luaV_tostring(L, o) ? svalue(o) : NULL);
+ luaC_checkGC(L);
+ lua_unlock(L);
+ return s;
+ }
+}
+
+
+LUA_API size_t lua_strlen (lua_State *L, int idx) {
+ StkId o = luaA_indexAcceptable(L, idx);
+ if (o == NULL)
+ return 0;
+ else if (ttisstring(o))
+ return tsvalue(o)->tsv.len;
+ else {
+ size_t l;
+ lua_lock(L); /* `luaV_tostring' may create a new string */
+ l = (luaV_tostring(L, o) ? tsvalue(o)->tsv.len : 0);
+ lua_unlock(L);
+ return l;
+ }
+}
+
+
+LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
+ StkId o = luaA_indexAcceptable(L, idx);
+ return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f;
+}
+
+
+LUA_API void *lua_touserdata (lua_State *L, int idx) {
+ StkId o = luaA_indexAcceptable(L, idx);
+ if (o == NULL) return NULL;
+ switch (ttype(o)) {
+ case LUA_TUSERDATA: return (uvalue(o) + 1);
+ case LUA_TLIGHTUSERDATA: return pvalue(o);
+ default: return NULL;
+ }
+}
+
+
+LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
+ StkId o = luaA_indexAcceptable(L, idx);
+ return (o == NULL || !ttisthread(o)) ? NULL : thvalue(o);
+}
+
+
+LUA_API const void *lua_topointer (lua_State *L, int idx) {
+ StkId o = luaA_indexAcceptable(L, idx);
+ if (o == NULL) return NULL;
+ else {
+ switch (ttype(o)) {
+ case LUA_TTABLE: return hvalue(o);
+ case LUA_TFUNCTION: return clvalue(o);
+ case LUA_TTHREAD: return thvalue(o);
+ case LUA_TUSERDATA:
+ case LUA_TLIGHTUSERDATA:
+ return lua_touserdata(L, idx);
+ default: return NULL;
+ }
+ }
+}
+
+
+
+/*
+** push functions (C -> stack)
+*/
+
+
+LUA_API void lua_pushnil (lua_State *L) {
+ lua_lock(L);
+ setnilvalue(L->top);
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
+ lua_lock(L);
+ setnvalue(L->top, n);
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
+ lua_lock(L);
+ luaC_checkGC(L);
+ setsvalue2s(L->top, luaS_newlstr(L, s, len));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_pushstring (lua_State *L, const char *s) {
+ if (s == NULL)
+ lua_pushnil(L);
+ else
+ lua_pushlstring(L, s, strlen(s));
+}
+
+
+LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
+ va_list argp) {
+ const char *ret;
+ lua_lock(L);
+ luaC_checkGC(L);
+ ret = luaO_pushvfstring(L, fmt, argp);
+ lua_unlock(L);
+ return ret;
+}
+
+
+LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
+ const char *ret;
+ va_list argp;
+ lua_lock(L);
+ luaC_checkGC(L);
+ va_start(argp, fmt);
+ ret = luaO_pushvfstring(L, fmt, argp);
+ va_end(argp);
+ lua_unlock(L);
+ return ret;
+}
+
+
+LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
+ Closure *cl;
+ lua_lock(L);
+ luaC_checkGC(L);
+ api_checknelems(L, n);
+ cl = luaF_newCclosure(L, n);
+ cl->c.f = fn;
+ L->top -= n;
+ while (n--)
+ setobj2n(&cl->c.upvalue[n], L->top+n);
+ setclvalue(L->top, cl);
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_pushboolean (lua_State *L, int b) {
+ lua_lock(L);
+ setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
+ lua_lock(L);
+ setpvalue(L->top, p);
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+
+/*
+** get functions (Lua -> stack)
+*/
+
+
+LUA_API void lua_gettable (lua_State *L, int idx) {
+ StkId t;
+ lua_lock(L);
+ t = luaA_index(L, idx);
+ setobj2s(L->top - 1, luaV_gettable(L, t, L->top - 1, 0));
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_rawget (lua_State *L, int idx) {
+ StkId t;
+ lua_lock(L);
+ t = luaA_index(L, idx);
+ api_check(L, ttistable(t));
+ setobj2s(L->top - 1, luaH_get(hvalue(t), L->top - 1));
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
+ StkId o;
+ lua_lock(L);
+ o = luaA_index(L, idx);
+ api_check(L, ttistable(o));
+ setobj2s(L->top, luaH_getnum(hvalue(o), n));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_newtable (lua_State *L) {
+ lua_lock(L);
+ luaC_checkGC(L);
+ sethvalue(L->top, luaH_new(L, 0, 0));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API int lua_getmetatable (lua_State *L, int objindex) {
+ const TObject *obj;
+ Table *mt = NULL;
+ int res;
+ lua_lock(L);
+ obj = luaA_indexAcceptable(L, objindex);
+ if (obj != NULL) {
+ switch (ttype(obj)) {
+ case LUA_TTABLE:
+ mt = hvalue(obj)->metatable;
+ break;
+ case LUA_TUSERDATA:
+ mt = uvalue(obj)->uv.metatable;
+ break;
+ }
+ }
+ if (mt == NULL || mt == hvalue(defaultmeta(L)))
+ res = 0;
+ else {
+ sethvalue(L->top, mt);
+ api_incr_top(L);
+ res = 1;
+ }
+ lua_unlock(L);
+ return res;
+}
+
+
+LUA_API void lua_getfenv (lua_State *L, int idx) {
+ StkId o;
+ lua_lock(L);
+ o = luaA_index(L, idx);
+ setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+/*
+** set functions (stack -> Lua)
+*/
+
+
+LUA_API void lua_settable (lua_State *L, int idx) {
+ StkId t;
+ lua_lock(L);
+ api_checknelems(L, 2);
+ t = luaA_index(L, idx);
+ luaV_settable(L, t, L->top - 2, L->top - 1);
+ L->top -= 2; /* pop index and value */
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_rawset (lua_State *L, int idx) {
+ StkId t;
+ lua_lock(L);
+ api_checknelems(L, 2);
+ t = luaA_index(L, idx);
+ api_check(L, ttistable(t));
+ setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */
+ L->top -= 2;
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
+ StkId o;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ o = luaA_index(L, idx);
+ api_check(L, ttistable(o));
+ setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */
+ L->top--;
+ lua_unlock(L);
+}
+
+
+LUA_API int lua_setmetatable (lua_State *L, int objindex) {
+ TObject *obj, *mt;
+ int res = 1;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ obj = luaA_index(L, objindex);
+ mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L);
+ api_check(L, ttistable(mt));
+ switch (ttype(obj)) {
+ case LUA_TTABLE: {
+ hvalue(obj)->metatable = hvalue(mt); /* write barrier */
+ break;
+ }
+ case LUA_TUSERDATA: {
+ uvalue(obj)->uv.metatable = hvalue(mt); /* write barrier */
+ break;
+ }
+ default: {
+ res = 0; /* cannot set */
+ break;
+ }
+ }
+ L->top--;
+ lua_unlock(L);
+ return res;
+}
+
+
+LUA_API int lua_setfenv (lua_State *L, int idx) {
+ StkId o;
+ int res = 0;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ o = luaA_index(L, idx);
+ L->top--;
+ api_check(L, ttistable(L->top));
+ if (isLfunction(o)) {
+ res = 1;
+ clvalue(o)->l.g = *(L->top);
+ }
+ lua_unlock(L);
+ return res;
+}
+
+
+/*
+** `load' and `call' functions (run Lua code)
+*/
+
+LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
+ StkId func;
+ lua_lock(L);
+ api_checknelems(L, nargs+1);
+ func = L->top - (nargs+1);
+ luaD_call(L, func, nresults);
+ lua_unlock(L);
+}
+
+
+
+/*
+** Execute a protected call.
+*/
+struct CallS { /* data to `f_call' */
+ StkId func;
+ int nresults;
+};
+
+
+static void f_call (lua_State *L, void *ud) {
+ struct CallS *c = cast(struct CallS *, ud);
+ luaD_call(L, c->func, c->nresults);
+}
+
+
+
+LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
+ struct CallS c;
+ int status;
+ ptrdiff_t func;
+ lua_lock(L);
+ func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc));
+ c.func = L->top - (nargs+1); /* function to be called */
+ c.nresults = nresults;
+ status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
+ lua_unlock(L);
+ return status;
+}
+
+
+/*
+** Execute a protected C call.
+*/
+struct CCallS { /* data to `f_Ccall' */
+ lua_CFunction func;
+ void *ud;
+};
+
+
+static void f_Ccall (lua_State *L, void *ud) {
+ struct CCallS *c = cast(struct CCallS *, ud);
+ Closure *cl;
+ cl = luaF_newCclosure(L, 0);
+ cl->c.f = c->func;
+ setclvalue(L->top, cl); /* push function */
+ incr_top(L);
+ setpvalue(L->top, c->ud); /* push only argument */
+ incr_top(L);
+ luaD_call(L, L->top - 2, 0);
+}
+
+
+LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
+ struct CCallS c;
+ int status;
+ lua_lock(L);
+ c.func = func;
+ c.ud = ud;
+ status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
+ lua_unlock(L);
+ return status;
+}
+
+
+LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data,
+ const char *chunkname) {
+ ZIO z;
+ int status;
+ int c;
+ lua_lock(L);
+ if (!chunkname) chunkname = "?";
+ luaZ_init(&z, reader, data, chunkname);
+ c = luaZ_lookahead(&z);
+ status = luaD_protectedparser(L, &z, (c == LUA_SIGNATURE[0]));
+ lua_unlock(L);
+ return status;
+}
+
+
+LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) {
+ int status;
+ TObject *o;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ o = L->top - 1;
+ if (isLfunction(o) && clvalue(o)->l.nupvalues == 0) {
+ luaU_dump(L, clvalue(o)->l.p, writer, data);
+ status = 1;
+ }
+ else
+ status = 0;
+ lua_unlock(L);
+ return status;
+}
+
+
+/*
+** Garbage-collection functions
+*/
+
+/* GC values are expressed in Kbytes: #bytes/2^10 */
+#define GCscalel(x) ((x)>>10)
+#define GCscale(x) (cast(int, GCscalel(x)))
+#define GCunscale(x) (cast(lu_mem, x)<<10)
+
+LUA_API int lua_getgcthreshold (lua_State *L) {
+ int threshold;
+ lua_lock(L);
+ threshold = GCscale(G(L)->GCthreshold);
+ lua_unlock(L);
+ return threshold;
+}
+
+LUA_API int lua_getgccount (lua_State *L) {
+ int count;
+ lua_lock(L);
+ count = GCscale(G(L)->nblocks);
+ lua_unlock(L);
+ return count;
+}
+
+LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
+ lua_lock(L);
+ if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM))
+ G(L)->GCthreshold = MAX_LUMEM;
+ else
+ G(L)->GCthreshold = GCunscale(newthreshold);
+ luaC_checkGC(L);
+ lua_unlock(L);
+}
+
+
+/*
+** miscellaneous functions
+*/
+
+
+LUA_API const char *lua_version (void) {
+ return LUA_VERSION;
+}
+
+
+LUA_API int lua_error (lua_State *L) {
+ lua_lock(L);
+ api_checknelems(L, 1);
+ luaG_errormsg(L);
+ lua_unlock(L);
+ return 0; /* to avoid warnings */
+}
+
+
+LUA_API int lua_next (lua_State *L, int idx) {
+ StkId t;
+ int more;
+ lua_lock(L);
+ t = luaA_index(L, idx);
+ api_check(L, ttistable(t));
+ more = luaH_next(L, hvalue(t), L->top - 1);
+ if (more) {
+ api_incr_top(L);
+ }
+ else /* no more elements */
+ L->top -= 1; /* remove key */
+ lua_unlock(L);
+ return more;
+}
+
+
+LUA_API void lua_concat (lua_State *L, int n) {
+ lua_lock(L);
+ luaC_checkGC(L);
+ api_checknelems(L, n);
+ if (n >= 2) {
+ luaV_concat(L, n, L->top - L->base - 1);
+ L->top -= (n-1);
+ }
+ else if (n == 0) { /* push empty string */
+ setsvalue2s(L->top, luaS_newlstr(L, NULL, 0));
+ api_incr_top(L);
+ }
+ /* else n == 1; nothing to do */
+ lua_unlock(L);
+}
+
+
+LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
+ Udata *u;
+ lua_lock(L);
+ luaC_checkGC(L);
+ u = luaS_newudata(L, size);
+ setuvalue(L->top, u);
+ api_incr_top(L);
+ lua_unlock(L);
+ return u + 1;
+}
+
+
+LUA_API int lua_pushupvalues (lua_State *L) {
+ Closure *func;
+ int n, i;
+ lua_lock(L);
+ api_check(L, iscfunction(L->base - 1));
+ func = clvalue(L->base - 1);
+ n = func->c.nupvalues;
+ luaD_checkstack(L, n + LUA_MINSTACK);
+ for (i=0; i<n; i++) {
+ setobj2s(L->top, &func->c.upvalue[i]);
+ L->top++;
+ }
+ lua_unlock(L);
+ return n;
+}
+
+
+static const char *aux_upvalue (lua_State *L, int funcindex, int n,
+ TObject **val) {
+ Closure *f;
+ StkId fi = luaA_index(L, funcindex);
+ if (!ttisfunction(fi)) return NULL;
+ f = clvalue(fi);
+ if (f->c.isC) {
+ if (n > f->c.nupvalues) return NULL;
+ *val = &f->c.upvalue[n-1];
+ return "";
+ }
+ else {
+ Proto *p = f->l.p;
+ if (n > p->sizeupvalues) return NULL;
+ *val = f->l.upvals[n-1]->v;
+ return getstr(p->upvalues[n-1]);
+ }
+}
+
+
+LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
+ const char *name;
+ TObject *val;
+ lua_lock(L);
+ name = aux_upvalue(L, funcindex, n, &val);
+ if (name) {
+ setobj2s(L->top, val);
+ api_incr_top(L);
+ }
+ lua_unlock(L);
+ return name;
+}
+
+
+LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
+ const char *name;
+ TObject *val;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ name = aux_upvalue(L, funcindex, n, &val);
+ if (name) {
+ L->top--;
+ setobj(val, L->top); /* write barrier */
+ }
+ lua_unlock(L);
+ return name;
+}
+
diff --git a/lib/lua/src/lcode.c b/lib/lua/src/lcode.c
index a873ed8..0b2f6b1 100644
--- a/lib/lua/src/lcode.c
+++ b/lib/lua/src/lcode.c
@@ -1,714 +1,714 @@
-/*
-** $Id: lcode.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** Code generator for Lua
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stdlib.h>
-
-#define lcode_c
-
-#include "lua.h"
-
-#include "lcode.h"
-#include "ldebug.h"
-#include "ldo.h"
-#include "llex.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lparser.h"
-#include "ltable.h"
-
-
-#define hasjumps(e) ((e)->t != (e)->f)
-
-
-void luaK_nil (FuncState *fs, int from, int n) {
- Instruction *previous;
- if (fs->pc > fs->lasttarget && /* no jumps to current position? */
- GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == OP_LOADNIL) {
- int pfrom = GETARG_A(*previous);
- int pto = GETARG_B(*previous);
- if (pfrom <= from && from <= pto+1) { /* can connect both? */
- if (from+n-1 > pto)
- SETARG_B(*previous, from+n-1);
- return;
- }
- }
- luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
-}
-
-
-int luaK_jump (FuncState *fs) {
- int jpc = fs->jpc; /* save list of jumps to here */
- int j;
- fs->jpc = NO_JUMP;
- j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
- luaK_concat(fs, &j, jpc); /* keep them on hold */
- return j;
-}
-
-
-static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) {
- luaK_codeABC(fs, op, A, B, C);
- return luaK_jump(fs);
-}
-
-
-static void luaK_fixjump (FuncState *fs, int pc, int dest) {
- Instruction *jmp = &fs->f->code[pc];
- int offset = dest-(pc+1);
- lua_assert(dest != NO_JUMP);
- if (abs(offset) > MAXARG_sBx)
- luaX_syntaxerror(fs->ls, "control structure too long");
- SETARG_sBx(*jmp, offset);
-}
-
-
-/*
-** returns current `pc' and marks it as a jump target (to avoid wrong
-** optimizations with consecutive instructions not in the same basic block).
-*/
-int luaK_getlabel (FuncState *fs) {
- fs->lasttarget = fs->pc;
- return fs->pc;
-}
-
-
-static int luaK_getjump (FuncState *fs, int pc) {
- int offset = GETARG_sBx(fs->f->code[pc]);
- if (offset == NO_JUMP) /* point to itself represents end of list */
- return NO_JUMP; /* end of list */
- else
- return (pc+1)+offset; /* turn offset into absolute position */
-}
-
-
-static Instruction *getjumpcontrol (FuncState *fs, int pc) {
- Instruction *pi = &fs->f->code[pc];
- if (pc >= 1 && testOpMode(GET_OPCODE(*(pi-1)), OpModeT))
- return pi-1;
- else
- return pi;
-}
-
-
-/*
-** check whether list has any jump that do not produce a value
-** (or produce an inverted value)
-*/
-static int need_value (FuncState *fs, int list, int cond) {
- for (; list != NO_JUMP; list = luaK_getjump(fs, list)) {
- Instruction i = *getjumpcontrol(fs, list);
- if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1;
- }
- return 0; /* not found */
-}
-
-
-static void patchtestreg (Instruction *i, int reg) {
- if (reg == NO_REG) reg = GETARG_B(*i);
- SETARG_A(*i, reg);
-}
-
-
-static void luaK_patchlistaux (FuncState *fs, int list,
- int ttarget, int treg, int ftarget, int freg, int dtarget) {
- while (list != NO_JUMP) {
- int next = luaK_getjump(fs, list);
- Instruction *i = getjumpcontrol(fs, list);
- if (GET_OPCODE(*i) != OP_TEST) {
- lua_assert(dtarget != NO_JUMP);
- luaK_fixjump(fs, list, dtarget); /* jump to default target */
- }
- else {
- if (GETARG_C(*i)) {
- lua_assert(ttarget != NO_JUMP);
- patchtestreg(i, treg);
- luaK_fixjump(fs, list, ttarget);
- }
- else {
- lua_assert(ftarget != NO_JUMP);
- patchtestreg(i, freg);
- luaK_fixjump(fs, list, ftarget);
- }
- }
- list = next;
- }
-}
-
-
-static void luaK_dischargejpc (FuncState *fs) {
- luaK_patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc);
- fs->jpc = NO_JUMP;
-}
-
-
-void luaK_patchlist (FuncState *fs, int list, int target) {
- if (target == fs->pc)
- luaK_patchtohere(fs, list);
- else {
- lua_assert(target < fs->pc);
- luaK_patchlistaux(fs, list, target, NO_REG, target, NO_REG, target);
- }
-}
-
-
-void luaK_patchtohere (FuncState *fs, int list) {
- luaK_getlabel(fs);
- luaK_concat(fs, &fs->jpc, list);
-}
-
-
-void luaK_concat (FuncState *fs, int *l1, int l2) {
- if (l2 == NO_JUMP) return;
- else if (*l1 == NO_JUMP)
- *l1 = l2;
- else {
- int list = *l1;
- int next;
- while ((next = luaK_getjump(fs, list)) != NO_JUMP) /* find last element */
- list = next;
- luaK_fixjump(fs, list, l2);
- }
-}
-
-
-void luaK_checkstack (FuncState *fs, int n) {
- int newstack = fs->freereg + n;
- if (newstack > fs->f->maxstacksize) {
- if (newstack >= MAXSTACK)
- luaX_syntaxerror(fs->ls, "function or expression too complex");
- fs->f->maxstacksize = cast(lu_byte, newstack);
- }
-}
-
-
-void luaK_reserveregs (FuncState *fs, int n) {
- luaK_checkstack(fs, n);
- fs->freereg += n;
-}
-
-
-static void freereg (FuncState *fs, int reg) {
- if (reg >= fs->nactvar && reg < MAXSTACK) {
- fs->freereg--;
- lua_assert(reg == fs->freereg);
- }
-}
-
-
-static void freeexp (FuncState *fs, expdesc *e) {
- if (e->k == VNONRELOC)
- freereg(fs, e->info);
-}
-
-
-static int addk (FuncState *fs, TObject *k, TObject *v) {
- const TObject *idx = luaH_get(fs->h, k);
- if (ttisnumber(idx)) {
- lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v));
- return cast(int, nvalue(idx));
- }
- else { /* constant not found; create a new entry */
- Proto *f = fs->f;
- luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject,
- MAXARG_Bx, "constant table overflow");
- setobj2n(&f->k[fs->nk], v);
- setnvalue(luaH_set(fs->L, fs->h, k), cast(lua_Number, fs->nk));
- return fs->nk++;
- }
-}
-
-
-int luaK_stringK (FuncState *fs, TString *s) {
- TObject o;
- setsvalue(&o, s);
- return addk(fs, &o, &o);
-}
-
-
-int luaK_numberK (FuncState *fs, lua_Number r) {
- TObject o;
- setnvalue(&o, r);
- return addk(fs, &o, &o);
-}
-
-
-static int nil_constant (FuncState *fs) {
- TObject k, v;
- setnilvalue(&v);
- sethvalue(&k, fs->h); /* cannot use nil as key; instead use table itself */
- return addk(fs, &k, &v);
-}
-
-
-void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) {
- if (e->k == VCALL) { /* expression is an open function call? */
- SETARG_C(getcode(fs, e), nresults+1);
- if (nresults == 1) { /* `regular' expression? */
- e->k = VNONRELOC;
- e->info = GETARG_A(getcode(fs, e));
- }
- }
-}
-
-
-void luaK_dischargevars (FuncState *fs, expdesc *e) {
- switch (e->k) {
- case VLOCAL: {
- e->k = VNONRELOC;
- break;
- }
- case VUPVAL: {
- e->info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->info, 0);
- e->k = VRELOCABLE;
- break;
- }
- case VGLOBAL: {
- e->info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->info);
- e->k = VRELOCABLE;
- break;
- }
- case VINDEXED: {
- freereg(fs, e->aux);
- freereg(fs, e->info);
- e->info = luaK_codeABC(fs, OP_GETTABLE, 0, e->info, e->aux);
- e->k = VRELOCABLE;
- break;
- }
- case VCALL: {
- luaK_setcallreturns(fs, e, 1);
- break;
- }
- default: break; /* there is one value available (somewhere) */
- }
-}
-
-
-static int code_label (FuncState *fs, int A, int b, int jump) {
- luaK_getlabel(fs); /* those instructions may be jump targets */
- return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
-}
-
-
-static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
- luaK_dischargevars(fs, e);
- switch (e->k) {
- case VNIL: {
- luaK_nil(fs, reg, 1);
- break;
- }
- case VFALSE: case VTRUE: {
- luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
- break;
- }
- case VK: {
- luaK_codeABx(fs, OP_LOADK, reg, e->info);
- break;
- }
- case VRELOCABLE: {
- Instruction *pc = &getcode(fs, e);
- SETARG_A(*pc, reg);
- break;
- }
- case VNONRELOC: {
- if (reg != e->info)
- luaK_codeABC(fs, OP_MOVE, reg, e->info, 0);
- break;
- }
- default: {
- lua_assert(e->k == VVOID || e->k == VJMP);
- return; /* nothing to do... */
- }
- }
- e->info = reg;
- e->k = VNONRELOC;
-}
-
-
-static void discharge2anyreg (FuncState *fs, expdesc *e) {
- if (e->k != VNONRELOC) {
- luaK_reserveregs(fs, 1);
- discharge2reg(fs, e, fs->freereg-1);
- }
-}
-
-
-static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) {
- discharge2reg(fs, e, reg);
- if (e->k == VJMP)
- luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */
- if (hasjumps(e)) {
- int final; /* position after whole expression */
- int p_f = NO_JUMP; /* position of an eventual LOAD false */
- int p_t = NO_JUMP; /* position of an eventual LOAD true */
- if (need_value(fs, e->t, 1) || need_value(fs, e->f, 0)) {
- int fj = NO_JUMP; /* first jump (over LOAD ops.) */
- if (e->k != VJMP)
- fj = luaK_jump(fs);
- p_f = code_label(fs, reg, 0, 1);
- p_t = code_label(fs, reg, 1, 0);
- luaK_patchtohere(fs, fj);
- }
- final = luaK_getlabel(fs);
- luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);
- luaK_patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t);
- }
- e->f = e->t = NO_JUMP;
- e->info = reg;
- e->k = VNONRELOC;
-}
-
-
-void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
- luaK_dischargevars(fs, e);
- freeexp(fs, e);
- luaK_reserveregs(fs, 1);
- luaK_exp2reg(fs, e, fs->freereg - 1);
-}
-
-
-int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
- luaK_dischargevars(fs, e);
- if (e->k == VNONRELOC) {
- if (!hasjumps(e)) return e->info; /* exp is already in a register */
- if (e->info >= fs->nactvar) { /* reg. is not a local? */
- luaK_exp2reg(fs, e, e->info); /* put value on it */
- return e->info;
- }
- }
- luaK_exp2nextreg(fs, e); /* default */
- return e->info;
-}
-
-
-void luaK_exp2val (FuncState *fs, expdesc *e) {
- if (hasjumps(e))
- luaK_exp2anyreg(fs, e);
- else
- luaK_dischargevars(fs, e);
-}
-
-
-int luaK_exp2RK (FuncState *fs, expdesc *e) {
- luaK_exp2val(fs, e);
- switch (e->k) {
- case VNIL: {
- if (fs->nk + MAXSTACK <= MAXARG_C) { /* constant fit in argC? */
- e->info = nil_constant(fs);
- e->k = VK;
- return e->info + MAXSTACK;
- }
- else break;
- }
- case VK: {
- if (e->info + MAXSTACK <= MAXARG_C) /* constant fit in argC? */
- return e->info + MAXSTACK;
- else break;
- }
- default: break;
- }
- /* not a constant in the right range: put it in a register */
- return luaK_exp2anyreg(fs, e);
-}
-
-
-void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) {
- switch (var->k) {
- case VLOCAL: {
- freeexp(fs, exp);
- luaK_exp2reg(fs, exp, var->info);
- return;
- }
- case VUPVAL: {
- int e = luaK_exp2anyreg(fs, exp);
- luaK_codeABC(fs, OP_SETUPVAL, e, var->info, 0);
- break;
- }
- case VGLOBAL: {
- int e = luaK_exp2anyreg(fs, exp);
- luaK_codeABx(fs, OP_SETGLOBAL, e, var->info);
- break;
- }
- case VINDEXED: {
- int e = luaK_exp2RK(fs, exp);
- luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e);
- break;
- }
- default: {
- lua_assert(0); /* invalid var kind to store */
- break;
- }
- }
- freeexp(fs, exp);
-}
-
-
-void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
- int func;
- luaK_exp2anyreg(fs, e);
- freeexp(fs, e);
- func = fs->freereg;
- luaK_reserveregs(fs, 2);
- luaK_codeABC(fs, OP_SELF, func, e->info, luaK_exp2RK(fs, key));
- freeexp(fs, key);
- e->info = func;
- e->k = VNONRELOC;
-}
-
-
-static void invertjump (FuncState *fs, expdesc *e) {
- Instruction *pc = getjumpcontrol(fs, e->info);
- lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) &&
- GET_OPCODE(*pc) != OP_TEST);
- SETARG_A(*pc, !(GETARG_A(*pc)));
-}
-
-
-static int jumponcond (FuncState *fs, expdesc *e, int cond) {
- if (e->k == VRELOCABLE) {
- Instruction ie = getcode(fs, e);
- if (GET_OPCODE(ie) == OP_NOT) {
- fs->pc--; /* remove previous OP_NOT */
- return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond);
- }
- /* else go through */
- }
- discharge2anyreg(fs, e);
- freeexp(fs, e);
- return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond);
-}
-
-
-void luaK_goiftrue (FuncState *fs, expdesc *e) {
- int pc; /* pc of last jump */
- luaK_dischargevars(fs, e);
- switch (e->k) {
- case VK: case VTRUE: {
- pc = NO_JUMP; /* always true; do nothing */
- break;
- }
- case VFALSE: {
- pc = luaK_jump(fs); /* always jump */
- break;
- }
- case VJMP: {
- invertjump(fs, e);
- pc = e->info;
- break;
- }
- default: {
- pc = jumponcond(fs, e, 0);
- break;
- }
- }
- luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
-}
-
-
-void luaK_goiffalse (FuncState *fs, expdesc *e) {
- int pc; /* pc of last jump */
- luaK_dischargevars(fs, e);
- switch (e->k) {
- case VNIL: case VFALSE: {
- pc = NO_JUMP; /* always false; do nothing */
- break;
- }
- case VTRUE: {
- pc = luaK_jump(fs); /* always jump */
- break;
- }
- case VJMP: {
- pc = e->info;
- break;
- }
- default: {
- pc = jumponcond(fs, e, 1);
- break;
- }
- }
- luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
-}
-
-
-static void codenot (FuncState *fs, expdesc *e) {
- luaK_dischargevars(fs, e);
- switch (e->k) {
- case VNIL: case VFALSE: {
- e->k = VTRUE;
- break;
- }
- case VK: case VTRUE: {
- e->k = VFALSE;
- break;
- }
- case VJMP: {
- invertjump(fs, e);
- break;
- }
- case VRELOCABLE:
- case VNONRELOC: {
- discharge2anyreg(fs, e);
- freeexp(fs, e);
- e->info = luaK_codeABC(fs, OP_NOT, 0, e->info, 0);
- e->k = VRELOCABLE;
- break;
- }
- default: {
- lua_assert(0); /* cannot happen */
- break;
- }
- }
- /* interchange true and false lists */
- { int temp = e->f; e->f = e->t; e->t = temp; }
-}
-
-
-void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
- t->aux = luaK_exp2RK(fs, k);
- t->k = VINDEXED;
-}
-
-
-void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
- if (op == OPR_MINUS) {
- luaK_exp2val(fs, e);
- if (e->k == VK && ttisnumber(&fs->f->k[e->info]))
- e->info = luaK_numberK(fs, -nvalue(&fs->f->k[e->info]));
- else {
- luaK_exp2anyreg(fs, e);
- freeexp(fs, e);
- e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0);
- e->k = VRELOCABLE;
- }
- }
- else /* op == NOT */
- codenot(fs, e);
-}
-
-
-void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
- switch (op) {
- case OPR_AND: {
- luaK_goiftrue(fs, v);
- luaK_patchtohere(fs, v->t);
- v->t = NO_JUMP;
- break;
- }
- case OPR_OR: {
- luaK_goiffalse(fs, v);
- luaK_patchtohere(fs, v->f);
- v->f = NO_JUMP;
- break;
- }
- case OPR_CONCAT: {
- luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
- break;
- }
- default: {
- luaK_exp2RK(fs, v);
- break;
- }
- }
-}
-
-
-static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
- int o1, int o2) {
- if (op <= OPR_POW) { /* arithmetic operator? */
- OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); /* ORDER OP */
- res->info = luaK_codeABC(fs, opc, 0, o1, o2);
- res->k = VRELOCABLE;
- }
- else { /* test operator */
- static const OpCode ops[] = {OP_EQ, OP_EQ, OP_LT, OP_LE, OP_LT, OP_LE};
- int cond = 1;
- if (op >= OPR_GT) { /* `>' or `>='? */
- int temp; /* exchange args and replace by `<' or `<=' */
- temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
- }
- else if (op == OPR_NE) cond = 0;
- res->info = luaK_condjump(fs, ops[op - OPR_NE], cond, o1, o2);
- res->k = VJMP;
- }
-}
-
-
-void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
- switch (op) {
- case OPR_AND: {
- lua_assert(e1->t == NO_JUMP); /* list must be closed */
- luaK_dischargevars(fs, e2);
- luaK_concat(fs, &e1->f, e2->f);
- e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->t = e2->t;
- break;
- }
- case OPR_OR: {
- lua_assert(e1->f == NO_JUMP); /* list must be closed */
- luaK_dischargevars(fs, e2);
- luaK_concat(fs, &e1->t, e2->t);
- e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->f = e2->f;
- break;
- }
- case OPR_CONCAT: {
- luaK_exp2val(fs, e2);
- if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
- lua_assert(e1->info == GETARG_B(getcode(fs, e2))-1);
- freeexp(fs, e1);
- SETARG_B(getcode(fs, e2), e1->info);
- e1->k = e2->k; e1->info = e2->info;
- }
- else {
- luaK_exp2nextreg(fs, e2);
- freeexp(fs, e2);
- freeexp(fs, e1);
- e1->info = luaK_codeABC(fs, OP_CONCAT, 0, e1->info, e2->info);
- e1->k = VRELOCABLE;
- }
- break;
- }
- default: {
- int o1 = luaK_exp2RK(fs, e1);
- int o2 = luaK_exp2RK(fs, e2);
- freeexp(fs, e2);
- freeexp(fs, e1);
- codebinop(fs, e1, op, o1, o2);
- }
- }
-}
-
-
-void luaK_fixline (FuncState *fs, int line) {
- fs->f->lineinfo[fs->pc - 1] = line;
-}
-
-
-int luaK_code (FuncState *fs, Instruction i, int line) {
- Proto *f = fs->f;
- luaK_dischargejpc(fs); /* `pc' will change */
- /* put new instruction in code array */
- luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
- MAX_INT, "code size overflow");
- f->code[fs->pc] = i;
- /* save corresponding line information */
- luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
- MAX_INT, "code size overflow");
- f->lineinfo[fs->pc] = line;
- return fs->pc++;
-}
-
-
-int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
- lua_assert(getOpMode(o) == iABC);
- return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
-}
-
-
-int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
- lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
- return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
-}
-
+/*
+** $Id: lcode.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** Code generator for Lua
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdlib.h>
+
+#define lcode_c
+
+#include "lua.h"
+
+#include "lcode.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "llex.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lparser.h"
+#include "ltable.h"
+
+
+#define hasjumps(e) ((e)->t != (e)->f)
+
+
+void luaK_nil (FuncState *fs, int from, int n) {
+ Instruction *previous;
+ if (fs->pc > fs->lasttarget && /* no jumps to current position? */
+ GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == OP_LOADNIL) {
+ int pfrom = GETARG_A(*previous);
+ int pto = GETARG_B(*previous);
+ if (pfrom <= from && from <= pto+1) { /* can connect both? */
+ if (from+n-1 > pto)
+ SETARG_B(*previous, from+n-1);
+ return;
+ }
+ }
+ luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
+}
+
+
+int luaK_jump (FuncState *fs) {
+ int jpc = fs->jpc; /* save list of jumps to here */
+ int j;
+ fs->jpc = NO_JUMP;
+ j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
+ luaK_concat(fs, &j, jpc); /* keep them on hold */
+ return j;
+}
+
+
+static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) {
+ luaK_codeABC(fs, op, A, B, C);
+ return luaK_jump(fs);
+}
+
+
+static void luaK_fixjump (FuncState *fs, int pc, int dest) {
+ Instruction *jmp = &fs->f->code[pc];
+ int offset = dest-(pc+1);
+ lua_assert(dest != NO_JUMP);
+ if (abs(offset) > MAXARG_sBx)
+ luaX_syntaxerror(fs->ls, "control structure too long");
+ SETARG_sBx(*jmp, offset);
+}
+
+
+/*
+** returns current `pc' and marks it as a jump target (to avoid wrong
+** optimizations with consecutive instructions not in the same basic block).
+*/
+int luaK_getlabel (FuncState *fs) {
+ fs->lasttarget = fs->pc;
+ return fs->pc;
+}
+
+
+static int luaK_getjump (FuncState *fs, int pc) {
+ int offset = GETARG_sBx(fs->f->code[pc]);
+ if (offset == NO_JUMP) /* point to itself represents end of list */
+ return NO_JUMP; /* end of list */
+ else
+ return (pc+1)+offset; /* turn offset into absolute position */
+}
+
+
+static Instruction *getjumpcontrol (FuncState *fs, int pc) {
+ Instruction *pi = &fs->f->code[pc];
+ if (pc >= 1 && testOpMode(GET_OPCODE(*(pi-1)), OpModeT))
+ return pi-1;
+ else
+ return pi;
+}
+
+
+/*
+** check whether list has any jump that do not produce a value
+** (or produce an inverted value)
+*/
+static int need_value (FuncState *fs, int list, int cond) {
+ for (; list != NO_JUMP; list = luaK_getjump(fs, list)) {
+ Instruction i = *getjumpcontrol(fs, list);
+ if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1;
+ }
+ return 0; /* not found */
+}
+
+
+static void patchtestreg (Instruction *i, int reg) {
+ if (reg == NO_REG) reg = GETARG_B(*i);
+ SETARG_A(*i, reg);
+}
+
+
+static void luaK_patchlistaux (FuncState *fs, int list,
+ int ttarget, int treg, int ftarget, int freg, int dtarget) {
+ while (list != NO_JUMP) {
+ int next = luaK_getjump(fs, list);
+ Instruction *i = getjumpcontrol(fs, list);
+ if (GET_OPCODE(*i) != OP_TEST) {
+ lua_assert(dtarget != NO_JUMP);
+ luaK_fixjump(fs, list, dtarget); /* jump to default target */
+ }
+ else {
+ if (GETARG_C(*i)) {
+ lua_assert(ttarget != NO_JUMP);
+ patchtestreg(i, treg);
+ luaK_fixjump(fs, list, ttarget);
+ }
+ else {
+ lua_assert(ftarget != NO_JUMP);
+ patchtestreg(i, freg);
+ luaK_fixjump(fs, list, ftarget);
+ }
+ }
+ list = next;
+ }
+}
+
+
+static void luaK_dischargejpc (FuncState *fs) {
+ luaK_patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc);
+ fs->jpc = NO_JUMP;
+}
+
+
+void luaK_patchlist (FuncState *fs, int list, int target) {
+ if (target == fs->pc)
+ luaK_patchtohere(fs, list);
+ else {
+ lua_assert(target < fs->pc);
+ luaK_patchlistaux(fs, list, target, NO_REG, target, NO_REG, target);
+ }
+}
+
+
+void luaK_patchtohere (FuncState *fs, int list) {
+ luaK_getlabel(fs);
+ luaK_concat(fs, &fs->jpc, list);
+}
+
+
+void luaK_concat (FuncState *fs, int *l1, int l2) {
+ if (l2 == NO_JUMP) return;
+ else if (*l1 == NO_JUMP)
+ *l1 = l2;
+ else {
+ int list = *l1;
+ int next;
+ while ((next = luaK_getjump(fs, list)) != NO_JUMP) /* find last element */
+ list = next;
+ luaK_fixjump(fs, list, l2);
+ }
+}
+
+
+void luaK_checkstack (FuncState *fs, int n) {
+ int newstack = fs->freereg + n;
+ if (newstack > fs->f->maxstacksize) {
+ if (newstack >= MAXSTACK)
+ luaX_syntaxerror(fs->ls, "function or expression too complex");
+ fs->f->maxstacksize = cast(lu_byte, newstack);
+ }
+}
+
+
+void luaK_reserveregs (FuncState *fs, int n) {
+ luaK_checkstack(fs, n);
+ fs->freereg += n;
+}
+
+
+static void freereg (FuncState *fs, int reg) {
+ if (reg >= fs->nactvar && reg < MAXSTACK) {
+ fs->freereg--;
+ lua_assert(reg == fs->freereg);
+ }
+}
+
+
+static void freeexp (FuncState *fs, expdesc *e) {
+ if (e->k == VNONRELOC)
+ freereg(fs, e->info);
+}
+
+
+static int addk (FuncState *fs, TObject *k, TObject *v) {
+ const TObject *idx = luaH_get(fs->h, k);
+ if (ttisnumber(idx)) {
+ lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v));
+ return cast(int, nvalue(idx));
+ }
+ else { /* constant not found; create a new entry */
+ Proto *f = fs->f;
+ luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject,
+ MAXARG_Bx, "constant table overflow");
+ setobj2n(&f->k[fs->nk], v);
+ setnvalue(luaH_set(fs->L, fs->h, k), cast(lua_Number, fs->nk));
+ return fs->nk++;
+ }
+}
+
+
+int luaK_stringK (FuncState *fs, TString *s) {
+ TObject o;
+ setsvalue(&o, s);
+ return addk(fs, &o, &o);
+}
+
+
+int luaK_numberK (FuncState *fs, lua_Number r) {
+ TObject o;
+ setnvalue(&o, r);
+ return addk(fs, &o, &o);
+}
+
+
+static int nil_constant (FuncState *fs) {
+ TObject k, v;
+ setnilvalue(&v);
+ sethvalue(&k, fs->h); /* cannot use nil as key; instead use table itself */
+ return addk(fs, &k, &v);
+}
+
+
+void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) {
+ if (e->k == VCALL) { /* expression is an open function call? */
+ SETARG_C(getcode(fs, e), nresults+1);
+ if (nresults == 1) { /* `regular' expression? */
+ e->k = VNONRELOC;
+ e->info = GETARG_A(getcode(fs, e));
+ }
+ }
+}
+
+
+void luaK_dischargevars (FuncState *fs, expdesc *e) {
+ switch (e->k) {
+ case VLOCAL: {
+ e->k = VNONRELOC;
+ break;
+ }
+ case VUPVAL: {
+ e->info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->info, 0);
+ e->k = VRELOCABLE;
+ break;
+ }
+ case VGLOBAL: {
+ e->info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->info);
+ e->k = VRELOCABLE;
+ break;
+ }
+ case VINDEXED: {
+ freereg(fs, e->aux);
+ freereg(fs, e->info);
+ e->info = luaK_codeABC(fs, OP_GETTABLE, 0, e->info, e->aux);
+ e->k = VRELOCABLE;
+ break;
+ }
+ case VCALL: {
+ luaK_setcallreturns(fs, e, 1);
+ break;
+ }
+ default: break; /* there is one value available (somewhere) */
+ }
+}
+
+
+static int code_label (FuncState *fs, int A, int b, int jump) {
+ luaK_getlabel(fs); /* those instructions may be jump targets */
+ return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
+}
+
+
+static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
+ luaK_dischargevars(fs, e);
+ switch (e->k) {
+ case VNIL: {
+ luaK_nil(fs, reg, 1);
+ break;
+ }
+ case VFALSE: case VTRUE: {
+ luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
+ break;
+ }
+ case VK: {
+ luaK_codeABx(fs, OP_LOADK, reg, e->info);
+ break;
+ }
+ case VRELOCABLE: {
+ Instruction *pc = &getcode(fs, e);
+ SETARG_A(*pc, reg);
+ break;
+ }
+ case VNONRELOC: {
+ if (reg != e->info)
+ luaK_codeABC(fs, OP_MOVE, reg, e->info, 0);
+ break;
+ }
+ default: {
+ lua_assert(e->k == VVOID || e->k == VJMP);
+ return; /* nothing to do... */
+ }
+ }
+ e->info = reg;
+ e->k = VNONRELOC;
+}
+
+
+static void discharge2anyreg (FuncState *fs, expdesc *e) {
+ if (e->k != VNONRELOC) {
+ luaK_reserveregs(fs, 1);
+ discharge2reg(fs, e, fs->freereg-1);
+ }
+}
+
+
+static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) {
+ discharge2reg(fs, e, reg);
+ if (e->k == VJMP)
+ luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */
+ if (hasjumps(e)) {
+ int final; /* position after whole expression */
+ int p_f = NO_JUMP; /* position of an eventual LOAD false */
+ int p_t = NO_JUMP; /* position of an eventual LOAD true */
+ if (need_value(fs, e->t, 1) || need_value(fs, e->f, 0)) {
+ int fj = NO_JUMP; /* first jump (over LOAD ops.) */
+ if (e->k != VJMP)
+ fj = luaK_jump(fs);
+ p_f = code_label(fs, reg, 0, 1);
+ p_t = code_label(fs, reg, 1, 0);
+ luaK_patchtohere(fs, fj);
+ }
+ final = luaK_getlabel(fs);
+ luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);
+ luaK_patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t);
+ }
+ e->f = e->t = NO_JUMP;
+ e->info = reg;
+ e->k = VNONRELOC;
+}
+
+
+void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
+ luaK_dischargevars(fs, e);
+ freeexp(fs, e);
+ luaK_reserveregs(fs, 1);
+ luaK_exp2reg(fs, e, fs->freereg - 1);
+}
+
+
+int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
+ luaK_dischargevars(fs, e);
+ if (e->k == VNONRELOC) {
+ if (!hasjumps(e)) return e->info; /* exp is already in a register */
+ if (e->info >= fs->nactvar) { /* reg. is not a local? */
+ luaK_exp2reg(fs, e, e->info); /* put value on it */
+ return e->info;
+ }
+ }
+ luaK_exp2nextreg(fs, e); /* default */
+ return e->info;
+}
+
+
+void luaK_exp2val (FuncState *fs, expdesc *e) {
+ if (hasjumps(e))
+ luaK_exp2anyreg(fs, e);
+ else
+ luaK_dischargevars(fs, e);
+}
+
+
+int luaK_exp2RK (FuncState *fs, expdesc *e) {
+ luaK_exp2val(fs, e);
+ switch (e->k) {
+ case VNIL: {
+ if (fs->nk + MAXSTACK <= MAXARG_C) { /* constant fit in argC? */
+ e->info = nil_constant(fs);
+ e->k = VK;
+ return e->info + MAXSTACK;
+ }
+ else break;
+ }
+ case VK: {
+ if (e->info + MAXSTACK <= MAXARG_C) /* constant fit in argC? */
+ return e->info + MAXSTACK;
+ else break;
+ }
+ default: break;
+ }
+ /* not a constant in the right range: put it in a register */
+ return luaK_exp2anyreg(fs, e);
+}
+
+
+void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) {
+ switch (var->k) {
+ case VLOCAL: {
+ freeexp(fs, exp);
+ luaK_exp2reg(fs, exp, var->info);
+ return;
+ }
+ case VUPVAL: {
+ int e = luaK_exp2anyreg(fs, exp);
+ luaK_codeABC(fs, OP_SETUPVAL, e, var->info, 0);
+ break;
+ }
+ case VGLOBAL: {
+ int e = luaK_exp2anyreg(fs, exp);
+ luaK_codeABx(fs, OP_SETGLOBAL, e, var->info);
+ break;
+ }
+ case VINDEXED: {
+ int e = luaK_exp2RK(fs, exp);
+ luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e);
+ break;
+ }
+ default: {
+ lua_assert(0); /* invalid var kind to store */
+ break;
+ }
+ }
+ freeexp(fs, exp);
+}
+
+
+void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
+ int func;
+ luaK_exp2anyreg(fs, e);
+ freeexp(fs, e);
+ func = fs->freereg;
+ luaK_reserveregs(fs, 2);
+ luaK_codeABC(fs, OP_SELF, func, e->info, luaK_exp2RK(fs, key));
+ freeexp(fs, key);
+ e->info = func;
+ e->k = VNONRELOC;
+}
+
+
+static void invertjump (FuncState *fs, expdesc *e) {
+ Instruction *pc = getjumpcontrol(fs, e->info);
+ lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) &&
+ GET_OPCODE(*pc) != OP_TEST);
+ SETARG_A(*pc, !(GETARG_A(*pc)));
+}
+
+
+static int jumponcond (FuncState *fs, expdesc *e, int cond) {
+ if (e->k == VRELOCABLE) {
+ Instruction ie = getcode(fs, e);
+ if (GET_OPCODE(ie) == OP_NOT) {
+ fs->pc--; /* remove previous OP_NOT */
+ return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond);
+ }
+ /* else go through */
+ }
+ discharge2anyreg(fs, e);
+ freeexp(fs, e);
+ return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond);
+}
+
+
+void luaK_goiftrue (FuncState *fs, expdesc *e) {
+ int pc; /* pc of last jump */
+ luaK_dischargevars(fs, e);
+ switch (e->k) {
+ case VK: case VTRUE: {
+ pc = NO_JUMP; /* always true; do nothing */
+ break;
+ }
+ case VFALSE: {
+ pc = luaK_jump(fs); /* always jump */
+ break;
+ }
+ case VJMP: {
+ invertjump(fs, e);
+ pc = e->info;
+ break;
+ }
+ default: {
+ pc = jumponcond(fs, e, 0);
+ break;
+ }
+ }
+ luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
+}
+
+
+void luaK_goiffalse (FuncState *fs, expdesc *e) {
+ int pc; /* pc of last jump */
+ luaK_dischargevars(fs, e);
+ switch (e->k) {
+ case VNIL: case VFALSE: {
+ pc = NO_JUMP; /* always false; do nothing */
+ break;
+ }
+ case VTRUE: {
+ pc = luaK_jump(fs); /* always jump */
+ break;
+ }
+ case VJMP: {
+ pc = e->info;
+ break;
+ }
+ default: {
+ pc = jumponcond(fs, e, 1);
+ break;
+ }
+ }
+ luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
+}
+
+
+static void codenot (FuncState *fs, expdesc *e) {
+ luaK_dischargevars(fs, e);
+ switch (e->k) {
+ case VNIL: case VFALSE: {
+ e->k = VTRUE;
+ break;
+ }
+ case VK: case VTRUE: {
+ e->k = VFALSE;
+ break;
+ }
+ case VJMP: {
+ invertjump(fs, e);
+ break;
+ }
+ case VRELOCABLE:
+ case VNONRELOC: {
+ discharge2anyreg(fs, e);
+ freeexp(fs, e);
+ e->info = luaK_codeABC(fs, OP_NOT, 0, e->info, 0);
+ e->k = VRELOCABLE;
+ break;
+ }
+ default: {
+ lua_assert(0); /* cannot happen */
+ break;
+ }
+ }
+ /* interchange true and false lists */
+ { int temp = e->f; e->f = e->t; e->t = temp; }
+}
+
+
+void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
+ t->aux = luaK_exp2RK(fs, k);
+ t->k = VINDEXED;
+}
+
+
+void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
+ if (op == OPR_MINUS) {
+ luaK_exp2val(fs, e);
+ if (e->k == VK && ttisnumber(&fs->f->k[e->info]))
+ e->info = luaK_numberK(fs, -nvalue(&fs->f->k[e->info]));
+ else {
+ luaK_exp2anyreg(fs, e);
+ freeexp(fs, e);
+ e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0);
+ e->k = VRELOCABLE;
+ }
+ }
+ else /* op == NOT */
+ codenot(fs, e);
+}
+
+
+void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
+ switch (op) {
+ case OPR_AND: {
+ luaK_goiftrue(fs, v);
+ luaK_patchtohere(fs, v->t);
+ v->t = NO_JUMP;
+ break;
+ }
+ case OPR_OR: {
+ luaK_goiffalse(fs, v);
+ luaK_patchtohere(fs, v->f);
+ v->f = NO_JUMP;
+ break;
+ }
+ case OPR_CONCAT: {
+ luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
+ break;
+ }
+ default: {
+ luaK_exp2RK(fs, v);
+ break;
+ }
+ }
+}
+
+
+static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
+ int o1, int o2) {
+ if (op <= OPR_POW) { /* arithmetic operator? */
+ OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); /* ORDER OP */
+ res->info = luaK_codeABC(fs, opc, 0, o1, o2);
+ res->k = VRELOCABLE;
+ }
+ else { /* test operator */
+ static const OpCode ops[] = {OP_EQ, OP_EQ, OP_LT, OP_LE, OP_LT, OP_LE};
+ int cond = 1;
+ if (op >= OPR_GT) { /* `>' or `>='? */
+ int temp; /* exchange args and replace by `<' or `<=' */
+ temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
+ }
+ else if (op == OPR_NE) cond = 0;
+ res->info = luaK_condjump(fs, ops[op - OPR_NE], cond, o1, o2);
+ res->k = VJMP;
+ }
+}
+
+
+void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
+ switch (op) {
+ case OPR_AND: {
+ lua_assert(e1->t == NO_JUMP); /* list must be closed */
+ luaK_dischargevars(fs, e2);
+ luaK_concat(fs, &e1->f, e2->f);
+ e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->t = e2->t;
+ break;
+ }
+ case OPR_OR: {
+ lua_assert(e1->f == NO_JUMP); /* list must be closed */
+ luaK_dischargevars(fs, e2);
+ luaK_concat(fs, &e1->t, e2->t);
+ e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->f = e2->f;
+ break;
+ }
+ case OPR_CONCAT: {
+ luaK_exp2val(fs, e2);
+ if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
+ lua_assert(e1->info == GETARG_B(getcode(fs, e2))-1);
+ freeexp(fs, e1);
+ SETARG_B(getcode(fs, e2), e1->info);
+ e1->k = e2->k; e1->info = e2->info;
+ }
+ else {
+ luaK_exp2nextreg(fs, e2);
+ freeexp(fs, e2);
+ freeexp(fs, e1);
+ e1->info = luaK_codeABC(fs, OP_CONCAT, 0, e1->info, e2->info);
+ e1->k = VRELOCABLE;
+ }
+ break;
+ }
+ default: {
+ int o1 = luaK_exp2RK(fs, e1);
+ int o2 = luaK_exp2RK(fs, e2);
+ freeexp(fs, e2);
+ freeexp(fs, e1);
+ codebinop(fs, e1, op, o1, o2);
+ }
+ }
+}
+
+
+void luaK_fixline (FuncState *fs, int line) {
+ fs->f->lineinfo[fs->pc - 1] = line;
+}
+
+
+int luaK_code (FuncState *fs, Instruction i, int line) {
+ Proto *f = fs->f;
+ luaK_dischargejpc(fs); /* `pc' will change */
+ /* put new instruction in code array */
+ luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
+ MAX_INT, "code size overflow");
+ f->code[fs->pc] = i;
+ /* save corresponding line information */
+ luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
+ MAX_INT, "code size overflow");
+ f->lineinfo[fs->pc] = line;
+ return fs->pc++;
+}
+
+
+int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
+ lua_assert(getOpMode(o) == iABC);
+ return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
+}
+
+
+int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
+ lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
+ return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
+}
+
diff --git a/lib/lua/src/ldebug.c b/lib/lua/src/ldebug.c
index 0b8e987..65114c7 100644
--- a/lib/lua/src/ldebug.c
+++ b/lib/lua/src/ldebug.c
@@ -1,585 +1,585 @@
-/*
-** $Id: ldebug.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** Debug Interface
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stdlib.h>
-#include <string.h>
-
-#define ldebug_c
-
-#include "lua.h"
-
-#include "lapi.h"
-#include "lcode.h"
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-#include "lvm.h"
-
-
-
-static const char *getfuncname (CallInfo *ci, const char **name);
-
-
-#define isLua(ci) (!((ci)->state & CI_C))
-
-
-static int currentpc (CallInfo *ci) {
- if (!isLua(ci)) return -1; /* function is not a Lua function? */
- if (ci->state & CI_HASFRAME) /* function has a frame? */
- ci->u.l.savedpc = *ci->u.l.pc; /* use `pc' from there */
- /* function's pc is saved */
- return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);
-}
-
-
-static int currentline (CallInfo *ci) {
- int pc = currentpc(ci);
- if (pc < 0)
- return -1; /* only active lua functions have current-line information */
- else
- return getline(ci_func(ci)->l.p, pc);
-}
-
-
-void luaG_inithooks (lua_State *L) {
- CallInfo *ci;
- for (ci = L->ci; ci != L->base_ci; ci--) /* update all `savedpc's */
- currentpc(ci);
- L->hookinit = 1;
-}
-
-
-/*
-** this function can be called asynchronous (e.g. during a signal)
-*/
-LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
- if (func == NULL || mask == 0) { /* turn off hooks? */
- mask = 0;
- func = NULL;
- }
- L->hook = func;
- L->basehookcount = count;
- resethookcount(L);
- L->hookmask = cast(lu_byte, mask);
- L->hookinit = 0;
- return 1;
-}
-
-
-LUA_API lua_Hook lua_gethook (lua_State *L) {
- return L->hook;
-}
-
-
-LUA_API int lua_gethookmask (lua_State *L) {
- return L->hookmask;
-}
-
-
-LUA_API int lua_gethookcount (lua_State *L) {
- return L->basehookcount;
-}
-
-
-LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
- int status;
- CallInfo *ci;
- lua_lock(L);
- for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
- level--;
- if (!(ci->state & CI_C)) /* Lua function? */
- level -= ci->u.l.tailcalls; /* skip lost tail calls */
- }
- if (level > 0 || ci == L->base_ci) status = 0; /* there is no such level */
- else if (level < 0) { /* level is of a lost tail call */
- status = 1;
- ar->i_ci = 0;
- }
- else {
- status = 1;
- ar->i_ci = ci - L->base_ci;
- }
- lua_unlock(L);
- return status;
-}
-
-
-static Proto *getluaproto (CallInfo *ci) {
- return (isLua(ci) ? ci_func(ci)->l.p : NULL);
-}
-
-
-LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
- const char *name;
- CallInfo *ci;
- Proto *fp;
- lua_lock(L);
- name = NULL;
- ci = L->base_ci + ar->i_ci;
- fp = getluaproto(ci);
- if (fp) { /* is a Lua function? */
- name = luaF_getlocalname(fp, n, currentpc(ci));
- if (name)
- luaA_pushobject(L, ci->base+(n-1)); /* push value */
- }
- lua_unlock(L);
- return name;
-}
-
-
-LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
- const char *name;
- CallInfo *ci;
- Proto *fp;
- lua_lock(L);
- name = NULL;
- ci = L->base_ci + ar->i_ci;
- fp = getluaproto(ci);
- L->top--; /* pop new value */
- if (fp) { /* is a Lua function? */
- name = luaF_getlocalname(fp, n, currentpc(ci));
- if (!name || name[0] == '(') /* `(' starts private locals */
- name = NULL;
- else
- setobjs2s(ci->base+(n-1), L->top);
- }
- lua_unlock(L);
- return name;
-}
-
-
-static void funcinfo (lua_Debug *ar, StkId func) {
- Closure *cl = clvalue(func);
- if (cl->c.isC) {
- ar->source = "=[C]";
- ar->linedefined = -1;
- ar->what = "C";
- }
- else {
- ar->source = getstr(cl->l.p->source);
- ar->linedefined = cl->l.p->lineDefined;
- ar->what = (ar->linedefined == 0) ? "main" : "Lua";
- }
- luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
-}
-
-
-static const char *travglobals (lua_State *L, const TObject *o) {
- Table *g = hvalue(gt(L));
- int i = sizenode(g);
- while (i--) {
- Node *n = gnode(g, i);
- if (luaO_rawequalObj(o, gval(n)) && ttisstring(gkey(n)))
- return getstr(tsvalue(gkey(n)));
- }
- return NULL;
-}
-
-
-static void info_tailcall (lua_State *L, lua_Debug *ar) {
- ar->name = ar->namewhat = "";
- ar->what = "tail";
- ar->linedefined = ar->currentline = -1;
- ar->source = "=(tail call)";
- luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
- ar->nups = 0;
- setnilvalue(L->top);
-}
-
-
-static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
- StkId f, CallInfo *ci) {
- int status = 1;
- for (; *what; what++) {
- switch (*what) {
- case 'S': {
- funcinfo(ar, f);
- break;
- }
- case 'l': {
- ar->currentline = (ci) ? currentline(ci) : -1;
- break;
- }
- case 'u': {
- ar->nups = clvalue(f)->c.nupvalues;
- break;
- }
- case 'n': {
- ar->namewhat = (ci) ? getfuncname(ci, &ar->name) : NULL;
- if (ar->namewhat == NULL) {
- /* try to find a global name */
- if ((ar->name = travglobals(L, f)) != NULL)
- ar->namewhat = "global";
- else ar->namewhat = ""; /* not found */
- }
- break;
- }
- case 'f': {
- setobj2s(L->top, f);
- break;
- }
- default: status = 0; /* invalid option */
- }
- }
- return status;
-}
-
-
-LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
- int status = 1;
- lua_lock(L);
- if (*what == '>') {
- StkId f = L->top - 1;
- if (!ttisfunction(f))
- luaG_runerror(L, "value for `lua_getinfo' is not a function");
- status = auxgetinfo(L, what + 1, ar, f, NULL);
- L->top--; /* pop function */
- }
- else if (ar->i_ci != 0) { /* no tail call? */
- CallInfo *ci = L->base_ci + ar->i_ci;
- lua_assert(ttisfunction(ci->base - 1));
- status = auxgetinfo(L, what, ar, ci->base - 1, ci);
- }
- else
- info_tailcall(L, ar);
- if (strchr(what, 'f')) incr_top(L);
- lua_unlock(L);
- return status;
-}
-
-
-/*
-** {======================================================
-** Symbolic Execution and code checker
-** =======================================================
-*/
-
-#define check(x) if (!(x)) return 0;
-
-#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
-
-#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
-
-
-
-static int precheck (const Proto *pt) {
- check(pt->maxstacksize <= MAXSTACK);
- check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
- lua_assert(pt->numparams+pt->is_vararg <= pt->maxstacksize);
- check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
- return 1;
-}
-
-
-static int checkopenop (const Proto *pt, int pc) {
- Instruction i = pt->code[pc+1];
- switch (GET_OPCODE(i)) {
- case OP_CALL:
- case OP_TAILCALL:
- case OP_RETURN: {
- check(GETARG_B(i) == 0);
- return 1;
- }
- case OP_SETLISTO: return 1;
- default: return 0; /* invalid instruction after an open call */
- }
-}
-
-
-static int checkRK (const Proto *pt, int r) {
- return (r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek));
-}
-
-
-static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
- int pc;
- int last; /* stores position of last instruction that changed `reg' */
- last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
- check(precheck(pt));
- for (pc = 0; pc < lastpc; pc++) {
- const Instruction i = pt->code[pc];
- OpCode op = GET_OPCODE(i);
- int a = GETARG_A(i);
- int b = 0;
- int c = 0;
- checkreg(pt, a);
- switch (getOpMode(op)) {
- case iABC: {
- b = GETARG_B(i);
- c = GETARG_C(i);
- if (testOpMode(op, OpModeBreg)) {
- checkreg(pt, b);
- }
- else if (testOpMode(op, OpModeBrk))
- check(checkRK(pt, b));
- if (testOpMode(op, OpModeCrk))
- check(checkRK(pt, c));
- break;
- }
- case iABx: {
- b = GETARG_Bx(i);
- if (testOpMode(op, OpModeK)) check(b < pt->sizek);
- break;
- }
- case iAsBx: {
- b = GETARG_sBx(i);
- break;
- }
- }
- if (testOpMode(op, OpModesetA)) {
- if (a == reg) last = pc; /* change register `a' */
- }
- if (testOpMode(op, OpModeT)) {
- check(pc+2 < pt->sizecode); /* check skip */
- check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
- }
- switch (op) {
- case OP_LOADBOOL: {
- check(c == 0 || pc+2 < pt->sizecode); /* check its jump */
- break;
- }
- case OP_LOADNIL: {
- if (a <= reg && reg <= b)
- last = pc; /* set registers from `a' to `b' */
- break;
- }
- case OP_GETUPVAL:
- case OP_SETUPVAL: {
- check(b < pt->nups);
- break;
- }
- case OP_GETGLOBAL:
- case OP_SETGLOBAL: {
- check(ttisstring(&pt->k[b]));
- break;
- }
- case OP_SELF: {
- checkreg(pt, a+1);
- if (reg == a+1) last = pc;
- break;
- }
- case OP_CONCAT: {
- /* `c' is a register, and at least two operands */
- check(c < MAXSTACK && b < c);
- break;
- }
- case OP_TFORLOOP:
- checkreg(pt, a+c+5);
- if (reg >= a) last = pc; /* affect all registers above base */
- /* go through */
- case OP_FORLOOP:
- checkreg(pt, a+2);
- /* go through */
- case OP_JMP: {
- int dest = pc+1+b;
- check(0 <= dest && dest < pt->sizecode);
- /* not full check and jump is forward and do not skip `lastpc'? */
- if (reg != NO_REG && pc < dest && dest <= lastpc)
- pc += b; /* do the jump */
- break;
- }
- case OP_CALL:
- case OP_TAILCALL: {
- if (b != 0) {
- checkreg(pt, a+b-1);
- }
- c--; /* c = num. returns */
- if (c == LUA_MULTRET) {
- check(checkopenop(pt, pc));
- }
- else if (c != 0)
- checkreg(pt, a+c-1);
- if (reg >= a) last = pc; /* affect all registers above base */
- break;
- }
- case OP_RETURN: {
- b--; /* b = num. returns */
- if (b > 0) checkreg(pt, a+b-1);
- break;
- }
- case OP_SETLIST: {
- checkreg(pt, a + (b&(LFIELDS_PER_FLUSH-1)) + 1);
- break;
- }
- case OP_CLOSURE: {
- int nup;
- check(b < pt->sizep);
- nup = pt->p[b]->nups;
- check(pc + nup < pt->sizecode);
- for (; nup>0; nup--) {
- OpCode op1 = GET_OPCODE(pt->code[pc+nup]);
- check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
- }
- break;
- }
- default: break;
- }
- }
- return pt->code[last];
-}
-
-#undef check
-#undef checkjump
-#undef checkreg
-
-/* }====================================================== */
-
-
-int luaG_checkcode (const Proto *pt) {
- return luaG_symbexec(pt, pt->sizecode, NO_REG);
-}
-
-
-static const char *kname (Proto *p, int c) {
- c = c - MAXSTACK;
- if (c >= 0 && ttisstring(&p->k[c]))
- return svalue(&p->k[c]);
- else
- return "?";
-}
-
-
-static const char *getobjname (CallInfo *ci, int stackpos, const char **name) {
- if (isLua(ci)) { /* a Lua function? */
- Proto *p = ci_func(ci)->l.p;
- int pc = currentpc(ci);
- Instruction i;
- *name = luaF_getlocalname(p, stackpos+1, pc);
- if (*name) /* is a local? */
- return "local";
- i = luaG_symbexec(p, pc, stackpos); /* try symbolic execution */
- lua_assert(pc != -1);
- switch (GET_OPCODE(i)) {
- case OP_GETGLOBAL: {
- int g = GETARG_Bx(i); /* global index */
- lua_assert(ttisstring(&p->k[g]));
- *name = svalue(&p->k[g]);
- return "global";
- }
- case OP_MOVE: {
- int a = GETARG_A(i);
- int b = GETARG_B(i); /* move from `b' to `a' */
- if (b < a)
- return getobjname(ci, b, name); /* get name for `b' */
- break;
- }
- case OP_GETTABLE: {
- int k = GETARG_C(i); /* key index */
- *name = kname(p, k);
- return "field";
- }
- case OP_SELF: {
- int k = GETARG_C(i); /* key index */
- *name = kname(p, k);
- return "method";
- }
- default: break;
- }
- }
- return NULL; /* no useful name found */
-}
-
-
-static const char *getfuncname (CallInfo *ci, const char **name) {
- Instruction i;
- if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1))
- return NULL; /* calling function is not Lua (or is unknown) */
- ci--; /* calling function */
- i = ci_func(ci)->l.p->code[currentpc(ci)];
- if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL)
- return getobjname(ci, GETARG_A(i), name);
- else
- return NULL; /* no useful name can be found */
-}
-
-
-/* only ANSI way to check whether a pointer points to an array */
-static int isinstack (CallInfo *ci, const TObject *o) {
- StkId p;
- for (p = ci->base; p < ci->top; p++)
- if (o == p) return 1;
- return 0;
-}
-
-
-void luaG_typeerror (lua_State *L, const TObject *o, const char *op) {
- const char *name = NULL;
- const char *t = luaT_typenames[ttype(o)];
- const char *kind = (isinstack(L->ci, o)) ?
- getobjname(L->ci, o - L->base, &name) : NULL;
- if (kind)
- luaG_runerror(L, "attempt to %s %s `%s' (a %s value)",
- op, kind, name, t);
- else
- luaG_runerror(L, "attempt to %s a %s value", op, t);
-}
-
-
-void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
- if (ttisstring(p1)) p1 = p2;
- lua_assert(!ttisstring(p1));
- luaG_typeerror(L, p1, "concatenate");
-}
-
-
-void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2) {
- TObject temp;
- if (luaV_tonumber(p1, &temp) == NULL)
- p2 = p1; /* first operand is wrong */
- luaG_typeerror(L, p2, "perform arithmetic on");
-}
-
-
-int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) {
- const char *t1 = luaT_typenames[ttype(p1)];
- const char *t2 = luaT_typenames[ttype(p2)];
- if (t1[2] == t2[2])
- luaG_runerror(L, "attempt to compare two %s values", t1);
- else
- luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
- return 0;
-}
-
-
-static void addinfo (lua_State *L, const char *msg) {
- CallInfo *ci = L->ci;
- if (isLua(ci)) { /* is Lua code? */
- char buff[LUA_IDSIZE]; /* add file:line information */
- int line = currentline(ci);
- luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
- luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
- }
-}
-
-
-void luaG_errormsg (lua_State *L) {
- if (L->errfunc != 0) { /* is there an error handling function? */
- StkId errfunc = restorestack(L, L->errfunc);
- if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
- setobjs2s(L->top, L->top - 1); /* move argument */
- setobjs2s(L->top - 1, errfunc); /* push function */
- incr_top(L);
- luaD_call(L, L->top - 2, 1); /* call it */
- }
- luaD_throw(L, LUA_ERRRUN);
-}
-
-
-void luaG_runerror (lua_State *L, const char *fmt, ...) {
- va_list argp;
- va_start(argp, fmt);
- addinfo(L, luaO_pushvfstring(L, fmt, argp));
- va_end(argp);
- luaG_errormsg(L);
-}
-
+/*
+** $Id: ldebug.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** Debug Interface
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#define ldebug_c
+
+#include "lua.h"
+
+#include "lapi.h"
+#include "lcode.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+#include "lvm.h"
+
+
+
+static const char *getfuncname (CallInfo *ci, const char **name);
+
+
+#define isLua(ci) (!((ci)->state & CI_C))
+
+
+static int currentpc (CallInfo *ci) {
+ if (!isLua(ci)) return -1; /* function is not a Lua function? */
+ if (ci->state & CI_HASFRAME) /* function has a frame? */
+ ci->u.l.savedpc = *ci->u.l.pc; /* use `pc' from there */
+ /* function's pc is saved */
+ return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);
+}
+
+
+static int currentline (CallInfo *ci) {
+ int pc = currentpc(ci);
+ if (pc < 0)
+ return -1; /* only active lua functions have current-line information */
+ else
+ return getline(ci_func(ci)->l.p, pc);
+}
+
+
+void luaG_inithooks (lua_State *L) {
+ CallInfo *ci;
+ for (ci = L->ci; ci != L->base_ci; ci--) /* update all `savedpc's */
+ currentpc(ci);
+ L->hookinit = 1;
+}
+
+
+/*
+** this function can be called asynchronous (e.g. during a signal)
+*/
+LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
+ if (func == NULL || mask == 0) { /* turn off hooks? */
+ mask = 0;
+ func = NULL;
+ }
+ L->hook = func;
+ L->basehookcount = count;
+ resethookcount(L);
+ L->hookmask = cast(lu_byte, mask);
+ L->hookinit = 0;
+ return 1;
+}
+
+
+LUA_API lua_Hook lua_gethook (lua_State *L) {
+ return L->hook;
+}
+
+
+LUA_API int lua_gethookmask (lua_State *L) {
+ return L->hookmask;
+}
+
+
+LUA_API int lua_gethookcount (lua_State *L) {
+ return L->basehookcount;
+}
+
+
+LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
+ int status;
+ CallInfo *ci;
+ lua_lock(L);
+ for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
+ level--;
+ if (!(ci->state & CI_C)) /* Lua function? */
+ level -= ci->u.l.tailcalls; /* skip lost tail calls */
+ }
+ if (level > 0 || ci == L->base_ci) status = 0; /* there is no such level */
+ else if (level < 0) { /* level is of a lost tail call */
+ status = 1;
+ ar->i_ci = 0;
+ }
+ else {
+ status = 1;
+ ar->i_ci = ci - L->base_ci;
+ }
+ lua_unlock(L);
+ return status;
+}
+
+
+static Proto *getluaproto (CallInfo *ci) {
+ return (isLua(ci) ? ci_func(ci)->l.p : NULL);
+}
+
+
+LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
+ const char *name;
+ CallInfo *ci;
+ Proto *fp;
+ lua_lock(L);
+ name = NULL;
+ ci = L->base_ci + ar->i_ci;
+ fp = getluaproto(ci);
+ if (fp) { /* is a Lua function? */
+ name = luaF_getlocalname(fp, n, currentpc(ci));
+ if (name)
+ luaA_pushobject(L, ci->base+(n-1)); /* push value */
+ }
+ lua_unlock(L);
+ return name;
+}
+
+
+LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
+ const char *name;
+ CallInfo *ci;
+ Proto *fp;
+ lua_lock(L);
+ name = NULL;
+ ci = L->base_ci + ar->i_ci;
+ fp = getluaproto(ci);
+ L->top--; /* pop new value */
+ if (fp) { /* is a Lua function? */
+ name = luaF_getlocalname(fp, n, currentpc(ci));
+ if (!name || name[0] == '(') /* `(' starts private locals */
+ name = NULL;
+ else
+ setobjs2s(ci->base+(n-1), L->top);
+ }
+ lua_unlock(L);
+ return name;
+}
+
+
+static void funcinfo (lua_Debug *ar, StkId func) {
+ Closure *cl = clvalue(func);
+ if (cl->c.isC) {
+ ar->source = "=[C]";
+ ar->linedefined = -1;
+ ar->what = "C";
+ }
+ else {
+ ar->source = getstr(cl->l.p->source);
+ ar->linedefined = cl->l.p->lineDefined;
+ ar->what = (ar->linedefined == 0) ? "main" : "Lua";
+ }
+ luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
+}
+
+
+static const char *travglobals (lua_State *L, const TObject *o) {
+ Table *g = hvalue(gt(L));
+ int i = sizenode(g);
+ while (i--) {
+ Node *n = gnode(g, i);
+ if (luaO_rawequalObj(o, gval(n)) && ttisstring(gkey(n)))
+ return getstr(tsvalue(gkey(n)));
+ }
+ return NULL;
+}
+
+
+static void info_tailcall (lua_State *L, lua_Debug *ar) {
+ ar->name = ar->namewhat = "";
+ ar->what = "tail";
+ ar->linedefined = ar->currentline = -1;
+ ar->source = "=(tail call)";
+ luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
+ ar->nups = 0;
+ setnilvalue(L->top);
+}
+
+
+static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
+ StkId f, CallInfo *ci) {
+ int status = 1;
+ for (; *what; what++) {
+ switch (*what) {
+ case 'S': {
+ funcinfo(ar, f);
+ break;
+ }
+ case 'l': {
+ ar->currentline = (ci) ? currentline(ci) : -1;
+ break;
+ }
+ case 'u': {
+ ar->nups = clvalue(f)->c.nupvalues;
+ break;
+ }
+ case 'n': {
+ ar->namewhat = (ci) ? getfuncname(ci, &ar->name) : NULL;
+ if (ar->namewhat == NULL) {
+ /* try to find a global name */
+ if ((ar->name = travglobals(L, f)) != NULL)
+ ar->namewhat = "global";
+ else ar->namewhat = ""; /* not found */
+ }
+ break;
+ }
+ case 'f': {
+ setobj2s(L->top, f);
+ break;
+ }
+ default: status = 0; /* invalid option */
+ }
+ }
+ return status;
+}
+
+
+LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
+ int status = 1;
+ lua_lock(L);
+ if (*what == '>') {
+ StkId f = L->top - 1;
+ if (!ttisfunction(f))
+ luaG_runerror(L, "value for `lua_getinfo' is not a function");
+ status = auxgetinfo(L, what + 1, ar, f, NULL);
+ L->top--; /* pop function */
+ }
+ else if (ar->i_ci != 0) { /* no tail call? */
+ CallInfo *ci = L->base_ci + ar->i_ci;
+ lua_assert(ttisfunction(ci->base - 1));
+ status = auxgetinfo(L, what, ar, ci->base - 1, ci);
+ }
+ else
+ info_tailcall(L, ar);
+ if (strchr(what, 'f')) incr_top(L);
+ lua_unlock(L);
+ return status;
+}
+
+
+/*
+** {======================================================
+** Symbolic Execution and code checker
+** =======================================================
+*/
+
+#define check(x) if (!(x)) return 0;
+
+#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
+
+#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
+
+
+
+static int precheck (const Proto *pt) {
+ check(pt->maxstacksize <= MAXSTACK);
+ check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
+ lua_assert(pt->numparams+pt->is_vararg <= pt->maxstacksize);
+ check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
+ return 1;
+}
+
+
+static int checkopenop (const Proto *pt, int pc) {
+ Instruction i = pt->code[pc+1];
+ switch (GET_OPCODE(i)) {
+ case OP_CALL:
+ case OP_TAILCALL:
+ case OP_RETURN: {
+ check(GETARG_B(i) == 0);
+ return 1;
+ }
+ case OP_SETLISTO: return 1;
+ default: return 0; /* invalid instruction after an open call */
+ }
+}
+
+
+static int checkRK (const Proto *pt, int r) {
+ return (r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek));
+}
+
+
+static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
+ int pc;
+ int last; /* stores position of last instruction that changed `reg' */
+ last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
+ check(precheck(pt));
+ for (pc = 0; pc < lastpc; pc++) {
+ const Instruction i = pt->code[pc];
+ OpCode op = GET_OPCODE(i);
+ int a = GETARG_A(i);
+ int b = 0;
+ int c = 0;
+ checkreg(pt, a);
+ switch (getOpMode(op)) {
+ case iABC: {
+ b = GETARG_B(i);
+ c = GETARG_C(i);
+ if (testOpMode(op, OpModeBreg)) {
+ checkreg(pt, b);
+ }
+ else if (testOpMode(op, OpModeBrk))
+ check(checkRK(pt, b));
+ if (testOpMode(op, OpModeCrk))
+ check(checkRK(pt, c));
+ break;
+ }
+ case iABx: {
+ b = GETARG_Bx(i);
+ if (testOpMode(op, OpModeK)) check(b < pt->sizek);
+ break;
+ }
+ case iAsBx: {
+ b = GETARG_sBx(i);
+ break;
+ }
+ }
+ if (testOpMode(op, OpModesetA)) {
+ if (a == reg) last = pc; /* change register `a' */
+ }
+ if (testOpMode(op, OpModeT)) {
+ check(pc+2 < pt->sizecode); /* check skip */
+ check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
+ }
+ switch (op) {
+ case OP_LOADBOOL: {
+ check(c == 0 || pc+2 < pt->sizecode); /* check its jump */
+ break;
+ }
+ case OP_LOADNIL: {
+ if (a <= reg && reg <= b)
+ last = pc; /* set registers from `a' to `b' */
+ break;
+ }
+ case OP_GETUPVAL:
+ case OP_SETUPVAL: {
+ check(b < pt->nups);
+ break;
+ }
+ case OP_GETGLOBAL:
+ case OP_SETGLOBAL: {
+ check(ttisstring(&pt->k[b]));
+ break;
+ }
+ case OP_SELF: {
+ checkreg(pt, a+1);
+ if (reg == a+1) last = pc;
+ break;
+ }
+ case OP_CONCAT: {
+ /* `c' is a register, and at least two operands */
+ check(c < MAXSTACK && b < c);
+ break;
+ }
+ case OP_TFORLOOP:
+ checkreg(pt, a+c+5);
+ if (reg >= a) last = pc; /* affect all registers above base */
+ /* go through */
+ case OP_FORLOOP:
+ checkreg(pt, a+2);
+ /* go through */
+ case OP_JMP: {
+ int dest = pc+1+b;
+ check(0 <= dest && dest < pt->sizecode);
+ /* not full check and jump is forward and do not skip `lastpc'? */
+ if (reg != NO_REG && pc < dest && dest <= lastpc)
+ pc += b; /* do the jump */
+ break;
+ }
+ case OP_CALL:
+ case OP_TAILCALL: {
+ if (b != 0) {
+ checkreg(pt, a+b-1);
+ }
+ c--; /* c = num. returns */
+ if (c == LUA_MULTRET) {
+ check(checkopenop(pt, pc));
+ }
+ else if (c != 0)
+ checkreg(pt, a+c-1);
+ if (reg >= a) last = pc; /* affect all registers above base */
+ break;
+ }
+ case OP_RETURN: {
+ b--; /* b = num. returns */
+ if (b > 0) checkreg(pt, a+b-1);
+ break;
+ }
+ case OP_SETLIST: {
+ checkreg(pt, a + (b&(LFIELDS_PER_FLUSH-1)) + 1);
+ break;
+ }
+ case OP_CLOSURE: {
+ int nup;
+ check(b < pt->sizep);
+ nup = pt->p[b]->nups;
+ check(pc + nup < pt->sizecode);
+ for (; nup>0; nup--) {
+ OpCode op1 = GET_OPCODE(pt->code[pc+nup]);
+ check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
+ }
+ break;
+ }
+ default: break;
+ }
+ }
+ return pt->code[last];
+}
+
+#undef check
+#undef checkjump
+#undef checkreg
+
+/* }====================================================== */
+
+
+int luaG_checkcode (const Proto *pt) {
+ return luaG_symbexec(pt, pt->sizecode, NO_REG);
+}
+
+
+static const char *kname (Proto *p, int c) {
+ c = c - MAXSTACK;
+ if (c >= 0 && ttisstring(&p->k[c]))
+ return svalue(&p->k[c]);
+ else
+ return "?";
+}
+
+
+static const char *getobjname (CallInfo *ci, int stackpos, const char **name) {
+ if (isLua(ci)) { /* a Lua function? */
+ Proto *p = ci_func(ci)->l.p;
+ int pc = currentpc(ci);
+ Instruction i;
+ *name = luaF_getlocalname(p, stackpos+1, pc);
+ if (*name) /* is a local? */
+ return "local";
+ i = luaG_symbexec(p, pc, stackpos); /* try symbolic execution */
+ lua_assert(pc != -1);
+ switch (GET_OPCODE(i)) {
+ case OP_GETGLOBAL: {
+ int g = GETARG_Bx(i); /* global index */
+ lua_assert(ttisstring(&p->k[g]));
+ *name = svalue(&p->k[g]);
+ return "global";
+ }
+ case OP_MOVE: {
+ int a = GETARG_A(i);
+ int b = GETARG_B(i); /* move from `b' to `a' */
+ if (b < a)
+ return getobjname(ci, b, name); /* get name for `b' */
+ break;
+ }
+ case OP_GETTABLE: {
+ int k = GETARG_C(i); /* key index */
+ *name = kname(p, k);
+ return "field";
+ }
+ case OP_SELF: {
+ int k = GETARG_C(i); /* key index */
+ *name = kname(p, k);
+ return "method";
+ }
+ default: break;
+ }
+ }
+ return NULL; /* no useful name found */
+}
+
+
+static const char *getfuncname (CallInfo *ci, const char **name) {
+ Instruction i;
+ if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1))
+ return NULL; /* calling function is not Lua (or is unknown) */
+ ci--; /* calling function */
+ i = ci_func(ci)->l.p->code[currentpc(ci)];
+ if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL)
+ return getobjname(ci, GETARG_A(i), name);
+ else
+ return NULL; /* no useful name can be found */
+}
+
+
+/* only ANSI way to check whether a pointer points to an array */
+static int isinstack (CallInfo *ci, const TObject *o) {
+ StkId p;
+ for (p = ci->base; p < ci->top; p++)
+ if (o == p) return 1;
+ return 0;
+}
+
+
+void luaG_typeerror (lua_State *L, const TObject *o, const char *op) {
+ const char *name = NULL;
+ const char *t = luaT_typenames[ttype(o)];
+ const char *kind = (isinstack(L->ci, o)) ?
+ getobjname(L->ci, o - L->base, &name) : NULL;
+ if (kind)
+ luaG_runerror(L, "attempt to %s %s `%s' (a %s value)",
+ op, kind, name, t);
+ else
+ luaG_runerror(L, "attempt to %s a %s value", op, t);
+}
+
+
+void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
+ if (ttisstring(p1)) p1 = p2;
+ lua_assert(!ttisstring(p1));
+ luaG_typeerror(L, p1, "concatenate");
+}
+
+
+void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2) {
+ TObject temp;
+ if (luaV_tonumber(p1, &temp) == NULL)
+ p2 = p1; /* first operand is wrong */
+ luaG_typeerror(L, p2, "perform arithmetic on");
+}
+
+
+int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) {
+ const char *t1 = luaT_typenames[ttype(p1)];
+ const char *t2 = luaT_typenames[ttype(p2)];
+ if (t1[2] == t2[2])
+ luaG_runerror(L, "attempt to compare two %s values", t1);
+ else
+ luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
+ return 0;
+}
+
+
+static void addinfo (lua_State *L, const char *msg) {
+ CallInfo *ci = L->ci;
+ if (isLua(ci)) { /* is Lua code? */
+ char buff[LUA_IDSIZE]; /* add file:line information */
+ int line = currentline(ci);
+ luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
+ luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
+ }
+}
+
+
+void luaG_errormsg (lua_State *L) {
+ if (L->errfunc != 0) { /* is there an error handling function? */
+ StkId errfunc = restorestack(L, L->errfunc);
+ if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
+ setobjs2s(L->top, L->top - 1); /* move argument */
+ setobjs2s(L->top - 1, errfunc); /* push function */
+ incr_top(L);
+ luaD_call(L, L->top - 2, 1); /* call it */
+ }
+ luaD_throw(L, LUA_ERRRUN);
+}
+
+
+void luaG_runerror (lua_State *L, const char *fmt, ...) {
+ va_list argp;
+ va_start(argp, fmt);
+ addinfo(L, luaO_pushvfstring(L, fmt, argp));
+ va_end(argp);
+ luaG_errormsg(L);
+}
+
diff --git a/lib/lua/src/ldo.c b/lib/lua/src/ldo.c
index 8c64852..aa4cf70 100644
--- a/lib/lua/src/ldo.c
+++ b/lib/lua/src/ldo.c
@@ -1,465 +1,465 @@
-/*
-** $Id: ldo.c,v 1.4 2004-11-27 21:35:20 pixel Exp $
-** Stack and Call structure of Lua
-** See Copyright Notice in lua.h
-*/
-
-
-#include <setjmp.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define ldo_c
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lparser.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-#include "lundump.h"
-#include "lvm.h"
-#include "lzio.h"
-
-
-
-
-/*
-** {======================================================
-** Error-recovery functions (based on long jumps)
-** =======================================================
-*/
-
-
-/* chain list of long jump buffers */
-struct lua_longjmp {
- struct lua_longjmp *previous;
- jmp_buf b;
- volatile int status; /* error code */
-};
-
-
-static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
- switch (errcode) {
- case LUA_ERRMEM: {
- setsvalue2s(oldtop, luaS_new(L, MEMERRMSG));
- break;
- }
- case LUA_ERRERR: {
- setsvalue2s(oldtop, luaS_new(L, "error in error handling"));
- break;
- }
- case LUA_ERRSYNTAX:
- case LUA_ERRRUN: {
- setobjs2s(oldtop, L->top - 1); /* error message on current top */
- break;
- }
- }
- L->top = oldtop + 1;
-}
-
-
-void luaD_throw (lua_State *L, int errcode) {
- if (L->errorJmp) {
- L->errorJmp->status = errcode;
- longjmp(L->errorJmp->b, 1);
- }
- else {
- G(L)->panic(L);
- exit(EXIT_FAILURE);
- }
-}
-
-
-int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
- struct lua_longjmp lj;
- lj.status = 0;
- lj.previous = L->errorJmp; /* chain new error handler */
- L->errorJmp = &lj;
- if (setjmp(lj.b) == 0)
- (*f)(L, ud);
- L->errorJmp = lj.previous; /* restore old error handler */
- return lj.status;
-}
-
-
-static void restore_stack_limit (lua_State *L) {
- L->stack_last = L->stack+L->stacksize-1;
- if (L->size_ci > LUA_MAXCALLS) { /* there was an overflow? */
- int inuse = (L->ci - L->base_ci);
- if (inuse + 1 < LUA_MAXCALLS) /* can `undo' overflow? */
- luaD_reallocCI(L, LUA_MAXCALLS);
- }
-}
-
-/* }====================================================== */
-
-
-static void correctstack (lua_State *L, TObject *oldstack) {
- CallInfo *ci;
- GCObject *up;
- L->top = (L->top - oldstack) + L->stack;
- for (up = L->openupval; up != NULL; up = up->gch.next)
- gcotouv(up)->v = (gcotouv(up)->v - oldstack) + L->stack;
- for (ci = L->base_ci; ci <= L->ci; ci++) {
- ci->top = (ci->top - oldstack) + L->stack;
- ci->base = (ci->base - oldstack) + L->stack;
- }
- L->base = L->ci->base;
-}
-
-
-void luaD_reallocstack (lua_State *L, int newsize) {
- TObject *oldstack = L->stack;
- luaM_reallocvector(L, L->stack, L->stacksize, newsize, TObject);
- L->stacksize = newsize;
- L->stack_last = L->stack+newsize-1-EXTRA_STACK;
- correctstack(L, oldstack);
-}
-
-
-void luaD_reallocCI (lua_State *L, int newsize) {
- CallInfo *oldci = L->base_ci;
- luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
- L->size_ci = cast(unsigned short, newsize);
- L->ci = (L->ci - oldci) + L->base_ci;
- L->end_ci = L->base_ci + L->size_ci;
-}
-
-
-void luaD_growstack (lua_State *L, int n) {
- if (n <= L->stacksize) /* double size is enough? */
- luaD_reallocstack(L, 2*L->stacksize);
- else
- luaD_reallocstack(L, L->stacksize + n + EXTRA_STACK);
-}
-
-
-static void luaD_growCI (lua_State *L) {
- if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */
- luaD_throw(L, LUA_ERRERR);
- else {
- luaD_reallocCI(L, 2*L->size_ci);
- if (L->size_ci > LUA_MAXCALLS)
- luaG_runerror(L, "stack overflow");
- }
-}
-
-
-void luaD_callhook (lua_State *L, int event, int line) {
- lua_Hook hook = L->hook;
- if (hook && L->allowhook) {
- ptrdiff_t top = savestack(L, L->top);
- ptrdiff_t ci_top = savestack(L, L->ci->top);
- lua_Debug ar;
- ar.event = event;
- ar.currentline = line;
- if (event == LUA_HOOKTAILRET)
- ar.i_ci = 0; /* tail call; no debug information about it */
- else
- ar.i_ci = L->ci - L->base_ci;
- luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
- L->ci->top = L->top + LUA_MINSTACK;
- L->allowhook = 0; /* cannot call hooks inside a hook */
- lua_unlock(L);
- (*hook)(L, &ar);
- lua_lock(L);
- lua_assert(!L->allowhook);
- L->allowhook = 1;
- L->ci->top = restorestack(L, ci_top);
- L->top = restorestack(L, top);
- }
-}
-
-
-static void adjust_varargs (lua_State *L, int nfixargs, StkId base) {
- int i;
- Table *htab;
- TObject nname;
- int actual = L->top - base; /* actual number of arguments */
- if (actual < nfixargs) {
- luaD_checkstack(L, nfixargs - actual);
- for (; actual < nfixargs; ++actual)
- setnilvalue(L->top++);
- }
- actual -= nfixargs; /* number of extra arguments */
- htab = luaH_new(L, actual, 1); /* create `arg' table */
- for (i=0; i<actual; i++) /* put extra arguments into `arg' table */
- setobj2n(luaH_setnum(L, htab, i+1), L->top - actual + i);
- /* store counter in field `n' */
- setsvalue(&nname, luaS_newliteral(L, "n"));
- setnvalue(luaH_set(L, htab, &nname), cast(lua_Number, actual));
- L->top -= actual; /* remove extra elements from the stack */
- sethvalue(L->top, htab);
- incr_top(L);
-}
-
-
-static StkId tryfuncTM (lua_State *L, StkId func) {
- const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
- StkId p;
- ptrdiff_t funcr = savestack(L, func);
- if (!ttisfunction(tm))
- luaG_typeerror(L, func, "call");
- /* Open a hole inside the stack at `func' */
- for (p = L->top; p > func; p--) setobjs2s(p, p-1);
- incr_top(L);
- func = restorestack(L, funcr); /* previous call may change stack */
- setobj2s(func, tm); /* tag method is the new function to be called */
- return func;
-}
-
-
-StkId luaD_precall (lua_State *L, StkId func) {
- LClosure *cl;
- ptrdiff_t funcr = savestack(L, func);
- if (!ttisfunction(func)) /* `func' is not a function? */
- func = tryfuncTM(L, func); /* check the `function' tag method */
- if (L->ci + 1 == L->end_ci) luaD_growCI(L);
- else condhardstacktests(luaD_reallocCI(L, L->size_ci));
- cl = &clvalue(func)->l;
- if (!cl->isC) { /* Lua function? prepare its call */
- CallInfo *ci;
- Proto *p = cl->p;
- if (p->is_vararg) /* varargs? */
- adjust_varargs(L, p->numparams, func+1);
- luaD_checkstack(L, p->maxstacksize);
- ci = ++L->ci; /* now `enter' new function */
- L->base = L->ci->base = restorestack(L, funcr) + 1;
- ci->top = L->base + p->maxstacksize;
- ci->u.l.savedpc = p->code; /* starting point */
- ci->u.l.tailcalls = 0;
- ci->state = CI_SAVEDPC;
- while (L->top < ci->top)
- setnilvalue(L->top++);
- L->top = ci->top;
- return NULL;
- }
- else { /* if is a C function, call it */
- CallInfo *ci;
- int n;
- luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
- ci = ++L->ci; /* now `enter' new function */
- L->base = L->ci->base = restorestack(L, funcr) + 1;
- ci->top = L->top + LUA_MINSTACK;
- ci->state = CI_C; /* a C function */
- if (L->hookmask & LUA_MASKCALL)
- luaD_callhook(L, LUA_HOOKCALL, -1);
- lua_unlock(L);
-#ifdef LUA_COMPATUPVALUES
- lua_pushupvalues(L);
-#endif
- n = (*clvalue(L->base - 1)->c.f)(L); /* do the actual call */
- lua_lock(L);
- return L->top - n;
- }
-}
-
-
-static StkId callrethooks (lua_State *L, StkId firstResult) {
- ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
- luaD_callhook(L, LUA_HOOKRET, -1);
- if (!(L->ci->state & CI_C)) { /* Lua function? */
- while (L->ci->u.l.tailcalls--) /* call hook for eventual tail calls */
- luaD_callhook(L, LUA_HOOKTAILRET, -1);
- }
- return restorestack(L, fr);
-}
-
-
-void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
- StkId res;
- if (L->hookmask & LUA_MASKRET)
- firstResult = callrethooks(L, firstResult);
- res = L->base - 1; /* res == final position of 1st result */
- L->ci--;
- L->base = L->ci->base; /* restore base */
- /* move results to correct place */
- while (wanted != 0 && firstResult < L->top) {
- setobjs2s(res++, firstResult++);
- wanted--;
- }
- while (wanted-- > 0)
- setnilvalue(res++);
- L->top = res;
-}
-
-
-/*
-** Call a function (C or Lua). The function to be called is at *func.
-** The arguments are on the stack, right after the function.
-** When returns, all the results are on the stack, starting at the original
-** function position.
-*/
-void luaD_call (lua_State *L, StkId func, int nResults) {
- StkId firstResult;
- lua_assert(!(L->ci->state & CI_CALLING));
- if (++L->nCcalls >= LUA_MAXCCALLS) {
- if (L->nCcalls == LUA_MAXCCALLS)
- luaG_runerror(L, "C stack overflow");
- else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3)))
- luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
- }
- firstResult = luaD_precall(L, func);
- if (firstResult == NULL) /* is a Lua function? */
- firstResult = luaV_execute(L); /* call it */
- luaD_poscall(L, nResults, firstResult);
- L->nCcalls--;
- luaC_checkGC(L);
-}
-
-
-static void resume (lua_State *L, void *ud) {
- StkId firstResult;
- int nargs = *cast(int *, ud);
- CallInfo *ci = L->ci;
- if (ci == L->base_ci) { /* no activation record? */
- if (nargs >= L->top - L->base)
- luaG_runerror(L, "cannot resume dead coroutine");
- luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */
- }
- else if (ci->state & CI_YIELD) { /* inside a yield? */
- if (ci->state & CI_C) { /* `common' yield? */
- /* finish interrupted execution of `OP_CALL' */
- int nresults;
- lua_assert((ci-1)->state & CI_SAVEDPC);
- lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL ||
- GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL);
- nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1;
- luaD_poscall(L, nresults, L->top - nargs); /* complete it */
- if (nresults >= 0) L->top = L->ci->top;
- }
- else { /* yielded inside a hook: just continue its execution */
- ci->state &= ~CI_YIELD;
- }
- }
- else
- luaG_runerror(L, "cannot resume non-suspended coroutine");
- firstResult = luaV_execute(L);
- if (firstResult != NULL) /* return? */
- luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */
-}
-
-
-LUA_API int lua_resume (lua_State *L, int nargs) {
- int status;
- lu_byte old_allowhooks;
- lua_lock(L);
- old_allowhooks = L->allowhook;
- lua_assert(L->errfunc == 0 && L->nCcalls == 0);
- status = luaD_rawrunprotected(L, resume, &nargs);
- if (status != 0) { /* error? */
- L->ci = L->base_ci; /* go back to initial level */
- L->base = L->ci->base;
- L->nCcalls = 0;
- luaF_close(L, L->base); /* close eventual pending closures */
- seterrorobj(L, status, L->base);
- L->allowhook = old_allowhooks;
- restore_stack_limit(L);
- }
- lua_unlock(L);
- return status;
-}
-
-
-LUA_API int lua_yield (lua_State *L, int nresults) {
- CallInfo *ci;
- lua_lock(L);
- ci = L->ci;
- if (L->nCcalls > 0)
- luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
- if (ci->state & CI_C) { /* usual yield */
- if ((ci-1)->state & CI_C)
- luaG_runerror(L, "cannot yield a C function");
- if (L->top - nresults > L->base) { /* is there garbage in the stack? */
- int i;
- for (i=0; i<nresults; i++) /* move down results */
- setobjs2s(L->base + i, L->top - nresults + i);
- L->top = L->base + nresults;
- }
- } /* else it's an yield inside a hook: nothing to do */
- ci->state |= CI_YIELD;
- lua_unlock(L);
- return -1;
-}
-
-LUA_API void lua_break (lua_State *L) {
- CallInfo * ci;
- lua_lock(L);
- ci = L->ci;
- ci->state |= CI_BREAK;
- lua_unlock(L);
-}
-
-int luaD_pcall (lua_State *L, Pfunc func, void *u,
- ptrdiff_t old_top, ptrdiff_t ef) {
- int status;
- unsigned short oldnCcalls = L->nCcalls;
- ptrdiff_t old_ci = saveci(L, L->ci);
- lu_byte old_allowhooks = L->allowhook;
- ptrdiff_t old_errfunc = L->errfunc;
- L->errfunc = ef;
- status = luaD_rawrunprotected(L, func, u);
- if (status != 0) { /* an error occurred? */
- StkId oldtop = restorestack(L, old_top);
- luaF_close(L, oldtop); /* close eventual pending closures */
- seterrorobj(L, status, oldtop);
- L->nCcalls = oldnCcalls;
- L->ci = restoreci(L, old_ci);
- L->base = L->ci->base;
- L->allowhook = old_allowhooks;
- restore_stack_limit(L);
- }
- L->errfunc = old_errfunc;
- return status;
-}
-
-
-
-/*
-** Execute a protected parser.
-*/
-struct SParser { /* data to `f_parser' */
- ZIO *z;
- Mbuffer buff; /* buffer to be used by the scanner */
- int bin;
-};
-
-static void f_parser (lua_State *L, void *ud) {
- struct SParser *p;
- Proto *tf;
- Closure *cl;
- luaC_checkGC(L);
- p = cast(struct SParser *, ud);
- tf = p->bin ? luaU_undump(L, p->z, &p->buff) : luaY_parser(L, p->z, &p->buff);
- cl = luaF_newLclosure(L, 0, gt(L));
- cl->l.p = tf;
- setclvalue(L->top, cl);
- incr_top(L);
-}
-
-
-int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
- struct SParser p;
- int status;
- ptrdiff_t oldtopr = savestack(L, L->top); /* save current top */
- p.z = z; p.bin = bin;
- luaZ_initbuffer(L, &p.buff);
- status = luaD_rawrunprotected(L, f_parser, &p);
- luaZ_freebuffer(L, &p.buff);
- if (status != 0) { /* error? */
- StkId oldtop = restorestack(L, oldtopr);
- seterrorobj(L, status, oldtop);
- }
- return status;
-}
-
-
+/*
+** $Id: ldo.c,v 1.5 2004-11-27 21:46:07 pixel Exp $
+** Stack and Call structure of Lua
+** See Copyright Notice in lua.h
+*/
+
+
+#include <setjmp.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ldo_c
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lparser.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+#include "lundump.h"
+#include "lvm.h"
+#include "lzio.h"
+
+
+
+
+/*
+** {======================================================
+** Error-recovery functions (based on long jumps)
+** =======================================================
+*/
+
+
+/* chain list of long jump buffers */
+struct lua_longjmp {
+ struct lua_longjmp *previous;
+ jmp_buf b;
+ volatile int status; /* error code */
+};
+
+
+static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
+ switch (errcode) {
+ case LUA_ERRMEM: {
+ setsvalue2s(oldtop, luaS_new(L, MEMERRMSG));
+ break;
+ }
+ case LUA_ERRERR: {
+ setsvalue2s(oldtop, luaS_new(L, "error in error handling"));
+ break;
+ }
+ case LUA_ERRSYNTAX:
+ case LUA_ERRRUN: {
+ setobjs2s(oldtop, L->top - 1); /* error message on current top */
+ break;
+ }
+ }
+ L->top = oldtop + 1;
+}
+
+
+void luaD_throw (lua_State *L, int errcode) {
+ if (L->errorJmp) {
+ L->errorJmp->status = errcode;
+ longjmp(L->errorJmp->b, 1);
+ }
+ else {
+ G(L)->panic(L);
+ exit(EXIT_FAILURE);
+ }
+}
+
+
+int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
+ struct lua_longjmp lj;
+ lj.status = 0;
+ lj.previous = L->errorJmp; /* chain new error handler */
+ L->errorJmp = &lj;
+ if (setjmp(lj.b) == 0)
+ (*f)(L, ud);
+ L->errorJmp = lj.previous; /* restore old error handler */
+ return lj.status;
+}
+
+
+static void restore_stack_limit (lua_State *L) {
+ L->stack_last = L->stack+L->stacksize-1;
+ if (L->size_ci > LUA_MAXCALLS) { /* there was an overflow? */
+ int inuse = (L->ci - L->base_ci);
+ if (inuse + 1 < LUA_MAXCALLS) /* can `undo' overflow? */
+ luaD_reallocCI(L, LUA_MAXCALLS);
+ }
+}
+
+/* }====================================================== */
+
+
+static void correctstack (lua_State *L, TObject *oldstack) {
+ CallInfo *ci;
+ GCObject *up;
+ L->top = (L->top - oldstack) + L->stack;
+ for (up = L->openupval; up != NULL; up = up->gch.next)
+ gcotouv(up)->v = (gcotouv(up)->v - oldstack) + L->stack;
+ for (ci = L->base_ci; ci <= L->ci; ci++) {
+ ci->top = (ci->top - oldstack) + L->stack;
+ ci->base = (ci->base - oldstack) + L->stack;
+ }
+ L->base = L->ci->base;
+}
+
+
+void luaD_reallocstack (lua_State *L, int newsize) {
+ TObject *oldstack = L->stack;
+ luaM_reallocvector(L, L->stack, L->stacksize, newsize, TObject);
+ L->stacksize = newsize;
+ L->stack_last = L->stack+newsize-1-EXTRA_STACK;
+ correctstack(L, oldstack);
+}
+
+
+void luaD_reallocCI (lua_State *L, int newsize) {
+ CallInfo *oldci = L->base_ci;
+ luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
+ L->size_ci = cast(unsigned short, newsize);
+ L->ci = (L->ci - oldci) + L->base_ci;
+ L->end_ci = L->base_ci + L->size_ci;
+}
+
+
+void luaD_growstack (lua_State *L, int n) {
+ if (n <= L->stacksize) /* double size is enough? */
+ luaD_reallocstack(L, 2*L->stacksize);
+ else
+ luaD_reallocstack(L, L->stacksize + n + EXTRA_STACK);
+}
+
+
+static void luaD_growCI (lua_State *L) {
+ if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */
+ luaD_throw(L, LUA_ERRERR);
+ else {
+ luaD_reallocCI(L, 2*L->size_ci);
+ if (L->size_ci > LUA_MAXCALLS)
+ luaG_runerror(L, "stack overflow");
+ }
+}
+
+
+void luaD_callhook (lua_State *L, int event, int line) {
+ lua_Hook hook = L->hook;
+ if (hook && L->allowhook) {
+ ptrdiff_t top = savestack(L, L->top);
+ ptrdiff_t ci_top = savestack(L, L->ci->top);
+ lua_Debug ar;
+ ar.event = event;
+ ar.currentline = line;
+ if (event == LUA_HOOKTAILRET)
+ ar.i_ci = 0; /* tail call; no debug information about it */
+ else
+ ar.i_ci = L->ci - L->base_ci;
+ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
+ L->ci->top = L->top + LUA_MINSTACK;
+ L->allowhook = 0; /* cannot call hooks inside a hook */
+ lua_unlock(L);
+ (*hook)(L, &ar);
+ lua_lock(L);
+ lua_assert(!L->allowhook);
+ L->allowhook = 1;
+ L->ci->top = restorestack(L, ci_top);
+ L->top = restorestack(L, top);
+ }
+}
+
+
+static void adjust_varargs (lua_State *L, int nfixargs, StkId base) {
+ int i;
+ Table *htab;
+ TObject nname;
+ int actual = L->top - base; /* actual number of arguments */
+ if (actual < nfixargs) {
+ luaD_checkstack(L, nfixargs - actual);
+ for (; actual < nfixargs; ++actual)
+ setnilvalue(L->top++);
+ }
+ actual -= nfixargs; /* number of extra arguments */
+ htab = luaH_new(L, actual, 1); /* create `arg' table */
+ for (i=0; i<actual; i++) /* put extra arguments into `arg' table */
+ setobj2n(luaH_setnum(L, htab, i+1), L->top - actual + i);
+ /* store counter in field `n' */
+ setsvalue(&nname, luaS_newliteral(L, "n"));
+ setnvalue(luaH_set(L, htab, &nname), cast(lua_Number, actual));
+ L->top -= actual; /* remove extra elements from the stack */
+ sethvalue(L->top, htab);
+ incr_top(L);
+}
+
+
+static StkId tryfuncTM (lua_State *L, StkId func) {
+ const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
+ StkId p;
+ ptrdiff_t funcr = savestack(L, func);
+ if (!ttisfunction(tm))
+ luaG_typeerror(L, func, "call");
+ /* Open a hole inside the stack at `func' */
+ for (p = L->top; p > func; p--) setobjs2s(p, p-1);
+ incr_top(L);
+ func = restorestack(L, funcr); /* previous call may change stack */
+ setobj2s(func, tm); /* tag method is the new function to be called */
+ return func;
+}
+
+
+StkId luaD_precall (lua_State *L, StkId func) {
+ LClosure *cl;
+ ptrdiff_t funcr = savestack(L, func);
+ if (!ttisfunction(func)) /* `func' is not a function? */
+ func = tryfuncTM(L, func); /* check the `function' tag method */
+ if (L->ci + 1 == L->end_ci) luaD_growCI(L);
+ else condhardstacktests(luaD_reallocCI(L, L->size_ci));
+ cl = &clvalue(func)->l;
+ if (!cl->isC) { /* Lua function? prepare its call */
+ CallInfo *ci;
+ Proto *p = cl->p;
+ if (p->is_vararg) /* varargs? */
+ adjust_varargs(L, p->numparams, func+1);
+ luaD_checkstack(L, p->maxstacksize);
+ ci = ++L->ci; /* now `enter' new function */
+ L->base = L->ci->base = restorestack(L, funcr) + 1;
+ ci->top = L->base + p->maxstacksize;
+ ci->u.l.savedpc = p->code; /* starting point */
+ ci->u.l.tailcalls = 0;
+ ci->state = CI_SAVEDPC;
+ while (L->top < ci->top)
+ setnilvalue(L->top++);
+ L->top = ci->top;
+ return NULL;
+ }
+ else { /* if is a C function, call it */
+ CallInfo *ci;
+ int n;
+ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
+ ci = ++L->ci; /* now `enter' new function */
+ L->base = L->ci->base = restorestack(L, funcr) + 1;
+ ci->top = L->top + LUA_MINSTACK;
+ ci->state = CI_C; /* a C function */
+ if (L->hookmask & LUA_MASKCALL)
+ luaD_callhook(L, LUA_HOOKCALL, -1);
+ lua_unlock(L);
+#ifdef LUA_COMPATUPVALUES
+ lua_pushupvalues(L);
+#endif
+ n = (*clvalue(L->base - 1)->c.f)(L); /* do the actual call */
+ lua_lock(L);
+ return L->top - n;
+ }
+}
+
+
+static StkId callrethooks (lua_State *L, StkId firstResult) {
+ ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
+ luaD_callhook(L, LUA_HOOKRET, -1);
+ if (!(L->ci->state & CI_C)) { /* Lua function? */
+ while (L->ci->u.l.tailcalls--) /* call hook for eventual tail calls */
+ luaD_callhook(L, LUA_HOOKTAILRET, -1);
+ }
+ return restorestack(L, fr);
+}
+
+
+void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
+ StkId res;
+ if (L->hookmask & LUA_MASKRET)
+ firstResult = callrethooks(L, firstResult);
+ res = L->base - 1; /* res == final position of 1st result */
+ L->ci--;
+ L->base = L->ci->base; /* restore base */
+ /* move results to correct place */
+ while (wanted != 0 && firstResult < L->top) {
+ setobjs2s(res++, firstResult++);
+ wanted--;
+ }
+ while (wanted-- > 0)
+ setnilvalue(res++);
+ L->top = res;
+}
+
+
+/*
+** Call a function (C or Lua). The function to be called is at *func.
+** The arguments are on the stack, right after the function.
+** When returns, all the results are on the stack, starting at the original
+** function position.
+*/
+void luaD_call (lua_State *L, StkId func, int nResults) {
+ StkId firstResult;
+ lua_assert(!(L->ci->state & CI_CALLING));
+ if (++L->nCcalls >= LUA_MAXCCALLS) {
+ if (L->nCcalls == LUA_MAXCCALLS)
+ luaG_runerror(L, "C stack overflow");
+ else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3)))
+ luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
+ }
+ firstResult = luaD_precall(L, func);
+ if (firstResult == NULL) /* is a Lua function? */
+ firstResult = luaV_execute(L); /* call it */
+ luaD_poscall(L, nResults, firstResult);
+ L->nCcalls--;
+ luaC_checkGC(L);
+}
+
+
+static void resume (lua_State *L, void *ud) {
+ StkId firstResult;
+ int nargs = *cast(int *, ud);
+ CallInfo *ci = L->ci;
+ if (ci == L->base_ci) { /* no activation record? */
+ if (nargs >= L->top - L->base)
+ luaG_runerror(L, "cannot resume dead coroutine");
+ luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */
+ }
+ else if (ci->state & CI_YIELD) { /* inside a yield? */
+ if (ci->state & CI_C) { /* `common' yield? */
+ /* finish interrupted execution of `OP_CALL' */
+ int nresults;
+ lua_assert((ci-1)->state & CI_SAVEDPC);
+ lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL ||
+ GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL);
+ nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1;
+ luaD_poscall(L, nresults, L->top - nargs); /* complete it */
+ if (nresults >= 0) L->top = L->ci->top;
+ }
+ else { /* yielded inside a hook: just continue its execution */
+ ci->state &= ~CI_YIELD;
+ }
+ }
+ else
+ luaG_runerror(L, "cannot resume non-suspended coroutine");
+ firstResult = luaV_execute(L);
+ if (firstResult != NULL) /* return? */
+ luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */
+}
+
+
+LUA_API int lua_resume (lua_State *L, int nargs) {
+ int status;
+ lu_byte old_allowhooks;
+ lua_lock(L);
+ old_allowhooks = L->allowhook;
+ lua_assert(L->errfunc == 0 && L->nCcalls == 0);
+ status = luaD_rawrunprotected(L, resume, &nargs);
+ if (status != 0) { /* error? */
+ L->ci = L->base_ci; /* go back to initial level */
+ L->base = L->ci->base;
+ L->nCcalls = 0;
+ luaF_close(L, L->base); /* close eventual pending closures */
+ seterrorobj(L, status, L->base);
+ L->allowhook = old_allowhooks;
+ restore_stack_limit(L);
+ }
+ lua_unlock(L);
+ return status;
+}
+
+
+LUA_API int lua_yield (lua_State *L, int nresults) {
+ CallInfo *ci;
+ lua_lock(L);
+ ci = L->ci;
+ if (L->nCcalls > 0)
+ luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
+ if (ci->state & CI_C) { /* usual yield */
+ if ((ci-1)->state & CI_C)
+ luaG_runerror(L, "cannot yield a C function");
+ if (L->top - nresults > L->base) { /* is there garbage in the stack? */
+ int i;
+ for (i=0; i<nresults; i++) /* move down results */
+ setobjs2s(L->base + i, L->top - nresults + i);
+ L->top = L->base + nresults;
+ }
+ } /* else it's an yield inside a hook: nothing to do */
+ ci->state |= CI_YIELD;
+ lua_unlock(L);
+ return -1;
+}
+
+LUA_API void lua_break (lua_State *L) {
+ CallInfo * ci;
+ lua_lock(L);
+ ci = L->ci;
+ ci->state |= CI_BREAK;
+ lua_unlock(L);
+}
+
+int luaD_pcall (lua_State *L, Pfunc func, void *u,
+ ptrdiff_t old_top, ptrdiff_t ef) {
+ int status;
+ unsigned short oldnCcalls = L->nCcalls;
+ ptrdiff_t old_ci = saveci(L, L->ci);
+ lu_byte old_allowhooks = L->allowhook;
+ ptrdiff_t old_errfunc = L->errfunc;
+ L->errfunc = ef;
+ status = luaD_rawrunprotected(L, func, u);
+ if (status != 0) { /* an error occurred? */
+ StkId oldtop = restorestack(L, old_top);
+ luaF_close(L, oldtop); /* close eventual pending closures */
+ seterrorobj(L, status, oldtop);
+ L->nCcalls = oldnCcalls;
+ L->ci = restoreci(L, old_ci);
+ L->base = L->ci->base;
+ L->allowhook = old_allowhooks;
+ restore_stack_limit(L);
+ }
+ L->errfunc = old_errfunc;
+ return status;
+}
+
+
+
+/*
+** Execute a protected parser.
+*/
+struct SParser { /* data to `f_parser' */
+ ZIO *z;
+ Mbuffer buff; /* buffer to be used by the scanner */
+ int bin;
+};
+
+static void f_parser (lua_State *L, void *ud) {
+ struct SParser *p;
+ Proto *tf;
+ Closure *cl;
+ luaC_checkGC(L);
+ p = cast(struct SParser *, ud);
+ tf = p->bin ? luaU_undump(L, p->z, &p->buff) : luaY_parser(L, p->z, &p->buff);
+ cl = luaF_newLclosure(L, 0, gt(L));
+ cl->l.p = tf;
+ setclvalue(L->top, cl);
+ incr_top(L);
+}
+
+
+int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
+ struct SParser p;
+ int status;
+ ptrdiff_t oldtopr = savestack(L, L->top); /* save current top */
+ p.z = z; p.bin = bin;
+ luaZ_initbuffer(L, &p.buff);
+ status = luaD_rawrunprotected(L, f_parser, &p);
+ luaZ_freebuffer(L, &p.buff);
+ if (status != 0) { /* error? */
+ StkId oldtop = restorestack(L, oldtopr);
+ seterrorobj(L, status, oldtop);
+ }
+ return status;
+}
+
+
diff --git a/lib/lua/src/ldump.c b/lib/lua/src/ldump.c
index 47a2140..2bcfd5d 100644
--- a/lib/lua/src/ldump.c
+++ b/lib/lua/src/ldump.c
@@ -1,170 +1,170 @@
-/*
-** $Id: ldump.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** save bytecodes
-** See Copyright Notice in lua.h
-*/
-
-#include <stddef.h>
-
-#define ldump_c
-
-#include "lua.h"
-
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lstate.h"
-#include "lundump.h"
-
-#define DumpVector(b,n,size,D) DumpBlock(b,(n)*(size),D)
-#define DumpLiteral(s,D) DumpBlock("" s,(sizeof(s))-1,D)
-
-typedef struct {
- lua_State* L;
- lua_Chunkwriter write;
- void* data;
-} DumpState;
-
-static void DumpBlock(const void* b, size_t size, DumpState* D)
-{
- lua_unlock(D->L);
- (*D->write)(D->L,b,size,D->data);
- lua_lock(D->L);
-}
-
-static void DumpByte(int y, DumpState* D)
-{
- char x=(char)y;
- DumpBlock(&x,sizeof(x),D);
-}
-
-static void DumpInt(int x, DumpState* D)
-{
- DumpBlock(&x,sizeof(x),D);
-}
-
-static void DumpSize(size_t x, DumpState* D)
-{
- DumpBlock(&x,sizeof(x),D);
-}
-
-static void DumpNumber(lua_Number x, DumpState* D)
-{
- DumpBlock(&x,sizeof(x),D);
-}
-
-static void DumpString(TString* s, DumpState* D)
-{
- if (s==NULL || getstr(s)==NULL)
- DumpSize(0,D);
- else
- {
- size_t size=s->tsv.len+1; /* include trailing '\0' */
- DumpSize(size,D);
- DumpBlock(getstr(s),size,D);
- }
-}
-
-static void DumpCode(const Proto* f, DumpState* D)
-{
- DumpInt(f->sizecode,D);
- DumpVector(f->code,f->sizecode,sizeof(*f->code),D);
-}
-
-static void DumpLocals(const Proto* f, DumpState* D)
-{
- int i,n=f->sizelocvars;
- DumpInt(n,D);
- for (i=0; i<n; i++)
- {
- DumpString(f->locvars[i].varname,D);
- DumpInt(f->locvars[i].startpc,D);
- DumpInt(f->locvars[i].endpc,D);
- }
-}
-
-static void DumpLines(const Proto* f, DumpState* D)
-{
- DumpInt(f->sizelineinfo,D);
- DumpVector(f->lineinfo,f->sizelineinfo,sizeof(*f->lineinfo),D);
-}
-
-static void DumpUpvalues(const Proto* f, DumpState* D)
-{
- int i,n=f->sizeupvalues;
- DumpInt(n,D);
- for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
-}
-
-static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
-
-static void DumpConstants(const Proto* f, DumpState* D)
-{
- int i,n;
- DumpInt(n=f->sizek,D);
- for (i=0; i<n; i++)
- {
- const TObject* o=&f->k[i];
- DumpByte(ttype(o),D);
- switch (ttype(o))
- {
- case LUA_TNUMBER:
- DumpNumber(nvalue(o),D);
- break;
- case LUA_TSTRING:
- DumpString(tsvalue(o),D);
- break;
- case LUA_TNIL:
- break;
- default:
- lua_assert(0); /* cannot happen */
- break;
- }
- }
- DumpInt(n=f->sizep,D);
- for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
-}
-
-static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
-{
- DumpString((f->source==p) ? NULL : f->source,D);
- DumpInt(f->lineDefined,D);
- DumpByte(f->nups,D);
- DumpByte(f->numparams,D);
- DumpByte(f->is_vararg,D);
- DumpByte(f->maxstacksize,D);
- DumpLines(f,D);
- DumpLocals(f,D);
- DumpUpvalues(f,D);
- DumpConstants(f,D);
- DumpCode(f,D);
-}
-
-static void DumpHeader(DumpState* D)
-{
- DumpLiteral(LUA_SIGNATURE,D);
- DumpByte(VERSION,D);
- DumpByte(luaU_endianness(),D);
- DumpByte(sizeof(int),D);
- DumpByte(sizeof(size_t),D);
- DumpByte(sizeof(Instruction),D);
- DumpByte(SIZE_OP,D);
- DumpByte(SIZE_A,D);
- DumpByte(SIZE_B,D);
- DumpByte(SIZE_C,D);
- DumpByte(sizeof(lua_Number),D);
- DumpNumber(TEST_NUMBER,D);
-}
-
-/*
-** dump function as precompiled chunk
-*/
-void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data)
-{
- DumpState D;
- D.L=L;
- D.write=w;
- D.data=data;
- DumpHeader(&D);
- DumpFunction(Main,NULL,&D);
-}
-
+/*
+** $Id: ldump.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** save bytecodes
+** See Copyright Notice in lua.h
+*/
+
+#include <stddef.h>
+
+#define ldump_c
+
+#include "lua.h"
+
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lstate.h"
+#include "lundump.h"
+
+#define DumpVector(b,n,size,D) DumpBlock(b,(n)*(size),D)
+#define DumpLiteral(s,D) DumpBlock("" s,(sizeof(s))-1,D)
+
+typedef struct {
+ lua_State* L;
+ lua_Chunkwriter write;
+ void* data;
+} DumpState;
+
+static void DumpBlock(const void* b, size_t size, DumpState* D)
+{
+ lua_unlock(D->L);
+ (*D->write)(D->L,b,size,D->data);
+ lua_lock(D->L);
+}
+
+static void DumpByte(int y, DumpState* D)
+{
+ char x=(char)y;
+ DumpBlock(&x,sizeof(x),D);
+}
+
+static void DumpInt(int x, DumpState* D)
+{
+ DumpBlock(&x,sizeof(x),D);
+}
+
+static void DumpSize(size_t x, DumpState* D)
+{
+ DumpBlock(&x,sizeof(x),D);
+}
+
+static void DumpNumber(lua_Number x, DumpState* D)
+{
+ DumpBlock(&x,sizeof(x),D);
+}
+
+static void DumpString(TString* s, DumpState* D)
+{
+ if (s==NULL || getstr(s)==NULL)
+ DumpSize(0,D);
+ else
+ {
+ size_t size=s->tsv.len+1; /* include trailing '\0' */
+ DumpSize(size,D);
+ DumpBlock(getstr(s),size,D);
+ }
+}
+
+static void DumpCode(const Proto* f, DumpState* D)
+{
+ DumpInt(f->sizecode,D);
+ DumpVector(f->code,f->sizecode,sizeof(*f->code),D);
+}
+
+static void DumpLocals(const Proto* f, DumpState* D)
+{
+ int i,n=f->sizelocvars;
+ DumpInt(n,D);
+ for (i=0; i<n; i++)
+ {
+ DumpString(f->locvars[i].varname,D);
+ DumpInt(f->locvars[i].startpc,D);
+ DumpInt(f->locvars[i].endpc,D);
+ }
+}
+
+static void DumpLines(const Proto* f, DumpState* D)
+{
+ DumpInt(f->sizelineinfo,D);
+ DumpVector(f->lineinfo,f->sizelineinfo,sizeof(*f->lineinfo),D);
+}
+
+static void DumpUpvalues(const Proto* f, DumpState* D)
+{
+ int i,n=f->sizeupvalues;
+ DumpInt(n,D);
+ for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
+}
+
+static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
+
+static void DumpConstants(const Proto* f, DumpState* D)
+{
+ int i,n;
+ DumpInt(n=f->sizek,D);
+ for (i=0; i<n; i++)
+ {
+ const TObject* o=&f->k[i];
+ DumpByte(ttype(o),D);
+ switch (ttype(o))
+ {
+ case LUA_TNUMBER:
+ DumpNumber(nvalue(o),D);
+ break;
+ case LUA_TSTRING:
+ DumpString(tsvalue(o),D);
+ break;
+ case LUA_TNIL:
+ break;
+ default:
+ lua_assert(0); /* cannot happen */
+ break;
+ }
+ }
+ DumpInt(n=f->sizep,D);
+ for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
+}
+
+static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
+{
+ DumpString((f->source==p) ? NULL : f->source,D);
+ DumpInt(f->lineDefined,D);
+ DumpByte(f->nups,D);
+ DumpByte(f->numparams,D);
+ DumpByte(f->is_vararg,D);
+ DumpByte(f->maxstacksize,D);
+ DumpLines(f,D);
+ DumpLocals(f,D);
+ DumpUpvalues(f,D);
+ DumpConstants(f,D);
+ DumpCode(f,D);
+}
+
+static void DumpHeader(DumpState* D)
+{
+ DumpLiteral(LUA_SIGNATURE,D);
+ DumpByte(VERSION,D);
+ DumpByte(luaU_endianness(),D);
+ DumpByte(sizeof(int),D);
+ DumpByte(sizeof(size_t),D);
+ DumpByte(sizeof(Instruction),D);
+ DumpByte(SIZE_OP,D);
+ DumpByte(SIZE_A,D);
+ DumpByte(SIZE_B,D);
+ DumpByte(SIZE_C,D);
+ DumpByte(sizeof(lua_Number),D);
+ DumpNumber(TEST_NUMBER,D);
+}
+
+/*
+** dump function as precompiled chunk
+*/
+void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data)
+{
+ DumpState D;
+ D.L=L;
+ D.write=w;
+ D.data=data;
+ DumpHeader(&D);
+ DumpFunction(Main,NULL,&D);
+}
+
diff --git a/lib/lua/src/lfunc.c b/lib/lua/src/lfunc.c
index 4e72e53..7dc41e2 100644
--- a/lib/lua/src/lfunc.c
+++ b/lib/lua/src/lfunc.c
@@ -1,135 +1,135 @@
-/*
-** $Id: lfunc.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** Auxiliary functions to manipulate prototypes and closures
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stdlib.h>
-
-#define lfunc_c
-
-#include "lua.h"
-
-#include "lfunc.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-
-
-#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
- cast(int, sizeof(TObject)*((n)-1)))
-
-#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
- cast(int, sizeof(TObject *)*((n)-1)))
-
-
-
-Closure *luaF_newCclosure (lua_State *L, int nelems) {
- Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
- luaC_link(L, valtogco(c), LUA_TFUNCTION);
- c->c.isC = 1;
- c->c.nupvalues = cast(lu_byte, nelems);
- return c;
-}
-
-
-Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e) {
- Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
- luaC_link(L, valtogco(c), LUA_TFUNCTION);
- c->l.isC = 0;
- c->l.g = *e;
- c->l.nupvalues = cast(lu_byte, nelems);
- return c;
-}
-
-
-UpVal *luaF_findupval (lua_State *L, StkId level) {
- GCObject **pp = &L->openupval;
- UpVal *p;
- UpVal *v;
- while ((p = ngcotouv(*pp)) != NULL && p->v >= level) {
- if (p->v == level) return p;
- pp = &p->next;
- }
- v = luaM_new(L, UpVal); /* not found: create a new one */
- v->tt = LUA_TUPVAL;
- v->marked = 1; /* open upvalues should not be collected */
- v->v = level; /* current value lives in the stack */
- v->next = *pp; /* chain it in the proper position */
- *pp = valtogco(v);
- return v;
-}
-
-
-void luaF_close (lua_State *L, StkId level) {
- UpVal *p;
- while ((p = ngcotouv(L->openupval)) != NULL && p->v >= level) {
- setobj(&p->value, p->v); /* save current value (write barrier) */
- p->v = &p->value; /* now current value lives here */
- L->openupval = p->next; /* remove from `open' list */
- luaC_link(L, valtogco(p), LUA_TUPVAL);
- }
-}
-
-
-Proto *luaF_newproto (lua_State *L) {
- Proto *f = luaM_new(L, Proto);
- luaC_link(L, valtogco(f), LUA_TPROTO);
- f->k = NULL;
- f->sizek = 0;
- f->p = NULL;
- f->sizep = 0;
- f->code = NULL;
- f->sizecode = 0;
- f->sizelineinfo = 0;
- f->sizeupvalues = 0;
- f->nups = 0;
- f->upvalues = NULL;
- f->numparams = 0;
- f->is_vararg = 0;
- f->maxstacksize = 0;
- f->lineinfo = NULL;
- f->sizelocvars = 0;
- f->locvars = NULL;
- f->lineDefined = 0;
- f->source = NULL;
- return f;
-}
-
-
-void luaF_freeproto (lua_State *L, Proto *f) {
- luaM_freearray(L, f->code, f->sizecode, Instruction);
- luaM_freearray(L, f->p, f->sizep, Proto *);
- luaM_freearray(L, f->k, f->sizek, TObject);
- luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
- luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
- luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
- luaM_freelem(L, f);
-}
-
-
-void luaF_freeclosure (lua_State *L, Closure *c) {
- int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
- sizeLclosure(c->l.nupvalues);
- luaM_free(L, c, size);
-}
-
-
-/*
-** Look for n-th local variable at line `line' in function `func'.
-** Returns NULL if not found.
-*/
-const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
- int i;
- for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
- if (pc < f->locvars[i].endpc) { /* is variable active? */
- local_number--;
- if (local_number == 0)
- return getstr(f->locvars[i].varname);
- }
- }
- return NULL; /* not found */
-}
-
+/*
+** $Id: lfunc.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** Auxiliary functions to manipulate prototypes and closures
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdlib.h>
+
+#define lfunc_c
+
+#include "lua.h"
+
+#include "lfunc.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+
+
+#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
+ cast(int, sizeof(TObject)*((n)-1)))
+
+#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
+ cast(int, sizeof(TObject *)*((n)-1)))
+
+
+
+Closure *luaF_newCclosure (lua_State *L, int nelems) {
+ Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
+ luaC_link(L, valtogco(c), LUA_TFUNCTION);
+ c->c.isC = 1;
+ c->c.nupvalues = cast(lu_byte, nelems);
+ return c;
+}
+
+
+Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e) {
+ Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
+ luaC_link(L, valtogco(c), LUA_TFUNCTION);
+ c->l.isC = 0;
+ c->l.g = *e;
+ c->l.nupvalues = cast(lu_byte, nelems);
+ return c;
+}
+
+
+UpVal *luaF_findupval (lua_State *L, StkId level) {
+ GCObject **pp = &L->openupval;
+ UpVal *p;
+ UpVal *v;
+ while ((p = ngcotouv(*pp)) != NULL && p->v >= level) {
+ if (p->v == level) return p;
+ pp = &p->next;
+ }
+ v = luaM_new(L, UpVal); /* not found: create a new one */
+ v->tt = LUA_TUPVAL;
+ v->marked = 1; /* open upvalues should not be collected */
+ v->v = level; /* current value lives in the stack */
+ v->next = *pp; /* chain it in the proper position */
+ *pp = valtogco(v);
+ return v;
+}
+
+
+void luaF_close (lua_State *L, StkId level) {
+ UpVal *p;
+ while ((p = ngcotouv(L->openupval)) != NULL && p->v >= level) {
+ setobj(&p->value, p->v); /* save current value (write barrier) */
+ p->v = &p->value; /* now current value lives here */
+ L->openupval = p->next; /* remove from `open' list */
+ luaC_link(L, valtogco(p), LUA_TUPVAL);
+ }
+}
+
+
+Proto *luaF_newproto (lua_State *L) {
+ Proto *f = luaM_new(L, Proto);
+ luaC_link(L, valtogco(f), LUA_TPROTO);
+ f->k = NULL;
+ f->sizek = 0;
+ f->p = NULL;
+ f->sizep = 0;
+ f->code = NULL;
+ f->sizecode = 0;
+ f->sizelineinfo = 0;
+ f->sizeupvalues = 0;
+ f->nups = 0;
+ f->upvalues = NULL;
+ f->numparams = 0;
+ f->is_vararg = 0;
+ f->maxstacksize = 0;
+ f->lineinfo = NULL;
+ f->sizelocvars = 0;
+ f->locvars = NULL;
+ f->lineDefined = 0;
+ f->source = NULL;
+ return f;
+}
+
+
+void luaF_freeproto (lua_State *L, Proto *f) {
+ luaM_freearray(L, f->code, f->sizecode, Instruction);
+ luaM_freearray(L, f->p, f->sizep, Proto *);
+ luaM_freearray(L, f->k, f->sizek, TObject);
+ luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
+ luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
+ luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
+ luaM_freelem(L, f);
+}
+
+
+void luaF_freeclosure (lua_State *L, Closure *c) {
+ int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
+ sizeLclosure(c->l.nupvalues);
+ luaM_free(L, c, size);
+}
+
+
+/*
+** Look for n-th local variable at line `line' in function `func'.
+** Returns NULL if not found.
+*/
+const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
+ int i;
+ for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
+ if (pc < f->locvars[i].endpc) { /* is variable active? */
+ local_number--;
+ if (local_number == 0)
+ return getstr(f->locvars[i].varname);
+ }
+ }
+ return NULL; /* not found */
+}
+
diff --git a/lib/lua/src/lgc.c b/lib/lua/src/lgc.c
index f565df6..15ddbb6 100644
--- a/lib/lua/src/lgc.c
+++ b/lib/lua/src/lgc.c
@@ -1,493 +1,493 @@
-/*
-** $Id: lgc.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** Garbage Collector
-** See Copyright Notice in lua.h
-*/
-
-#include <string.h>
-
-#define lgc_c
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-
-
-typedef struct GCState {
- GCObject *tmark; /* list of marked objects to be traversed */
- GCObject *wk; /* list of traversed key-weak tables (to be cleared) */
- GCObject *wv; /* list of traversed value-weak tables */
- GCObject *wkv; /* list of traversed key-value weak tables */
- global_State *g;
-} GCState;
-
-
-/*
-** some userful bit tricks
-*/
-#define setbit(x,b) ((x) |= (1<<(b)))
-#define resetbit(x,b) ((x) &= cast(lu_byte, ~(1<<(b))))
-#define testbit(x,b) ((x) & (1<<(b)))
-
-#define unmark(x) resetbit((x)->gch.marked, 0)
-#define ismarked(x) ((x)->gch.marked & ((1<<4)|1))
-
-#define stringmark(s) setbit((s)->tsv.marked, 0)
-
-
-#define isfinalized(u) (!testbit((u)->uv.marked, 1))
-#define markfinalized(u) resetbit((u)->uv.marked, 1)
-
-
-#define KEYWEAKBIT 1
-#define VALUEWEAKBIT 2
-#define KEYWEAK (1<<KEYWEAKBIT)
-#define VALUEWEAK (1<<VALUEWEAKBIT)
-
-
-
-#define markobject(st,o) { checkconsistency(o); \
- if (iscollectable(o) && !ismarked(gcvalue(o))) reallymarkobject(st,gcvalue(o)); }
-
-#define condmarkobject(st,o,c) { checkconsistency(o); \
- if (iscollectable(o) && !ismarked(gcvalue(o)) && (c)) \
- reallymarkobject(st,gcvalue(o)); }
-
-#define markvalue(st,t) { if (!ismarked(valtogco(t))) \
- reallymarkobject(st, valtogco(t)); }
-
-
-
-static void reallymarkobject (GCState *st, GCObject *o) {
- lua_assert(!ismarked(o));
- setbit(o->gch.marked, 0); /* mark object */
- switch (o->gch.tt) {
- case LUA_TUSERDATA: {
- markvalue(st, gcotou(o)->uv.metatable);
- break;
- }
- case LUA_TFUNCTION: {
- gcotocl(o)->c.gclist = st->tmark;
- st->tmark = o;
- break;
- }
- case LUA_TTABLE: {
- gcotoh(o)->gclist = st->tmark;
- st->tmark = o;
- break;
- }
- case LUA_TTHREAD: {
- gcototh(o)->gclist = st->tmark;
- st->tmark = o;
- break;
- }
- case LUA_TPROTO: {
- gcotop(o)->gclist = st->tmark;
- st->tmark = o;
- break;
- }
- default: lua_assert(o->gch.tt == LUA_TSTRING);
- }
-}
-
-
-static void marktmu (GCState *st) {
- GCObject *u;
- for (u = st->g->tmudata; u; u = u->gch.next) {
- unmark(u); /* may be marked, if left from previous GC */
- reallymarkobject(st, u);
- }
-}
-
-
-/* move `dead' udata that need finalization to list `tmudata' */
-void luaC_separateudata (lua_State *L) {
- GCObject **p = &G(L)->rootudata;
- GCObject *curr;
- GCObject *collected = NULL; /* to collect udata with gc event */
- GCObject **lastcollected = &collected;
- while ((curr = *p) != NULL) {
- lua_assert(curr->gch.tt == LUA_TUSERDATA);
- if (ismarked(curr) || isfinalized(gcotou(curr)))
- p = &curr->gch.next; /* don't bother with them */
-
- else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) {
- markfinalized(gcotou(curr)); /* don't need finalization */
- p = &curr->gch.next;
- }
- else { /* must call its gc method */
- *p = curr->gch.next;
- curr->gch.next = NULL; /* link `curr' at the end of `collected' list */
- *lastcollected = curr;
- lastcollected = &curr->gch.next;
- }
- }
- /* insert collected udata with gc event into `tmudata' list */
- *lastcollected = G(L)->tmudata;
- G(L)->tmudata = collected;
-}
-
-
-static void removekey (Node *n) {
- setnilvalue(gval(n)); /* remove corresponding value ... */
- if (iscollectable(gkey(n)))
- setttype(gkey(n), LUA_TNONE); /* dead key; remove it */
-}
-
-
-static void traversetable (GCState *st, Table *h) {
- int i;
- int weakkey = 0;
- int weakvalue = 0;
- const TObject *mode;
- markvalue(st, h->metatable);
- lua_assert(h->lsizenode || h->node == st->g->dummynode);
- mode = gfasttm(st->g, h->metatable, TM_MODE);
- if (mode && ttisstring(mode)) { /* is there a weak mode? */
- weakkey = (strchr(svalue(mode), 'k') != NULL);
- weakvalue = (strchr(svalue(mode), 'v') != NULL);
- if (weakkey || weakvalue) { /* is really weak? */
- GCObject **weaklist;
- h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
- h->marked |= cast(lu_byte, (weakkey << KEYWEAKBIT) |
- (weakvalue << VALUEWEAKBIT));
- weaklist = (weakkey && weakvalue) ? &st->wkv :
- (weakkey) ? &st->wk :
- &st->wv;
- h->gclist = *weaklist; /* must be cleared after GC, ... */
- *weaklist = valtogco(h); /* ... so put in the appropriate list */
- }
- }
- if (!weakvalue) {
- i = h->sizearray;
- while (i--)
- markobject(st, &h->array[i]);
- }
- i = sizenode(h);
- while (i--) {
- Node *n = gnode(h, i);
- if (!ttisnil(gval(n))) {
- lua_assert(!ttisnil(gkey(n)));
- condmarkobject(st, gkey(n), !weakkey);
- condmarkobject(st, gval(n), !weakvalue);
- }
- }
-}
-
-
-static void traverseproto (GCState *st, Proto *f) {
- int i;
- stringmark(f->source);
- for (i=0; i<f->sizek; i++) { /* mark literal strings */
- if (ttisstring(f->k+i))
- stringmark(tsvalue(f->k+i));
- }
- for (i=0; i<f->sizeupvalues; i++) /* mark upvalue names */
- stringmark(f->upvalues[i]);
- for (i=0; i<f->sizep; i++) /* mark nested protos */
- markvalue(st, f->p[i]);
- for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */
- stringmark(f->locvars[i].varname);
- lua_assert(luaG_checkcode(f));
-}
-
-
-
-static void traverseclosure (GCState *st, Closure *cl) {
- if (cl->c.isC) {
- int i;
- for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
- markobject(st, &cl->c.upvalue[i]);
- }
- else {
- int i;
- lua_assert(cl->l.nupvalues == cl->l.p->nups);
- markvalue(st, hvalue(&cl->l.g));
- markvalue(st, cl->l.p);
- for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
- UpVal *u = cl->l.upvals[i];
- if (!u->marked) {
- markobject(st, &u->value);
- u->marked = 1;
- }
- }
- }
-}
-
-
-static void checkstacksizes (lua_State *L, StkId max) {
- int used = L->ci - L->base_ci; /* number of `ci' in use */
- if (4*used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
- luaD_reallocCI(L, L->size_ci/2); /* still big enough... */
- else condhardstacktests(luaD_reallocCI(L, L->size_ci));
- used = max - L->stack; /* part of stack in use */
- if (4*used < L->stacksize && 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize)
- luaD_reallocstack(L, L->stacksize/2); /* still big enough... */
- else condhardstacktests(luaD_reallocstack(L, L->stacksize));
-}
-
-
-static void traversestack (GCState *st, lua_State *L1) {
- StkId o, lim;
- CallInfo *ci;
- markobject(st, gt(L1));
- lim = L1->top;
- for (ci = L1->base_ci; ci <= L1->ci; ci++) {
- lua_assert(ci->top <= L1->stack_last);
- lua_assert(ci->state & (CI_C | CI_HASFRAME | CI_SAVEDPC));
- if (!(ci->state & CI_C) && lim < ci->top)
- lim = ci->top;
- }
- for (o = L1->stack; o < L1->top; o++)
- markobject(st, o);
- for (; o <= lim; o++)
- setnilvalue(o);
- checkstacksizes(L1, lim);
-}
-
-
-static void propagatemarks (GCState *st) {
- while (st->tmark) { /* traverse marked objects */
- switch (st->tmark->gch.tt) {
- case LUA_TTABLE: {
- Table *h = gcotoh(st->tmark);
- st->tmark = h->gclist;
- traversetable(st, h);
- break;
- }
- case LUA_TFUNCTION: {
- Closure *cl = gcotocl(st->tmark);
- st->tmark = cl->c.gclist;
- traverseclosure(st, cl);
- break;
- }
- case LUA_TTHREAD: {
- lua_State *th = gcototh(st->tmark);
- st->tmark = th->gclist;
- traversestack(st, th);
- break;
- }
- case LUA_TPROTO: {
- Proto *p = gcotop(st->tmark);
- st->tmark = p->gclist;
- traverseproto(st, p);
- break;
- }
- default: lua_assert(0);
- }
- }
-}
-
-
-static int valismarked (const TObject *o) {
- if (ttisstring(o))
- stringmark(tsvalue(o)); /* strings are `values', so are never weak */
- return !iscollectable(o) || testbit(o->value.gc->gch.marked, 0);
-}
-
-
-/*
-** clear collected keys from weaktables
-*/
-static void cleartablekeys (GCObject *l) {
- while (l) {
- Table *h = gcotoh(l);
- int i = sizenode(h);
- lua_assert(h->marked & KEYWEAK);
- while (i--) {
- Node *n = gnode(h, i);
- if (!valismarked(gkey(n))) /* key was collected? */
- removekey(n); /* remove entry from table */
- }
- l = h->gclist;
- }
-}
-
-
-/*
-** clear collected values from weaktables
-*/
-static void cleartablevalues (GCObject *l) {
- while (l) {
- Table *h = gcotoh(l);
- int i = h->sizearray;
- lua_assert(h->marked & VALUEWEAK);
- while (i--) {
- TObject *o = &h->array[i];
- if (!valismarked(o)) /* value was collected? */
- setnilvalue(o); /* remove value */
- }
- i = sizenode(h);
- while (i--) {
- Node *n = gnode(h, i);
- if (!valismarked(gval(n))) /* value was collected? */
- removekey(n); /* remove entry from table */
- }
- l = h->gclist;
- }
-}
-
-
-static void freeobj (lua_State *L, GCObject *o) {
- switch (o->gch.tt) {
- case LUA_TPROTO: luaF_freeproto(L, gcotop(o)); break;
- case LUA_TFUNCTION: luaF_freeclosure(L, gcotocl(o)); break;
- case LUA_TUPVAL: luaM_freelem(L, gcotouv(o)); break;
- case LUA_TTABLE: luaH_free(L, gcotoh(o)); break;
- case LUA_TTHREAD: {
- lua_assert(gcototh(o) != L && gcototh(o) != G(L)->mainthread);
- luaE_freethread(L, gcototh(o));
- break;
- }
- case LUA_TSTRING: {
- luaM_free(L, o, sizestring(gcotots(o)->tsv.len));
- break;
- }
- case LUA_TUSERDATA: {
- luaM_free(L, o, sizeudata(gcotou(o)->uv.len));
- break;
- }
- default: lua_assert(0);
- }
-}
-
-
-static int sweeplist (lua_State *L, GCObject **p, int limit) {
- GCObject *curr;
- int count = 0; /* number of collected items */
- while ((curr = *p) != NULL) {
- if (curr->gch.marked > limit) {
- unmark(curr);
- p = &curr->gch.next;
- }
- else {
- count++;
- *p = curr->gch.next;
- freeobj(L, curr);
- }
- }
- return count;
-}
-
-
-static void sweepstrings (lua_State *L, int all) {
- int i;
- for (i=0; i<G(L)->strt.size; i++) { /* for each list */
- G(L)->strt.nuse -= sweeplist(L, &G(L)->strt.hash[i], all);
- }
-}
-
-
-static void checkSizes (lua_State *L) {
- /* check size of string hash */
- if (G(L)->strt.nuse < cast(ls_nstr, G(L)->strt.size/4) &&
- G(L)->strt.size > MINSTRTABSIZE*2)
- luaS_resize(L, G(L)->strt.size/2); /* table is too big */
- /* check size of buffer */
- if (luaZ_sizebuffer(&G(L)->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
- size_t newsize = luaZ_sizebuffer(&G(L)->buff) / 2;
- luaZ_resizebuffer(L, &G(L)->buff, newsize);
- }
- G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
-}
-
-
-static void do1gcTM (lua_State *L, Udata *udata) {
- const TObject *tm = fasttm(L, udata->uv.metatable, TM_GC);
- if (tm != NULL) {
- setobj2s(L->top, tm);
- setuvalue(L->top+1, udata);
- L->top += 2;
- luaD_call(L, L->top - 2, 0);
- }
-}
-
-
-void luaC_callGCTM (lua_State *L) {
- lu_byte oldah = L->allowhook;
- L->allowhook = 0; /* stop debug hooks during GC tag methods */
- L->top++; /* reserve space to keep udata while runs its gc method */
- while (G(L)->tmudata != NULL) {
- GCObject *o = G(L)->tmudata;
- Udata *udata = gcotou(o);
- G(L)->tmudata = udata->uv.next; /* remove udata from `tmudata' */
- udata->uv.next = G(L)->rootudata; /* return it to `root' list */
- G(L)->rootudata = o;
- setuvalue(L->top - 1, udata); /* keep a reference to it */
- unmark(o);
- markfinalized(udata);
- do1gcTM(L, udata);
- }
- L->top--;
- L->allowhook = oldah; /* restore hooks */
-}
-
-
-void luaC_sweep (lua_State *L, int all) {
- if (all) all = 256; /* larger than any mark */
- sweeplist(L, &G(L)->rootudata, all);
- sweepstrings(L, all);
- sweeplist(L, &G(L)->rootgc, all);
-}
-
-
-/* mark root set */
-static void markroot (GCState *st, lua_State *L) {
- global_State *g = st->g;
- markobject(st, defaultmeta(L));
- markobject(st, registry(L));
- traversestack(st, g->mainthread);
- if (L != g->mainthread) /* another thread is running? */
- markvalue(st, L); /* cannot collect it */
-}
-
-
-static void mark (lua_State *L) {
- GCState st;
- GCObject *wkv;
- st.g = G(L);
- st.tmark = NULL;
- st.wkv = st.wk = st.wv = NULL;
- markroot(&st, L);
- propagatemarks(&st); /* mark all reachable objects */
- cleartablevalues(st.wkv);
- cleartablevalues(st.wv);
- wkv = st.wkv; /* keys must be cleared after preserving udata */
- st.wkv = NULL;
- st.wv = NULL;
- luaC_separateudata(L); /* separate userdata to be preserved */
- marktmu(&st); /* mark `preserved' userdata */
- propagatemarks(&st); /* remark, to propagate `preserveness' */
- cleartablekeys(wkv);
- /* `propagatemarks' may resuscitate some weak tables; clear them too */
- cleartablekeys(st.wk);
- cleartablevalues(st.wv);
- cleartablekeys(st.wkv);
- cleartablevalues(st.wkv);
-}
-
-
-void luaC_collectgarbage (lua_State *L) {
- mark(L);
- luaC_sweep(L, 0);
- checkSizes(L);
- luaC_callGCTM(L);
-}
-
-
-void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
- o->gch.next = G(L)->rootgc;
- G(L)->rootgc = o;
- o->gch.marked = 0;
- o->gch.tt = tt;
-}
-
+/*
+** $Id: lgc.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** Garbage Collector
+** See Copyright Notice in lua.h
+*/
+
+#include <string.h>
+
+#define lgc_c
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+
+
+typedef struct GCState {
+ GCObject *tmark; /* list of marked objects to be traversed */
+ GCObject *wk; /* list of traversed key-weak tables (to be cleared) */
+ GCObject *wv; /* list of traversed value-weak tables */
+ GCObject *wkv; /* list of traversed key-value weak tables */
+ global_State *g;
+} GCState;
+
+
+/*
+** some userful bit tricks
+*/
+#define setbit(x,b) ((x) |= (1<<(b)))
+#define resetbit(x,b) ((x) &= cast(lu_byte, ~(1<<(b))))
+#define testbit(x,b) ((x) & (1<<(b)))
+
+#define unmark(x) resetbit((x)->gch.marked, 0)
+#define ismarked(x) ((x)->gch.marked & ((1<<4)|1))
+
+#define stringmark(s) setbit((s)->tsv.marked, 0)
+
+
+#define isfinalized(u) (!testbit((u)->uv.marked, 1))
+#define markfinalized(u) resetbit((u)->uv.marked, 1)
+
+
+#define KEYWEAKBIT 1
+#define VALUEWEAKBIT 2
+#define KEYWEAK (1<<KEYWEAKBIT)
+#define VALUEWEAK (1<<VALUEWEAKBIT)
+
+
+
+#define markobject(st,o) { checkconsistency(o); \
+ if (iscollectable(o) && !ismarked(gcvalue(o))) reallymarkobject(st,gcvalue(o)); }
+
+#define condmarkobject(st,o,c) { checkconsistency(o); \
+ if (iscollectable(o) && !ismarked(gcvalue(o)) && (c)) \
+ reallymarkobject(st,gcvalue(o)); }
+
+#define markvalue(st,t) { if (!ismarked(valtogco(t))) \
+ reallymarkobject(st, valtogco(t)); }
+
+
+
+static void reallymarkobject (GCState *st, GCObject *o) {
+ lua_assert(!ismarked(o));
+ setbit(o->gch.marked, 0); /* mark object */
+ switch (o->gch.tt) {
+ case LUA_TUSERDATA: {
+ markvalue(st, gcotou(o)->uv.metatable);
+ break;
+ }
+ case LUA_TFUNCTION: {
+ gcotocl(o)->c.gclist = st->tmark;
+ st->tmark = o;
+ break;
+ }
+ case LUA_TTABLE: {
+ gcotoh(o)->gclist = st->tmark;
+ st->tmark = o;
+ break;
+ }
+ case LUA_TTHREAD: {
+ gcototh(o)->gclist = st->tmark;
+ st->tmark = o;
+ break;
+ }
+ case LUA_TPROTO: {
+ gcotop(o)->gclist = st->tmark;
+ st->tmark = o;
+ break;
+ }
+ default: lua_assert(o->gch.tt == LUA_TSTRING);
+ }
+}
+
+
+static void marktmu (GCState *st) {
+ GCObject *u;
+ for (u = st->g->tmudata; u; u = u->gch.next) {
+ unmark(u); /* may be marked, if left from previous GC */
+ reallymarkobject(st, u);
+ }
+}
+
+
+/* move `dead' udata that need finalization to list `tmudata' */
+void luaC_separateudata (lua_State *L) {
+ GCObject **p = &G(L)->rootudata;
+ GCObject *curr;
+ GCObject *collected = NULL; /* to collect udata with gc event */
+ GCObject **lastcollected = &collected;
+ while ((curr = *p) != NULL) {
+ lua_assert(curr->gch.tt == LUA_TUSERDATA);
+ if (ismarked(curr) || isfinalized(gcotou(curr)))
+ p = &curr->gch.next; /* don't bother with them */
+
+ else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) {
+ markfinalized(gcotou(curr)); /* don't need finalization */
+ p = &curr->gch.next;
+ }
+ else { /* must call its gc method */
+ *p = curr->gch.next;
+ curr->gch.next = NULL; /* link `curr' at the end of `collected' list */
+ *lastcollected = curr;
+ lastcollected = &curr->gch.next;
+ }
+ }
+ /* insert collected udata with gc event into `tmudata' list */
+ *lastcollected = G(L)->tmudata;
+ G(L)->tmudata = collected;
+}
+
+
+static void removekey (Node *n) {
+ setnilvalue(gval(n)); /* remove corresponding value ... */
+ if (iscollectable(gkey(n)))
+ setttype(gkey(n), LUA_TNONE); /* dead key; remove it */
+}
+
+
+static void traversetable (GCState *st, Table *h) {
+ int i;
+ int weakkey = 0;
+ int weakvalue = 0;
+ const TObject *mode;
+ markvalue(st, h->metatable);
+ lua_assert(h->lsizenode || h->node == st->g->dummynode);
+ mode = gfasttm(st->g, h->metatable, TM_MODE);
+ if (mode && ttisstring(mode)) { /* is there a weak mode? */
+ weakkey = (strchr(svalue(mode), 'k') != NULL);
+ weakvalue = (strchr(svalue(mode), 'v') != NULL);
+ if (weakkey || weakvalue) { /* is really weak? */
+ GCObject **weaklist;
+ h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
+ h->marked |= cast(lu_byte, (weakkey << KEYWEAKBIT) |
+ (weakvalue << VALUEWEAKBIT));
+ weaklist = (weakkey && weakvalue) ? &st->wkv :
+ (weakkey) ? &st->wk :
+ &st->wv;
+ h->gclist = *weaklist; /* must be cleared after GC, ... */
+ *weaklist = valtogco(h); /* ... so put in the appropriate list */
+ }
+ }
+ if (!weakvalue) {
+ i = h->sizearray;
+ while (i--)
+ markobject(st, &h->array[i]);
+ }
+ i = sizenode(h);
+ while (i--) {
+ Node *n = gnode(h, i);
+ if (!ttisnil(gval(n))) {
+ lua_assert(!ttisnil(gkey(n)));
+ condmarkobject(st, gkey(n), !weakkey);
+ condmarkobject(st, gval(n), !weakvalue);
+ }
+ }
+}
+
+
+static void traverseproto (GCState *st, Proto *f) {
+ int i;
+ stringmark(f->source);
+ for (i=0; i<f->sizek; i++) { /* mark literal strings */
+ if (ttisstring(f->k+i))
+ stringmark(tsvalue(f->k+i));
+ }
+ for (i=0; i<f->sizeupvalues; i++) /* mark upvalue names */
+ stringmark(f->upvalues[i]);
+ for (i=0; i<f->sizep; i++) /* mark nested protos */
+ markvalue(st, f->p[i]);
+ for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */
+ stringmark(f->locvars[i].varname);
+ lua_assert(luaG_checkcode(f));
+}
+
+
+
+static void traverseclosure (GCState *st, Closure *cl) {
+ if (cl->c.isC) {
+ int i;
+ for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
+ markobject(st, &cl->c.upvalue[i]);
+ }
+ else {
+ int i;
+ lua_assert(cl->l.nupvalues == cl->l.p->nups);
+ markvalue(st, hvalue(&cl->l.g));
+ markvalue(st, cl->l.p);
+ for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
+ UpVal *u = cl->l.upvals[i];
+ if (!u->marked) {
+ markobject(st, &u->value);
+ u->marked = 1;
+ }
+ }
+ }
+}
+
+
+static void checkstacksizes (lua_State *L, StkId max) {
+ int used = L->ci - L->base_ci; /* number of `ci' in use */
+ if (4*used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
+ luaD_reallocCI(L, L->size_ci/2); /* still big enough... */
+ else condhardstacktests(luaD_reallocCI(L, L->size_ci));
+ used = max - L->stack; /* part of stack in use */
+ if (4*used < L->stacksize && 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize)
+ luaD_reallocstack(L, L->stacksize/2); /* still big enough... */
+ else condhardstacktests(luaD_reallocstack(L, L->stacksize));
+}
+
+
+static void traversestack (GCState *st, lua_State *L1) {
+ StkId o, lim;
+ CallInfo *ci;
+ markobject(st, gt(L1));
+ lim = L1->top;
+ for (ci = L1->base_ci; ci <= L1->ci; ci++) {
+ lua_assert(ci->top <= L1->stack_last);
+ lua_assert(ci->state & (CI_C | CI_HASFRAME | CI_SAVEDPC));
+ if (!(ci->state & CI_C) && lim < ci->top)
+ lim = ci->top;
+ }
+ for (o = L1->stack; o < L1->top; o++)
+ markobject(st, o);
+ for (; o <= lim; o++)
+ setnilvalue(o);
+ checkstacksizes(L1, lim);
+}
+
+
+static void propagatemarks (GCState *st) {
+ while (st->tmark) { /* traverse marked objects */
+ switch (st->tmark->gch.tt) {
+ case LUA_TTABLE: {
+ Table *h = gcotoh(st->tmark);
+ st->tmark = h->gclist;
+ traversetable(st, h);
+ break;
+ }
+ case LUA_TFUNCTION: {
+ Closure *cl = gcotocl(st->tmark);
+ st->tmark = cl->c.gclist;
+ traverseclosure(st, cl);
+ break;
+ }
+ case LUA_TTHREAD: {
+ lua_State *th = gcototh(st->tmark);
+ st->tmark = th->gclist;
+ traversestack(st, th);
+ break;
+ }
+ case LUA_TPROTO: {
+ Proto *p = gcotop(st->tmark);
+ st->tmark = p->gclist;
+ traverseproto(st, p);
+ break;
+ }
+ default: lua_assert(0);
+ }
+ }
+}
+
+
+static int valismarked (const TObject *o) {
+ if (ttisstring(o))
+ stringmark(tsvalue(o)); /* strings are `values', so are never weak */
+ return !iscollectable(o) || testbit(o->value.gc->gch.marked, 0);
+}
+
+
+/*
+** clear collected keys from weaktables
+*/
+static void cleartablekeys (GCObject *l) {
+ while (l) {
+ Table *h = gcotoh(l);
+ int i = sizenode(h);
+ lua_assert(h->marked & KEYWEAK);
+ while (i--) {
+ Node *n = gnode(h, i);
+ if (!valismarked(gkey(n))) /* key was collected? */
+ removekey(n); /* remove entry from table */
+ }
+ l = h->gclist;
+ }
+}
+
+
+/*
+** clear collected values from weaktables
+*/
+static void cleartablevalues (GCObject *l) {
+ while (l) {
+ Table *h = gcotoh(l);
+ int i = h->sizearray;
+ lua_assert(h->marked & VALUEWEAK);
+ while (i--) {
+ TObject *o = &h->array[i];
+ if (!valismarked(o)) /* value was collected? */
+ setnilvalue(o); /* remove value */
+ }
+ i = sizenode(h);
+ while (i--) {
+ Node *n = gnode(h, i);
+ if (!valismarked(gval(n))) /* value was collected? */
+ removekey(n); /* remove entry from table */
+ }
+ l = h->gclist;
+ }
+}
+
+
+static void freeobj (lua_State *L, GCObject *o) {
+ switch (o->gch.tt) {
+ case LUA_TPROTO: luaF_freeproto(L, gcotop(o)); break;
+ case LUA_TFUNCTION: luaF_freeclosure(L, gcotocl(o)); break;
+ case LUA_TUPVAL: luaM_freelem(L, gcotouv(o)); break;
+ case LUA_TTABLE: luaH_free(L, gcotoh(o)); break;
+ case LUA_TTHREAD: {
+ lua_assert(gcototh(o) != L && gcototh(o) != G(L)->mainthread);
+ luaE_freethread(L, gcototh(o));
+ break;
+ }
+ case LUA_TSTRING: {
+ luaM_free(L, o, sizestring(gcotots(o)->tsv.len));
+ break;
+ }
+ case LUA_TUSERDATA: {
+ luaM_free(L, o, sizeudata(gcotou(o)->uv.len));
+ break;
+ }
+ default: lua_assert(0);
+ }
+}
+
+
+static int sweeplist (lua_State *L, GCObject **p, int limit) {
+ GCObject *curr;
+ int count = 0; /* number of collected items */
+ while ((curr = *p) != NULL) {
+ if (curr->gch.marked > limit) {
+ unmark(curr);
+ p = &curr->gch.next;
+ }
+ else {
+ count++;
+ *p = curr->gch.next;
+ freeobj(L, curr);
+ }
+ }
+ return count;
+}
+
+
+static void sweepstrings (lua_State *L, int all) {
+ int i;
+ for (i=0; i<G(L)->strt.size; i++) { /* for each list */
+ G(L)->strt.nuse -= sweeplist(L, &G(L)->strt.hash[i], all);
+ }
+}
+
+
+static void checkSizes (lua_State *L) {
+ /* check size of string hash */
+ if (G(L)->strt.nuse < cast(ls_nstr, G(L)->strt.size/4) &&
+ G(L)->strt.size > MINSTRTABSIZE*2)
+ luaS_resize(L, G(L)->strt.size/2); /* table is too big */
+ /* check size of buffer */
+ if (luaZ_sizebuffer(&G(L)->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
+ size_t newsize = luaZ_sizebuffer(&G(L)->buff) / 2;
+ luaZ_resizebuffer(L, &G(L)->buff, newsize);
+ }
+ G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
+}
+
+
+static void do1gcTM (lua_State *L, Udata *udata) {
+ const TObject *tm = fasttm(L, udata->uv.metatable, TM_GC);
+ if (tm != NULL) {
+ setobj2s(L->top, tm);
+ setuvalue(L->top+1, udata);
+ L->top += 2;
+ luaD_call(L, L->top - 2, 0);
+ }
+}
+
+
+void luaC_callGCTM (lua_State *L) {
+ lu_byte oldah = L->allowhook;
+ L->allowhook = 0; /* stop debug hooks during GC tag methods */
+ L->top++; /* reserve space to keep udata while runs its gc method */
+ while (G(L)->tmudata != NULL) {
+ GCObject *o = G(L)->tmudata;
+ Udata *udata = gcotou(o);
+ G(L)->tmudata = udata->uv.next; /* remove udata from `tmudata' */
+ udata->uv.next = G(L)->rootudata; /* return it to `root' list */
+ G(L)->rootudata = o;
+ setuvalue(L->top - 1, udata); /* keep a reference to it */
+ unmark(o);
+ markfinalized(udata);
+ do1gcTM(L, udata);
+ }
+ L->top--;
+ L->allowhook = oldah; /* restore hooks */
+}
+
+
+void luaC_sweep (lua_State *L, int all) {
+ if (all) all = 256; /* larger than any mark */
+ sweeplist(L, &G(L)->rootudata, all);
+ sweepstrings(L, all);
+ sweeplist(L, &G(L)->rootgc, all);
+}
+
+
+/* mark root set */
+static void markroot (GCState *st, lua_State *L) {
+ global_State *g = st->g;
+ markobject(st, defaultmeta(L));
+ markobject(st, registry(L));
+ traversestack(st, g->mainthread);
+ if (L != g->mainthread) /* another thread is running? */
+ markvalue(st, L); /* cannot collect it */
+}
+
+
+static void mark (lua_State *L) {
+ GCState st;
+ GCObject *wkv;
+ st.g = G(L);
+ st.tmark = NULL;
+ st.wkv = st.wk = st.wv = NULL;
+ markroot(&st, L);
+ propagatemarks(&st); /* mark all reachable objects */
+ cleartablevalues(st.wkv);
+ cleartablevalues(st.wv);
+ wkv = st.wkv; /* keys must be cleared after preserving udata */
+ st.wkv = NULL;
+ st.wv = NULL;
+ luaC_separateudata(L); /* separate userdata to be preserved */
+ marktmu(&st); /* mark `preserved' userdata */
+ propagatemarks(&st); /* remark, to propagate `preserveness' */
+ cleartablekeys(wkv);
+ /* `propagatemarks' may resuscitate some weak tables; clear them too */
+ cleartablekeys(st.wk);
+ cleartablevalues(st.wv);
+ cleartablekeys(st.wkv);
+ cleartablevalues(st.wkv);
+}
+
+
+void luaC_collectgarbage (lua_State *L) {
+ mark(L);
+ luaC_sweep(L, 0);
+ checkSizes(L);
+ luaC_callGCTM(L);
+}
+
+
+void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
+ o->gch.next = G(L)->rootgc;
+ G(L)->rootgc = o;
+ o->gch.marked = 0;
+ o->gch.tt = tt;
+}
+
diff --git a/lib/lua/src/llex.c b/lib/lua/src/llex.c
index 6382cce..ff88f92 100644
--- a/lib/lua/src/llex.c
+++ b/lib/lua/src/llex.c
@@ -1,442 +1,442 @@
-/*
-** $Id: llex.c,v 1.4 2004-11-27 21:35:20 pixel Exp $
-** Lexical Analyzer
-** See Copyright Notice in lua.h
-*/
-
-
-#include <ctype.h>
-#include <string.h>
-
-#define llex_c
-
-#include "lua.h"
-
-#include "ldo.h"
-#include "llex.h"
-#include "lobject.h"
-#include "lparser.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "lzio.h"
-
-
-
-#define next(LS) (LS->current = zgetc(LS->z))
-
-
-
-/* ORDER RESERVED */
-static const char *const token2string [] = {
- "and", "break", "do", "else", "elseif",
- "end", "false", "for", "function", "if",
- "in", "local", "nil", "not", "or", "repeat",
- "return", "then", "true", "until", "while", "*name",
- "..", "...", "==", ">=", "<=", "~=",
- "*number", "*string", "<eof>"
-};
-
-
-void luaX_init (lua_State *L) {
- int i;
- for (i=0; i<NUM_RESERVED; i++) {
- TString *ts = luaS_new(L, token2string[i]);
- luaS_fix(ts); /* reserved words are never collected */
- lua_assert(strlen(token2string[i])+1 <= TOKEN_LEN);
- ts->tsv.reserved = cast(lu_byte, i+1); /* reserved word */
- }
-}
-
-
-#define MAXSRC 80
-
-
-void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) {
- if (val > limit) {
- msg = luaO_pushfstring(ls->L, "too many %s (limit=%d)", msg, limit);
- luaX_syntaxerror(ls, msg);
- }
-}
-
-
-void luaX_errorline (LexState *ls, const char *s, const char *token, int line) {
- lua_State *L = ls->L;
- char buff[MAXSRC];
- luaO_chunkid(buff, getstr(ls->source), MAXSRC);
- luaO_pushfstring(L, "%s:%d: %s near `%s'", buff, line, s, token);
- luaD_throw(L, LUA_ERRSYNTAX);
-}
-
-
-static void luaX_error (LexState *ls, const char *s, const char *token) {
- luaX_errorline(ls, s, token, ls->linenumber);
-}
-
-
-void luaX_syntaxerror (LexState *ls, const char *msg) {
- const char *lasttoken;
- switch (ls->t.token) {
- case TK_NAME:
- lasttoken = getstr(ls->t.seminfo.ts);
- break;
- case TK_STRING:
- case TK_NUMBER:
- lasttoken = luaZ_buffer(ls->buff);
- break;
- default:
- lasttoken = luaX_token2str(ls, ls->t.token);
- break;
- }
- luaX_error(ls, msg, lasttoken);
-}
-
-
-const char *luaX_token2str (LexState *ls, int token) {
- if (token < FIRST_RESERVED) {
- lua_assert(token == (unsigned char)token);
- return luaO_pushfstring(ls->L, "%c", token);
- }
- else
- return token2string[token-FIRST_RESERVED];
-}
-
-
-static void luaX_lexerror (LexState *ls, const char *s, int token) {
- if (token == TK_EOS)
- luaX_error(ls, s, luaX_token2str(ls, token));
- else
- luaX_error(ls, s, luaZ_buffer(ls->buff));
-}
-
-
-static void inclinenumber (LexState *LS) {
- next(LS); /* skip `\n' */
- ++LS->linenumber;
- luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk");
-}
-
-
-void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) {
- LS->L = L;
- LS->lookahead.token = TK_EOS; /* no look-ahead token */
- LS->z = z;
- LS->fs = NULL;
- LS->linenumber = 1;
- LS->lastline = 1;
- LS->source = source;
- next(LS); /* read first char */
- if (LS->current == '#') {
- do { /* skip first line */
- next(LS);
- } while (LS->current != '\n' && LS->current != EOZ);
- }
-}
-
-
-
-/*
-** =======================================================
-** LEXICAL ANALYZER
-** =======================================================
-*/
-
-
-/* use buffer to store names, literal strings and numbers */
-
-/* extra space to allocate when growing buffer */
-#define EXTRABUFF 32
-
-/* maximum number of chars that can be read without checking buffer size */
-#define MAXNOCHECK 5
-
-#define checkbuffer(LS, len) \
- if (((len)+MAXNOCHECK)*sizeof(char) > luaZ_sizebuffer((LS)->buff)) \
- luaZ_openspace((LS)->L, (LS)->buff, (len)+EXTRABUFF)
-
-#define save(LS, c, l) \
- (luaZ_buffer((LS)->buff)[l++] = cast(char, c))
-#define save_and_next(LS, l) (save(LS, LS->current, l), next(LS))
-
-
-static size_t readname (LexState *LS) {
- size_t l = 0;
- checkbuffer(LS, l);
- do {
- checkbuffer(LS, l);
- save_and_next(LS, l);
- } while (isalnum(LS->current) || LS->current == '_');
- save(LS, '\0', l);
- return l-1;
-}
-
-
-/* LUA_NUMBER */
-static void read_numeral (LexState *LS, int comma, SemInfo *seminfo) {
- int oct = 0, hex = 0;
- size_t l = 0;
- checkbuffer(LS, l);
- if (comma) save(LS, '.', l);
- else if (LS->current == '0') {
- oct = 1;
- checkbuffer(LS, 1);
- save_and_next(LS, l);
- if (LS->current == 'x') {
- oct = 0;
- hex = 1;
- checkbuffer(LS, 1);
- save_and_next(LS, l);
- }
- }
- while (isdigit(LS->current) || (hex && isxdigit(LS->current))) {
- checkbuffer(LS, l);
- save_and_next(LS, l);
- }
- checkbuffer(LS, 1);
- if (LS->current == '.') {
- save_and_next(LS, l);
- if (hex || oct) {
- save(LS, '\0', l);
- luaX_lexerror(LS,
- "error in number, mixing decimal point with octal or hexadecimal",
- TK_NUMBER);
- }
- if (LS->current == '.') {
- save_and_next(LS, l);
- save(LS, '\0', l);
- luaX_lexerror(LS,
- "ambiguous syntax (decimal point x string concatenation)",
- TK_NUMBER);
- }
- }
- while (isdigit(LS->current)) {
- checkbuffer(LS, l);
- save_and_next(LS, l);
- }
- if (LS->current == 'e' || LS->current == 'E') {
- save_and_next(LS, l); /* read `E' */
- if (hex || oct) {
- save(LS, '\0', l);
- luaX_lexerror(LS,
- "error in number, mixing exponential with octal or hexadecimal",
- TK_NUMBER);
- }
- if (LS->current == '+' || LS->current == '-')
- save_and_next(LS, l); /* optional exponent sign */
- while (isdigit(LS->current)) {
- checkbuffer(LS, l);
- save_and_next(LS, l);
- }
- }
- save(LS, '\0', l);
- if (!luaO_str2d(luaZ_buffer(LS->buff), &seminfo->r))
- luaX_lexerror(LS, "malformed number", TK_NUMBER);
-}
-
-
-static void read_long_string (LexState *LS, SemInfo *seminfo) {
- int cont = 0;
- size_t l = 0;
- checkbuffer(LS, l);
- save(LS, '[', l); /* save first `[' */
- save_and_next(LS, l); /* pass the second `[' */
- if (LS->current == '\n') /* string starts with a newline? */
- inclinenumber(LS); /* skip it */
- for (;;) {
- checkbuffer(LS, l);
- switch (LS->current) {
- case EOZ:
- save(LS, '\0', l);
- luaX_lexerror(LS, (seminfo) ? "unfinished long string" :
- "unfinished long comment", TK_EOS);
- break; /* to avoid warnings */
- case '[':
- save_and_next(LS, l);
- if (LS->current == '[') {
- cont++;
- save_and_next(LS, l);
- }
- continue;
- case ']':
- save_and_next(LS, l);
- if (LS->current == ']') {
- if (cont == 0) goto endloop;
- cont--;
- save_and_next(LS, l);
- }
- continue;
- case '\n':
- save(LS, '\n', l);
- inclinenumber(LS);
- if (!seminfo) l = 0; /* reset buffer to avoid wasting space */
- continue;
- default:
- save_and_next(LS, l);
- }
- } endloop:
- save_and_next(LS, l); /* skip the second `]' */
- save(LS, '\0', l);
- if (seminfo)
- seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 2, l - 5);
-}
-
-
-static void read_string (LexState *LS, int del, SemInfo *seminfo) {
- size_t l = 0;
- checkbuffer(LS, l);
- save_and_next(LS, l);
- while (LS->current != del) {
- checkbuffer(LS, l);
- switch (LS->current) {
- case EOZ:
- save(LS, '\0', l);
- luaX_lexerror(LS, "unfinished string", TK_EOS);
- break; /* to avoid warnings */
- case '\n':
- save(LS, '\0', l);
- luaX_lexerror(LS, "unfinished string", TK_STRING);
- break; /* to avoid warnings */
- case '\\':
- next(LS); /* do not save the `\' */
- switch (LS->current) {
- case 'a': save(LS, '\a', l); next(LS); break;
- case 'b': save(LS, '\b', l); next(LS); break;
- case 'f': save(LS, '\f', l); next(LS); break;
- case 'n': save(LS, '\n', l); next(LS); break;
- case 'r': save(LS, '\r', l); next(LS); break;
- case 't': save(LS, '\t', l); next(LS); break;
- case 'v': save(LS, '\v', l); next(LS); break;
- case '\n': save(LS, '\n', l); inclinenumber(LS); break;
- case EOZ: break; /* will raise an error next loop */
- default: {
- if (!isdigit(LS->current))
- save_and_next(LS, l); /* handles \\, \", \', and \? */
- else { /* \xxx */
- int c = 0;
- int i = 0;
- do {
- c = 10*c + (LS->current-'0');
- next(LS);
- } while (++i<3 && isdigit(LS->current));
- if (c > UCHAR_MAX) {
- save(LS, '\0', l);
- luaX_lexerror(LS, "escape sequence too large", TK_STRING);
- }
- save(LS, c, l);
- }
- }
- }
- break;
- default:
- save_and_next(LS, l);
- }
- }
- save_and_next(LS, l); /* skip delimiter */
- save(LS, '\0', l);
- seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 1, l - 3);
-}
-
-
-int luaX_lex (LexState *LS, SemInfo *seminfo) {
- for (;;) {
- switch (LS->current) {
-
- case '\n': {
- inclinenumber(LS);
- continue;
- }
- case '-': {
- next(LS);
- if (LS->current != '-') return '-';
- /* else is a comment */
- next(LS);
- if (LS->current == '[' && (next(LS), LS->current == '['))
- read_long_string(LS, NULL); /* long comment */
- else /* short comment */
- while (LS->current != '\n' && LS->current != EOZ)
- next(LS);
- continue;
- }
- case '[': {
- next(LS);
- if (LS->current != '[') return '[';
- else {
- read_long_string(LS, seminfo);
- return TK_STRING;
- }
- }
- case '=': {
- next(LS);
- if (LS->current != '=') return '=';
- else { next(LS); return TK_EQ; }
- }
- case '<': {
- next(LS);
- if (LS->current != '=') return '<';
- else { next(LS); return TK_LE; }
- }
- case '>': {
- next(LS);
- if (LS->current != '=') return '>';
- else { next(LS); return TK_GE; }
- }
- case '~': {
- next(LS);
- if (LS->current != '=') return '~';
- else { next(LS); return TK_NE; }
- }
- case '"':
- case '\'': {
- read_string(LS, LS->current, seminfo);
- return TK_STRING;
- }
- case '.': {
- next(LS);
- if (LS->current == '.') {
- next(LS);
- if (LS->current == '.') {
- next(LS);
- return TK_DOTS; /* ... */
- }
- else return TK_CONCAT; /* .. */
- }
- else if (!isdigit(LS->current)) return '.';
- else {
- read_numeral(LS, 1, seminfo);
- return TK_NUMBER;
- }
- }
- case EOZ: {
- return TK_EOS;
- }
- default: {
- if (isspace(LS->current)) {
- next(LS);
- continue;
- }
- else if (isdigit(LS->current)) {
- read_numeral(LS, 0, seminfo);
- return TK_NUMBER;
- }
- else if (isalpha(LS->current) || LS->current == '_') {
- /* identifier or reserved word */
- size_t l = readname(LS);
- TString *ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff), l);
- if (ts->tsv.reserved > 0) /* reserved word? */
- return ts->tsv.reserved - 1 + FIRST_RESERVED;
- seminfo->ts = ts;
- return TK_NAME;
- }
- else {
- int c = LS->current;
- if (iscntrl(c))
- luaX_error(LS, "invalid control char",
- luaO_pushfstring(LS->L, "char(%d)", c));
- next(LS);
- return c; /* single-char tokens (+ - / ...) */
- }
- }
- }
- }
-}
-
-#undef next
+/*
+** $Id: llex.c,v 1.5 2004-11-27 21:46:07 pixel Exp $
+** Lexical Analyzer
+** See Copyright Notice in lua.h
+*/
+
+
+#include <ctype.h>
+#include <string.h>
+
+#define llex_c
+
+#include "lua.h"
+
+#include "ldo.h"
+#include "llex.h"
+#include "lobject.h"
+#include "lparser.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "lzio.h"
+
+
+
+#define next(LS) (LS->current = zgetc(LS->z))
+
+
+
+/* ORDER RESERVED */
+static const char *const token2string [] = {
+ "and", "break", "do", "else", "elseif",
+ "end", "false", "for", "function", "if",
+ "in", "local", "nil", "not", "or", "repeat",
+ "return", "then", "true", "until", "while", "*name",
+ "..", "...", "==", ">=", "<=", "~=",
+ "*number", "*string", "<eof>"
+};
+
+
+void luaX_init (lua_State *L) {
+ int i;
+ for (i=0; i<NUM_RESERVED; i++) {
+ TString *ts = luaS_new(L, token2string[i]);
+ luaS_fix(ts); /* reserved words are never collected */
+ lua_assert(strlen(token2string[i])+1 <= TOKEN_LEN);
+ ts->tsv.reserved = cast(lu_byte, i+1); /* reserved word */
+ }
+}
+
+
+#define MAXSRC 80
+
+
+void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) {
+ if (val > limit) {
+ msg = luaO_pushfstring(ls->L, "too many %s (limit=%d)", msg, limit);
+ luaX_syntaxerror(ls, msg);
+ }
+}
+
+
+void luaX_errorline (LexState *ls, const char *s, const char *token, int line) {
+ lua_State *L = ls->L;
+ char buff[MAXSRC];
+ luaO_chunkid(buff, getstr(ls->source), MAXSRC);
+ luaO_pushfstring(L, "%s:%d: %s near `%s'", buff, line, s, token);
+ luaD_throw(L, LUA_ERRSYNTAX);
+}
+
+
+static void luaX_error (LexState *ls, const char *s, const char *token) {
+ luaX_errorline(ls, s, token, ls->linenumber);
+}
+
+
+void luaX_syntaxerror (LexState *ls, const char *msg) {
+ const char *lasttoken;
+ switch (ls->t.token) {
+ case TK_NAME:
+ lasttoken = getstr(ls->t.seminfo.ts);
+ break;
+ case TK_STRING:
+ case TK_NUMBER:
+ lasttoken = luaZ_buffer(ls->buff);
+ break;
+ default:
+ lasttoken = luaX_token2str(ls, ls->t.token);
+ break;
+ }
+ luaX_error(ls, msg, lasttoken);
+}
+
+
+const char *luaX_token2str (LexState *ls, int token) {
+ if (token < FIRST_RESERVED) {
+ lua_assert(token == (unsigned char)token);
+ return luaO_pushfstring(ls->L, "%c", token);
+ }
+ else
+ return token2string[token-FIRST_RESERVED];
+}
+
+
+static void luaX_lexerror (LexState *ls, const char *s, int token) {
+ if (token == TK_EOS)
+ luaX_error(ls, s, luaX_token2str(ls, token));
+ else
+ luaX_error(ls, s, luaZ_buffer(ls->buff));
+}
+
+
+static void inclinenumber (LexState *LS) {
+ next(LS); /* skip `\n' */
+ ++LS->linenumber;
+ luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk");
+}
+
+
+void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) {
+ LS->L = L;
+ LS->lookahead.token = TK_EOS; /* no look-ahead token */
+ LS->z = z;
+ LS->fs = NULL;
+ LS->linenumber = 1;
+ LS->lastline = 1;
+ LS->source = source;
+ next(LS); /* read first char */
+ if (LS->current == '#') {
+ do { /* skip first line */
+ next(LS);
+ } while (LS->current != '\n' && LS->current != EOZ);
+ }
+}
+
+
+
+/*
+** =======================================================
+** LEXICAL ANALYZER
+** =======================================================
+*/
+
+
+/* use buffer to store names, literal strings and numbers */
+
+/* extra space to allocate when growing buffer */
+#define EXTRABUFF 32
+
+/* maximum number of chars that can be read without checking buffer size */
+#define MAXNOCHECK 5
+
+#define checkbuffer(LS, len) \
+ if (((len)+MAXNOCHECK)*sizeof(char) > luaZ_sizebuffer((LS)->buff)) \
+ luaZ_openspace((LS)->L, (LS)->buff, (len)+EXTRABUFF)
+
+#define save(LS, c, l) \
+ (luaZ_buffer((LS)->buff)[l++] = cast(char, c))
+#define save_and_next(LS, l) (save(LS, LS->current, l), next(LS))
+
+
+static size_t readname (LexState *LS) {
+ size_t l = 0;
+ checkbuffer(LS, l);
+ do {
+ checkbuffer(LS, l);
+ save_and_next(LS, l);
+ } while (isalnum(LS->current) || LS->current == '_');
+ save(LS, '\0', l);
+ return l-1;
+}
+
+
+/* LUA_NUMBER */
+static void read_numeral (LexState *LS, int comma, SemInfo *seminfo) {
+ int oct = 0, hex = 0;
+ size_t l = 0;
+ checkbuffer(LS, l);
+ if (comma) save(LS, '.', l);
+ else if (LS->current == '0') {
+ oct = 1;
+ checkbuffer(LS, 1);
+ save_and_next(LS, l);
+ if (LS->current == 'x') {
+ oct = 0;
+ hex = 1;
+ checkbuffer(LS, 1);
+ save_and_next(LS, l);
+ }
+ }
+ while (isdigit(LS->current) || (hex && isxdigit(LS->current))) {
+ checkbuffer(LS, l);
+ save_and_next(LS, l);
+ }
+ checkbuffer(LS, 1);
+ if (LS->current == '.') {
+ save_and_next(LS, l);
+ if (hex || oct) {
+ save(LS, '\0', l);
+ luaX_lexerror(LS,
+ "error in number, mixing decimal point with octal or hexadecimal",
+ TK_NUMBER);
+ }
+ if (LS->current == '.') {
+ save_and_next(LS, l);
+ save(LS, '\0', l);
+ luaX_lexerror(LS,
+ "ambiguous syntax (decimal point x string concatenation)",
+ TK_NUMBER);
+ }
+ }
+ while (isdigit(LS->current)) {
+ checkbuffer(LS, l);
+ save_and_next(LS, l);
+ }
+ if (LS->current == 'e' || LS->current == 'E') {
+ save_and_next(LS, l); /* read `E' */
+ if (hex || oct) {
+ save(LS, '\0', l);
+ luaX_lexerror(LS,
+ "error in number, mixing exponential with octal or hexadecimal",
+ TK_NUMBER);
+ }
+ if (LS->current == '+' || LS->current == '-')
+ save_and_next(LS, l); /* optional exponent sign */
+ while (isdigit(LS->current)) {
+ checkbuffer(LS, l);
+ save_and_next(LS, l);
+ }
+ }
+ save(LS, '\0', l);
+ if (!luaO_str2d(luaZ_buffer(LS->buff), &seminfo->r))
+ luaX_lexerror(LS, "malformed number", TK_NUMBER);
+}
+
+
+static void read_long_string (LexState *LS, SemInfo *seminfo) {
+ int cont = 0;
+ size_t l = 0;
+ checkbuffer(LS, l);
+ save(LS, '[', l); /* save first `[' */
+ save_and_next(LS, l); /* pass the second `[' */
+ if (LS->current == '\n') /* string starts with a newline? */
+ inclinenumber(LS); /* skip it */
+ for (;;) {
+ checkbuffer(LS, l);
+ switch (LS->current) {
+ case EOZ:
+ save(LS, '\0', l);
+ luaX_lexerror(LS, (seminfo) ? "unfinished long string" :
+ "unfinished long comment", TK_EOS);
+ break; /* to avoid warnings */
+ case '[':
+ save_and_next(LS, l);
+ if (LS->current == '[') {
+ cont++;
+ save_and_next(LS, l);
+ }
+ continue;
+ case ']':
+ save_and_next(LS, l);
+ if (LS->current == ']') {
+ if (cont == 0) goto endloop;
+ cont--;
+ save_and_next(LS, l);
+ }
+ continue;
+ case '\n':
+ save(LS, '\n', l);
+ inclinenumber(LS);
+ if (!seminfo) l = 0; /* reset buffer to avoid wasting space */
+ continue;
+ default:
+ save_and_next(LS, l);
+ }
+ } endloop:
+ save_and_next(LS, l); /* skip the second `]' */
+ save(LS, '\0', l);
+ if (seminfo)
+ seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 2, l - 5);
+}
+
+
+static void read_string (LexState *LS, int del, SemInfo *seminfo) {
+ size_t l = 0;
+ checkbuffer(LS, l);
+ save_and_next(LS, l);
+ while (LS->current != del) {
+ checkbuffer(LS, l);
+ switch (LS->current) {
+ case EOZ:
+ save(LS, '\0', l);
+ luaX_lexerror(LS, "unfinished string", TK_EOS);
+ break; /* to avoid warnings */
+ case '\n':
+ save(LS, '\0', l);
+ luaX_lexerror(LS, "unfinished string", TK_STRING);
+ break; /* to avoid warnings */
+ case '\\':
+ next(LS); /* do not save the `\' */
+ switch (LS->current) {
+ case 'a': save(LS, '\a', l); next(LS); break;
+ case 'b': save(LS, '\b', l); next(LS); break;
+ case 'f': save(LS, '\f', l); next(LS); break;
+ case 'n': save(LS, '\n', l); next(LS); break;
+ case 'r': save(LS, '\r', l); next(LS); break;
+ case 't': save(LS, '\t', l); next(LS); break;
+ case 'v': save(LS, '\v', l); next(LS); break;
+ case '\n': save(LS, '\n', l); inclinenumber(LS); break;
+ case EOZ: break; /* will raise an error next loop */
+ default: {
+ if (!isdigit(LS->current))
+ save_and_next(LS, l); /* handles \\, \", \', and \? */
+ else { /* \xxx */
+ int c = 0;
+ int i = 0;
+ do {
+ c = 10*c + (LS->current-'0');
+ next(LS);
+ } while (++i<3 && isdigit(LS->current));
+ if (c > UCHAR_MAX) {
+ save(LS, '\0', l);
+ luaX_lexerror(LS, "escape sequence too large", TK_STRING);
+ }
+ save(LS, c, l);
+ }
+ }
+ }
+ break;
+ default:
+ save_and_next(LS, l);
+ }
+ }
+ save_and_next(LS, l); /* skip delimiter */
+ save(LS, '\0', l);
+ seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 1, l - 3);
+}
+
+
+int luaX_lex (LexState *LS, SemInfo *seminfo) {
+ for (;;) {
+ switch (LS->current) {
+
+ case '\n': {
+ inclinenumber(LS);
+ continue;
+ }
+ case '-': {
+ next(LS);
+ if (LS->current != '-') return '-';
+ /* else is a comment */
+ next(LS);
+ if (LS->current == '[' && (next(LS), LS->current == '['))
+ read_long_string(LS, NULL); /* long comment */
+ else /* short comment */
+ while (LS->current != '\n' && LS->current != EOZ)
+ next(LS);
+ continue;
+ }
+ case '[': {
+ next(LS);
+ if (LS->current != '[') return '[';
+ else {
+ read_long_string(LS, seminfo);
+ return TK_STRING;
+ }
+ }
+ case '=': {
+ next(LS);
+ if (LS->current != '=') return '=';
+ else { next(LS); return TK_EQ; }
+ }
+ case '<': {
+ next(LS);
+ if (LS->current != '=') return '<';
+ else { next(LS); return TK_LE; }
+ }
+ case '>': {
+ next(LS);
+ if (LS->current != '=') return '>';
+ else { next(LS); return TK_GE; }
+ }
+ case '~': {
+ next(LS);
+ if (LS->current != '=') return '~';
+ else { next(LS); return TK_NE; }
+ }
+ case '"':
+ case '\'': {
+ read_string(LS, LS->current, seminfo);
+ return TK_STRING;
+ }
+ case '.': {
+ next(LS);
+ if (LS->current == '.') {
+ next(LS);
+ if (LS->current == '.') {
+ next(LS);
+ return TK_DOTS; /* ... */
+ }
+ else return TK_CONCAT; /* .. */
+ }
+ else if (!isdigit(LS->current)) return '.';
+ else {
+ read_numeral(LS, 1, seminfo);
+ return TK_NUMBER;
+ }
+ }
+ case EOZ: {
+ return TK_EOS;
+ }
+ default: {
+ if (isspace(LS->current)) {
+ next(LS);
+ continue;
+ }
+ else if (isdigit(LS->current)) {
+ read_numeral(LS, 0, seminfo);
+ return TK_NUMBER;
+ }
+ else if (isalpha(LS->current) || LS->current == '_') {
+ /* identifier or reserved word */
+ size_t l = readname(LS);
+ TString *ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff), l);
+ if (ts->tsv.reserved > 0) /* reserved word? */
+ return ts->tsv.reserved - 1 + FIRST_RESERVED;
+ seminfo->ts = ts;
+ return TK_NAME;
+ }
+ else {
+ int c = LS->current;
+ if (iscntrl(c))
+ luaX_error(LS, "invalid control char",
+ luaO_pushfstring(LS->L, "char(%d)", c));
+ next(LS);
+ return c; /* single-char tokens (+ - / ...) */
+ }
+ }
+ }
+ }
+}
+
+#undef next
diff --git a/lib/lua/src/lmem.c b/lib/lua/src/lmem.c
index e14f798..b10ec3f 100644
--- a/lib/lua/src/lmem.c
+++ b/lib/lua/src/lmem.c
@@ -1,91 +1,91 @@
-/*
-** $Id: lmem.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** Interface to Memory Manager
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stdlib.h>
-
-#define lmem_c
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-
-
-
-/*
-** definition for realloc function. It must assure that l_realloc(NULL,
-** 0, x) allocates a new block (ANSI C assures that). (`os' is the old
-** block size; some allocators may use that.)
-*/
-#ifndef l_realloc
-#define l_realloc(b,os,s) realloc(b,s)
-#endif
-
-/*
-** definition for free function. (`os' is the old block size; some
-** allocators may use that.)
-*/
-#ifndef l_free
-#define l_free(b,os) free(b)
-#endif
-
-
-#define MINSIZEARRAY 4
-
-
-void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
- int limit, const char *errormsg) {
- void *newblock;
- int newsize = (*size)*2;
- if (newsize < MINSIZEARRAY)
- newsize = MINSIZEARRAY; /* minimum size */
- else if (*size >= limit/2) { /* cannot double it? */
- if (*size < limit - MINSIZEARRAY) /* try something smaller... */
- newsize = limit; /* still have at least MINSIZEARRAY free places */
- else luaG_runerror(L, errormsg);
- }
- newblock = luaM_realloc(L, block,
- cast(lu_mem, *size)*cast(lu_mem, size_elems),
- cast(lu_mem, newsize)*cast(lu_mem, size_elems));
- *size = newsize; /* update only when everything else is OK */
- return newblock;
-}
-
-
-/*
-** generic allocation routine.
-*/
-void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem size) {
- lua_assert((oldsize == 0) == (block == NULL));
- if (size == 0) {
- if (block != NULL) {
- l_free(block, oldsize);
- block = NULL;
- }
- else return NULL; /* avoid `nblocks' computations when oldsize==size==0 */
- }
- else if (size >= MAX_SIZET)
- luaG_runerror(L, "memory allocation error: block too big");
- else {
- block = l_realloc(block, oldsize, size);
- if (block == NULL) {
- if (L)
- luaD_throw(L, LUA_ERRMEM);
- else return NULL; /* error before creating state! */
- }
- }
- if (L) {
- lua_assert(G(L) != NULL && G(L)->nblocks > 0);
- G(L)->nblocks -= oldsize;
- G(L)->nblocks += size;
- }
- return block;
-}
-
+/*
+** $Id: lmem.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** Interface to Memory Manager
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdlib.h>
+
+#define lmem_c
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+
+
+
+/*
+** definition for realloc function. It must assure that l_realloc(NULL,
+** 0, x) allocates a new block (ANSI C assures that). (`os' is the old
+** block size; some allocators may use that.)
+*/
+#ifndef l_realloc
+#define l_realloc(b,os,s) realloc(b,s)
+#endif
+
+/*
+** definition for free function. (`os' is the old block size; some
+** allocators may use that.)
+*/
+#ifndef l_free
+#define l_free(b,os) free(b)
+#endif
+
+
+#define MINSIZEARRAY 4
+
+
+void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
+ int limit, const char *errormsg) {
+ void *newblock;
+ int newsize = (*size)*2;
+ if (newsize < MINSIZEARRAY)
+ newsize = MINSIZEARRAY; /* minimum size */
+ else if (*size >= limit/2) { /* cannot double it? */
+ if (*size < limit - MINSIZEARRAY) /* try something smaller... */
+ newsize = limit; /* still have at least MINSIZEARRAY free places */
+ else luaG_runerror(L, errormsg);
+ }
+ newblock = luaM_realloc(L, block,
+ cast(lu_mem, *size)*cast(lu_mem, size_elems),
+ cast(lu_mem, newsize)*cast(lu_mem, size_elems));
+ *size = newsize; /* update only when everything else is OK */
+ return newblock;
+}
+
+
+/*
+** generic allocation routine.
+*/
+void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem size) {
+ lua_assert((oldsize == 0) == (block == NULL));
+ if (size == 0) {
+ if (block != NULL) {
+ l_free(block, oldsize);
+ block = NULL;
+ }
+ else return NULL; /* avoid `nblocks' computations when oldsize==size==0 */
+ }
+ else if (size >= MAX_SIZET)
+ luaG_runerror(L, "memory allocation error: block too big");
+ else {
+ block = l_realloc(block, oldsize, size);
+ if (block == NULL) {
+ if (L)
+ luaD_throw(L, LUA_ERRMEM);
+ else return NULL; /* error before creating state! */
+ }
+ }
+ if (L) {
+ lua_assert(G(L) != NULL && G(L)->nblocks > 0);
+ G(L)->nblocks -= oldsize;
+ G(L)->nblocks += size;
+ }
+ return block;
+}
+
diff --git a/lib/lua/src/lobject.c b/lib/lua/src/lobject.c
index 7153a1c..bdc83b3 100644
--- a/lib/lua/src/lobject.c
+++ b/lib/lua/src/lobject.c
@@ -1,198 +1,198 @@
-/*
-** $Id: lobject.c,v 1.4 2004-11-27 21:35:20 pixel Exp $
-** Some generic functions over Lua objects
-** See Copyright Notice in lua.h
-*/
-
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define lobject_c
-
-#include "lua.h"
-
-#include "ldo.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "lvm.h"
-
-const TObject luaO_nilobject = {LUA_TNIL, {NULL}};
-
-
-/*
-** converts an integer to a "floating point byte", represented as
-** (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm)
-*/
-int luaO_int2fb (unsigned int x) {
- int m = 0; /* mantissa */
- while (x >= (1<<3)) {
- x = (x+1) >> 1;
- m++;
- }
- return (m << 3) | cast(int, x);
-}
-
-
-int luaO_log2 (unsigned int x) {
- static const lu_byte log_8[255] = {
- 0,
- 1,1,
- 2,2,2,2,
- 3,3,3,3,3,3,3,3,
- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
- };
- if (x >= 0x00010000) {
- if (x >= 0x01000000) return log_8[((x>>24) & 0xff) - 1]+24;
- else return log_8[((x>>16) & 0xff) - 1]+16;
- }
- else {
- if (x >= 0x00000100) return log_8[((x>>8) & 0xff) - 1]+8;
- else if (x) return log_8[(x & 0xff) - 1];
- return -1; /* special `log' for 0 */
- }
-}
-
-
-int luaO_rawequalObj (const TObject *t1, const TObject *t2) {
- if (ttype(t1) != ttype(t2)) return 0;
- else switch (ttype(t1)) {
- case LUA_TNIL:
- return 1;
- case LUA_TNUMBER:
- return nvalue(t1) == nvalue(t2);
- case LUA_TBOOLEAN:
- return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
- case LUA_TLIGHTUSERDATA:
- return pvalue(t1) == pvalue(t2);
- default:
- lua_assert(iscollectable(t1));
- return gcvalue(t1) == gcvalue(t2);
- }
-}
-
-
-int luaO_str2d (const char *s, lua_Number *result) {
- char *endptr;
- size_t l = strlen(s);
- lua_Number res;
- if ((l > 0) && (s[0] == '0')) {
- if ((l > 2) && (s[1] == 'x')) {
- res = strtol(s + 2, &endptr, 16);
- } else {
- res = strtol(s + 1, &endptr, 8);
- }
- } else {
- res = strtod(s, &endptr);
- }
- if (endptr == s) return 0; /* no conversion */
- while (isspace((unsigned char)(*endptr))) endptr++;
- if (*endptr != '\0') return 0; /* invalid trailing characters? */
- *result = res;
- return 1;
-}
-
-
-
-static void pushstr (lua_State *L, const char *str) {
- setsvalue2s(L->top, luaS_new(L, str));
- incr_top(L);
-}
-
-
-/* this function handles only `%d', `%c', %f, and `%s' formats */
-const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
- int n = 1;
- pushstr(L, "");
- for (;;) {
- const char *e = strchr(fmt, '%');
- if (e == NULL) break;
- setsvalue2s(L->top, luaS_newlstr(L, fmt, e-fmt));
- incr_top(L);
- switch (*(e+1)) {
- case 's':
- pushstr(L, va_arg(argp, char *));
- break;
- case 'c': {
- char buff[2];
- buff[0] = cast(char, va_arg(argp, int));
- buff[1] = '\0';
- pushstr(L, buff);
- break;
- }
- case 'd':
- setnvalue(L->top, cast(lua_Number, va_arg(argp, int)));
- incr_top(L);
- break;
- case 'f':
- setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber)));
- incr_top(L);
- break;
- case '%':
- pushstr(L, "%");
- break;
- default: lua_assert(0);
- }
- n += 2;
- fmt = e+2;
- }
- pushstr(L, fmt);
- luaV_concat(L, n+1, L->top - L->base - 1);
- L->top -= n;
- return svalue(L->top - 1);
-}
-
-
-const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
- const char *msg;
- va_list argp;
- va_start(argp, fmt);
- msg = luaO_pushvfstring(L, fmt, argp);
- va_end(argp);
- return msg;
-}
-
-
-void luaO_chunkid (char *out, const char *source, int bufflen) {
- if (*source == '=') {
- strncpy(out, source+1, bufflen); /* remove first char */
- out[bufflen-1] = '\0'; /* ensures null termination */
- }
- else { /* out = "source", or "...source" */
- if (*source == '@') {
- int l;
- source++; /* skip the `@' */
- bufflen -= sizeof(" `...' ");
- l = strlen(source);
- strcpy(out, "");
- if (l>bufflen) {
- source += (l-bufflen); /* get last part of file name */
- strcat(out, "...");
- }
- strcat(out, source);
- }
- else { /* out = [string "string"] */
- int len = strcspn(source, "\n"); /* stop at first newline */
- bufflen -= sizeof(" [string \"...\"] ");
- if (len > bufflen) len = bufflen;
- strcpy(out, "[string \"");
- if (source[len] != '\0') { /* must truncate? */
- strncat(out, source, len);
- strcat(out, "...");
- }
- else
- strcat(out, source);
- strcat(out, "\"]");
- }
- }
-}
+/*
+** $Id: lobject.c,v 1.5 2004-11-27 21:46:07 pixel Exp $
+** Some generic functions over Lua objects
+** See Copyright Notice in lua.h
+*/
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lobject_c
+
+#include "lua.h"
+
+#include "ldo.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "lvm.h"
+
+const TObject luaO_nilobject = {LUA_TNIL, {NULL}};
+
+
+/*
+** converts an integer to a "floating point byte", represented as
+** (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm)
+*/
+int luaO_int2fb (unsigned int x) {
+ int m = 0; /* mantissa */
+ while (x >= (1<<3)) {
+ x = (x+1) >> 1;
+ m++;
+ }
+ return (m << 3) | cast(int, x);
+}
+
+
+int luaO_log2 (unsigned int x) {
+ static const lu_byte log_8[255] = {
+ 0,
+ 1,1,
+ 2,2,2,2,
+ 3,3,3,3,3,3,3,3,
+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
+ };
+ if (x >= 0x00010000) {
+ if (x >= 0x01000000) return log_8[((x>>24) & 0xff) - 1]+24;
+ else return log_8[((x>>16) & 0xff) - 1]+16;
+ }
+ else {
+ if (x >= 0x00000100) return log_8[((x>>8) & 0xff) - 1]+8;
+ else if (x) return log_8[(x & 0xff) - 1];
+ return -1; /* special `log' for 0 */
+ }
+}
+
+
+int luaO_rawequalObj (const TObject *t1, const TObject *t2) {
+ if (ttype(t1) != ttype(t2)) return 0;
+ else switch (ttype(t1)) {
+ case LUA_TNIL:
+ return 1;
+ case LUA_TNUMBER:
+ return nvalue(t1) == nvalue(t2);
+ case LUA_TBOOLEAN:
+ return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
+ case LUA_TLIGHTUSERDATA:
+ return pvalue(t1) == pvalue(t2);
+ default:
+ lua_assert(iscollectable(t1));
+ return gcvalue(t1) == gcvalue(t2);
+ }
+}
+
+
+int luaO_str2d (const char *s, lua_Number *result) {
+ char *endptr;
+ size_t l = strlen(s);
+ lua_Number res;
+ if ((l > 0) && (s[0] == '0')) {
+ if ((l > 2) && (s[1] == 'x')) {
+ res = strtol(s + 2, &endptr, 16);
+ } else {
+ res = strtol(s + 1, &endptr, 8);
+ }
+ } else {
+ res = strtod(s, &endptr);
+ }
+ if (endptr == s) return 0; /* no conversion */
+ while (isspace((unsigned char)(*endptr))) endptr++;
+ if (*endptr != '\0') return 0; /* invalid trailing characters? */
+ *result = res;
+ return 1;
+}
+
+
+
+static void pushstr (lua_State *L, const char *str) {
+ setsvalue2s(L->top, luaS_new(L, str));
+ incr_top(L);
+}
+
+
+/* this function handles only `%d', `%c', %f, and `%s' formats */
+const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
+ int n = 1;
+ pushstr(L, "");
+ for (;;) {
+ const char *e = strchr(fmt, '%');
+ if (e == NULL) break;
+ setsvalue2s(L->top, luaS_newlstr(L, fmt, e-fmt));
+ incr_top(L);
+ switch (*(e+1)) {
+ case 's':
+ pushstr(L, va_arg(argp, char *));
+ break;
+ case 'c': {
+ char buff[2];
+ buff[0] = cast(char, va_arg(argp, int));
+ buff[1] = '\0';
+ pushstr(L, buff);
+ break;
+ }
+ case 'd':
+ setnvalue(L->top, cast(lua_Number, va_arg(argp, int)));
+ incr_top(L);
+ break;
+ case 'f':
+ setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber)));
+ incr_top(L);
+ break;
+ case '%':
+ pushstr(L, "%");
+ break;
+ default: lua_assert(0);
+ }
+ n += 2;
+ fmt = e+2;
+ }
+ pushstr(L, fmt);
+ luaV_concat(L, n+1, L->top - L->base - 1);
+ L->top -= n;
+ return svalue(L->top - 1);
+}
+
+
+const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
+ const char *msg;
+ va_list argp;
+ va_start(argp, fmt);
+ msg = luaO_pushvfstring(L, fmt, argp);
+ va_end(argp);
+ return msg;
+}
+
+
+void luaO_chunkid (char *out, const char *source, int bufflen) {
+ if (*source == '=') {
+ strncpy(out, source+1, bufflen); /* remove first char */
+ out[bufflen-1] = '\0'; /* ensures null termination */
+ }
+ else { /* out = "source", or "...source" */
+ if (*source == '@') {
+ int l;
+ source++; /* skip the `@' */
+ bufflen -= sizeof(" `...' ");
+ l = strlen(source);
+ strcpy(out, "");
+ if (l>bufflen) {
+ source += (l-bufflen); /* get last part of file name */
+ strcat(out, "...");
+ }
+ strcat(out, source);
+ }
+ else { /* out = [string "string"] */
+ int len = strcspn(source, "\n"); /* stop at first newline */
+ bufflen -= sizeof(" [string \"...\"] ");
+ if (len > bufflen) len = bufflen;
+ strcpy(out, "[string \"");
+ if (source[len] != '\0') { /* must truncate? */
+ strncat(out, source, len);
+ strcat(out, "...");
+ }
+ else
+ strcat(out, source);
+ strcat(out, "\"]");
+ }
+ }
+}
diff --git a/lib/lua/src/lopcodes.c b/lib/lua/src/lopcodes.c
index 6d405d4..c018ea8 100644
--- a/lib/lua/src/lopcodes.c
+++ b/lib/lua/src/lopcodes.c
@@ -1,102 +1,102 @@
-/*
-** $Id: lopcodes.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** extracted automatically from lopcodes.h by mkprint.lua
-** DO NOT EDIT
-** See Copyright Notice in lua.h
-*/
-
-
-#define lopcodes_c
-
-#include "lua.h"
-
-#include "lobject.h"
-#include "lopcodes.h"
-
-
-#ifdef LUA_OPNAMES
-
-const char *const luaP_opnames[] = {
- "MOVE",
- "LOADK",
- "LOADBOOL",
- "LOADNIL",
- "GETUPVAL",
- "GETGLOBAL",
- "GETTABLE",
- "SETGLOBAL",
- "SETUPVAL",
- "SETTABLE",
- "NEWTABLE",
- "SELF",
- "ADD",
- "SUB",
- "MUL",
- "DIV",
- "POW",
- "UNM",
- "NOT",
- "CONCAT",
- "JMP",
- "EQ",
- "LT",
- "LE",
- "TEST",
- "CALL",
- "TAILCALL",
- "RETURN",
- "FORLOOP",
- "TFORLOOP",
- "TFORPREP",
- "SETLIST",
- "SETLISTO",
- "CLOSE",
- "CLOSURE"
-};
-
-#endif
-
-#define opmode(t,b,bk,ck,sa,k,m) (((t)<<OpModeT) | \
- ((b)<<OpModeBreg) | ((bk)<<OpModeBrk) | ((ck)<<OpModeCrk) | \
- ((sa)<<OpModesetA) | ((k)<<OpModeK) | (m))
-
-
-const lu_byte luaP_opmodes[NUM_OPCODES] = {
-/* T B Bk Ck sA K mode opcode */
- opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_MOVE */
- ,opmode(0, 0, 0, 0, 1, 1, iABx) /* OP_LOADK */
- ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_LOADBOOL */
- ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_LOADNIL */
- ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_GETUPVAL */
- ,opmode(0, 0, 0, 0, 1, 1, iABx) /* OP_GETGLOBAL */
- ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_GETTABLE */
- ,opmode(0, 0, 0, 0, 0, 1, iABx) /* OP_SETGLOBAL */
- ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */
- ,opmode(0, 0, 1, 1, 0, 0, iABC) /* OP_SETTABLE */
- ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_NEWTABLE */
- ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_SELF */
- ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_ADD */
- ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_SUB */
- ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_MUL */
- ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_DIV */
- ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_POW */
- ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_UNM */
- ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_NOT */
- ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_CONCAT */
- ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_JMP */
- ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_EQ */
- ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_LT */
- ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_LE */
- ,opmode(1, 1, 0, 0, 1, 0, iABC) /* OP_TEST */
- ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_CALL */
- ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_TAILCALL */
- ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_RETURN */
- ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_FORLOOP */
- ,opmode(1, 0, 0, 0, 0, 0, iABC) /* OP_TFORLOOP */
- ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_TFORPREP */
- ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLIST */
- ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLISTO */
- ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_CLOSE */
- ,opmode(0, 0, 0, 0, 1, 0, iABx) /* OP_CLOSURE */
-};
-
+/*
+** $Id: lopcodes.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** extracted automatically from lopcodes.h by mkprint.lua
+** DO NOT EDIT
+** See Copyright Notice in lua.h
+*/
+
+
+#define lopcodes_c
+
+#include "lua.h"
+
+#include "lobject.h"
+#include "lopcodes.h"
+
+
+#ifdef LUA_OPNAMES
+
+const char *const luaP_opnames[] = {
+ "MOVE",
+ "LOADK",
+ "LOADBOOL",
+ "LOADNIL",
+ "GETUPVAL",
+ "GETGLOBAL",
+ "GETTABLE",
+ "SETGLOBAL",
+ "SETUPVAL",
+ "SETTABLE",
+ "NEWTABLE",
+ "SELF",
+ "ADD",
+ "SUB",
+ "MUL",
+ "DIV",
+ "POW",
+ "UNM",
+ "NOT",
+ "CONCAT",
+ "JMP",
+ "EQ",
+ "LT",
+ "LE",
+ "TEST",
+ "CALL",
+ "TAILCALL",
+ "RETURN",
+ "FORLOOP",
+ "TFORLOOP",
+ "TFORPREP",
+ "SETLIST",
+ "SETLISTO",
+ "CLOSE",
+ "CLOSURE"
+};
+
+#endif
+
+#define opmode(t,b,bk,ck,sa,k,m) (((t)<<OpModeT) | \
+ ((b)<<OpModeBreg) | ((bk)<<OpModeBrk) | ((ck)<<OpModeCrk) | \
+ ((sa)<<OpModesetA) | ((k)<<OpModeK) | (m))
+
+
+const lu_byte luaP_opmodes[NUM_OPCODES] = {
+/* T B Bk Ck sA K mode opcode */
+ opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_MOVE */
+ ,opmode(0, 0, 0, 0, 1, 1, iABx) /* OP_LOADK */
+ ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_LOADBOOL */
+ ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_LOADNIL */
+ ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_GETUPVAL */
+ ,opmode(0, 0, 0, 0, 1, 1, iABx) /* OP_GETGLOBAL */
+ ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_GETTABLE */
+ ,opmode(0, 0, 0, 0, 0, 1, iABx) /* OP_SETGLOBAL */
+ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */
+ ,opmode(0, 0, 1, 1, 0, 0, iABC) /* OP_SETTABLE */
+ ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_NEWTABLE */
+ ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_SELF */
+ ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_ADD */
+ ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_SUB */
+ ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_MUL */
+ ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_DIV */
+ ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_POW */
+ ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_UNM */
+ ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_NOT */
+ ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_CONCAT */
+ ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_JMP */
+ ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_EQ */
+ ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_LT */
+ ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_LE */
+ ,opmode(1, 1, 0, 0, 1, 0, iABC) /* OP_TEST */
+ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_CALL */
+ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_TAILCALL */
+ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_RETURN */
+ ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_FORLOOP */
+ ,opmode(1, 0, 0, 0, 0, 0, iABC) /* OP_TFORLOOP */
+ ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_TFORPREP */
+ ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLIST */
+ ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLISTO */
+ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_CLOSE */
+ ,opmode(0, 0, 0, 0, 1, 0, iABx) /* OP_CLOSURE */
+};
+
diff --git a/lib/lua/src/lparser.c b/lib/lua/src/lparser.c
index 2b557d4..a242338 100644
--- a/lib/lua/src/lparser.c
+++ b/lib/lua/src/lparser.c
@@ -1,1329 +1,1329 @@
-/*
-** $Id: lparser.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** Lua Parser
-** See Copyright Notice in lua.h
-*/
-
-
-#include <string.h>
-
-#define lparser_c
-
-#include "lua.h"
-
-#include "lcode.h"
-#include "ldebug.h"
-#include "lfunc.h"
-#include "llex.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lparser.h"
-#include "lstate.h"
-#include "lstring.h"
-
-
-
-
-#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
-
-
-#define enterlevel(ls) if (++(ls)->nestlevel > LUA_MAXPARSERLEVEL) \
- luaX_syntaxerror(ls, "too many syntax levels");
-#define leavelevel(ls) ((ls)->nestlevel--)
-
-
-/*
-** nodes for block list (list of active blocks)
-*/
-typedef struct BlockCnt {
- struct BlockCnt *previous; /* chain */
- int breaklist; /* list of jumps out of this loop */
- int nactvar; /* # active local variables outside the breakable structure */
- int upval; /* true if some variable in the block is an upvalue */
- int isbreakable; /* true if `block' is a loop */
-} BlockCnt;
-
-
-
-/*
-** prototypes for recursive non-terminal functions
-*/
-static void chunk (LexState *ls);
-static void expr (LexState *ls, expdesc *v);
-
-
-
-static void next (LexState *ls) {
- ls->lastline = ls->linenumber;
- if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
- ls->t = ls->lookahead; /* use this one */
- ls->lookahead.token = TK_EOS; /* and discharge it */
- }
- else
- ls->t.token = luaX_lex(ls, &ls->t.seminfo); /* read next token */
-}
-
-
-static void lookahead (LexState *ls) {
- lua_assert(ls->lookahead.token == TK_EOS);
- ls->lookahead.token = luaX_lex(ls, &ls->lookahead.seminfo);
-}
-
-
-static void error_expected (LexState *ls, int token) {
- luaX_syntaxerror(ls,
- luaO_pushfstring(ls->L, "`%s' expected", luaX_token2str(ls, token)));
-}
-
-
-static int testnext (LexState *ls, int c) {
- if (ls->t.token == c) {
- next(ls);
- return 1;
- }
- else return 0;
-}
-
-
-static void check (LexState *ls, int c) {
- if (!testnext(ls, c))
- error_expected(ls, c);
-}
-
-
-#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
-
-
-
-static void check_match (LexState *ls, int what, int who, int where) {
- if (!testnext(ls, what)) {
- if (where == ls->linenumber)
- error_expected(ls, what);
- else {
- luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
- "`%s' expected (to close `%s' at line %d)",
- luaX_token2str(ls, what), luaX_token2str(ls, who), where));
- }
- }
-}
-
-
-static TString *str_checkname (LexState *ls) {
- TString *ts;
- check_condition(ls, (ls->t.token == TK_NAME), "<name> expected");
- ts = ls->t.seminfo.ts;
- next(ls);
- return ts;
-}
-
-
-static void init_exp (expdesc *e, expkind k, int i) {
- e->f = e->t = NO_JUMP;
- e->k = k;
- e->info = i;
-}
-
-
-static void codestring (LexState *ls, expdesc *e, TString *s) {
- init_exp(e, VK, luaK_stringK(ls->fs, s));
-}
-
-
-static void checkname(LexState *ls, expdesc *e) {
- codestring(ls, e, str_checkname(ls));
-}
-
-
-static int luaI_registerlocalvar (LexState *ls, TString *varname) {
- FuncState *fs = ls->fs;
- Proto *f = fs->f;
- luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
- LocVar, MAX_INT, "");
- f->locvars[fs->nlocvars].varname = varname;
- return fs->nlocvars++;
-}
-
-
-static void new_localvar (LexState *ls, TString *name, int n) {
- FuncState *fs = ls->fs;
- luaX_checklimit(ls, fs->nactvar+n+1, MAXVARS, "local variables");
- fs->actvar[fs->nactvar+n] = luaI_registerlocalvar(ls, name);
-}
-
-
-static void adjustlocalvars (LexState *ls, int nvars) {
- FuncState *fs = ls->fs;
- fs->nactvar += nvars;
- for (; nvars; nvars--) {
- getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
- }
-}
-
-
-static void removevars (LexState *ls, int tolevel) {
- FuncState *fs = ls->fs;
- while (fs->nactvar > tolevel)
- getlocvar(fs, --fs->nactvar).endpc = fs->pc;
-}
-
-
-static void new_localvarstr (LexState *ls, const char *name, int n) {
- new_localvar(ls, luaS_new(ls->L, name), n);
-}
-
-
-static void create_local (LexState *ls, const char *name) {
- new_localvarstr(ls, name, 0);
- adjustlocalvars(ls, 1);
-}
-
-
-static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
- int i;
- Proto *f = fs->f;
- for (i=0; i<f->nups; i++) {
- if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) {
- lua_assert(fs->f->upvalues[i] == name);
- return i;
- }
- }
- /* new one */
- luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues");
- luaM_growvector(fs->L, fs->f->upvalues, f->nups, fs->f->sizeupvalues,
- TString *, MAX_INT, "");
- fs->f->upvalues[f->nups] = name;
- fs->upvalues[f->nups] = *v;
- return f->nups++;
-}
-
-
-static int searchvar (FuncState *fs, TString *n) {
- int i;
- for (i=fs->nactvar-1; i >= 0; i--) {
- if (n == getlocvar(fs, i).varname)
- return i;
- }
- return -1; /* not found */
-}
-
-
-static void markupval (FuncState *fs, int level) {
- BlockCnt *bl = fs->bl;
- while (bl && bl->nactvar > level) bl = bl->previous;
- if (bl) bl->upval = 1;
-}
-
-
-static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
- if (fs == NULL) /* no more levels? */
- init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
- else {
- int v = searchvar(fs, n); /* look up at current level */
- if (v >= 0) {
- init_exp(var, VLOCAL, v);
- if (!base)
- markupval(fs, v); /* local will be used as an upval */
- }
- else { /* not found at current level; try upper one */
- singlevaraux(fs->prev, n, var, 0);
- if (var->k == VGLOBAL) {
- if (base)
- var->info = luaK_stringK(fs, n); /* info points to global name */
- }
- else { /* LOCAL or UPVAL */
- var->info = indexupvalue(fs, n, var);
- var->k = VUPVAL; /* upvalue in this level */
- }
- }
- }
-}
-
-
-static TString *singlevar (LexState *ls, expdesc *var, int base) {
- TString *varname = str_checkname(ls);
- singlevaraux(ls->fs, varname, var, base);
- return varname;
-}
-
-
-static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
- FuncState *fs = ls->fs;
- int extra = nvars - nexps;
- if (e->k == VCALL) {
- extra++; /* includes call itself */
- if (extra <= 0) extra = 0;
- else luaK_reserveregs(fs, extra-1);
- luaK_setcallreturns(fs, e, extra); /* call provides the difference */
- }
- else {
- if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
- if (extra > 0) {
- int reg = fs->freereg;
- luaK_reserveregs(fs, extra);
- luaK_nil(fs, reg, extra);
- }
- }
-}
-
-
-static void code_params (LexState *ls, int nparams, int dots) {
- FuncState *fs = ls->fs;
- adjustlocalvars(ls, nparams);
- luaX_checklimit(ls, fs->nactvar, MAXPARAMS, "parameters");
- fs->f->numparams = cast(lu_byte, fs->nactvar);
- fs->f->is_vararg = cast(lu_byte, dots);
- if (dots)
- create_local(ls, "arg");
- luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
-}
-
-
-static void enterblock (FuncState *fs, BlockCnt *bl, int isbreakable) {
- bl->breaklist = NO_JUMP;
- bl->isbreakable = isbreakable;
- bl->nactvar = fs->nactvar;
- bl->upval = 0;
- bl->previous = fs->bl;
- fs->bl = bl;
- lua_assert(fs->freereg == fs->nactvar);
-}
-
-
-static void leaveblock (FuncState *fs) {
- BlockCnt *bl = fs->bl;
- fs->bl = bl->previous;
- removevars(fs->ls, bl->nactvar);
- if (bl->upval)
- luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
- lua_assert(bl->nactvar == fs->nactvar);
- fs->freereg = fs->nactvar; /* free registers */
- luaK_patchtohere(fs, bl->breaklist);
-}
-
-
-static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
- FuncState *fs = ls->fs;
- Proto *f = fs->f;
- int i;
- luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
- MAXARG_Bx, "constant table overflow");
- f->p[fs->np++] = func->f;
- init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
- for (i=0; i<func->f->nups; i++) {
- OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
- luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
- }
-}
-
-
-static void open_func (LexState *ls, FuncState *fs) {
- Proto *f = luaF_newproto(ls->L);
- fs->f = f;
- fs->prev = ls->fs; /* linked list of funcstates */
- fs->ls = ls;
- fs->L = ls->L;
- ls->fs = fs;
- fs->pc = 0;
- fs->lasttarget = 0;
- fs->jpc = NO_JUMP;
- fs->freereg = 0;
- fs->nk = 0;
- fs->h = luaH_new(ls->L, 0, 0);
- fs->np = 0;
- fs->nlocvars = 0;
- fs->nactvar = 0;
- fs->bl = NULL;
- f->source = ls->source;
- f->maxstacksize = 2; /* registers 0/1 are always valid */
-}
-
-
-static void close_func (LexState *ls) {
- lua_State *L = ls->L;
- FuncState *fs = ls->fs;
- Proto *f = fs->f;
- removevars(ls, 0);
- luaK_codeABC(fs, OP_RETURN, 0, 1, 0); /* final return */
- luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
- f->sizecode = fs->pc;
- luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
- f->sizelineinfo = fs->pc;
- luaM_reallocvector(L, f->k, f->sizek, fs->nk, TObject);
- f->sizek = fs->nk;
- luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
- f->sizep = fs->np;
- luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
- f->sizelocvars = fs->nlocvars;
- luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
- f->sizeupvalues = f->nups;
- lua_assert(luaG_checkcode(f));
- lua_assert(fs->bl == NULL);
- ls->fs = fs->prev;
-}
-
-
-Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) {
- struct LexState lexstate;
- struct FuncState funcstate;
- lexstate.buff = buff;
- lexstate.nestlevel = 0;
- luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z)));
- open_func(&lexstate, &funcstate);
- next(&lexstate); /* read first token */
- chunk(&lexstate);
- check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
- close_func(&lexstate);
- lua_assert(funcstate.prev == NULL);
- lua_assert(funcstate.f->nups == 0);
- lua_assert(lexstate.nestlevel == 0);
- return funcstate.f;
-}
-
-
-
-/*============================================================*/
-/* GRAMMAR RULES */
-/*============================================================*/
-
-
-static void luaY_field (LexState *ls, expdesc *v) {
- /* field -> ['.' | ':'] NAME */
- FuncState *fs = ls->fs;
- expdesc key;
- luaK_exp2anyreg(fs, v);
- next(ls); /* skip the dot or colon */
- checkname(ls, &key);
- luaK_indexed(fs, v, &key);
-}
-
-
-static void luaY_index (LexState *ls, expdesc *v) {
- /* index -> '[' expr ']' */
- next(ls); /* skip the '[' */
- expr(ls, v);
- luaK_exp2val(ls->fs, v);
- check(ls, ']');
-}
-
-
-/*
-** {======================================================================
-** Rules for Constructors
-** =======================================================================
-*/
-
-
-struct ConsControl {
- expdesc v; /* last list item read */
- expdesc *t; /* table descriptor */
- int nh; /* total number of `record' elements */
- int na; /* total number of array elements */
- int tostore; /* number of array elements pending to be stored */
-};
-
-
-static void recfield (LexState *ls, struct ConsControl *cc) {
- /* recfield -> (NAME | `['exp1`]') = exp1 */
- FuncState *fs = ls->fs;
- int reg = ls->fs->freereg;
- expdesc key, val;
- if (ls->t.token == TK_NAME) {
- luaX_checklimit(ls, cc->nh, MAX_INT, "items in a constructor");
- cc->nh++;
- checkname(ls, &key);
- }
- else /* ls->t.token == '[' */
- luaY_index(ls, &key);
- check(ls, '=');
- luaK_exp2RK(fs, &key);
- expr(ls, &val);
- luaK_codeABC(fs, OP_SETTABLE, cc->t->info, luaK_exp2RK(fs, &key),
- luaK_exp2RK(fs, &val));
- fs->freereg = reg; /* free registers */
-}
-
-
-static void closelistfield (FuncState *fs, struct ConsControl *cc) {
- if (cc->v.k == VVOID) return; /* there is no list item */
- luaK_exp2nextreg(fs, &cc->v);
- cc->v.k = VVOID;
- if (cc->tostore == LFIELDS_PER_FLUSH) {
- luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); /* flush */
- cc->tostore = 0; /* no more items pending */
- fs->freereg = cc->t->info + 1; /* free registers */
- }
-}
-
-
-static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
- if (cc->tostore == 0) return;
- if (cc->v.k == VCALL) {
- luaK_setcallreturns(fs, &cc->v, LUA_MULTRET);
- luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1);
- }
- else {
- if (cc->v.k != VVOID)
- luaK_exp2nextreg(fs, &cc->v);
- luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1);
- }
- fs->freereg = cc->t->info + 1; /* free registers */
-}
-
-
-static void listfield (LexState *ls, struct ConsControl *cc) {
- expr(ls, &cc->v);
- luaX_checklimit(ls, cc->na, MAXARG_Bx, "items in a constructor");
- cc->na++;
- cc->tostore++;
-}
-
-
-static void constructor (LexState *ls, expdesc *t) {
- /* constructor -> ?? */
- FuncState *fs = ls->fs;
- int line = ls->linenumber;
- int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
- struct ConsControl cc;
- cc.na = cc.nh = cc.tostore = 0;
- cc.t = t;
- init_exp(t, VRELOCABLE, pc);
- init_exp(&cc.v, VVOID, 0); /* no value (yet) */
- luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
- check(ls, '{');
- do {
- lua_assert(cc.v.k == VVOID || cc.tostore > 0);
- testnext(ls, ';'); /* compatibility only */
- if (ls->t.token == '}') break;
- closelistfield(fs, &cc);
- switch(ls->t.token) {
- case TK_NAME: { /* may be listfields or recfields */
- lookahead(ls);
- if (ls->lookahead.token != '=') /* expression? */
- listfield(ls, &cc);
- else
- recfield(ls, &cc);
- break;
- }
- case '[': { /* constructor_item -> recfield */
- recfield(ls, &cc);
- break;
- }
- default: { /* constructor_part -> listfield */
- listfield(ls, &cc);
- break;
- }
- }
- } while (testnext(ls, ',') || testnext(ls, ';'));
- check_match(ls, '}', '{', line);
- lastlistfield(fs, &cc);
- SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
- SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1); /* set initial table size */
-}
-
-/* }====================================================================== */
-
-
-
-static void parlist (LexState *ls) {
- /* parlist -> [ param { `,' param } ] */
- int nparams = 0;
- int dots = 0;
- if (ls->t.token != ')') { /* is `parlist' not empty? */
- do {
- switch (ls->t.token) {
- case TK_DOTS: dots = 1; next(ls); break;
- case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break;
- default: luaX_syntaxerror(ls, "<name> or `...' expected");
- }
- } while (!dots && testnext(ls, ','));
- }
- code_params(ls, nparams, dots);
-}
-
-
-static void body (LexState *ls, expdesc *e, int needself, int line) {
- /* body -> `(' parlist `)' chunk END */
- FuncState new_fs;
- open_func(ls, &new_fs);
- new_fs.f->lineDefined = line;
- check(ls, '(');
- if (needself)
- create_local(ls, "self");
- parlist(ls);
- check(ls, ')');
- chunk(ls);
- check_match(ls, TK_END, TK_FUNCTION, line);
- close_func(ls);
- pushclosure(ls, &new_fs, e);
-}
-
-
-static int explist1 (LexState *ls, expdesc *v) {
- /* explist1 -> expr { `,' expr } */
- int n = 1; /* at least one expression */
- expr(ls, v);
- while (testnext(ls, ',')) {
- luaK_exp2nextreg(ls->fs, v);
- expr(ls, v);
- n++;
- }
- return n;
-}
-
-
-static void funcargs (LexState *ls, expdesc *f) {
- FuncState *fs = ls->fs;
- expdesc args;
- int base, nparams;
- int line = ls->linenumber;
- switch (ls->t.token) {
- case '(': { /* funcargs -> `(' [ explist1 ] `)' */
- if (line != ls->lastline)
- luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
- next(ls);
- if (ls->t.token == ')') /* arg list is empty? */
- args.k = VVOID;
- else {
- explist1(ls, &args);
- luaK_setcallreturns(fs, &args, LUA_MULTRET);
- }
- check_match(ls, ')', '(', line);
- break;
- }
- case '{': { /* funcargs -> constructor */
- constructor(ls, &args);
- break;
- }
- case TK_STRING: { /* funcargs -> STRING */
- codestring(ls, &args, ls->t.seminfo.ts);
- next(ls); /* must use `seminfo' before `next' */
- break;
- }
- default: {
- luaX_syntaxerror(ls, "function arguments expected");
- return;
- }
- }
- lua_assert(f->k == VNONRELOC);
- base = f->info; /* base register for call */
- if (args.k == VCALL)
- nparams = LUA_MULTRET; /* open call */
- else {
- if (args.k != VVOID)
- luaK_exp2nextreg(fs, &args); /* close last argument */
- nparams = fs->freereg - (base+1);
- }
- init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
- luaK_fixline(fs, line);
- fs->freereg = base+1; /* call remove function and arguments and leaves
- (unless changed) one result */
-}
-
-
-
-
-/*
-** {======================================================================
-** Expression parsing
-** =======================================================================
-*/
-
-
-static void prefixexp (LexState *ls, expdesc *v) {
- /* prefixexp -> NAME | '(' expr ')' */
- switch (ls->t.token) {
- case '(': {
- int line = ls->linenumber;
- next(ls);
- expr(ls, v);
- check_match(ls, ')', '(', line);
- luaK_dischargevars(ls->fs, v);
- return;
- }
- case TK_NAME: {
- singlevar(ls, v, 1);
- return;
- }
-#ifdef LUA_COMPATUPSYNTAX
- case '%': { /* for compatibility only */
- TString *varname;
- int line = ls->linenumber;
- next(ls); /* skip `%' */
- varname = singlevar(ls, v, 1);
- if (v->k != VUPVAL)
- luaX_errorline(ls, "global upvalues are obsolete",
- getstr(varname), line);
- return;
- }
-#endif
- default: {
- luaX_syntaxerror(ls, "unexpected symbol");
- return;
- }
- }
-}
-
-
-static void primaryexp (LexState *ls, expdesc *v) {
- /* primaryexp ->
- prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
- FuncState *fs = ls->fs;
- prefixexp(ls, v);
- for (;;) {
- switch (ls->t.token) {
- case '.': { /* field */
- luaY_field(ls, v);
- break;
- }
- case '[': { /* `[' exp1 `]' */
- expdesc key;
- luaK_exp2anyreg(fs, v);
- luaY_index(ls, &key);
- luaK_indexed(fs, v, &key);
- break;
- }
- case ':': { /* `:' NAME funcargs */
- expdesc key;
- next(ls);
- checkname(ls, &key);
- luaK_self(fs, v, &key);
- funcargs(ls, v);
- break;
- }
- case '(': case TK_STRING: case '{': { /* funcargs */
- luaK_exp2nextreg(fs, v);
- funcargs(ls, v);
- break;
- }
- default: return;
- }
- }
-}
-
-
-static void simpleexp (LexState *ls, expdesc *v) {
- /* simpleexp -> NUMBER | STRING | NIL | constructor | FUNCTION body
- | primaryexp */
- switch (ls->t.token) {
- case TK_NUMBER: {
- init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r));
- next(ls); /* must use `seminfo' before `next' */
- break;
- }
- case TK_STRING: {
- codestring(ls, v, ls->t.seminfo.ts);
- next(ls); /* must use `seminfo' before `next' */
- break;
- }
- case TK_NIL: {
- init_exp(v, VNIL, 0);
- next(ls);
- break;
- }
- case TK_TRUE: {
- init_exp(v, VTRUE, 0);
- next(ls);
- break;
- }
- case TK_FALSE: {
- init_exp(v, VFALSE, 0);
- next(ls);
- break;
- }
- case '{': { /* constructor */
- constructor(ls, v);
- break;
- }
- case TK_FUNCTION: {
- next(ls);
- body(ls, v, 0, ls->linenumber);
- break;
- }
- default: {
- primaryexp(ls, v);
- break;
- }
- }
-}
-
-
-static UnOpr getunopr (int op) {
- switch (op) {
- case TK_NOT: return OPR_NOT;
- case '-': return OPR_MINUS;
- default: return OPR_NOUNOPR;
- }
-}
-
-
-static BinOpr getbinopr (int op) {
- switch (op) {
- case '+': return OPR_ADD;
- case '-': return OPR_SUB;
- case '*': return OPR_MULT;
- case '/': return OPR_DIV;
- case '^': return OPR_POW;
- case TK_CONCAT: return OPR_CONCAT;
- case TK_NE: return OPR_NE;
- case TK_EQ: return OPR_EQ;
- case '<': return OPR_LT;
- case TK_LE: return OPR_LE;
- case '>': return OPR_GT;
- case TK_GE: return OPR_GE;
- case TK_AND: return OPR_AND;
- case TK_OR: return OPR_OR;
- default: return OPR_NOBINOPR;
- }
-}
-
-
-static const struct {
- lu_byte left; /* left priority for each binary operator */
- lu_byte right; /* right priority */
-} priority[] = { /* ORDER OPR */
- {6, 6}, {6, 6}, {7, 7}, {7, 7}, /* arithmetic */
- {10, 9}, {5, 4}, /* power and concat (right associative) */
- {3, 3}, {3, 3}, /* equality */
- {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
- {2, 2}, {1, 1} /* logical (and/or) */
-};
-
-#define UNARY_PRIORITY 8 /* priority for unary operators */
-
-
-/*
-** subexpr -> (simplexep | unop subexpr) { binop subexpr }
-** where `binop' is any binary operator with a priority higher than `limit'
-*/
-static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
- BinOpr op;
- UnOpr uop;
- enterlevel(ls);
- uop = getunopr(ls->t.token);
- if (uop != OPR_NOUNOPR) {
- next(ls);
- subexpr(ls, v, UNARY_PRIORITY);
- luaK_prefix(ls->fs, uop, v);
- }
- else simpleexp(ls, v);
- /* expand while operators have priorities higher than `limit' */
- op = getbinopr(ls->t.token);
- while (op != OPR_NOBINOPR && cast(int, priority[op].left) > limit) {
- expdesc v2;
- BinOpr nextop;
- next(ls);
- luaK_infix(ls->fs, op, v);
- /* read sub-expression with higher priority */
- nextop = subexpr(ls, &v2, cast(int, priority[op].right));
- luaK_posfix(ls->fs, op, v, &v2);
- op = nextop;
- }
- leavelevel(ls);
- return op; /* return first untreated operator */
-}
-
-
-static void expr (LexState *ls, expdesc *v) {
- subexpr(ls, v, -1);
-}
-
-/* }==================================================================== */
-
-
-
-/*
-** {======================================================================
-** Rules for Statements
-** =======================================================================
-*/
-
-
-static int block_follow (int token) {
- switch (token) {
- case TK_ELSE: case TK_ELSEIF: case TK_END:
- case TK_UNTIL: case TK_EOS:
- return 1;
- default: return 0;
- }
-}
-
-
-static void block (LexState *ls) {
- /* block -> chunk */
- FuncState *fs = ls->fs;
- BlockCnt bl;
- enterblock(fs, &bl, 0);
- chunk(ls);
- lua_assert(bl.breaklist == NO_JUMP);
- leaveblock(fs);
-}
-
-
-/*
-** structure to chain all variables in the left-hand side of an
-** assignment
-*/
-struct LHS_assign {
- struct LHS_assign *prev;
- expdesc v; /* variable (global, local, upvalue, or indexed) */
-};
-
-
-/*
-** check whether, in an assignment to a local variable, the local variable
-** is needed in a previous assignment (to a table). If so, save original
-** local value in a safe place and use this safe copy in the previous
-** assignment.
-*/
-static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
- FuncState *fs = ls->fs;
- int extra = fs->freereg; /* eventual position to save local variable */
- int conflict = 0;
- for (; lh; lh = lh->prev) {
- if (lh->v.k == VINDEXED) {
- if (lh->v.info == v->info) { /* conflict? */
- conflict = 1;
- lh->v.info = extra; /* previous assignment will use safe copy */
- }
- if (lh->v.aux == v->info) { /* conflict? */
- conflict = 1;
- lh->v.aux = extra; /* previous assignment will use safe copy */
- }
- }
- }
- if (conflict) {
- luaK_codeABC(fs, OP_MOVE, fs->freereg, v->info, 0); /* make copy */
- luaK_reserveregs(fs, 1);
- }
-}
-
-
-static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
- expdesc e;
- check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
- "syntax error");
- if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
- struct LHS_assign nv;
- nv.prev = lh;
- primaryexp(ls, &nv.v);
- if (nv.v.k == VLOCAL)
- check_conflict(ls, lh, &nv.v);
- assignment(ls, &nv, nvars+1);
- }
- else { /* assignment -> `=' explist1 */
- int nexps;
- check(ls, '=');
- nexps = explist1(ls, &e);
- if (nexps != nvars) {
- adjust_assign(ls, nvars, nexps, &e);
- if (nexps > nvars)
- ls->fs->freereg -= nexps - nvars; /* remove extra values */
- }
- else {
- luaK_setcallreturns(ls->fs, &e, 1); /* close last expression */
- luaK_storevar(ls->fs, &lh->v, &e);
- return; /* avoid default */
- }
- }
- init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
- luaK_storevar(ls->fs, &lh->v, &e);
-}
-
-
-static void cond (LexState *ls, expdesc *v) {
- /* cond -> exp */
- expr(ls, v); /* read condition */
- if (v->k == VNIL) v->k = VFALSE; /* `falses' are all equal here */
- luaK_goiftrue(ls->fs, v);
- luaK_patchtohere(ls->fs, v->t);
-}
-
-
-/*
-** The while statement optimizes its code by coding the condition
-** after its body (and thus avoiding one jump in the loop).
-*/
-
-/*
-** maximum size of expressions for optimizing `while' code
-*/
-#ifndef MAXEXPWHILE
-#define MAXEXPWHILE 100
-#endif
-
-/*
-** the call `luaK_goiffalse' may grow the size of an expression by
-** at most this:
-*/
-#define EXTRAEXP 5
-
-static void whilestat (LexState *ls, int line) {
- /* whilestat -> WHILE cond DO block END */
- Instruction codeexp[MAXEXPWHILE + EXTRAEXP];
- int lineexp;
- int i;
- int sizeexp;
- FuncState *fs = ls->fs;
- int whileinit, blockinit, expinit;
- expdesc v;
- BlockCnt bl;
- next(ls); /* skip WHILE */
- whileinit = luaK_jump(fs); /* jump to condition (which will be moved) */
- expinit = luaK_getlabel(fs);
- expr(ls, &v); /* parse condition */
- if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */
- lineexp = ls->linenumber;
- luaK_goiffalse(fs, &v);
- luaK_concat(fs, &v.f, fs->jpc);
- fs->jpc = NO_JUMP;
- sizeexp = fs->pc - expinit; /* size of expression code */
- if (sizeexp > MAXEXPWHILE)
- luaX_syntaxerror(ls, "`while' condition too complex");
- for (i = 0; i < sizeexp; i++) /* save `exp' code */
- codeexp[i] = fs->f->code[expinit + i];
- fs->pc = expinit; /* remove `exp' code */
- enterblock(fs, &bl, 1);
- check(ls, TK_DO);
- blockinit = luaK_getlabel(fs);
- block(ls);
- luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */
- /* move `exp' back to code */
- if (v.t != NO_JUMP) v.t += fs->pc - expinit;
- if (v.f != NO_JUMP) v.f += fs->pc - expinit;
- for (i=0; i<sizeexp; i++)
- luaK_code(fs, codeexp[i], lineexp);
- check_match(ls, TK_END, TK_WHILE, line);
- leaveblock(fs);
- luaK_patchlist(fs, v.t, blockinit); /* true conditions go back to loop */
- luaK_patchtohere(fs, v.f); /* false conditions finish the loop */
-}
-
-
-static void repeatstat (LexState *ls, int line) {
- /* repeatstat -> REPEAT block UNTIL cond */
- FuncState *fs = ls->fs;
- int repeat_init = luaK_getlabel(fs);
- expdesc v;
- BlockCnt bl;
- enterblock(fs, &bl, 1);
- next(ls);
- block(ls);
- check_match(ls, TK_UNTIL, TK_REPEAT, line);
- cond(ls, &v);
- luaK_patchlist(fs, v.f, repeat_init);
- leaveblock(fs);
-}
-
-
-static int exp1 (LexState *ls) {
- expdesc e;
- int k;
- expr(ls, &e);
- k = e.k;
- luaK_exp2nextreg(ls->fs, &e);
- return k;
-}
-
-
-static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
- BlockCnt bl;
- FuncState *fs = ls->fs;
- int prep, endfor;
- adjustlocalvars(ls, nvars); /* scope for all variables */
- check(ls, TK_DO);
- enterblock(fs, &bl, 1); /* loop block */
- prep = luaK_getlabel(fs);
- block(ls);
- luaK_patchtohere(fs, prep-1);
- endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
- luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3);
- luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
- luaK_patchlist(fs, (isnum) ? endfor : luaK_jump(fs), prep);
- leaveblock(fs);
-}
-
-
-static void fornum (LexState *ls, TString *varname, int line) {
- /* fornum -> NAME = exp1,exp1[,exp1] DO body */
- FuncState *fs = ls->fs;
- int base = fs->freereg;
- new_localvar(ls, varname, 0);
- new_localvarstr(ls, "(for limit)", 1);
- new_localvarstr(ls, "(for step)", 2);
- check(ls, '=');
- exp1(ls); /* initial value */
- check(ls, ',');
- exp1(ls); /* limit */
- if (testnext(ls, ','))
- exp1(ls); /* optional step */
- else { /* default step = 1 */
- luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
- luaK_reserveregs(fs, 1);
- }
- luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1);
- luaK_jump(fs);
- forbody(ls, base, line, 3, 1);
-}
-
-
-static void forlist (LexState *ls, TString *indexname) {
- /* forlist -> NAME {,NAME} IN explist1 DO body */
- FuncState *fs = ls->fs;
- expdesc e;
- int nvars = 0;
- int line;
- int base = fs->freereg;
- new_localvarstr(ls, "(for generator)", nvars++);
- new_localvarstr(ls, "(for state)", nvars++);
- new_localvar(ls, indexname, nvars++);
- while (testnext(ls, ','))
- new_localvar(ls, str_checkname(ls), nvars++);
- check(ls, TK_IN);
- line = ls->linenumber;
- adjust_assign(ls, nvars, explist1(ls, &e), &e);
- luaK_checkstack(fs, 3); /* extra space to call generator */
- luaK_codeAsBx(fs, OP_TFORPREP, base, NO_JUMP);
- forbody(ls, base, line, nvars, 0);
-}
-
-
-static void forstat (LexState *ls, int line) {
- /* forstat -> fornum | forlist */
- FuncState *fs = ls->fs;
- TString *varname;
- BlockCnt bl;
- enterblock(fs, &bl, 0); /* block to control variable scope */
- next(ls); /* skip `for' */
- varname = str_checkname(ls); /* first variable name */
- switch (ls->t.token) {
- case '=': fornum(ls, varname, line); break;
- case ',': case TK_IN: forlist(ls, varname); break;
- default: luaX_syntaxerror(ls, "`=' or `in' expected");
- }
- check_match(ls, TK_END, TK_FOR, line);
- leaveblock(fs);
-}
-
-
-static void test_then_block (LexState *ls, expdesc *v) {
- /* test_then_block -> [IF | ELSEIF] cond THEN block */
- next(ls); /* skip IF or ELSEIF */
- cond(ls, v);
- check(ls, TK_THEN);
- block(ls); /* `then' part */
-}
-
-
-static void ifstat (LexState *ls, int line) {
- /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
- FuncState *fs = ls->fs;
- expdesc v;
- int escapelist = NO_JUMP;
- test_then_block(ls, &v); /* IF cond THEN block */
- while (ls->t.token == TK_ELSEIF) {
- luaK_concat(fs, &escapelist, luaK_jump(fs));
- luaK_patchtohere(fs, v.f);
- test_then_block(ls, &v); /* ELSEIF cond THEN block */
- }
- if (ls->t.token == TK_ELSE) {
- luaK_concat(fs, &escapelist, luaK_jump(fs));
- luaK_patchtohere(fs, v.f);
- next(ls); /* skip ELSE (after patch, for correct line info) */
- block(ls); /* `else' part */
- }
- else
- luaK_concat(fs, &escapelist, v.f);
- luaK_patchtohere(fs, escapelist);
- check_match(ls, TK_END, TK_IF, line);
-}
-
-
-static void localfunc (LexState *ls) {
- expdesc v, b;
- new_localvar(ls, str_checkname(ls), 0);
- init_exp(&v, VLOCAL, ls->fs->freereg++);
- adjustlocalvars(ls, 1);
- body(ls, &b, 0, ls->linenumber);
- luaK_storevar(ls->fs, &v, &b);
-}
-
-
-static void localstat (LexState *ls) {
- /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
- int nvars = 0;
- int nexps;
- expdesc e;
- do {
- new_localvar(ls, str_checkname(ls), nvars++);
- } while (testnext(ls, ','));
- if (testnext(ls, '='))
- nexps = explist1(ls, &e);
- else {
- e.k = VVOID;
- nexps = 0;
- }
- adjust_assign(ls, nvars, nexps, &e);
- adjustlocalvars(ls, nvars);
-}
-
-
-static int funcname (LexState *ls, expdesc *v) {
- /* funcname -> NAME {field} [`:' NAME] */
- int needself = 0;
- singlevar(ls, v, 1);
- while (ls->t.token == '.')
- luaY_field(ls, v);
- if (ls->t.token == ':') {
- needself = 1;
- luaY_field(ls, v);
- }
- return needself;
-}
-
-
-static void funcstat (LexState *ls, int line) {
- /* funcstat -> FUNCTION funcname body */
- int needself;
- expdesc v, b;
- next(ls); /* skip FUNCTION */
- needself = funcname(ls, &v);
- body(ls, &b, needself, line);
- luaK_storevar(ls->fs, &v, &b);
- luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
-}
-
-
-static void exprstat (LexState *ls) {
- /* stat -> func | assignment */
- FuncState *fs = ls->fs;
- struct LHS_assign v;
- primaryexp(ls, &v.v);
- if (v.v.k == VCALL) { /* stat -> func */
- luaK_setcallreturns(fs, &v.v, 0); /* call statement uses no results */
- }
- else { /* stat -> assignment */
- v.prev = NULL;
- assignment(ls, &v, 1);
- }
-}
-
-
-static void retstat (LexState *ls) {
- /* stat -> RETURN explist */
- FuncState *fs = ls->fs;
- expdesc e;
- int first, nret; /* registers with returned values */
- next(ls); /* skip RETURN */
- if (block_follow(ls->t.token) || ls->t.token == ';')
- first = nret = 0; /* return no values */
- else {
- nret = explist1(ls, &e); /* optional return values */
- if (e.k == VCALL) {
- luaK_setcallreturns(fs, &e, LUA_MULTRET);
- if (nret == 1) { /* tail call? */
- SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
- lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
- }
- first = fs->nactvar;
- nret = LUA_MULTRET; /* return all values */
- }
- else {
- if (nret == 1) /* only one single value? */
- first = luaK_exp2anyreg(fs, &e);
- else {
- luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
- first = fs->nactvar; /* return all `active' values */
- lua_assert(nret == fs->freereg - first);
- }
- }
- }
- luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
-}
-
-
-static void breakstat (LexState *ls) {
- /* stat -> BREAK [NAME] */
- FuncState *fs = ls->fs;
- BlockCnt *bl = fs->bl;
- int upval = 0;
- next(ls); /* skip BREAK */
- while (bl && !bl->isbreakable) {
- upval |= bl->upval;
- bl = bl->previous;
- }
- if (!bl)
- luaX_syntaxerror(ls, "no loop to break");
- if (upval)
- luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
- luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
-}
-
-
-static int statement (LexState *ls) {
- int line = ls->linenumber; /* may be needed for error messages */
- switch (ls->t.token) {
- case TK_IF: { /* stat -> ifstat */
- ifstat(ls, line);
- return 0;
- }
- case TK_WHILE: { /* stat -> whilestat */
- whilestat(ls, line);
- return 0;
- }
- case TK_DO: { /* stat -> DO block END */
- next(ls); /* skip DO */
- block(ls);
- check_match(ls, TK_END, TK_DO, line);
- return 0;
- }
- case TK_FOR: { /* stat -> forstat */
- forstat(ls, line);
- return 0;
- }
- case TK_REPEAT: { /* stat -> repeatstat */
- repeatstat(ls, line);
- return 0;
- }
- case TK_FUNCTION: {
- funcstat(ls, line); /* stat -> funcstat */
- return 0;
- }
- case TK_LOCAL: { /* stat -> localstat */
- next(ls); /* skip LOCAL */
- if (testnext(ls, TK_FUNCTION)) /* local function? */
- localfunc(ls);
- else
- localstat(ls);
- return 0;
- }
- case TK_RETURN: { /* stat -> retstat */
- retstat(ls);
- return 1; /* must be last statement */
- }
- case TK_BREAK: { /* stat -> breakstat */
- breakstat(ls);
- return 1; /* must be last statement */
- }
- default: {
- exprstat(ls);
- return 0; /* to avoid warnings */
- }
- }
-}
-
-
-static void chunk (LexState *ls) {
- /* chunk -> { stat [`;'] } */
- int islast = 0;
- enterlevel(ls);
- while (!islast && !block_follow(ls->t.token)) {
- islast = statement(ls);
- testnext(ls, ';');
- lua_assert(ls->fs->freereg >= ls->fs->nactvar);
- ls->fs->freereg = ls->fs->nactvar; /* free registers */
- }
- leavelevel(ls);
-}
-
-/* }====================================================================== */
+/*
+** $Id: lparser.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** Lua Parser
+** See Copyright Notice in lua.h
+*/
+
+
+#include <string.h>
+
+#define lparser_c
+
+#include "lua.h"
+
+#include "lcode.h"
+#include "ldebug.h"
+#include "lfunc.h"
+#include "llex.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lparser.h"
+#include "lstate.h"
+#include "lstring.h"
+
+
+
+
+#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
+
+
+#define enterlevel(ls) if (++(ls)->nestlevel > LUA_MAXPARSERLEVEL) \
+ luaX_syntaxerror(ls, "too many syntax levels");
+#define leavelevel(ls) ((ls)->nestlevel--)
+
+
+/*
+** nodes for block list (list of active blocks)
+*/
+typedef struct BlockCnt {
+ struct BlockCnt *previous; /* chain */
+ int breaklist; /* list of jumps out of this loop */
+ int nactvar; /* # active local variables outside the breakable structure */
+ int upval; /* true if some variable in the block is an upvalue */
+ int isbreakable; /* true if `block' is a loop */
+} BlockCnt;
+
+
+
+/*
+** prototypes for recursive non-terminal functions
+*/
+static void chunk (LexState *ls);
+static void expr (LexState *ls, expdesc *v);
+
+
+
+static void next (LexState *ls) {
+ ls->lastline = ls->linenumber;
+ if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
+ ls->t = ls->lookahead; /* use this one */
+ ls->lookahead.token = TK_EOS; /* and discharge it */
+ }
+ else
+ ls->t.token = luaX_lex(ls, &ls->t.seminfo); /* read next token */
+}
+
+
+static void lookahead (LexState *ls) {
+ lua_assert(ls->lookahead.token == TK_EOS);
+ ls->lookahead.token = luaX_lex(ls, &ls->lookahead.seminfo);
+}
+
+
+static void error_expected (LexState *ls, int token) {
+ luaX_syntaxerror(ls,
+ luaO_pushfstring(ls->L, "`%s' expected", luaX_token2str(ls, token)));
+}
+
+
+static int testnext (LexState *ls, int c) {
+ if (ls->t.token == c) {
+ next(ls);
+ return 1;
+ }
+ else return 0;
+}
+
+
+static void check (LexState *ls, int c) {
+ if (!testnext(ls, c))
+ error_expected(ls, c);
+}
+
+
+#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
+
+
+
+static void check_match (LexState *ls, int what, int who, int where) {
+ if (!testnext(ls, what)) {
+ if (where == ls->linenumber)
+ error_expected(ls, what);
+ else {
+ luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
+ "`%s' expected (to close `%s' at line %d)",
+ luaX_token2str(ls, what), luaX_token2str(ls, who), where));
+ }
+ }
+}
+
+
+static TString *str_checkname (LexState *ls) {
+ TString *ts;
+ check_condition(ls, (ls->t.token == TK_NAME), "<name> expected");
+ ts = ls->t.seminfo.ts;
+ next(ls);
+ return ts;
+}
+
+
+static void init_exp (expdesc *e, expkind k, int i) {
+ e->f = e->t = NO_JUMP;
+ e->k = k;
+ e->info = i;
+}
+
+
+static void codestring (LexState *ls, expdesc *e, TString *s) {
+ init_exp(e, VK, luaK_stringK(ls->fs, s));
+}
+
+
+static void checkname(LexState *ls, expdesc *e) {
+ codestring(ls, e, str_checkname(ls));
+}
+
+
+static int luaI_registerlocalvar (LexState *ls, TString *varname) {
+ FuncState *fs = ls->fs;
+ Proto *f = fs->f;
+ luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
+ LocVar, MAX_INT, "");
+ f->locvars[fs->nlocvars].varname = varname;
+ return fs->nlocvars++;
+}
+
+
+static void new_localvar (LexState *ls, TString *name, int n) {
+ FuncState *fs = ls->fs;
+ luaX_checklimit(ls, fs->nactvar+n+1, MAXVARS, "local variables");
+ fs->actvar[fs->nactvar+n] = luaI_registerlocalvar(ls, name);
+}
+
+
+static void adjustlocalvars (LexState *ls, int nvars) {
+ FuncState *fs = ls->fs;
+ fs->nactvar += nvars;
+ for (; nvars; nvars--) {
+ getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
+ }
+}
+
+
+static void removevars (LexState *ls, int tolevel) {
+ FuncState *fs = ls->fs;
+ while (fs->nactvar > tolevel)
+ getlocvar(fs, --fs->nactvar).endpc = fs->pc;
+}
+
+
+static void new_localvarstr (LexState *ls, const char *name, int n) {
+ new_localvar(ls, luaS_new(ls->L, name), n);
+}
+
+
+static void create_local (LexState *ls, const char *name) {
+ new_localvarstr(ls, name, 0);
+ adjustlocalvars(ls, 1);
+}
+
+
+static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
+ int i;
+ Proto *f = fs->f;
+ for (i=0; i<f->nups; i++) {
+ if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) {
+ lua_assert(fs->f->upvalues[i] == name);
+ return i;
+ }
+ }
+ /* new one */
+ luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues");
+ luaM_growvector(fs->L, fs->f->upvalues, f->nups, fs->f->sizeupvalues,
+ TString *, MAX_INT, "");
+ fs->f->upvalues[f->nups] = name;
+ fs->upvalues[f->nups] = *v;
+ return f->nups++;
+}
+
+
+static int searchvar (FuncState *fs, TString *n) {
+ int i;
+ for (i=fs->nactvar-1; i >= 0; i--) {
+ if (n == getlocvar(fs, i).varname)
+ return i;
+ }
+ return -1; /* not found */
+}
+
+
+static void markupval (FuncState *fs, int level) {
+ BlockCnt *bl = fs->bl;
+ while (bl && bl->nactvar > level) bl = bl->previous;
+ if (bl) bl->upval = 1;
+}
+
+
+static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
+ if (fs == NULL) /* no more levels? */
+ init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
+ else {
+ int v = searchvar(fs, n); /* look up at current level */
+ if (v >= 0) {
+ init_exp(var, VLOCAL, v);
+ if (!base)
+ markupval(fs, v); /* local will be used as an upval */
+ }
+ else { /* not found at current level; try upper one */
+ singlevaraux(fs->prev, n, var, 0);
+ if (var->k == VGLOBAL) {
+ if (base)
+ var->info = luaK_stringK(fs, n); /* info points to global name */
+ }
+ else { /* LOCAL or UPVAL */
+ var->info = indexupvalue(fs, n, var);
+ var->k = VUPVAL; /* upvalue in this level */
+ }
+ }
+ }
+}
+
+
+static TString *singlevar (LexState *ls, expdesc *var, int base) {
+ TString *varname = str_checkname(ls);
+ singlevaraux(ls->fs, varname, var, base);
+ return varname;
+}
+
+
+static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
+ FuncState *fs = ls->fs;
+ int extra = nvars - nexps;
+ if (e->k == VCALL) {
+ extra++; /* includes call itself */
+ if (extra <= 0) extra = 0;
+ else luaK_reserveregs(fs, extra-1);
+ luaK_setcallreturns(fs, e, extra); /* call provides the difference */
+ }
+ else {
+ if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
+ if (extra > 0) {
+ int reg = fs->freereg;
+ luaK_reserveregs(fs, extra);
+ luaK_nil(fs, reg, extra);
+ }
+ }
+}
+
+
+static void code_params (LexState *ls, int nparams, int dots) {
+ FuncState *fs = ls->fs;
+ adjustlocalvars(ls, nparams);
+ luaX_checklimit(ls, fs->nactvar, MAXPARAMS, "parameters");
+ fs->f->numparams = cast(lu_byte, fs->nactvar);
+ fs->f->is_vararg = cast(lu_byte, dots);
+ if (dots)
+ create_local(ls, "arg");
+ luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
+}
+
+
+static void enterblock (FuncState *fs, BlockCnt *bl, int isbreakable) {
+ bl->breaklist = NO_JUMP;
+ bl->isbreakable = isbreakable;
+ bl->nactvar = fs->nactvar;
+ bl->upval = 0;
+ bl->previous = fs->bl;
+ fs->bl = bl;
+ lua_assert(fs->freereg == fs->nactvar);
+}
+
+
+static void leaveblock (FuncState *fs) {
+ BlockCnt *bl = fs->bl;
+ fs->bl = bl->previous;
+ removevars(fs->ls, bl->nactvar);
+ if (bl->upval)
+ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
+ lua_assert(bl->nactvar == fs->nactvar);
+ fs->freereg = fs->nactvar; /* free registers */
+ luaK_patchtohere(fs, bl->breaklist);
+}
+
+
+static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
+ FuncState *fs = ls->fs;
+ Proto *f = fs->f;
+ int i;
+ luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
+ MAXARG_Bx, "constant table overflow");
+ f->p[fs->np++] = func->f;
+ init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
+ for (i=0; i<func->f->nups; i++) {
+ OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
+ luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
+ }
+}
+
+
+static void open_func (LexState *ls, FuncState *fs) {
+ Proto *f = luaF_newproto(ls->L);
+ fs->f = f;
+ fs->prev = ls->fs; /* linked list of funcstates */
+ fs->ls = ls;
+ fs->L = ls->L;
+ ls->fs = fs;
+ fs->pc = 0;
+ fs->lasttarget = 0;
+ fs->jpc = NO_JUMP;
+ fs->freereg = 0;
+ fs->nk = 0;
+ fs->h = luaH_new(ls->L, 0, 0);
+ fs->np = 0;
+ fs->nlocvars = 0;
+ fs->nactvar = 0;
+ fs->bl = NULL;
+ f->source = ls->source;
+ f->maxstacksize = 2; /* registers 0/1 are always valid */
+}
+
+
+static void close_func (LexState *ls) {
+ lua_State *L = ls->L;
+ FuncState *fs = ls->fs;
+ Proto *f = fs->f;
+ removevars(ls, 0);
+ luaK_codeABC(fs, OP_RETURN, 0, 1, 0); /* final return */
+ luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
+ f->sizecode = fs->pc;
+ luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
+ f->sizelineinfo = fs->pc;
+ luaM_reallocvector(L, f->k, f->sizek, fs->nk, TObject);
+ f->sizek = fs->nk;
+ luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
+ f->sizep = fs->np;
+ luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
+ f->sizelocvars = fs->nlocvars;
+ luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
+ f->sizeupvalues = f->nups;
+ lua_assert(luaG_checkcode(f));
+ lua_assert(fs->bl == NULL);
+ ls->fs = fs->prev;
+}
+
+
+Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) {
+ struct LexState lexstate;
+ struct FuncState funcstate;
+ lexstate.buff = buff;
+ lexstate.nestlevel = 0;
+ luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z)));
+ open_func(&lexstate, &funcstate);
+ next(&lexstate); /* read first token */
+ chunk(&lexstate);
+ check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
+ close_func(&lexstate);
+ lua_assert(funcstate.prev == NULL);
+ lua_assert(funcstate.f->nups == 0);
+ lua_assert(lexstate.nestlevel == 0);
+ return funcstate.f;
+}
+
+
+
+/*============================================================*/
+/* GRAMMAR RULES */
+/*============================================================*/
+
+
+static void luaY_field (LexState *ls, expdesc *v) {
+ /* field -> ['.' | ':'] NAME */
+ FuncState *fs = ls->fs;
+ expdesc key;
+ luaK_exp2anyreg(fs, v);
+ next(ls); /* skip the dot or colon */
+ checkname(ls, &key);
+ luaK_indexed(fs, v, &key);
+}
+
+
+static void luaY_index (LexState *ls, expdesc *v) {
+ /* index -> '[' expr ']' */
+ next(ls); /* skip the '[' */
+ expr(ls, v);
+ luaK_exp2val(ls->fs, v);
+ check(ls, ']');
+}
+
+
+/*
+** {======================================================================
+** Rules for Constructors
+** =======================================================================
+*/
+
+
+struct ConsControl {
+ expdesc v; /* last list item read */
+ expdesc *t; /* table descriptor */
+ int nh; /* total number of `record' elements */
+ int na; /* total number of array elements */
+ int tostore; /* number of array elements pending to be stored */
+};
+
+
+static void recfield (LexState *ls, struct ConsControl *cc) {
+ /* recfield -> (NAME | `['exp1`]') = exp1 */
+ FuncState *fs = ls->fs;
+ int reg = ls->fs->freereg;
+ expdesc key, val;
+ if (ls->t.token == TK_NAME) {
+ luaX_checklimit(ls, cc->nh, MAX_INT, "items in a constructor");
+ cc->nh++;
+ checkname(ls, &key);
+ }
+ else /* ls->t.token == '[' */
+ luaY_index(ls, &key);
+ check(ls, '=');
+ luaK_exp2RK(fs, &key);
+ expr(ls, &val);
+ luaK_codeABC(fs, OP_SETTABLE, cc->t->info, luaK_exp2RK(fs, &key),
+ luaK_exp2RK(fs, &val));
+ fs->freereg = reg; /* free registers */
+}
+
+
+static void closelistfield (FuncState *fs, struct ConsControl *cc) {
+ if (cc->v.k == VVOID) return; /* there is no list item */
+ luaK_exp2nextreg(fs, &cc->v);
+ cc->v.k = VVOID;
+ if (cc->tostore == LFIELDS_PER_FLUSH) {
+ luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); /* flush */
+ cc->tostore = 0; /* no more items pending */
+ fs->freereg = cc->t->info + 1; /* free registers */
+ }
+}
+
+
+static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
+ if (cc->tostore == 0) return;
+ if (cc->v.k == VCALL) {
+ luaK_setcallreturns(fs, &cc->v, LUA_MULTRET);
+ luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1);
+ }
+ else {
+ if (cc->v.k != VVOID)
+ luaK_exp2nextreg(fs, &cc->v);
+ luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1);
+ }
+ fs->freereg = cc->t->info + 1; /* free registers */
+}
+
+
+static void listfield (LexState *ls, struct ConsControl *cc) {
+ expr(ls, &cc->v);
+ luaX_checklimit(ls, cc->na, MAXARG_Bx, "items in a constructor");
+ cc->na++;
+ cc->tostore++;
+}
+
+
+static void constructor (LexState *ls, expdesc *t) {
+ /* constructor -> ?? */
+ FuncState *fs = ls->fs;
+ int line = ls->linenumber;
+ int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
+ struct ConsControl cc;
+ cc.na = cc.nh = cc.tostore = 0;
+ cc.t = t;
+ init_exp(t, VRELOCABLE, pc);
+ init_exp(&cc.v, VVOID, 0); /* no value (yet) */
+ luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
+ check(ls, '{');
+ do {
+ lua_assert(cc.v.k == VVOID || cc.tostore > 0);
+ testnext(ls, ';'); /* compatibility only */
+ if (ls->t.token == '}') break;
+ closelistfield(fs, &cc);
+ switch(ls->t.token) {
+ case TK_NAME: { /* may be listfields or recfields */
+ lookahead(ls);
+ if (ls->lookahead.token != '=') /* expression? */
+ listfield(ls, &cc);
+ else
+ recfield(ls, &cc);
+ break;
+ }
+ case '[': { /* constructor_item -> recfield */
+ recfield(ls, &cc);
+ break;
+ }
+ default: { /* constructor_part -> listfield */
+ listfield(ls, &cc);
+ break;
+ }
+ }
+ } while (testnext(ls, ',') || testnext(ls, ';'));
+ check_match(ls, '}', '{', line);
+ lastlistfield(fs, &cc);
+ SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
+ SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1); /* set initial table size */
+}
+
+/* }====================================================================== */
+
+
+
+static void parlist (LexState *ls) {
+ /* parlist -> [ param { `,' param } ] */
+ int nparams = 0;
+ int dots = 0;
+ if (ls->t.token != ')') { /* is `parlist' not empty? */
+ do {
+ switch (ls->t.token) {
+ case TK_DOTS: dots = 1; next(ls); break;
+ case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break;
+ default: luaX_syntaxerror(ls, "<name> or `...' expected");
+ }
+ } while (!dots && testnext(ls, ','));
+ }
+ code_params(ls, nparams, dots);
+}
+
+
+static void body (LexState *ls, expdesc *e, int needself, int line) {
+ /* body -> `(' parlist `)' chunk END */
+ FuncState new_fs;
+ open_func(ls, &new_fs);
+ new_fs.f->lineDefined = line;
+ check(ls, '(');
+ if (needself)
+ create_local(ls, "self");
+ parlist(ls);
+ check(ls, ')');
+ chunk(ls);
+ check_match(ls, TK_END, TK_FUNCTION, line);
+ close_func(ls);
+ pushclosure(ls, &new_fs, e);
+}
+
+
+static int explist1 (LexState *ls, expdesc *v) {
+ /* explist1 -> expr { `,' expr } */
+ int n = 1; /* at least one expression */
+ expr(ls, v);
+ while (testnext(ls, ',')) {
+ luaK_exp2nextreg(ls->fs, v);
+ expr(ls, v);
+ n++;
+ }
+ return n;
+}
+
+
+static void funcargs (LexState *ls, expdesc *f) {
+ FuncState *fs = ls->fs;
+ expdesc args;
+ int base, nparams;
+ int line = ls->linenumber;
+ switch (ls->t.token) {
+ case '(': { /* funcargs -> `(' [ explist1 ] `)' */
+ if (line != ls->lastline)
+ luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
+ next(ls);
+ if (ls->t.token == ')') /* arg list is empty? */
+ args.k = VVOID;
+ else {
+ explist1(ls, &args);
+ luaK_setcallreturns(fs, &args, LUA_MULTRET);
+ }
+ check_match(ls, ')', '(', line);
+ break;
+ }
+ case '{': { /* funcargs -> constructor */
+ constructor(ls, &args);
+ break;
+ }
+ case TK_STRING: { /* funcargs -> STRING */
+ codestring(ls, &args, ls->t.seminfo.ts);
+ next(ls); /* must use `seminfo' before `next' */
+ break;
+ }
+ default: {
+ luaX_syntaxerror(ls, "function arguments expected");
+ return;
+ }
+ }
+ lua_assert(f->k == VNONRELOC);
+ base = f->info; /* base register for call */
+ if (args.k == VCALL)
+ nparams = LUA_MULTRET; /* open call */
+ else {
+ if (args.k != VVOID)
+ luaK_exp2nextreg(fs, &args); /* close last argument */
+ nparams = fs->freereg - (base+1);
+ }
+ init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
+ luaK_fixline(fs, line);
+ fs->freereg = base+1; /* call remove function and arguments and leaves
+ (unless changed) one result */
+}
+
+
+
+
+/*
+** {======================================================================
+** Expression parsing
+** =======================================================================
+*/
+
+
+static void prefixexp (LexState *ls, expdesc *v) {
+ /* prefixexp -> NAME | '(' expr ')' */
+ switch (ls->t.token) {
+ case '(': {
+ int line = ls->linenumber;
+ next(ls);
+ expr(ls, v);
+ check_match(ls, ')', '(', line);
+ luaK_dischargevars(ls->fs, v);
+ return;
+ }
+ case TK_NAME: {
+ singlevar(ls, v, 1);
+ return;
+ }
+#ifdef LUA_COMPATUPSYNTAX
+ case '%': { /* for compatibility only */
+ TString *varname;
+ int line = ls->linenumber;
+ next(ls); /* skip `%' */
+ varname = singlevar(ls, v, 1);
+ if (v->k != VUPVAL)
+ luaX_errorline(ls, "global upvalues are obsolete",
+ getstr(varname), line);
+ return;
+ }
+#endif
+ default: {
+ luaX_syntaxerror(ls, "unexpected symbol");
+ return;
+ }
+ }
+}
+
+
+static void primaryexp (LexState *ls, expdesc *v) {
+ /* primaryexp ->
+ prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
+ FuncState *fs = ls->fs;
+ prefixexp(ls, v);
+ for (;;) {
+ switch (ls->t.token) {
+ case '.': { /* field */
+ luaY_field(ls, v);
+ break;
+ }
+ case '[': { /* `[' exp1 `]' */
+ expdesc key;
+ luaK_exp2anyreg(fs, v);
+ luaY_index(ls, &key);
+ luaK_indexed(fs, v, &key);
+ break;
+ }
+ case ':': { /* `:' NAME funcargs */
+ expdesc key;
+ next(ls);
+ checkname(ls, &key);
+ luaK_self(fs, v, &key);
+ funcargs(ls, v);
+ break;
+ }
+ case '(': case TK_STRING: case '{': { /* funcargs */
+ luaK_exp2nextreg(fs, v);
+ funcargs(ls, v);
+ break;
+ }
+ default: return;
+ }
+ }
+}
+
+
+static void simpleexp (LexState *ls, expdesc *v) {
+ /* simpleexp -> NUMBER | STRING | NIL | constructor | FUNCTION body
+ | primaryexp */
+ switch (ls->t.token) {
+ case TK_NUMBER: {
+ init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r));
+ next(ls); /* must use `seminfo' before `next' */
+ break;
+ }
+ case TK_STRING: {
+ codestring(ls, v, ls->t.seminfo.ts);
+ next(ls); /* must use `seminfo' before `next' */
+ break;
+ }
+ case TK_NIL: {
+ init_exp(v, VNIL, 0);
+ next(ls);
+ break;
+ }
+ case TK_TRUE: {
+ init_exp(v, VTRUE, 0);
+ next(ls);
+ break;
+ }
+ case TK_FALSE: {
+ init_exp(v, VFALSE, 0);
+ next(ls);
+ break;
+ }
+ case '{': { /* constructor */
+ constructor(ls, v);
+ break;
+ }
+ case TK_FUNCTION: {
+ next(ls);
+ body(ls, v, 0, ls->linenumber);
+ break;
+ }
+ default: {
+ primaryexp(ls, v);
+ break;
+ }
+ }
+}
+
+
+static UnOpr getunopr (int op) {
+ switch (op) {
+ case TK_NOT: return OPR_NOT;
+ case '-': return OPR_MINUS;
+ default: return OPR_NOUNOPR;
+ }
+}
+
+
+static BinOpr getbinopr (int op) {
+ switch (op) {
+ case '+': return OPR_ADD;
+ case '-': return OPR_SUB;
+ case '*': return OPR_MULT;
+ case '/': return OPR_DIV;
+ case '^': return OPR_POW;
+ case TK_CONCAT: return OPR_CONCAT;
+ case TK_NE: return OPR_NE;
+ case TK_EQ: return OPR_EQ;
+ case '<': return OPR_LT;
+ case TK_LE: return OPR_LE;
+ case '>': return OPR_GT;
+ case TK_GE: return OPR_GE;
+ case TK_AND: return OPR_AND;
+ case TK_OR: return OPR_OR;
+ default: return OPR_NOBINOPR;
+ }
+}
+
+
+static const struct {
+ lu_byte left; /* left priority for each binary operator */
+ lu_byte right; /* right priority */
+} priority[] = { /* ORDER OPR */
+ {6, 6}, {6, 6}, {7, 7}, {7, 7}, /* arithmetic */
+ {10, 9}, {5, 4}, /* power and concat (right associative) */
+ {3, 3}, {3, 3}, /* equality */
+ {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
+ {2, 2}, {1, 1} /* logical (and/or) */
+};
+
+#define UNARY_PRIORITY 8 /* priority for unary operators */
+
+
+/*
+** subexpr -> (simplexep | unop subexpr) { binop subexpr }
+** where `binop' is any binary operator with a priority higher than `limit'
+*/
+static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
+ BinOpr op;
+ UnOpr uop;
+ enterlevel(ls);
+ uop = getunopr(ls->t.token);
+ if (uop != OPR_NOUNOPR) {
+ next(ls);
+ subexpr(ls, v, UNARY_PRIORITY);
+ luaK_prefix(ls->fs, uop, v);
+ }
+ else simpleexp(ls, v);
+ /* expand while operators have priorities higher than `limit' */
+ op = getbinopr(ls->t.token);
+ while (op != OPR_NOBINOPR && cast(int, priority[op].left) > limit) {
+ expdesc v2;
+ BinOpr nextop;
+ next(ls);
+ luaK_infix(ls->fs, op, v);
+ /* read sub-expression with higher priority */
+ nextop = subexpr(ls, &v2, cast(int, priority[op].right));
+ luaK_posfix(ls->fs, op, v, &v2);
+ op = nextop;
+ }
+ leavelevel(ls);
+ return op; /* return first untreated operator */
+}
+
+
+static void expr (LexState *ls, expdesc *v) {
+ subexpr(ls, v, -1);
+}
+
+/* }==================================================================== */
+
+
+
+/*
+** {======================================================================
+** Rules for Statements
+** =======================================================================
+*/
+
+
+static int block_follow (int token) {
+ switch (token) {
+ case TK_ELSE: case TK_ELSEIF: case TK_END:
+ case TK_UNTIL: case TK_EOS:
+ return 1;
+ default: return 0;
+ }
+}
+
+
+static void block (LexState *ls) {
+ /* block -> chunk */
+ FuncState *fs = ls->fs;
+ BlockCnt bl;
+ enterblock(fs, &bl, 0);
+ chunk(ls);
+ lua_assert(bl.breaklist == NO_JUMP);
+ leaveblock(fs);
+}
+
+
+/*
+** structure to chain all variables in the left-hand side of an
+** assignment
+*/
+struct LHS_assign {
+ struct LHS_assign *prev;
+ expdesc v; /* variable (global, local, upvalue, or indexed) */
+};
+
+
+/*
+** check whether, in an assignment to a local variable, the local variable
+** is needed in a previous assignment (to a table). If so, save original
+** local value in a safe place and use this safe copy in the previous
+** assignment.
+*/
+static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
+ FuncState *fs = ls->fs;
+ int extra = fs->freereg; /* eventual position to save local variable */
+ int conflict = 0;
+ for (; lh; lh = lh->prev) {
+ if (lh->v.k == VINDEXED) {
+ if (lh->v.info == v->info) { /* conflict? */
+ conflict = 1;
+ lh->v.info = extra; /* previous assignment will use safe copy */
+ }
+ if (lh->v.aux == v->info) { /* conflict? */
+ conflict = 1;
+ lh->v.aux = extra; /* previous assignment will use safe copy */
+ }
+ }
+ }
+ if (conflict) {
+ luaK_codeABC(fs, OP_MOVE, fs->freereg, v->info, 0); /* make copy */
+ luaK_reserveregs(fs, 1);
+ }
+}
+
+
+static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
+ expdesc e;
+ check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
+ "syntax error");
+ if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
+ struct LHS_assign nv;
+ nv.prev = lh;
+ primaryexp(ls, &nv.v);
+ if (nv.v.k == VLOCAL)
+ check_conflict(ls, lh, &nv.v);
+ assignment(ls, &nv, nvars+1);
+ }
+ else { /* assignment -> `=' explist1 */
+ int nexps;
+ check(ls, '=');
+ nexps = explist1(ls, &e);
+ if (nexps != nvars) {
+ adjust_assign(ls, nvars, nexps, &e);
+ if (nexps > nvars)
+ ls->fs->freereg -= nexps - nvars; /* remove extra values */
+ }
+ else {
+ luaK_setcallreturns(ls->fs, &e, 1); /* close last expression */
+ luaK_storevar(ls->fs, &lh->v, &e);
+ return; /* avoid default */
+ }
+ }
+ init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
+ luaK_storevar(ls->fs, &lh->v, &e);
+}
+
+
+static void cond (LexState *ls, expdesc *v) {
+ /* cond -> exp */
+ expr(ls, v); /* read condition */
+ if (v->k == VNIL) v->k = VFALSE; /* `falses' are all equal here */
+ luaK_goiftrue(ls->fs, v);
+ luaK_patchtohere(ls->fs, v->t);
+}
+
+
+/*
+** The while statement optimizes its code by coding the condition
+** after its body (and thus avoiding one jump in the loop).
+*/
+
+/*
+** maximum size of expressions for optimizing `while' code
+*/
+#ifndef MAXEXPWHILE
+#define MAXEXPWHILE 100
+#endif
+
+/*
+** the call `luaK_goiffalse' may grow the size of an expression by
+** at most this:
+*/
+#define EXTRAEXP 5
+
+static void whilestat (LexState *ls, int line) {
+ /* whilestat -> WHILE cond DO block END */
+ Instruction codeexp[MAXEXPWHILE + EXTRAEXP];
+ int lineexp;
+ int i;
+ int sizeexp;
+ FuncState *fs = ls->fs;
+ int whileinit, blockinit, expinit;
+ expdesc v;
+ BlockCnt bl;
+ next(ls); /* skip WHILE */
+ whileinit = luaK_jump(fs); /* jump to condition (which will be moved) */
+ expinit = luaK_getlabel(fs);
+ expr(ls, &v); /* parse condition */
+ if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */
+ lineexp = ls->linenumber;
+ luaK_goiffalse(fs, &v);
+ luaK_concat(fs, &v.f, fs->jpc);
+ fs->jpc = NO_JUMP;
+ sizeexp = fs->pc - expinit; /* size of expression code */
+ if (sizeexp > MAXEXPWHILE)
+ luaX_syntaxerror(ls, "`while' condition too complex");
+ for (i = 0; i < sizeexp; i++) /* save `exp' code */
+ codeexp[i] = fs->f->code[expinit + i];
+ fs->pc = expinit; /* remove `exp' code */
+ enterblock(fs, &bl, 1);
+ check(ls, TK_DO);
+ blockinit = luaK_getlabel(fs);
+ block(ls);
+ luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */
+ /* move `exp' back to code */
+ if (v.t != NO_JUMP) v.t += fs->pc - expinit;
+ if (v.f != NO_JUMP) v.f += fs->pc - expinit;
+ for (i=0; i<sizeexp; i++)
+ luaK_code(fs, codeexp[i], lineexp);
+ check_match(ls, TK_END, TK_WHILE, line);
+ leaveblock(fs);
+ luaK_patchlist(fs, v.t, blockinit); /* true conditions go back to loop */
+ luaK_patchtohere(fs, v.f); /* false conditions finish the loop */
+}
+
+
+static void repeatstat (LexState *ls, int line) {
+ /* repeatstat -> REPEAT block UNTIL cond */
+ FuncState *fs = ls->fs;
+ int repeat_init = luaK_getlabel(fs);
+ expdesc v;
+ BlockCnt bl;
+ enterblock(fs, &bl, 1);
+ next(ls);
+ block(ls);
+ check_match(ls, TK_UNTIL, TK_REPEAT, line);
+ cond(ls, &v);
+ luaK_patchlist(fs, v.f, repeat_init);
+ leaveblock(fs);
+}
+
+
+static int exp1 (LexState *ls) {
+ expdesc e;
+ int k;
+ expr(ls, &e);
+ k = e.k;
+ luaK_exp2nextreg(ls->fs, &e);
+ return k;
+}
+
+
+static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
+ BlockCnt bl;
+ FuncState *fs = ls->fs;
+ int prep, endfor;
+ adjustlocalvars(ls, nvars); /* scope for all variables */
+ check(ls, TK_DO);
+ enterblock(fs, &bl, 1); /* loop block */
+ prep = luaK_getlabel(fs);
+ block(ls);
+ luaK_patchtohere(fs, prep-1);
+ endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
+ luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3);
+ luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
+ luaK_patchlist(fs, (isnum) ? endfor : luaK_jump(fs), prep);
+ leaveblock(fs);
+}
+
+
+static void fornum (LexState *ls, TString *varname, int line) {
+ /* fornum -> NAME = exp1,exp1[,exp1] DO body */
+ FuncState *fs = ls->fs;
+ int base = fs->freereg;
+ new_localvar(ls, varname, 0);
+ new_localvarstr(ls, "(for limit)", 1);
+ new_localvarstr(ls, "(for step)", 2);
+ check(ls, '=');
+ exp1(ls); /* initial value */
+ check(ls, ',');
+ exp1(ls); /* limit */
+ if (testnext(ls, ','))
+ exp1(ls); /* optional step */
+ else { /* default step = 1 */
+ luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
+ luaK_reserveregs(fs, 1);
+ }
+ luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1);
+ luaK_jump(fs);
+ forbody(ls, base, line, 3, 1);
+}
+
+
+static void forlist (LexState *ls, TString *indexname) {
+ /* forlist -> NAME {,NAME} IN explist1 DO body */
+ FuncState *fs = ls->fs;
+ expdesc e;
+ int nvars = 0;
+ int line;
+ int base = fs->freereg;
+ new_localvarstr(ls, "(for generator)", nvars++);
+ new_localvarstr(ls, "(for state)", nvars++);
+ new_localvar(ls, indexname, nvars++);
+ while (testnext(ls, ','))
+ new_localvar(ls, str_checkname(ls), nvars++);
+ check(ls, TK_IN);
+ line = ls->linenumber;
+ adjust_assign(ls, nvars, explist1(ls, &e), &e);
+ luaK_checkstack(fs, 3); /* extra space to call generator */
+ luaK_codeAsBx(fs, OP_TFORPREP, base, NO_JUMP);
+ forbody(ls, base, line, nvars, 0);
+}
+
+
+static void forstat (LexState *ls, int line) {
+ /* forstat -> fornum | forlist */
+ FuncState *fs = ls->fs;
+ TString *varname;
+ BlockCnt bl;
+ enterblock(fs, &bl, 0); /* block to control variable scope */
+ next(ls); /* skip `for' */
+ varname = str_checkname(ls); /* first variable name */
+ switch (ls->t.token) {
+ case '=': fornum(ls, varname, line); break;
+ case ',': case TK_IN: forlist(ls, varname); break;
+ default: luaX_syntaxerror(ls, "`=' or `in' expected");
+ }
+ check_match(ls, TK_END, TK_FOR, line);
+ leaveblock(fs);
+}
+
+
+static void test_then_block (LexState *ls, expdesc *v) {
+ /* test_then_block -> [IF | ELSEIF] cond THEN block */
+ next(ls); /* skip IF or ELSEIF */
+ cond(ls, v);
+ check(ls, TK_THEN);
+ block(ls); /* `then' part */
+}
+
+
+static void ifstat (LexState *ls, int line) {
+ /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
+ FuncState *fs = ls->fs;
+ expdesc v;
+ int escapelist = NO_JUMP;
+ test_then_block(ls, &v); /* IF cond THEN block */
+ while (ls->t.token == TK_ELSEIF) {
+ luaK_concat(fs, &escapelist, luaK_jump(fs));
+ luaK_patchtohere(fs, v.f);
+ test_then_block(ls, &v); /* ELSEIF cond THEN block */
+ }
+ if (ls->t.token == TK_ELSE) {
+ luaK_concat(fs, &escapelist, luaK_jump(fs));
+ luaK_patchtohere(fs, v.f);
+ next(ls); /* skip ELSE (after patch, for correct line info) */
+ block(ls); /* `else' part */
+ }
+ else
+ luaK_concat(fs, &escapelist, v.f);
+ luaK_patchtohere(fs, escapelist);
+ check_match(ls, TK_END, TK_IF, line);
+}
+
+
+static void localfunc (LexState *ls) {
+ expdesc v, b;
+ new_localvar(ls, str_checkname(ls), 0);
+ init_exp(&v, VLOCAL, ls->fs->freereg++);
+ adjustlocalvars(ls, 1);
+ body(ls, &b, 0, ls->linenumber);
+ luaK_storevar(ls->fs, &v, &b);
+}
+
+
+static void localstat (LexState *ls) {
+ /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
+ int nvars = 0;
+ int nexps;
+ expdesc e;
+ do {
+ new_localvar(ls, str_checkname(ls), nvars++);
+ } while (testnext(ls, ','));
+ if (testnext(ls, '='))
+ nexps = explist1(ls, &e);
+ else {
+ e.k = VVOID;
+ nexps = 0;
+ }
+ adjust_assign(ls, nvars, nexps, &e);
+ adjustlocalvars(ls, nvars);
+}
+
+
+static int funcname (LexState *ls, expdesc *v) {
+ /* funcname -> NAME {field} [`:' NAME] */
+ int needself = 0;
+ singlevar(ls, v, 1);
+ while (ls->t.token == '.')
+ luaY_field(ls, v);
+ if (ls->t.token == ':') {
+ needself = 1;
+ luaY_field(ls, v);
+ }
+ return needself;
+}
+
+
+static void funcstat (LexState *ls, int line) {
+ /* funcstat -> FUNCTION funcname body */
+ int needself;
+ expdesc v, b;
+ next(ls); /* skip FUNCTION */
+ needself = funcname(ls, &v);
+ body(ls, &b, needself, line);
+ luaK_storevar(ls->fs, &v, &b);
+ luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
+}
+
+
+static void exprstat (LexState *ls) {
+ /* stat -> func | assignment */
+ FuncState *fs = ls->fs;
+ struct LHS_assign v;
+ primaryexp(ls, &v.v);
+ if (v.v.k == VCALL) { /* stat -> func */
+ luaK_setcallreturns(fs, &v.v, 0); /* call statement uses no results */
+ }
+ else { /* stat -> assignment */
+ v.prev = NULL;
+ assignment(ls, &v, 1);
+ }
+}
+
+
+static void retstat (LexState *ls) {
+ /* stat -> RETURN explist */
+ FuncState *fs = ls->fs;
+ expdesc e;
+ int first, nret; /* registers with returned values */
+ next(ls); /* skip RETURN */
+ if (block_follow(ls->t.token) || ls->t.token == ';')
+ first = nret = 0; /* return no values */
+ else {
+ nret = explist1(ls, &e); /* optional return values */
+ if (e.k == VCALL) {
+ luaK_setcallreturns(fs, &e, LUA_MULTRET);
+ if (nret == 1) { /* tail call? */
+ SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
+ lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
+ }
+ first = fs->nactvar;
+ nret = LUA_MULTRET; /* return all values */
+ }
+ else {
+ if (nret == 1) /* only one single value? */
+ first = luaK_exp2anyreg(fs, &e);
+ else {
+ luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
+ first = fs->nactvar; /* return all `active' values */
+ lua_assert(nret == fs->freereg - first);
+ }
+ }
+ }
+ luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
+}
+
+
+static void breakstat (LexState *ls) {
+ /* stat -> BREAK [NAME] */
+ FuncState *fs = ls->fs;
+ BlockCnt *bl = fs->bl;
+ int upval = 0;
+ next(ls); /* skip BREAK */
+ while (bl && !bl->isbreakable) {
+ upval |= bl->upval;
+ bl = bl->previous;
+ }
+ if (!bl)
+ luaX_syntaxerror(ls, "no loop to break");
+ if (upval)
+ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
+ luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
+}
+
+
+static int statement (LexState *ls) {
+ int line = ls->linenumber; /* may be needed for error messages */
+ switch (ls->t.token) {
+ case TK_IF: { /* stat -> ifstat */
+ ifstat(ls, line);
+ return 0;
+ }
+ case TK_WHILE: { /* stat -> whilestat */
+ whilestat(ls, line);
+ return 0;
+ }
+ case TK_DO: { /* stat -> DO block END */
+ next(ls); /* skip DO */
+ block(ls);
+ check_match(ls, TK_END, TK_DO, line);
+ return 0;
+ }
+ case TK_FOR: { /* stat -> forstat */
+ forstat(ls, line);
+ return 0;
+ }
+ case TK_REPEAT: { /* stat -> repeatstat */
+ repeatstat(ls, line);
+ return 0;
+ }
+ case TK_FUNCTION: {
+ funcstat(ls, line); /* stat -> funcstat */
+ return 0;
+ }
+ case TK_LOCAL: { /* stat -> localstat */
+ next(ls); /* skip LOCAL */
+ if (testnext(ls, TK_FUNCTION)) /* local function? */
+ localfunc(ls);
+ else
+ localstat(ls);
+ return 0;
+ }
+ case TK_RETURN: { /* stat -> retstat */
+ retstat(ls);
+ return 1; /* must be last statement */
+ }
+ case TK_BREAK: { /* stat -> breakstat */
+ breakstat(ls);
+ return 1; /* must be last statement */
+ }
+ default: {
+ exprstat(ls);
+ return 0; /* to avoid warnings */
+ }
+ }
+}
+
+
+static void chunk (LexState *ls) {
+ /* chunk -> { stat [`;'] } */
+ int islast = 0;
+ enterlevel(ls);
+ while (!islast && !block_follow(ls->t.token)) {
+ islast = statement(ls);
+ testnext(ls, ';');
+ lua_assert(ls->fs->freereg >= ls->fs->nactvar);
+ ls->fs->freereg = ls->fs->nactvar; /* free registers */
+ }
+ leavelevel(ls);
+}
+
+/* }====================================================================== */
diff --git a/lib/lua/src/lstate.c b/lib/lua/src/lstate.c
index 53eb6aa..ccd6aeb 100644
--- a/lib/lua/src/lstate.c
+++ b/lib/lua/src/lstate.c
@@ -1,220 +1,220 @@
-/*
-** $Id: lstate.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** Global State
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stdlib.h>
-
-#define lstate_c
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "llex.h"
-#include "lmem.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-
-
-/*
-** macro to allow the inclusion of user information in Lua state
-*/
-#ifndef LUA_USERSTATE
-#define EXTRASPACE 0
-#else
-union UEXTRASPACE {L_Umaxalign a; LUA_USERSTATE b;};
-#define EXTRASPACE (sizeof(union UEXTRASPACE))
-#endif
-
-
-
-/*
-** you can change this function through the official API:
-** call `lua_setpanicf'
-*/
-static int default_panic (lua_State *L) {
- UNUSED(L);
- return 0;
-}
-
-
-static lua_State *mallocstate (lua_State *L) {
- lu_byte *block = (lu_byte *)luaM_malloc(L, sizeof(lua_State) + EXTRASPACE);
- if (block == NULL) return NULL;
- else {
- block += EXTRASPACE;
- return cast(lua_State *, block);
- }
-}
-
-
-static void freestate (lua_State *L, lua_State *L1) {
- luaM_free(L, cast(lu_byte *, L1) - EXTRASPACE,
- sizeof(lua_State) + EXTRASPACE);
-}
-
-
-static void stack_init (lua_State *L1, lua_State *L) {
- L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TObject);
- L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
- L1->top = L1->stack;
- L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
- L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
- L1->ci = L1->base_ci;
- L1->ci->state = CI_C; /* not a Lua function */
- setnilvalue(L1->top++); /* `function' entry for this `ci' */
- L1->base = L1->ci->base = L1->top;
- L1->ci->top = L1->top + LUA_MINSTACK;
- L1->size_ci = BASIC_CI_SIZE;
- L1->end_ci = L1->base_ci + L1->size_ci;
-}
-
-
-static void freestack (lua_State *L, lua_State *L1) {
- luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
- luaM_freearray(L, L1->stack, L1->stacksize, TObject);
-}
-
-
-/*
-** open parts that may cause memory-allocation errors
-*/
-static void f_luaopen (lua_State *L, void *ud) {
- /* create a new global state */
- global_State *g = luaM_new(NULL, global_State);
- UNUSED(ud);
- if (g == NULL) luaD_throw(L, LUA_ERRMEM);
- L->l_G = g;
- g->mainthread = L;
- g->GCthreshold = 0; /* mark it as unfinished state */
- g->strt.size = 0;
- g->strt.nuse = 0;
- g->strt.hash = NULL;
- setnilvalue(defaultmeta(L));
- setnilvalue(registry(L));
- luaZ_initbuffer(L, &g->buff);
- g->panic = default_panic;
- g->rootgc = NULL;
- g->rootudata = NULL;
- g->tmudata = NULL;
- setnilvalue(gkey(g->dummynode));
- setnilvalue(gval(g->dummynode));
- g->dummynode->next = NULL;
- g->nblocks = sizeof(lua_State) + sizeof(global_State);
- stack_init(L, L); /* init stack */
- /* create default meta table with a dummy table, and then close the loop */
- defaultmeta(L)->tt = LUA_TTABLE;
- sethvalue(defaultmeta(L), luaH_new(L, 0, 0));
- hvalue(defaultmeta(L))->metatable = hvalue(defaultmeta(L));
- sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */
- sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */
- luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
- luaT_init(L);
- luaX_init(L);
- luaS_fix(luaS_newliteral(L, MEMERRMSG));
- g->GCthreshold = 4*G(L)->nblocks;
-}
-
-
-static void preinit_state (lua_State *L) {
- L->stack = NULL;
- L->stacksize = 0;
- L->errorJmp = NULL;
- L->hook = NULL;
- L->hookmask = L->hookinit = 0;
- L->basehookcount = 0;
- L->allowhook = 1;
- resethookcount(L);
- L->openupval = NULL;
- L->size_ci = 0;
- L->nCcalls = 0;
- L->base_ci = L->ci = NULL;
- L->errfunc = 0;
- setnilvalue(gt(L));
-}
-
-
-static void close_state (lua_State *L) {
- luaF_close(L, L->stack); /* close all upvalues for this thread */
- if (G(L)) { /* close global state */
- luaC_sweep(L, 1); /* collect all elements */
- lua_assert(G(L)->rootgc == NULL);
- lua_assert(G(L)->rootudata == NULL);
- luaS_freeall(L);
- luaZ_freebuffer(L, &G(L)->buff);
- }
- freestack(L, L);
- if (G(L)) {
- lua_assert(G(L)->nblocks == sizeof(lua_State) + sizeof(global_State));
- luaM_freelem(NULL, G(L));
- }
- freestate(NULL, L);
-}
-
-
-lua_State *luaE_newthread (lua_State *L) {
- lua_State *L1 = mallocstate(L);
- luaC_link(L, valtogco(L1), LUA_TTHREAD);
- preinit_state(L1);
- L1->l_G = L->l_G;
- stack_init(L1, L); /* init stack */
- setobj2n(gt(L1), gt(L)); /* share table of globals */
- return L1;
-}
-
-
-void luaE_freethread (lua_State *L, lua_State *L1) {
- luaF_close(L1, L1->stack); /* close all upvalues for this thread */
- lua_assert(L1->openupval == NULL);
- freestack(L, L1);
- freestate(L, L1);
-}
-
-
-LUA_API lua_State *lua_open (void) {
- lua_State *L = mallocstate(NULL);
- if (L) { /* allocation OK? */
- L->tt = LUA_TTHREAD;
- L->marked = 0;
- L->next = L->gclist = NULL;
- preinit_state(L);
- L->l_G = NULL;
- if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
- /* memory allocation error: free partial state */
- close_state(L);
- L = NULL;
- }
- }
- lua_userstateopen(L);
- return L;
-}
-
-
-static void callallgcTM (lua_State *L, void *ud) {
- UNUSED(ud);
- luaC_callGCTM(L); /* call GC metamethods for all udata */
-}
-
-
-LUA_API void lua_close (lua_State *L) {
- lua_lock(L);
- L = G(L)->mainthread; /* only the main thread can be closed */
- luaF_close(L, L->stack); /* close all upvalues for this thread */
- luaC_separateudata(L); /* separate udata that have GC metamethods */
- L->errfunc = 0; /* no error function during GC metamethods */
- do { /* repeat until no more errors */
- L->ci = L->base_ci;
- L->base = L->top = L->ci->base;
- L->nCcalls = 0;
- } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
- lua_assert(G(L)->tmudata == NULL);
- close_state(L);
-}
-
+/*
+** $Id: lstate.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** Global State
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdlib.h>
+
+#define lstate_c
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "llex.h"
+#include "lmem.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+
+
+/*
+** macro to allow the inclusion of user information in Lua state
+*/
+#ifndef LUA_USERSTATE
+#define EXTRASPACE 0
+#else
+union UEXTRASPACE {L_Umaxalign a; LUA_USERSTATE b;};
+#define EXTRASPACE (sizeof(union UEXTRASPACE))
+#endif
+
+
+
+/*
+** you can change this function through the official API:
+** call `lua_setpanicf'
+*/
+static int default_panic (lua_State *L) {
+ UNUSED(L);
+ return 0;
+}
+
+
+static lua_State *mallocstate (lua_State *L) {
+ lu_byte *block = (lu_byte *)luaM_malloc(L, sizeof(lua_State) + EXTRASPACE);
+ if (block == NULL) return NULL;
+ else {
+ block += EXTRASPACE;
+ return cast(lua_State *, block);
+ }
+}
+
+
+static void freestate (lua_State *L, lua_State *L1) {
+ luaM_free(L, cast(lu_byte *, L1) - EXTRASPACE,
+ sizeof(lua_State) + EXTRASPACE);
+}
+
+
+static void stack_init (lua_State *L1, lua_State *L) {
+ L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TObject);
+ L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
+ L1->top = L1->stack;
+ L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
+ L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
+ L1->ci = L1->base_ci;
+ L1->ci->state = CI_C; /* not a Lua function */
+ setnilvalue(L1->top++); /* `function' entry for this `ci' */
+ L1->base = L1->ci->base = L1->top;
+ L1->ci->top = L1->top + LUA_MINSTACK;
+ L1->size_ci = BASIC_CI_SIZE;
+ L1->end_ci = L1->base_ci + L1->size_ci;
+}
+
+
+static void freestack (lua_State *L, lua_State *L1) {
+ luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
+ luaM_freearray(L, L1->stack, L1->stacksize, TObject);
+}
+
+
+/*
+** open parts that may cause memory-allocation errors
+*/
+static void f_luaopen (lua_State *L, void *ud) {
+ /* create a new global state */
+ global_State *g = luaM_new(NULL, global_State);
+ UNUSED(ud);
+ if (g == NULL) luaD_throw(L, LUA_ERRMEM);
+ L->l_G = g;
+ g->mainthread = L;
+ g->GCthreshold = 0; /* mark it as unfinished state */
+ g->strt.size = 0;
+ g->strt.nuse = 0;
+ g->strt.hash = NULL;
+ setnilvalue(defaultmeta(L));
+ setnilvalue(registry(L));
+ luaZ_initbuffer(L, &g->buff);
+ g->panic = default_panic;
+ g->rootgc = NULL;
+ g->rootudata = NULL;
+ g->tmudata = NULL;
+ setnilvalue(gkey(g->dummynode));
+ setnilvalue(gval(g->dummynode));
+ g->dummynode->next = NULL;
+ g->nblocks = sizeof(lua_State) + sizeof(global_State);
+ stack_init(L, L); /* init stack */
+ /* create default meta table with a dummy table, and then close the loop */
+ defaultmeta(L)->tt = LUA_TTABLE;
+ sethvalue(defaultmeta(L), luaH_new(L, 0, 0));
+ hvalue(defaultmeta(L))->metatable = hvalue(defaultmeta(L));
+ sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */
+ sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */
+ luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
+ luaT_init(L);
+ luaX_init(L);
+ luaS_fix(luaS_newliteral(L, MEMERRMSG));
+ g->GCthreshold = 4*G(L)->nblocks;
+}
+
+
+static void preinit_state (lua_State *L) {
+ L->stack = NULL;
+ L->stacksize = 0;
+ L->errorJmp = NULL;
+ L->hook = NULL;
+ L->hookmask = L->hookinit = 0;
+ L->basehookcount = 0;
+ L->allowhook = 1;
+ resethookcount(L);
+ L->openupval = NULL;
+ L->size_ci = 0;
+ L->nCcalls = 0;
+ L->base_ci = L->ci = NULL;
+ L->errfunc = 0;
+ setnilvalue(gt(L));
+}
+
+
+static void close_state (lua_State *L) {
+ luaF_close(L, L->stack); /* close all upvalues for this thread */
+ if (G(L)) { /* close global state */
+ luaC_sweep(L, 1); /* collect all elements */
+ lua_assert(G(L)->rootgc == NULL);
+ lua_assert(G(L)->rootudata == NULL);
+ luaS_freeall(L);
+ luaZ_freebuffer(L, &G(L)->buff);
+ }
+ freestack(L, L);
+ if (G(L)) {
+ lua_assert(G(L)->nblocks == sizeof(lua_State) + sizeof(global_State));
+ luaM_freelem(NULL, G(L));
+ }
+ freestate(NULL, L);
+}
+
+
+lua_State *luaE_newthread (lua_State *L) {
+ lua_State *L1 = mallocstate(L);
+ luaC_link(L, valtogco(L1), LUA_TTHREAD);
+ preinit_state(L1);
+ L1->l_G = L->l_G;
+ stack_init(L1, L); /* init stack */
+ setobj2n(gt(L1), gt(L)); /* share table of globals */
+ return L1;
+}
+
+
+void luaE_freethread (lua_State *L, lua_State *L1) {
+ luaF_close(L1, L1->stack); /* close all upvalues for this thread */
+ lua_assert(L1->openupval == NULL);
+ freestack(L, L1);
+ freestate(L, L1);
+}
+
+
+LUA_API lua_State *lua_open (void) {
+ lua_State *L = mallocstate(NULL);
+ if (L) { /* allocation OK? */
+ L->tt = LUA_TTHREAD;
+ L->marked = 0;
+ L->next = L->gclist = NULL;
+ preinit_state(L);
+ L->l_G = NULL;
+ if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
+ /* memory allocation error: free partial state */
+ close_state(L);
+ L = NULL;
+ }
+ }
+ lua_userstateopen(L);
+ return L;
+}
+
+
+static void callallgcTM (lua_State *L, void *ud) {
+ UNUSED(ud);
+ luaC_callGCTM(L); /* call GC metamethods for all udata */
+}
+
+
+LUA_API void lua_close (lua_State *L) {
+ lua_lock(L);
+ L = G(L)->mainthread; /* only the main thread can be closed */
+ luaF_close(L, L->stack); /* close all upvalues for this thread */
+ luaC_separateudata(L); /* separate udata that have GC metamethods */
+ L->errfunc = 0; /* no error function during GC metamethods */
+ do { /* repeat until no more errors */
+ L->ci = L->base_ci;
+ L->base = L->top = L->ci->base;
+ L->nCcalls = 0;
+ } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
+ lua_assert(G(L)->tmudata == NULL);
+ close_state(L);
+}
+
diff --git a/lib/lua/src/lstring.c b/lib/lua/src/lstring.c
index 863f510..56df94e 100644
--- a/lib/lua/src/lstring.c
+++ b/lib/lua/src/lstring.c
@@ -1,102 +1,102 @@
-/*
-** $Id: lstring.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** String table (keeps all strings handled by Lua)
-** See Copyright Notice in lua.h
-*/
-
-
-#include <string.h>
-
-#define lstring_c
-
-#include "lua.h"
-
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-
-
-
-void luaS_freeall (lua_State *L) {
- lua_assert(G(L)->strt.nuse==0);
- luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
-}
-
-
-void luaS_resize (lua_State *L, int newsize) {
- GCObject **newhash = luaM_newvector(L, newsize, GCObject *);
- stringtable *tb = &G(L)->strt;
- int i;
- for (i=0; i<newsize; i++) newhash[i] = NULL;
- /* rehash */
- for (i=0; i<tb->size; i++) {
- GCObject *p = tb->hash[i];
- while (p) { /* for each node in the list */
- GCObject *next = p->gch.next; /* save next */
- lu_hash h = gcotots(p)->tsv.hash;
- int h1 = lmod(h, newsize); /* new position */
- lua_assert(cast(int, h%newsize) == lmod(h, newsize));
- p->gch.next = newhash[h1]; /* chain it */
- newhash[h1] = p;
- p = next;
- }
- }
- luaM_freearray(L, tb->hash, tb->size, TString *);
- tb->size = newsize;
- tb->hash = newhash;
-}
-
-
-static TString *newlstr (lua_State *L, const char *str, size_t l, lu_hash h) {
- TString *ts = cast(TString *, luaM_malloc(L, sizestring(l)));
- stringtable *tb;
- ts->tsv.len = l;
- ts->tsv.hash = h;
- ts->tsv.marked = 0;
- ts->tsv.tt = LUA_TSTRING;
- ts->tsv.reserved = 0;
- memcpy(ts+1, str, l*sizeof(char));
- ((char *)(ts+1))[l] = '\0'; /* ending 0 */
- tb = &G(L)->strt;
- h = lmod(h, tb->size);
- ts->tsv.next = tb->hash[h]; /* chain new entry */
- tb->hash[h] = valtogco(ts);
- tb->nuse++;
- if (tb->nuse > cast(ls_nstr, tb->size) && tb->size <= MAX_INT/2)
- luaS_resize(L, tb->size*2); /* too crowded */
- return ts;
-}
-
-
-TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
- GCObject *o;
- lu_hash h = (lu_hash)l; /* seed */
- size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
- size_t l1;
- for (l1=l; l1>=step; l1-=step) /* compute hash */
- h = h ^ ((h<<5)+(h>>2)+(unsigned char)(str[l1-1]));
- for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
- o != NULL;
- o = o->gch.next) {
- TString *ts = gcotots(o);
- if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0))
- return ts;
- }
- return newlstr(L, str, l, h); /* not found */
-}
-
-
-Udata *luaS_newudata (lua_State *L, size_t s) {
- Udata *u;
- u = cast(Udata *, luaM_malloc(L, sizeudata(s)));
- u->uv.marked = (1<<1); /* is not finalized */
- u->uv.tt = LUA_TUSERDATA;
- u->uv.len = s;
- u->uv.metatable = hvalue(defaultmeta(L));
- /* chain it on udata list */
- u->uv.next = G(L)->rootudata;
- G(L)->rootudata = valtogco(u);
- return u;
-}
-
+/*
+** $Id: lstring.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** String table (keeps all strings handled by Lua)
+** See Copyright Notice in lua.h
+*/
+
+
+#include <string.h>
+
+#define lstring_c
+
+#include "lua.h"
+
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+
+
+
+void luaS_freeall (lua_State *L) {
+ lua_assert(G(L)->strt.nuse==0);
+ luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
+}
+
+
+void luaS_resize (lua_State *L, int newsize) {
+ GCObject **newhash = luaM_newvector(L, newsize, GCObject *);
+ stringtable *tb = &G(L)->strt;
+ int i;
+ for (i=0; i<newsize; i++) newhash[i] = NULL;
+ /* rehash */
+ for (i=0; i<tb->size; i++) {
+ GCObject *p = tb->hash[i];
+ while (p) { /* for each node in the list */
+ GCObject *next = p->gch.next; /* save next */
+ lu_hash h = gcotots(p)->tsv.hash;
+ int h1 = lmod(h, newsize); /* new position */
+ lua_assert(cast(int, h%newsize) == lmod(h, newsize));
+ p->gch.next = newhash[h1]; /* chain it */
+ newhash[h1] = p;
+ p = next;
+ }
+ }
+ luaM_freearray(L, tb->hash, tb->size, TString *);
+ tb->size = newsize;
+ tb->hash = newhash;
+}
+
+
+static TString *newlstr (lua_State *L, const char *str, size_t l, lu_hash h) {
+ TString *ts = cast(TString *, luaM_malloc(L, sizestring(l)));
+ stringtable *tb;
+ ts->tsv.len = l;
+ ts->tsv.hash = h;
+ ts->tsv.marked = 0;
+ ts->tsv.tt = LUA_TSTRING;
+ ts->tsv.reserved = 0;
+ memcpy(ts+1, str, l*sizeof(char));
+ ((char *)(ts+1))[l] = '\0'; /* ending 0 */
+ tb = &G(L)->strt;
+ h = lmod(h, tb->size);
+ ts->tsv.next = tb->hash[h]; /* chain new entry */
+ tb->hash[h] = valtogco(ts);
+ tb->nuse++;
+ if (tb->nuse > cast(ls_nstr, tb->size) && tb->size <= MAX_INT/2)
+ luaS_resize(L, tb->size*2); /* too crowded */
+ return ts;
+}
+
+
+TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
+ GCObject *o;
+ lu_hash h = (lu_hash)l; /* seed */
+ size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
+ size_t l1;
+ for (l1=l; l1>=step; l1-=step) /* compute hash */
+ h = h ^ ((h<<5)+(h>>2)+(unsigned char)(str[l1-1]));
+ for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
+ o != NULL;
+ o = o->gch.next) {
+ TString *ts = gcotots(o);
+ if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0))
+ return ts;
+ }
+ return newlstr(L, str, l, h); /* not found */
+}
+
+
+Udata *luaS_newudata (lua_State *L, size_t s) {
+ Udata *u;
+ u = cast(Udata *, luaM_malloc(L, sizeudata(s)));
+ u->uv.marked = (1<<1); /* is not finalized */
+ u->uv.tt = LUA_TUSERDATA;
+ u->uv.len = s;
+ u->uv.metatable = hvalue(defaultmeta(L));
+ /* chain it on udata list */
+ u->uv.next = G(L)->rootudata;
+ G(L)->rootudata = valtogco(u);
+ return u;
+}
+
diff --git a/lib/lua/src/ltable.c b/lib/lua/src/ltable.c
index 9f4cb6c..4969d84 100644
--- a/lib/lua/src/ltable.c
+++ b/lib/lua/src/ltable.c
@@ -1,509 +1,509 @@
-/*
-** $Id: ltable.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** Lua tables (hash)
-** See Copyright Notice in lua.h
-*/
-
-
-/*
-** Implementation of tables (aka arrays, objects, or hash tables).
-** Tables keep its elements in two parts: an array part and a hash part.
-** Non-negative integer keys are all candidates to be kept in the array
-** part. The actual size of the array is the largest `n' such that at
-** least half the slots between 0 and n are in use.
-** Hash uses a mix of chained scatter table with Brent's variation.
-** A main invariant of these tables is that, if an element is not
-** in its main position (i.e. the `original' position that its hash gives
-** to it), then the colliding element is in its own main position.
-** In other words, there are collisions only when two elements have the
-** same main position (i.e. the same hash values for that table size).
-** Because of that, the load factor of these tables can be 100% without
-** performance penalties.
-*/
-
-#include <string.h>
-
-#define ltable_c
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "ltable.h"
-
-
-/*
-** max size of array part is 2^MAXBITS
-*/
-#if BITS_INT > 26
-#define MAXBITS 24
-#else
-#define MAXBITS (BITS_INT-2)
-#endif
-
-/* check whether `x' < 2^MAXBITS */
-#define toobig(x) ((((x)-1) >> MAXBITS) != 0)
-
-
-/* function to convert a lua_Number to int (with any rounding method) */
-#ifndef lua_number2int
-#define lua_number2int(i,n) ((i)=(int)(n))
-#endif
-
-
-#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
-
-#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
-#define hashboolean(t,p) hashpow2(t, p)
-
-
-/*
-** for some types, it is better to avoid modulus by power of 2, as
-** they tend to have many 2 factors.
-*/
-#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
-
-
-#define hashpointer(t,p) hashmod(t, IntPoint(p))
-
-
-/*
-** number of ints inside a lua_Number
-*/
-#define numints cast(int, sizeof(lua_Number)/sizeof(int))
-
-
-/*
-** hash for lua_Numbers
-*/
-static Node *hashnum (const Table *t, lua_Number n) {
- unsigned int a[numints];
- int i;
- n += 1; /* normalize number (avoid -0) */
- lua_assert(sizeof(a) <= sizeof(n));
- memcpy(a, &n, sizeof(a));
- for (i = 1; i < numints; i++) a[0] += a[i];
- return hashmod(t, cast(lu_hash, a[0]));
-}
-
-
-
-/*
-** returns the `main' position of an element in a table (that is, the index
-** of its hash value)
-*/
-Node *luaH_mainposition (const Table *t, const TObject *key) {
- switch (ttype(key)) {
- case LUA_TNUMBER:
- return hashnum(t, nvalue(key));
- case LUA_TSTRING:
- return hashstr(t, tsvalue(key));
- case LUA_TBOOLEAN:
- return hashboolean(t, bvalue(key));
- case LUA_TLIGHTUSERDATA:
- return hashpointer(t, pvalue(key));
- default:
- return hashpointer(t, gcvalue(key));
- }
-}
-
-
-/*
-** returns the index for `key' if `key' is an appropriate key to live in
-** the array part of the table, -1 otherwise.
-*/
-static int arrayindex (const TObject *key) {
- if (ttisnumber(key)) {
- int k;
- lua_number2int(k, (nvalue(key)));
- if (cast(lua_Number, k) == nvalue(key) && k >= 1 && !toobig(k))
- return k;
- }
- return -1; /* `key' did not match some condition */
-}
-
-
-/*
-** returns the index of a `key' for table traversals. First goes all
-** elements in the array part, then elements in the hash part. The
-** beginning and end of a traversal are signalled by -1.
-*/
-static int luaH_index (lua_State *L, Table *t, StkId key) {
- int i;
- if (ttisnil(key)) return -1; /* first iteration */
- i = arrayindex(key);
- if (0 <= i && i <= t->sizearray) { /* is `key' inside array part? */
- return i-1; /* yes; that's the index (corrected to C) */
- }
- else {
- const TObject *v = luaH_get(t, key);
- if (v == &luaO_nilobject)
- luaG_runerror(L, "invalid key for `next'");
- i = cast(int, (cast(const lu_byte *, v) -
- cast(const lu_byte *, gval(gnode(t, 0)))) / sizeof(Node));
- return i + t->sizearray; /* hash elements are numbered after array ones */
- }
-}
-
-
-int luaH_next (lua_State *L, Table *t, StkId key) {
- int i = luaH_index(L, t, key); /* find original element */
- for (i++; i < t->sizearray; i++) { /* try first array part */
- if (!ttisnil(&t->array[i])) { /* a non-nil value? */
- setnvalue(key, cast(lua_Number, i+1));
- setobj2s(key+1, &t->array[i]);
- return 1;
- }
- }
- for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
- if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
- setobj2s(key, gkey(gnode(t, i)));
- setobj2s(key+1, gval(gnode(t, i)));
- return 1;
- }
- }
- return 0; /* no more elements */
-}
-
-
-/*
-** {=============================================================
-** Rehash
-** ==============================================================
-*/
-
-
-static void computesizes (int nums[], int ntotal, int *narray, int *nhash) {
- int i;
- int a = nums[0]; /* number of elements smaller than 2^i */
- int na = a; /* number of elements to go to array part */
- int n = (na == 0) ? -1 : 0; /* (log of) optimal size for array part */
- for (i = 1; a < *narray && *narray >= twoto(i-1); i++) {
- if (nums[i] > 0) {
- a += nums[i];
- if (a >= twoto(i-1)) { /* more than half elements in use? */
- n = i;
- na = a;
- }
- }
- }
- lua_assert(na <= *narray && *narray <= ntotal);
- *nhash = ntotal - na;
- *narray = (n == -1) ? 0 : twoto(n);
- lua_assert(na <= *narray && na >= *narray/2);
-}
-
-
-static void numuse (const Table *t, int *narray, int *nhash) {
- int nums[MAXBITS+1];
- int i, lg;
- int totaluse = 0;
- /* count elements in array part */
- for (i=0, lg=0; lg<=MAXBITS; lg++) { /* for each slice [2^(lg-1) to 2^lg) */
- int ttlg = twoto(lg); /* 2^lg */
- if (ttlg > t->sizearray) {
- ttlg = t->sizearray;
- if (i >= ttlg) break;
- }
- nums[lg] = 0;
- for (; i<ttlg; i++) {
- if (!ttisnil(&t->array[i])) {
- nums[lg]++;
- totaluse++;
- }
- }
- }
- for (; lg<=MAXBITS; lg++) nums[lg] = 0; /* reset other counts */
- *narray = totaluse; /* all previous uses were in array part */
- /* count elements in hash part */
- i = sizenode(t);
- while (i--) {
- Node *n = &t->node[i];
- if (!ttisnil(gval(n))) {
- int k = arrayindex(gkey(n));
- if (k >= 0) { /* is `key' an appropriate array index? */
- nums[luaO_log2(k-1)+1]++; /* count as such */
- (*narray)++;
- }
- totaluse++;
- }
- }
- computesizes(nums, totaluse, narray, nhash);
-}
-
-
-static void setarrayvector (lua_State *L, Table *t, int size) {
- int i;
- luaM_reallocvector(L, t->array, t->sizearray, size, TObject);
- for (i=t->sizearray; i<size; i++)
- setnilvalue(&t->array[i]);
- t->sizearray = size;
-}
-
-
-static void setnodevector (lua_State *L, Table *t, int lsize) {
- int i;
- int size = twoto(lsize);
- if (lsize > MAXBITS)
- luaG_runerror(L, "table overflow");
- if (lsize == 0) { /* no elements to hash part? */
- t->node = G(L)->dummynode; /* use common `dummynode' */
- lua_assert(ttisnil(gkey(t->node))); /* assert invariants: */
- lua_assert(ttisnil(gval(t->node)));
- lua_assert(t->node->next == NULL); /* (`dummynode' must be empty) */
- }
- else {
- t->node = luaM_newvector(L, size, Node);
- for (i=0; i<size; i++) {
- t->node[i].next = NULL;
- setnilvalue(gkey(gnode(t, i)));
- setnilvalue(gval(gnode(t, i)));
- }
- }
- t->lsizenode = cast(lu_byte, lsize);
- t->firstfree = gnode(t, size-1); /* first free position to be used */
-}
-
-
-static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
- int i;
- int oldasize = t->sizearray;
- int oldhsize = t->lsizenode;
- Node *nold;
- Node temp[1];
- if (oldhsize)
- nold = t->node; /* save old hash ... */
- else { /* old hash is `dummynode' */
- lua_assert(t->node == G(L)->dummynode);
- temp[0] = t->node[0]; /* copy it to `temp' */
- nold = temp;
- setnilvalue(gkey(G(L)->dummynode)); /* restate invariant */
- setnilvalue(gval(G(L)->dummynode));
- lua_assert(G(L)->dummynode->next == NULL);
- }
- if (nasize > oldasize) /* array part must grow? */
- setarrayvector(L, t, nasize);
- /* create new hash part with appropriate size */
- setnodevector(L, t, nhsize);
- /* re-insert elements */
- if (nasize < oldasize) { /* array part must shrink? */
- t->sizearray = nasize;
- /* re-insert elements from vanishing slice */
- for (i=nasize; i<oldasize; i++) {
- if (!ttisnil(&t->array[i]))
- setobjt2t(luaH_setnum(L, t, i+1), &t->array[i]);
- }
- /* shrink array */
- luaM_reallocvector(L, t->array, oldasize, nasize, TObject);
- }
- /* re-insert elements in hash part */
- for (i = twoto(oldhsize) - 1; i >= 0; i--) {
- Node *old = nold+i;
- if (!ttisnil(gval(old)))
- setobjt2t(luaH_set(L, t, gkey(old)), gval(old));
- }
- if (oldhsize)
- luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
-}
-
-
-static void rehash (lua_State *L, Table *t) {
- int nasize, nhsize;
- numuse(t, &nasize, &nhsize); /* compute new sizes for array and hash parts */
- resize(L, t, nasize, luaO_log2(nhsize)+1);
-}
-
-
-
-/*
-** }=============================================================
-*/
-
-
-Table *luaH_new (lua_State *L, int narray, int lnhash) {
- Table *t = luaM_new(L, Table);
- luaC_link(L, valtogco(t), LUA_TTABLE);
- t->metatable = hvalue(defaultmeta(L));
- t->flags = cast(lu_byte, ~0);
- /* temporary values (kept only if some malloc fails) */
- t->array = NULL;
- t->sizearray = 0;
- t->lsizenode = 0;
- t->node = NULL;
- setarrayvector(L, t, narray);
- setnodevector(L, t, lnhash);
- return t;
-}
-
-
-void luaH_free (lua_State *L, Table *t) {
- if (t->lsizenode)
- luaM_freearray(L, t->node, sizenode(t), Node);
- luaM_freearray(L, t->array, t->sizearray, TObject);
- luaM_freelem(L, t);
-}
-
-
-#if 0
-/*
-** try to remove an element from a hash table; cannot move any element
-** (because gc can call `remove' during a table traversal)
-*/
-void luaH_remove (Table *t, Node *e) {
- Node *mp = luaH_mainposition(t, gkey(e));
- if (e != mp) { /* element not in its main position? */
- while (mp->next != e) mp = mp->next; /* find previous */
- mp->next = e->next; /* remove `e' from its list */
- }
- else {
- if (e->next != NULL) ??
- }
- lua_assert(ttisnil(gval(node)));
- setnilvalue(gkey(e)); /* clear node `e' */
- e->next = NULL;
-}
-#endif
-
-
-/*
-** inserts a new key into a hash table; first, check whether key's main
-** position is free. If not, check whether colliding node is in its main
-** position or not: if it is not, move colliding node to an empty place and
-** put new key in its main position; otherwise (colliding node is in its main
-** position), new key goes to an empty position.
-*/
-static TObject *newkey (lua_State *L, Table *t, const TObject *key) {
- TObject *val;
- Node *mp = luaH_mainposition(t, key);
- if (!ttisnil(gval(mp))) { /* main position is not free? */
- Node *othern = luaH_mainposition(t, gkey(mp)); /* `mp' of colliding node */
- Node *n = t->firstfree; /* get a free place */
- if (othern != mp) { /* is colliding node out of its main position? */
- /* yes; move colliding node into free position */
- while (othern->next != mp) othern = othern->next; /* find previous */
- othern->next = n; /* redo the chain with `n' in place of `mp' */
- *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
- mp->next = NULL; /* now `mp' is free */
- setnilvalue(gval(mp));
- }
- else { /* colliding node is in its own main position */
- /* new node will go into free position */
- n->next = mp->next; /* chain new position */
- mp->next = n;
- mp = n;
- }
- }
- setobj2t(gkey(mp), key); /* write barrier */
- lua_assert(ttisnil(gval(mp)));
- for (;;) { /* correct `firstfree' */
- if (ttisnil(gkey(t->firstfree)))
- return gval(mp); /* OK; table still has a free place */
- else if (t->firstfree == t->node) break; /* cannot decrement from here */
- else (t->firstfree)--;
- }
- /* no more free places; must create one */
- setbvalue(gval(mp), 0); /* avoid new key being removed */
- rehash(L, t); /* grow table */
- val = cast(TObject *, luaH_get(t, key)); /* get new position */
- lua_assert(ttisboolean(val));
- setnilvalue(val);
- return val;
-}
-
-
-/*
-** generic search function
-*/
-static const TObject *luaH_getany (Table *t, const TObject *key) {
- if (ttisnil(key)) return &luaO_nilobject;
- else {
- Node *n = luaH_mainposition(t, key);
- do { /* check whether `key' is somewhere in the chain */
- if (luaO_rawequalObj(gkey(n), key)) return gval(n); /* that's it */
- else n = n->next;
- } while (n);
- return &luaO_nilobject;
- }
-}
-
-
-/*
-** search function for integers
-*/
-const TObject *luaH_getnum (Table *t, int key) {
- if (1 <= key && key <= t->sizearray)
- return &t->array[key-1];
- else {
- lua_Number nk = cast(lua_Number, key);
- Node *n = hashnum(t, nk);
- do { /* check whether `key' is somewhere in the chain */
- if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == nk)
- return gval(n); /* that's it */
- else n = n->next;
- } while (n);
- return &luaO_nilobject;
- }
-}
-
-
-/*
-** search function for strings
-*/
-const TObject *luaH_getstr (Table *t, TString *key) {
- Node *n = hashstr(t, key);
- do { /* check whether `key' is somewhere in the chain */
- if (ttisstring(gkey(n)) && tsvalue(gkey(n)) == key)
- return gval(n); /* that's it */
- else n = n->next;
- } while (n);
- return &luaO_nilobject;
-}
-
-
-/*
-** main search function
-*/
-const TObject *luaH_get (Table *t, const TObject *key) {
- switch (ttype(key)) {
- case LUA_TSTRING: return luaH_getstr(t, tsvalue(key));
- case LUA_TNUMBER: {
- int k;
- lua_number2int(k, (nvalue(key)));
- if (cast(lua_Number, k) == nvalue(key)) /* is an integer index? */
- return luaH_getnum(t, k); /* use specialized version */
- /* else go through */
- }
- default: return luaH_getany(t, key);
- }
-}
-
-
-TObject *luaH_set (lua_State *L, Table *t, const TObject *key) {
- const TObject *p = luaH_get(t, key);
- t->flags = 0;
- if (p != &luaO_nilobject)
- return cast(TObject *, p);
- else {
- if (ttisnil(key)) luaG_runerror(L, "table index is nil");
- else if (ttisnumber(key) && nvalue(key) != nvalue(key))
- luaG_runerror(L, "table index is NaN");
- return newkey(L, t, key);
- }
-}
-
-
-TObject *luaH_setnum (lua_State *L, Table *t, int key) {
- const TObject *p = luaH_getnum(t, key);
- if (p != &luaO_nilobject)
- return cast(TObject *, p);
- else {
- TObject k;
- setnvalue(&k, cast(lua_Number, key));
- return newkey(L, t, &k);
- }
-}
-
+/*
+** $Id: ltable.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** Lua tables (hash)
+** See Copyright Notice in lua.h
+*/
+
+
+/*
+** Implementation of tables (aka arrays, objects, or hash tables).
+** Tables keep its elements in two parts: an array part and a hash part.
+** Non-negative integer keys are all candidates to be kept in the array
+** part. The actual size of the array is the largest `n' such that at
+** least half the slots between 0 and n are in use.
+** Hash uses a mix of chained scatter table with Brent's variation.
+** A main invariant of these tables is that, if an element is not
+** in its main position (i.e. the `original' position that its hash gives
+** to it), then the colliding element is in its own main position.
+** In other words, there are collisions only when two elements have the
+** same main position (i.e. the same hash values for that table size).
+** Because of that, the load factor of these tables can be 100% without
+** performance penalties.
+*/
+
+#include <string.h>
+
+#define ltable_c
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "ltable.h"
+
+
+/*
+** max size of array part is 2^MAXBITS
+*/
+#if BITS_INT > 26
+#define MAXBITS 24
+#else
+#define MAXBITS (BITS_INT-2)
+#endif
+
+/* check whether `x' < 2^MAXBITS */
+#define toobig(x) ((((x)-1) >> MAXBITS) != 0)
+
+
+/* function to convert a lua_Number to int (with any rounding method) */
+#ifndef lua_number2int
+#define lua_number2int(i,n) ((i)=(int)(n))
+#endif
+
+
+#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
+
+#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
+#define hashboolean(t,p) hashpow2(t, p)
+
+
+/*
+** for some types, it is better to avoid modulus by power of 2, as
+** they tend to have many 2 factors.
+*/
+#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
+
+
+#define hashpointer(t,p) hashmod(t, IntPoint(p))
+
+
+/*
+** number of ints inside a lua_Number
+*/
+#define numints cast(int, sizeof(lua_Number)/sizeof(int))
+
+
+/*
+** hash for lua_Numbers
+*/
+static Node *hashnum (const Table *t, lua_Number n) {
+ unsigned int a[numints];
+ int i;
+ n += 1; /* normalize number (avoid -0) */
+ lua_assert(sizeof(a) <= sizeof(n));
+ memcpy(a, &n, sizeof(a));
+ for (i = 1; i < numints; i++) a[0] += a[i];
+ return hashmod(t, cast(lu_hash, a[0]));
+}
+
+
+
+/*
+** returns the `main' position of an element in a table (that is, the index
+** of its hash value)
+*/
+Node *luaH_mainposition (const Table *t, const TObject *key) {
+ switch (ttype(key)) {
+ case LUA_TNUMBER:
+ return hashnum(t, nvalue(key));
+ case LUA_TSTRING:
+ return hashstr(t, tsvalue(key));
+ case LUA_TBOOLEAN:
+ return hashboolean(t, bvalue(key));
+ case LUA_TLIGHTUSERDATA:
+ return hashpointer(t, pvalue(key));
+ default:
+ return hashpointer(t, gcvalue(key));
+ }
+}
+
+
+/*
+** returns the index for `key' if `key' is an appropriate key to live in
+** the array part of the table, -1 otherwise.
+*/
+static int arrayindex (const TObject *key) {
+ if (ttisnumber(key)) {
+ int k;
+ lua_number2int(k, (nvalue(key)));
+ if (cast(lua_Number, k) == nvalue(key) && k >= 1 && !toobig(k))
+ return k;
+ }
+ return -1; /* `key' did not match some condition */
+}
+
+
+/*
+** returns the index of a `key' for table traversals. First goes all
+** elements in the array part, then elements in the hash part. The
+** beginning and end of a traversal are signalled by -1.
+*/
+static int luaH_index (lua_State *L, Table *t, StkId key) {
+ int i;
+ if (ttisnil(key)) return -1; /* first iteration */
+ i = arrayindex(key);
+ if (0 <= i && i <= t->sizearray) { /* is `key' inside array part? */
+ return i-1; /* yes; that's the index (corrected to C) */
+ }
+ else {
+ const TObject *v = luaH_get(t, key);
+ if (v == &luaO_nilobject)
+ luaG_runerror(L, "invalid key for `next'");
+ i = cast(int, (cast(const lu_byte *, v) -
+ cast(const lu_byte *, gval(gnode(t, 0)))) / sizeof(Node));
+ return i + t->sizearray; /* hash elements are numbered after array ones */
+ }
+}
+
+
+int luaH_next (lua_State *L, Table *t, StkId key) {
+ int i = luaH_index(L, t, key); /* find original element */
+ for (i++; i < t->sizearray; i++) { /* try first array part */
+ if (!ttisnil(&t->array[i])) { /* a non-nil value? */
+ setnvalue(key, cast(lua_Number, i+1));
+ setobj2s(key+1, &t->array[i]);
+ return 1;
+ }
+ }
+ for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
+ if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
+ setobj2s(key, gkey(gnode(t, i)));
+ setobj2s(key+1, gval(gnode(t, i)));
+ return 1;
+ }
+ }
+ return 0; /* no more elements */
+}
+
+
+/*
+** {=============================================================
+** Rehash
+** ==============================================================
+*/
+
+
+static void computesizes (int nums[], int ntotal, int *narray, int *nhash) {
+ int i;
+ int a = nums[0]; /* number of elements smaller than 2^i */
+ int na = a; /* number of elements to go to array part */
+ int n = (na == 0) ? -1 : 0; /* (log of) optimal size for array part */
+ for (i = 1; a < *narray && *narray >= twoto(i-1); i++) {
+ if (nums[i] > 0) {
+ a += nums[i];
+ if (a >= twoto(i-1)) { /* more than half elements in use? */
+ n = i;
+ na = a;
+ }
+ }
+ }
+ lua_assert(na <= *narray && *narray <= ntotal);
+ *nhash = ntotal - na;
+ *narray = (n == -1) ? 0 : twoto(n);
+ lua_assert(na <= *narray && na >= *narray/2);
+}
+
+
+static void numuse (const Table *t, int *narray, int *nhash) {
+ int nums[MAXBITS+1];
+ int i, lg;
+ int totaluse = 0;
+ /* count elements in array part */
+ for (i=0, lg=0; lg<=MAXBITS; lg++) { /* for each slice [2^(lg-1) to 2^lg) */
+ int ttlg = twoto(lg); /* 2^lg */
+ if (ttlg > t->sizearray) {
+ ttlg = t->sizearray;
+ if (i >= ttlg) break;
+ }
+ nums[lg] = 0;
+ for (; i<ttlg; i++) {
+ if (!ttisnil(&t->array[i])) {
+ nums[lg]++;
+ totaluse++;
+ }
+ }
+ }
+ for (; lg<=MAXBITS; lg++) nums[lg] = 0; /* reset other counts */
+ *narray = totaluse; /* all previous uses were in array part */
+ /* count elements in hash part */
+ i = sizenode(t);
+ while (i--) {
+ Node *n = &t->node[i];
+ if (!ttisnil(gval(n))) {
+ int k = arrayindex(gkey(n));
+ if (k >= 0) { /* is `key' an appropriate array index? */
+ nums[luaO_log2(k-1)+1]++; /* count as such */
+ (*narray)++;
+ }
+ totaluse++;
+ }
+ }
+ computesizes(nums, totaluse, narray, nhash);
+}
+
+
+static void setarrayvector (lua_State *L, Table *t, int size) {
+ int i;
+ luaM_reallocvector(L, t->array, t->sizearray, size, TObject);
+ for (i=t->sizearray; i<size; i++)
+ setnilvalue(&t->array[i]);
+ t->sizearray = size;
+}
+
+
+static void setnodevector (lua_State *L, Table *t, int lsize) {
+ int i;
+ int size = twoto(lsize);
+ if (lsize > MAXBITS)
+ luaG_runerror(L, "table overflow");
+ if (lsize == 0) { /* no elements to hash part? */
+ t->node = G(L)->dummynode; /* use common `dummynode' */
+ lua_assert(ttisnil(gkey(t->node))); /* assert invariants: */
+ lua_assert(ttisnil(gval(t->node)));
+ lua_assert(t->node->next == NULL); /* (`dummynode' must be empty) */
+ }
+ else {
+ t->node = luaM_newvector(L, size, Node);
+ for (i=0; i<size; i++) {
+ t->node[i].next = NULL;
+ setnilvalue(gkey(gnode(t, i)));
+ setnilvalue(gval(gnode(t, i)));
+ }
+ }
+ t->lsizenode = cast(lu_byte, lsize);
+ t->firstfree = gnode(t, size-1); /* first free position to be used */
+}
+
+
+static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
+ int i;
+ int oldasize = t->sizearray;
+ int oldhsize = t->lsizenode;
+ Node *nold;
+ Node temp[1];
+ if (oldhsize)
+ nold = t->node; /* save old hash ... */
+ else { /* old hash is `dummynode' */
+ lua_assert(t->node == G(L)->dummynode);
+ temp[0] = t->node[0]; /* copy it to `temp' */
+ nold = temp;
+ setnilvalue(gkey(G(L)->dummynode)); /* restate invariant */
+ setnilvalue(gval(G(L)->dummynode));
+ lua_assert(G(L)->dummynode->next == NULL);
+ }
+ if (nasize > oldasize) /* array part must grow? */
+ setarrayvector(L, t, nasize);
+ /* create new hash part with appropriate size */
+ setnodevector(L, t, nhsize);
+ /* re-insert elements */
+ if (nasize < oldasize) { /* array part must shrink? */
+ t->sizearray = nasize;
+ /* re-insert elements from vanishing slice */
+ for (i=nasize; i<oldasize; i++) {
+ if (!ttisnil(&t->array[i]))
+ setobjt2t(luaH_setnum(L, t, i+1), &t->array[i]);
+ }
+ /* shrink array */
+ luaM_reallocvector(L, t->array, oldasize, nasize, TObject);
+ }
+ /* re-insert elements in hash part */
+ for (i = twoto(oldhsize) - 1; i >= 0; i--) {
+ Node *old = nold+i;
+ if (!ttisnil(gval(old)))
+ setobjt2t(luaH_set(L, t, gkey(old)), gval(old));
+ }
+ if (oldhsize)
+ luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
+}
+
+
+static void rehash (lua_State *L, Table *t) {
+ int nasize, nhsize;
+ numuse(t, &nasize, &nhsize); /* compute new sizes for array and hash parts */
+ resize(L, t, nasize, luaO_log2(nhsize)+1);
+}
+
+
+
+/*
+** }=============================================================
+*/
+
+
+Table *luaH_new (lua_State *L, int narray, int lnhash) {
+ Table *t = luaM_new(L, Table);
+ luaC_link(L, valtogco(t), LUA_TTABLE);
+ t->metatable = hvalue(defaultmeta(L));
+ t->flags = cast(lu_byte, ~0);
+ /* temporary values (kept only if some malloc fails) */
+ t->array = NULL;
+ t->sizearray = 0;
+ t->lsizenode = 0;
+ t->node = NULL;
+ setarrayvector(L, t, narray);
+ setnodevector(L, t, lnhash);
+ return t;
+}
+
+
+void luaH_free (lua_State *L, Table *t) {
+ if (t->lsizenode)
+ luaM_freearray(L, t->node, sizenode(t), Node);
+ luaM_freearray(L, t->array, t->sizearray, TObject);
+ luaM_freelem(L, t);
+}
+
+
+#if 0
+/*
+** try to remove an element from a hash table; cannot move any element
+** (because gc can call `remove' during a table traversal)
+*/
+void luaH_remove (Table *t, Node *e) {
+ Node *mp = luaH_mainposition(t, gkey(e));
+ if (e != mp) { /* element not in its main position? */
+ while (mp->next != e) mp = mp->next; /* find previous */
+ mp->next = e->next; /* remove `e' from its list */
+ }
+ else {
+ if (e->next != NULL) ??
+ }
+ lua_assert(ttisnil(gval(node)));
+ setnilvalue(gkey(e)); /* clear node `e' */
+ e->next = NULL;
+}
+#endif
+
+
+/*
+** inserts a new key into a hash table; first, check whether key's main
+** position is free. If not, check whether colliding node is in its main
+** position or not: if it is not, move colliding node to an empty place and
+** put new key in its main position; otherwise (colliding node is in its main
+** position), new key goes to an empty position.
+*/
+static TObject *newkey (lua_State *L, Table *t, const TObject *key) {
+ TObject *val;
+ Node *mp = luaH_mainposition(t, key);
+ if (!ttisnil(gval(mp))) { /* main position is not free? */
+ Node *othern = luaH_mainposition(t, gkey(mp)); /* `mp' of colliding node */
+ Node *n = t->firstfree; /* get a free place */
+ if (othern != mp) { /* is colliding node out of its main position? */
+ /* yes; move colliding node into free position */
+ while (othern->next != mp) othern = othern->next; /* find previous */
+ othern->next = n; /* redo the chain with `n' in place of `mp' */
+ *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
+ mp->next = NULL; /* now `mp' is free */
+ setnilvalue(gval(mp));
+ }
+ else { /* colliding node is in its own main position */
+ /* new node will go into free position */
+ n->next = mp->next; /* chain new position */
+ mp->next = n;
+ mp = n;
+ }
+ }
+ setobj2t(gkey(mp), key); /* write barrier */
+ lua_assert(ttisnil(gval(mp)));
+ for (;;) { /* correct `firstfree' */
+ if (ttisnil(gkey(t->firstfree)))
+ return gval(mp); /* OK; table still has a free place */
+ else if (t->firstfree == t->node) break; /* cannot decrement from here */
+ else (t->firstfree)--;
+ }
+ /* no more free places; must create one */
+ setbvalue(gval(mp), 0); /* avoid new key being removed */
+ rehash(L, t); /* grow table */
+ val = cast(TObject *, luaH_get(t, key)); /* get new position */
+ lua_assert(ttisboolean(val));
+ setnilvalue(val);
+ return val;
+}
+
+
+/*
+** generic search function
+*/
+static const TObject *luaH_getany (Table *t, const TObject *key) {
+ if (ttisnil(key)) return &luaO_nilobject;
+ else {
+ Node *n = luaH_mainposition(t, key);
+ do { /* check whether `key' is somewhere in the chain */
+ if (luaO_rawequalObj(gkey(n), key)) return gval(n); /* that's it */
+ else n = n->next;
+ } while (n);
+ return &luaO_nilobject;
+ }
+}
+
+
+/*
+** search function for integers
+*/
+const TObject *luaH_getnum (Table *t, int key) {
+ if (1 <= key && key <= t->sizearray)
+ return &t->array[key-1];
+ else {
+ lua_Number nk = cast(lua_Number, key);
+ Node *n = hashnum(t, nk);
+ do { /* check whether `key' is somewhere in the chain */
+ if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == nk)
+ return gval(n); /* that's it */
+ else n = n->next;
+ } while (n);
+ return &luaO_nilobject;
+ }
+}
+
+
+/*
+** search function for strings
+*/
+const TObject *luaH_getstr (Table *t, TString *key) {
+ Node *n = hashstr(t, key);
+ do { /* check whether `key' is somewhere in the chain */
+ if (ttisstring(gkey(n)) && tsvalue(gkey(n)) == key)
+ return gval(n); /* that's it */
+ else n = n->next;
+ } while (n);
+ return &luaO_nilobject;
+}
+
+
+/*
+** main search function
+*/
+const TObject *luaH_get (Table *t, const TObject *key) {
+ switch (ttype(key)) {
+ case LUA_TSTRING: return luaH_getstr(t, tsvalue(key));
+ case LUA_TNUMBER: {
+ int k;
+ lua_number2int(k, (nvalue(key)));
+ if (cast(lua_Number, k) == nvalue(key)) /* is an integer index? */
+ return luaH_getnum(t, k); /* use specialized version */
+ /* else go through */
+ }
+ default: return luaH_getany(t, key);
+ }
+}
+
+
+TObject *luaH_set (lua_State *L, Table *t, const TObject *key) {
+ const TObject *p = luaH_get(t, key);
+ t->flags = 0;
+ if (p != &luaO_nilobject)
+ return cast(TObject *, p);
+ else {
+ if (ttisnil(key)) luaG_runerror(L, "table index is nil");
+ else if (ttisnumber(key) && nvalue(key) != nvalue(key))
+ luaG_runerror(L, "table index is NaN");
+ return newkey(L, t, key);
+ }
+}
+
+
+TObject *luaH_setnum (lua_State *L, Table *t, int key) {
+ const TObject *p = luaH_getnum(t, key);
+ if (p != &luaO_nilobject)
+ return cast(TObject *, p);
+ else {
+ TObject k;
+ setnvalue(&k, cast(lua_Number, key));
+ return newkey(L, t, &k);
+ }
+}
+
diff --git a/lib/lua/src/ltests.c b/lib/lua/src/ltests.c
index 8e53314..a332684 100644
--- a/lib/lua/src/ltests.c
+++ b/lib/lua/src/ltests.c
@@ -1,852 +1,852 @@
-/*
-** $Id: ltests.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** Internal Module for Debugging of the Lua Implementation
-** See Copyright Notice in lua.h
-*/
-
-
-#include <ctype.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define ltests_c
-
-#include "lua.h"
-
-#include "lapi.h"
-#include "lauxlib.h"
-#include "lcode.h"
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lmem.h"
-#include "lopcodes.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "lualib.h"
-
-
-
-/*
-** The whole module only makes sense with LUA_DEBUG on
-*/
-#ifdef LUA_DEBUG
-
-
-#define lua_pushintegral(L,i) lua_pushnumber(L, cast(lua_Number, (i)))
-
-
-static lua_State *lua_state = NULL;
-
-int islocked = 0;
-
-
-#define func_at(L,k) (L->ci->base+(k) - 1)
-
-
-static void setnameval (lua_State *L, const char *name, int val) {
- lua_pushstring(L, name);
- lua_pushintegral(L, val);
- lua_settable(L, -3);
-}
-
-
-/*
-** {======================================================================
-** Controlled version for realloc.
-** =======================================================================
-*/
-
-#define MARK 0x55 /* 01010101 (a nice pattern) */
-
-#ifndef EXTERNMEMCHECK
-/* full memory check */
-#define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */
-#define MARKSIZE 16 /* size of marks after each block */
-#define blockhead(b) (cast(char *, b) - HEADER)
-#define setsize(newblock, size) (*cast(size_t *, newblock) = size)
-#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b))))
-#define fillmem(mem,size) memset(mem, -MARK, size)
-#else
-/* external memory check: don't do it twice */
-#define HEADER 0
-#define MARKSIZE 0
-#define blockhead(b) (b)
-#define setsize(newblock, size) /* empty */
-#define checkblocksize(b,size) (1)
-#define fillmem(mem,size) /* empty */
-#endif
-
-unsigned long memdebug_numblocks = 0;
-unsigned long memdebug_total = 0;
-unsigned long memdebug_maxmem = 0;
-unsigned long memdebug_memlimit = ULONG_MAX;
-
-
-static void *checkblock (void *block, size_t size) {
- void *b = blockhead(block);
- int i;
- for (i=0;i<MARKSIZE;i++)
- lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */
- return b;
-}
-
-
-static void freeblock (void *block, size_t size) {
- if (block) {
- lua_assert(checkblocksize(block, size));
- block = checkblock(block, size);
- fillmem(block, size+HEADER+MARKSIZE); /* erase block */
- free(block); /* free original block */
- memdebug_numblocks--;
- memdebug_total -= size;
- }
-}
-
-
-void *debug_realloc (void *block, size_t oldsize, size_t size) {
- lua_assert(oldsize == 0 || checkblocksize(block, oldsize));
- /* ISO does not specify what realloc(NULL, 0) does */
- lua_assert(block != NULL || size > 0);
- if (size == 0) {
- freeblock(block, oldsize);
- return NULL;
- }
- else if (size > oldsize && memdebug_total+size-oldsize > memdebug_memlimit)
- return NULL; /* to test memory allocation errors */
- else {
- void *newblock;
- int i;
- size_t realsize = HEADER+size+MARKSIZE;
- size_t commonsize = (oldsize < size) ? oldsize : size;
- if (realsize < size) return NULL; /* overflow! */
- newblock = malloc(realsize); /* alloc a new block */
- if (newblock == NULL) return NULL;
- if (block) {
- memcpy(cast(char *, newblock)+HEADER, block, commonsize);
- freeblock(block, oldsize); /* erase (and check) old copy */
- }
- /* initialize new part of the block with something `weird' */
- fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize);
- memdebug_total += size;
- if (memdebug_total > memdebug_maxmem)
- memdebug_maxmem = memdebug_total;
- memdebug_numblocks++;
- setsize(newblock, size);
- for (i=0;i<MARKSIZE;i++)
- *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i);
- return cast(char *, newblock)+HEADER;
- }
-}
-
-
-/* }====================================================================== */
-
-
-
-/*
-** {======================================================
-** Disassembler
-** =======================================================
-*/
-
-
-static char *buildop (Proto *p, int pc, char *buff) {
- Instruction i = p->code[pc];
- OpCode o = GET_OPCODE(i);
- const char *name = luaP_opnames[o];
- int line = getline(p, pc);
- sprintf(buff, "(%4d) %4d - ", line, pc);
- switch (getOpMode(o)) {
- case iABC:
- sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name,
- GETARG_A(i), GETARG_B(i), GETARG_C(i));
- break;
- case iABx:
- sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i));
- break;
- case iAsBx:
- sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i));
- break;
- }
- return buff;
-}
-
-
-#if 0
-void luaI_printcode (Proto *pt, int size) {
- int pc;
- for (pc=0; pc<size; pc++) {
- char buff[100];
- printf("%s\n", buildop(pt, pc, buff));
- }
- printf("-------\n");
-}
-#endif
-
-
-static int listcode (lua_State *L) {
- int pc;
- Proto *p;
- luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
- 1, "Lua function expected");
- p = clvalue(func_at(L, 1))->l.p;
- lua_newtable(L);
- setnameval(L, "maxstack", p->maxstacksize);
- setnameval(L, "numparams", p->numparams);
- for (pc=0; pc<p->sizecode; pc++) {
- char buff[100];
- lua_pushintegral(L, pc+1);
- lua_pushstring(L, buildop(p, pc, buff));
- lua_settable(L, -3);
- }
- return 1;
-}
-
-
-static int listk (lua_State *L) {
- Proto *p;
- int i;
- luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
- 1, "Lua function expected");
- p = clvalue(func_at(L, 1))->l.p;
- lua_newtable(L);
- for (i=0; i<p->sizek; i++) {
- lua_pushintegral(L, i+1);
- luaA_pushobject(L, p->k+i);
- lua_settable(L, -3);
- }
- return 1;
-}
-
-
-static int listlocals (lua_State *L) {
- Proto *p;
- int pc = luaL_checkint(L, 2) - 1;
- int i = 0;
- const char *name;
- luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
- 1, "Lua function expected");
- p = clvalue(func_at(L, 1))->l.p;
- while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
- lua_pushstring(L, name);
- return i-1;
-}
-
-/* }====================================================== */
-
-
-
-
-static int get_limits (lua_State *L) {
- lua_newtable(L);
- setnameval(L, "BITS_INT", BITS_INT);
- setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
- setnameval(L, "MAXVARS", MAXVARS);
- setnameval(L, "MAXPARAMS", MAXPARAMS);
- setnameval(L, "MAXSTACK", MAXSTACK);
- setnameval(L, "MAXUPVALUES", MAXUPVALUES);
- return 1;
-}
-
-
-static int mem_query (lua_State *L) {
- if (lua_isnone(L, 1)) {
- lua_pushintegral(L, memdebug_total);
- lua_pushintegral(L, memdebug_numblocks);
- lua_pushintegral(L, memdebug_maxmem);
- return 3;
- }
- else {
- memdebug_memlimit = luaL_checkint(L, 1);
- return 0;
- }
-}
-
-
-static int hash_query (lua_State *L) {
- if (lua_isnone(L, 2)) {
- luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
- lua_pushintegral(L, tsvalue(func_at(L, 1))->tsv.hash);
- }
- else {
- TObject *o = func_at(L, 1);
- Table *t;
- luaL_checktype(L, 2, LUA_TTABLE);
- t = hvalue(func_at(L, 2));
- lua_pushintegral(L, luaH_mainposition(t, o) - t->node);
- }
- return 1;
-}
-
-
-static int stacklevel (lua_State *L) {
- unsigned long a = 0;
- lua_pushintegral(L, (int)(L->top - L->stack));
- lua_pushintegral(L, (int)(L->stack_last - L->stack));
- lua_pushintegral(L, (int)(L->ci - L->base_ci));
- lua_pushintegral(L, (int)(L->end_ci - L->base_ci));
- lua_pushintegral(L, (unsigned long)&a);
- return 5;
-}
-
-
-static int table_query (lua_State *L) {
- const Table *t;
- int i = luaL_optint(L, 2, -1);
- luaL_checktype(L, 1, LUA_TTABLE);
- t = hvalue(func_at(L, 1));
- if (i == -1) {
- lua_pushintegral(L, t->sizearray);
- lua_pushintegral(L, sizenode(t));
- lua_pushintegral(L, t->firstfree - t->node);
- }
- else if (i < t->sizearray) {
- lua_pushintegral(L, i);
- luaA_pushobject(L, &t->array[i]);
- lua_pushnil(L);
- }
- else if ((i -= t->sizearray) < sizenode(t)) {
- if (!ttisnil(gval(gnode(t, i))) ||
- ttisnil(gkey(gnode(t, i))) ||
- ttisnumber(gkey(gnode(t, i)))) {
- luaA_pushobject(L, gkey(gnode(t, i)));
- }
- else
- lua_pushstring(L, "<undef>");
- luaA_pushobject(L, gval(gnode(t, i)));
- if (t->node[i].next)
- lua_pushintegral(L, t->node[i].next - t->node);
- else
- lua_pushnil(L);
- }
- return 3;
-}
-
-
-static int string_query (lua_State *L) {
- stringtable *tb = &G(L)->strt;
- int s = luaL_optint(L, 2, 0) - 1;
- if (s==-1) {
- lua_pushintegral(L ,tb->nuse);
- lua_pushintegral(L ,tb->size);
- return 2;
- }
- else if (s < tb->size) {
- GCObject *ts;
- int n = 0;
- for (ts = tb->hash[s]; ts; ts = ts->gch.next) {
- setsvalue2s(L->top, gcotots(ts));
- incr_top(L);
- n++;
- }
- return n;
- }
- return 0;
-}
-
-
-static int tref (lua_State *L) {
- int level = lua_gettop(L);
- int lock = luaL_optint(L, 2, 1);
- luaL_checkany(L, 1);
- lua_pushvalue(L, 1);
- lua_pushintegral(L, lua_ref(L, lock));
- assert(lua_gettop(L) == level+1); /* +1 for result */
- return 1;
-}
-
-static int getref (lua_State *L) {
- int level = lua_gettop(L);
- lua_getref(L, luaL_checkint(L, 1));
- assert(lua_gettop(L) == level+1);
- return 1;
-}
-
-static int unref (lua_State *L) {
- int level = lua_gettop(L);
- lua_unref(L, luaL_checkint(L, 1));
- assert(lua_gettop(L) == level);
- return 0;
-}
-
-static int metatable (lua_State *L) {
- luaL_checkany(L, 1);
- if (lua_isnone(L, 2)) {
- if (lua_getmetatable(L, 1) == 0)
- lua_pushnil(L);
- }
- else {
- lua_settop(L, 2);
- luaL_checktype(L, 2, LUA_TTABLE);
- lua_setmetatable(L, 1);
- }
- return 1;
-}
-
-
-static int upvalue (lua_State *L) {
- int n = luaL_checkint(L, 2);
- luaL_checktype(L, 1, LUA_TFUNCTION);
- if (lua_isnone(L, 3)) {
- const char *name = lua_getupvalue(L, 1, n);
- if (name == NULL) return 0;
- lua_pushstring(L, name);
- return 2;
- }
- else {
- const char *name = lua_setupvalue(L, 1, n);
- lua_pushstring(L, name);
- return 1;
- }
-}
-
-
-static int newuserdata (lua_State *L) {
- size_t size = luaL_checkint(L, 1);
- char *p = cast(char *, lua_newuserdata(L, size));
- while (size--) *p++ = '\0';
- return 1;
-}
-
-
-static int pushuserdata (lua_State *L) {
- lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1)));
- return 1;
-}
-
-
-static int udataval (lua_State *L) {
- lua_pushintegral(L, cast(int, lua_touserdata(L, 1)));
- return 1;
-}
-
-
-static int doonnewstack (lua_State *L) {
- lua_State *L1 = lua_newthread(L);
- size_t l;
- const char *s = luaL_checklstring(L, 1, &l);
- int status = luaL_loadbuffer(L1, s, l, s);
- if (status == 0)
- status = lua_pcall(L1, 0, 0, 0);
- lua_pushintegral(L, status);
- return 1;
-}
-
-
-static int s2d (lua_State *L) {
- lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1)));
- return 1;
-}
-
-static int d2s (lua_State *L) {
- double d = luaL_checknumber(L, 1);
- lua_pushlstring(L, cast(char *, &d), sizeof(d));
- return 1;
-}
-
-
-static int newstate (lua_State *L) {
- lua_State *L1 = lua_open();
- if (L1) {
- lua_userstateopen(L1); /* init lock */
- lua_pushintegral(L, (unsigned long)L1);
- }
- else
- lua_pushnil(L);
- return 1;
-}
-
-
-static int loadlib (lua_State *L) {
- static const luaL_reg libs[] = {
- {"mathlibopen", luaopen_math},
- {"strlibopen", luaopen_string},
- {"iolibopen", luaopen_io},
- {"tablibopen", luaopen_table},
- {"dblibopen", luaopen_debug},
- {"baselibopen", luaopen_base},
- {NULL, NULL}
- };
- lua_State *L1 = cast(lua_State *,
- cast(unsigned long, luaL_checknumber(L, 1)));
- lua_pushvalue(L1, LUA_GLOBALSINDEX);
- luaL_openlib(L1, NULL, libs, 0);
- return 0;
-}
-
-static int closestate (lua_State *L) {
- lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1)));
- lua_close(L1);
- lua_unlock(L); /* close cannot unlock that */
- return 0;
-}
-
-static int doremote (lua_State *L) {
- lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1)));
- size_t lcode;
- const char *code = luaL_checklstring(L, 2, &lcode);
- int status;
- lua_settop(L1, 0);
- status = luaL_loadbuffer(L1, code, lcode, code);
- if (status == 0)
- status = lua_pcall(L1, 0, LUA_MULTRET, 0);
- if (status != 0) {
- lua_pushnil(L);
- lua_pushintegral(L, status);
- lua_pushstring(L, lua_tostring(L1, -1));
- return 3;
- }
- else {
- int i = 0;
- while (!lua_isnone(L1, ++i))
- lua_pushstring(L, lua_tostring(L1, i));
- lua_pop(L1, i-1);
- return i-1;
- }
-}
-
-
-static int log2_aux (lua_State *L) {
- lua_pushintegral(L, luaO_log2(luaL_checkint(L, 1)));
- return 1;
-}
-
-static int int2fb_aux (lua_State *L) {
- int b = luaO_int2fb(luaL_checkint(L, 1));
- lua_pushintegral(L, b);
- lua_pushintegral(L, fb2int(b));
- return 2;
-}
-
-
-static int test_do (lua_State *L) {
- const char *p = luaL_checkstring(L, 1);
- if (*p == '@')
- lua_dofile(L, p+1);
- else
- lua_dostring(L, p);
- return lua_gettop(L);
-}
-
-
-
-/*
-** {======================================================
-** function to test the API with C. It interprets a kind of assembler
-** language with calls to the API, so the test can be driven by Lua code
-** =======================================================
-*/
-
-static const char *const delimits = " \t\n,;";
-
-static void skip (const char **pc) {
- while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
-}
-
-static int getnum_aux (lua_State *L, const char **pc) {
- int res = 0;
- int sig = 1;
- skip(pc);
- if (**pc == '.') {
- res = cast(int, lua_tonumber(L, -1));
- lua_pop(L, 1);
- (*pc)++;
- return res;
- }
- else if (**pc == '-') {
- sig = -1;
- (*pc)++;
- }
- while (isdigit(cast(int, **pc))) res = res*10 + (*(*pc)++) - '0';
- return sig*res;
-}
-
-static const char *getname_aux (char *buff, const char **pc) {
- int i = 0;
- skip(pc);
- while (**pc != '\0' && !strchr(delimits, **pc))
- buff[i++] = *(*pc)++;
- buff[i] = '\0';
- return buff;
-}
-
-
-#define EQ(s1) (strcmp(s1, inst) == 0)
-
-#define getnum (getnum_aux(L, &pc))
-#define getname (getname_aux(buff, &pc))
-
-
-static int testC (lua_State *L) {
- char buff[30];
- const char *pc = luaL_checkstring(L, 1);
- for (;;) {
- const char *inst = getname;
- if EQ("") return 0;
- else if EQ("isnumber") {
- lua_pushintegral(L, lua_isnumber(L, getnum));
- }
- else if EQ("isstring") {
- lua_pushintegral(L, lua_isstring(L, getnum));
- }
- else if EQ("istable") {
- lua_pushintegral(L, lua_istable(L, getnum));
- }
- else if EQ("iscfunction") {
- lua_pushintegral(L, lua_iscfunction(L, getnum));
- }
- else if EQ("isfunction") {
- lua_pushintegral(L, lua_isfunction(L, getnum));
- }
- else if EQ("isuserdata") {
- lua_pushintegral(L, lua_isuserdata(L, getnum));
- }
- else if EQ("isudataval") {
- lua_pushintegral(L, lua_islightuserdata(L, getnum));
- }
- else if EQ("isnil") {
- lua_pushintegral(L, lua_isnil(L, getnum));
- }
- else if EQ("isnull") {
- lua_pushintegral(L, lua_isnone(L, getnum));
- }
- else if EQ("tonumber") {
- lua_pushnumber(L, lua_tonumber(L, getnum));
- }
- else if EQ("tostring") {
- const char *s = lua_tostring(L, getnum);
- lua_pushstring(L, s);
- }
- else if EQ("strlen") {
- lua_pushintegral(L, lua_strlen(L, getnum));
- }
- else if EQ("tocfunction") {
- lua_pushcfunction(L, lua_tocfunction(L, getnum));
- }
- else if EQ("return") {
- return getnum;
- }
- else if EQ("gettop") {
- lua_pushintegral(L, lua_gettop(L));
- }
- else if EQ("settop") {
- lua_settop(L, getnum);
- }
- else if EQ("pop") {
- lua_pop(L, getnum);
- }
- else if EQ("pushnum") {
- lua_pushintegral(L, getnum);
- }
- else if EQ("pushnil") {
- lua_pushnil(L);
- }
- else if EQ("pushbool") {
- lua_pushboolean(L, getnum);
- }
- else if EQ("tobool") {
- lua_pushintegral(L, lua_toboolean(L, getnum));
- }
- else if EQ("pushvalue") {
- lua_pushvalue(L, getnum);
- }
- else if EQ("pushcclosure") {
- lua_pushcclosure(L, testC, getnum);
- }
- else if EQ("pushupvalues") {
- lua_pushupvalues(L);
- }
- else if EQ("remove") {
- lua_remove(L, getnum);
- }
- else if EQ("insert") {
- lua_insert(L, getnum);
- }
- else if EQ("replace") {
- lua_replace(L, getnum);
- }
- else if EQ("gettable") {
- lua_gettable(L, getnum);
- }
- else if EQ("settable") {
- lua_settable(L, getnum);
- }
- else if EQ("next") {
- lua_next(L, -2);
- }
- else if EQ("concat") {
- lua_concat(L, getnum);
- }
- else if EQ("lessthan") {
- int a = getnum;
- lua_pushboolean(L, lua_lessthan(L, a, getnum));
- }
- else if EQ("equal") {
- int a = getnum;
- lua_pushboolean(L, lua_equal(L, a, getnum));
- }
- else if EQ("rawcall") {
- int narg = getnum;
- int nres = getnum;
- lua_call(L, narg, nres);
- }
- else if EQ("call") {
- int narg = getnum;
- int nres = getnum;
- lua_pcall(L, narg, nres, 0);
- }
- else if EQ("loadstring") {
- size_t sl;
- const char *s = luaL_checklstring(L, getnum, &sl);
- luaL_loadbuffer(L, s, sl, s);
- }
- else if EQ("loadfile") {
- luaL_loadfile(L, luaL_checkstring(L, getnum));
- }
- else if EQ("setmetatable") {
- lua_setmetatable(L, getnum);
- }
- else if EQ("getmetatable") {
- if (lua_getmetatable(L, getnum) == 0)
- lua_pushnil(L);
- }
- else if EQ("type") {
- lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
- }
- else if EQ("getn") {
- int i = getnum;
- lua_pushintegral(L, luaL_getn(L, i));
- }
- else if EQ("setn") {
- int i = getnum;
- int n = cast(int, lua_tonumber(L, -1));
- luaL_setn(L, i, n);
- lua_pop(L, 1);
- }
- else luaL_error(L, "unknown instruction %s", buff);
- }
- return 0;
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** tests for yield inside hooks
-** =======================================================
-*/
-
-static void yieldf (lua_State *L, lua_Debug *ar) {
- lua_yield(L, 0);
-}
-
-static int setyhook (lua_State *L) {
- if (lua_isnoneornil(L, 1))
- lua_sethook(L, NULL, 0, 0); /* turn off hooks */
- else {
- const char *smask = luaL_checkstring(L, 1);
- int count = luaL_optint(L, 2, 0);
- int mask = 0;
- if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
- if (count > 0) mask |= LUA_MASKCOUNT;
- lua_sethook(L, yieldf, mask, count);
- }
- return 0;
-}
-
-
-static int coresume (lua_State *L) {
- int status;
- lua_State *co = lua_tothread(L, 1);
- luaL_argcheck(L, co, 1, "coroutine expected");
- status = lua_resume(co, 0);
- if (status != 0) {
- lua_pushboolean(L, 0);
- lua_insert(L, -2);
- return 2; /* return false + error message */
- }
- else {
- lua_pushboolean(L, 1);
- return 1;
- }
-}
-
-/* }====================================================== */
-
-
-
-static const struct luaL_reg tests_funcs[] = {
- {"hash", hash_query},
- {"limits", get_limits},
- {"listcode", listcode},
- {"listk", listk},
- {"listlocals", listlocals},
- {"loadlib", loadlib},
- {"stacklevel", stacklevel},
- {"querystr", string_query},
- {"querytab", table_query},
- {"doit", test_do},
- {"testC", testC},
- {"ref", tref},
- {"getref", getref},
- {"unref", unref},
- {"d2s", d2s},
- {"s2d", s2d},
- {"metatable", metatable},
- {"upvalue", upvalue},
- {"newuserdata", newuserdata},
- {"pushuserdata", pushuserdata},
- {"udataval", udataval},
- {"doonnewstack", doonnewstack},
- {"newstate", newstate},
- {"closestate", closestate},
- {"doremote", doremote},
- {"log2", log2_aux},
- {"int2fb", int2fb_aux},
- {"totalmem", mem_query},
- {"resume", coresume},
- {"setyhook", setyhook},
- {NULL, NULL}
-};
-
-
-static void fim (void) {
- if (!islocked)
- lua_close(lua_state);
- lua_assert(memdebug_numblocks == 0);
- lua_assert(memdebug_total == 0);
-}
-
-
-static int l_panic (lua_State *L) {
- UNUSED(L);
- fprintf(stderr, "unable to recover; exiting\n");
- return 0;
-}
-
-
-int luaB_opentests (lua_State *L) {
- lua_atpanic(L, l_panic);
- lua_userstateopen(L); /* init lock */
- lua_state = L; /* keep first state to be opened */
- luaL_openlib(L, "T", tests_funcs, 0);
- atexit(fim);
- return 0;
-}
-
-
-#undef main
-int main (int argc, char *argv[]) {
- char *limit = getenv("MEMLIMIT");
- if (limit)
- memdebug_memlimit = strtoul(limit, NULL, 10);
- l_main(argc, argv);
- return 0;
-}
-
-#endif
+/*
+** $Id: ltests.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** Internal Module for Debugging of the Lua Implementation
+** See Copyright Notice in lua.h
+*/
+
+
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ltests_c
+
+#include "lua.h"
+
+#include "lapi.h"
+#include "lauxlib.h"
+#include "lcode.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lmem.h"
+#include "lopcodes.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "lualib.h"
+
+
+
+/*
+** The whole module only makes sense with LUA_DEBUG on
+*/
+#ifdef LUA_DEBUG
+
+
+#define lua_pushintegral(L,i) lua_pushnumber(L, cast(lua_Number, (i)))
+
+
+static lua_State *lua_state = NULL;
+
+int islocked = 0;
+
+
+#define func_at(L,k) (L->ci->base+(k) - 1)
+
+
+static void setnameval (lua_State *L, const char *name, int val) {
+ lua_pushstring(L, name);
+ lua_pushintegral(L, val);
+ lua_settable(L, -3);
+}
+
+
+/*
+** {======================================================================
+** Controlled version for realloc.
+** =======================================================================
+*/
+
+#define MARK 0x55 /* 01010101 (a nice pattern) */
+
+#ifndef EXTERNMEMCHECK
+/* full memory check */
+#define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */
+#define MARKSIZE 16 /* size of marks after each block */
+#define blockhead(b) (cast(char *, b) - HEADER)
+#define setsize(newblock, size) (*cast(size_t *, newblock) = size)
+#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b))))
+#define fillmem(mem,size) memset(mem, -MARK, size)
+#else
+/* external memory check: don't do it twice */
+#define HEADER 0
+#define MARKSIZE 0
+#define blockhead(b) (b)
+#define setsize(newblock, size) /* empty */
+#define checkblocksize(b,size) (1)
+#define fillmem(mem,size) /* empty */
+#endif
+
+unsigned long memdebug_numblocks = 0;
+unsigned long memdebug_total = 0;
+unsigned long memdebug_maxmem = 0;
+unsigned long memdebug_memlimit = ULONG_MAX;
+
+
+static void *checkblock (void *block, size_t size) {
+ void *b = blockhead(block);
+ int i;
+ for (i=0;i<MARKSIZE;i++)
+ lua_assert(*(cast(char *, b)+HEADER+size+i) == MARK+i); /* corrupted block? */
+ return b;
+}
+
+
+static void freeblock (void *block, size_t size) {
+ if (block) {
+ lua_assert(checkblocksize(block, size));
+ block = checkblock(block, size);
+ fillmem(block, size+HEADER+MARKSIZE); /* erase block */
+ free(block); /* free original block */
+ memdebug_numblocks--;
+ memdebug_total -= size;
+ }
+}
+
+
+void *debug_realloc (void *block, size_t oldsize, size_t size) {
+ lua_assert(oldsize == 0 || checkblocksize(block, oldsize));
+ /* ISO does not specify what realloc(NULL, 0) does */
+ lua_assert(block != NULL || size > 0);
+ if (size == 0) {
+ freeblock(block, oldsize);
+ return NULL;
+ }
+ else if (size > oldsize && memdebug_total+size-oldsize > memdebug_memlimit)
+ return NULL; /* to test memory allocation errors */
+ else {
+ void *newblock;
+ int i;
+ size_t realsize = HEADER+size+MARKSIZE;
+ size_t commonsize = (oldsize < size) ? oldsize : size;
+ if (realsize < size) return NULL; /* overflow! */
+ newblock = malloc(realsize); /* alloc a new block */
+ if (newblock == NULL) return NULL;
+ if (block) {
+ memcpy(cast(char *, newblock)+HEADER, block, commonsize);
+ freeblock(block, oldsize); /* erase (and check) old copy */
+ }
+ /* initialize new part of the block with something `weird' */
+ fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize);
+ memdebug_total += size;
+ if (memdebug_total > memdebug_maxmem)
+ memdebug_maxmem = memdebug_total;
+ memdebug_numblocks++;
+ setsize(newblock, size);
+ for (i=0;i<MARKSIZE;i++)
+ *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i);
+ return cast(char *, newblock)+HEADER;
+ }
+}
+
+
+/* }====================================================================== */
+
+
+
+/*
+** {======================================================
+** Disassembler
+** =======================================================
+*/
+
+
+static char *buildop (Proto *p, int pc, char *buff) {
+ Instruction i = p->code[pc];
+ OpCode o = GET_OPCODE(i);
+ const char *name = luaP_opnames[o];
+ int line = getline(p, pc);
+ sprintf(buff, "(%4d) %4d - ", line, pc);
+ switch (getOpMode(o)) {
+ case iABC:
+ sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name,
+ GETARG_A(i), GETARG_B(i), GETARG_C(i));
+ break;
+ case iABx:
+ sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i));
+ break;
+ case iAsBx:
+ sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i));
+ break;
+ }
+ return buff;
+}
+
+
+#if 0
+void luaI_printcode (Proto *pt, int size) {
+ int pc;
+ for (pc=0; pc<size; pc++) {
+ char buff[100];
+ printf("%s\n", buildop(pt, pc, buff));
+ }
+ printf("-------\n");
+}
+#endif
+
+
+static int listcode (lua_State *L) {
+ int pc;
+ Proto *p;
+ luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
+ 1, "Lua function expected");
+ p = clvalue(func_at(L, 1))->l.p;
+ lua_newtable(L);
+ setnameval(L, "maxstack", p->maxstacksize);
+ setnameval(L, "numparams", p->numparams);
+ for (pc=0; pc<p->sizecode; pc++) {
+ char buff[100];
+ lua_pushintegral(L, pc+1);
+ lua_pushstring(L, buildop(p, pc, buff));
+ lua_settable(L, -3);
+ }
+ return 1;
+}
+
+
+static int listk (lua_State *L) {
+ Proto *p;
+ int i;
+ luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
+ 1, "Lua function expected");
+ p = clvalue(func_at(L, 1))->l.p;
+ lua_newtable(L);
+ for (i=0; i<p->sizek; i++) {
+ lua_pushintegral(L, i+1);
+ luaA_pushobject(L, p->k+i);
+ lua_settable(L, -3);
+ }
+ return 1;
+}
+
+
+static int listlocals (lua_State *L) {
+ Proto *p;
+ int pc = luaL_checkint(L, 2) - 1;
+ int i = 0;
+ const char *name;
+ luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
+ 1, "Lua function expected");
+ p = clvalue(func_at(L, 1))->l.p;
+ while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
+ lua_pushstring(L, name);
+ return i-1;
+}
+
+/* }====================================================== */
+
+
+
+
+static int get_limits (lua_State *L) {
+ lua_newtable(L);
+ setnameval(L, "BITS_INT", BITS_INT);
+ setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
+ setnameval(L, "MAXVARS", MAXVARS);
+ setnameval(L, "MAXPARAMS", MAXPARAMS);
+ setnameval(L, "MAXSTACK", MAXSTACK);
+ setnameval(L, "MAXUPVALUES", MAXUPVALUES);
+ return 1;
+}
+
+
+static int mem_query (lua_State *L) {
+ if (lua_isnone(L, 1)) {
+ lua_pushintegral(L, memdebug_total);
+ lua_pushintegral(L, memdebug_numblocks);
+ lua_pushintegral(L, memdebug_maxmem);
+ return 3;
+ }
+ else {
+ memdebug_memlimit = luaL_checkint(L, 1);
+ return 0;
+ }
+}
+
+
+static int hash_query (lua_State *L) {
+ if (lua_isnone(L, 2)) {
+ luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
+ lua_pushintegral(L, tsvalue(func_at(L, 1))->tsv.hash);
+ }
+ else {
+ TObject *o = func_at(L, 1);
+ Table *t;
+ luaL_checktype(L, 2, LUA_TTABLE);
+ t = hvalue(func_at(L, 2));
+ lua_pushintegral(L, luaH_mainposition(t, o) - t->node);
+ }
+ return 1;
+}
+
+
+static int stacklevel (lua_State *L) {
+ unsigned long a = 0;
+ lua_pushintegral(L, (int)(L->top - L->stack));
+ lua_pushintegral(L, (int)(L->stack_last - L->stack));
+ lua_pushintegral(L, (int)(L->ci - L->base_ci));
+ lua_pushintegral(L, (int)(L->end_ci - L->base_ci));
+ lua_pushintegral(L, (unsigned long)&a);
+ return 5;
+}
+
+
+static int table_query (lua_State *L) {
+ const Table *t;
+ int i = luaL_optint(L, 2, -1);
+ luaL_checktype(L, 1, LUA_TTABLE);
+ t = hvalue(func_at(L, 1));
+ if (i == -1) {
+ lua_pushintegral(L, t->sizearray);
+ lua_pushintegral(L, sizenode(t));
+ lua_pushintegral(L, t->firstfree - t->node);
+ }
+ else if (i < t->sizearray) {
+ lua_pushintegral(L, i);
+ luaA_pushobject(L, &t->array[i]);
+ lua_pushnil(L);
+ }
+ else if ((i -= t->sizearray) < sizenode(t)) {
+ if (!ttisnil(gval(gnode(t, i))) ||
+ ttisnil(gkey(gnode(t, i))) ||
+ ttisnumber(gkey(gnode(t, i)))) {
+ luaA_pushobject(L, gkey(gnode(t, i)));
+ }
+ else
+ lua_pushstring(L, "<undef>");
+ luaA_pushobject(L, gval(gnode(t, i)));
+ if (t->node[i].next)
+ lua_pushintegral(L, t->node[i].next - t->node);
+ else
+ lua_pushnil(L);
+ }
+ return 3;
+}
+
+
+static int string_query (lua_State *L) {
+ stringtable *tb = &G(L)->strt;
+ int s = luaL_optint(L, 2, 0) - 1;
+ if (s==-1) {
+ lua_pushintegral(L ,tb->nuse);
+ lua_pushintegral(L ,tb->size);
+ return 2;
+ }
+ else if (s < tb->size) {
+ GCObject *ts;
+ int n = 0;
+ for (ts = tb->hash[s]; ts; ts = ts->gch.next) {
+ setsvalue2s(L->top, gcotots(ts));
+ incr_top(L);
+ n++;
+ }
+ return n;
+ }
+ return 0;
+}
+
+
+static int tref (lua_State *L) {
+ int level = lua_gettop(L);
+ int lock = luaL_optint(L, 2, 1);
+ luaL_checkany(L, 1);
+ lua_pushvalue(L, 1);
+ lua_pushintegral(L, lua_ref(L, lock));
+ assert(lua_gettop(L) == level+1); /* +1 for result */
+ return 1;
+}
+
+static int getref (lua_State *L) {
+ int level = lua_gettop(L);
+ lua_getref(L, luaL_checkint(L, 1));
+ assert(lua_gettop(L) == level+1);
+ return 1;
+}
+
+static int unref (lua_State *L) {
+ int level = lua_gettop(L);
+ lua_unref(L, luaL_checkint(L, 1));
+ assert(lua_gettop(L) == level);
+ return 0;
+}
+
+static int metatable (lua_State *L) {
+ luaL_checkany(L, 1);
+ if (lua_isnone(L, 2)) {
+ if (lua_getmetatable(L, 1) == 0)
+ lua_pushnil(L);
+ }
+ else {
+ lua_settop(L, 2);
+ luaL_checktype(L, 2, LUA_TTABLE);
+ lua_setmetatable(L, 1);
+ }
+ return 1;
+}
+
+
+static int upvalue (lua_State *L) {
+ int n = luaL_checkint(L, 2);
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+ if (lua_isnone(L, 3)) {
+ const char *name = lua_getupvalue(L, 1, n);
+ if (name == NULL) return 0;
+ lua_pushstring(L, name);
+ return 2;
+ }
+ else {
+ const char *name = lua_setupvalue(L, 1, n);
+ lua_pushstring(L, name);
+ return 1;
+ }
+}
+
+
+static int newuserdata (lua_State *L) {
+ size_t size = luaL_checkint(L, 1);
+ char *p = cast(char *, lua_newuserdata(L, size));
+ while (size--) *p++ = '\0';
+ return 1;
+}
+
+
+static int pushuserdata (lua_State *L) {
+ lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1)));
+ return 1;
+}
+
+
+static int udataval (lua_State *L) {
+ lua_pushintegral(L, cast(int, lua_touserdata(L, 1)));
+ return 1;
+}
+
+
+static int doonnewstack (lua_State *L) {
+ lua_State *L1 = lua_newthread(L);
+ size_t l;
+ const char *s = luaL_checklstring(L, 1, &l);
+ int status = luaL_loadbuffer(L1, s, l, s);
+ if (status == 0)
+ status = lua_pcall(L1, 0, 0, 0);
+ lua_pushintegral(L, status);
+ return 1;
+}
+
+
+static int s2d (lua_State *L) {
+ lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1)));
+ return 1;
+}
+
+static int d2s (lua_State *L) {
+ double d = luaL_checknumber(L, 1);
+ lua_pushlstring(L, cast(char *, &d), sizeof(d));
+ return 1;
+}
+
+
+static int newstate (lua_State *L) {
+ lua_State *L1 = lua_open();
+ if (L1) {
+ lua_userstateopen(L1); /* init lock */
+ lua_pushintegral(L, (unsigned long)L1);
+ }
+ else
+ lua_pushnil(L);
+ return 1;
+}
+
+
+static int loadlib (lua_State *L) {
+ static const luaL_reg libs[] = {
+ {"mathlibopen", luaopen_math},
+ {"strlibopen", luaopen_string},
+ {"iolibopen", luaopen_io},
+ {"tablibopen", luaopen_table},
+ {"dblibopen", luaopen_debug},
+ {"baselibopen", luaopen_base},
+ {NULL, NULL}
+ };
+ lua_State *L1 = cast(lua_State *,
+ cast(unsigned long, luaL_checknumber(L, 1)));
+ lua_pushvalue(L1, LUA_GLOBALSINDEX);
+ luaL_openlib(L1, NULL, libs, 0);
+ return 0;
+}
+
+static int closestate (lua_State *L) {
+ lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1)));
+ lua_close(L1);
+ lua_unlock(L); /* close cannot unlock that */
+ return 0;
+}
+
+static int doremote (lua_State *L) {
+ lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1)));
+ size_t lcode;
+ const char *code = luaL_checklstring(L, 2, &lcode);
+ int status;
+ lua_settop(L1, 0);
+ status = luaL_loadbuffer(L1, code, lcode, code);
+ if (status == 0)
+ status = lua_pcall(L1, 0, LUA_MULTRET, 0);
+ if (status != 0) {
+ lua_pushnil(L);
+ lua_pushintegral(L, status);
+ lua_pushstring(L, lua_tostring(L1, -1));
+ return 3;
+ }
+ else {
+ int i = 0;
+ while (!lua_isnone(L1, ++i))
+ lua_pushstring(L, lua_tostring(L1, i));
+ lua_pop(L1, i-1);
+ return i-1;
+ }
+}
+
+
+static int log2_aux (lua_State *L) {
+ lua_pushintegral(L, luaO_log2(luaL_checkint(L, 1)));
+ return 1;
+}
+
+static int int2fb_aux (lua_State *L) {
+ int b = luaO_int2fb(luaL_checkint(L, 1));
+ lua_pushintegral(L, b);
+ lua_pushintegral(L, fb2int(b));
+ return 2;
+}
+
+
+static int test_do (lua_State *L) {
+ const char *p = luaL_checkstring(L, 1);
+ if (*p == '@')
+ lua_dofile(L, p+1);
+ else
+ lua_dostring(L, p);
+ return lua_gettop(L);
+}
+
+
+
+/*
+** {======================================================
+** function to test the API with C. It interprets a kind of assembler
+** language with calls to the API, so the test can be driven by Lua code
+** =======================================================
+*/
+
+static const char *const delimits = " \t\n,;";
+
+static void skip (const char **pc) {
+ while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
+}
+
+static int getnum_aux (lua_State *L, const char **pc) {
+ int res = 0;
+ int sig = 1;
+ skip(pc);
+ if (**pc == '.') {
+ res = cast(int, lua_tonumber(L, -1));
+ lua_pop(L, 1);
+ (*pc)++;
+ return res;
+ }
+ else if (**pc == '-') {
+ sig = -1;
+ (*pc)++;
+ }
+ while (isdigit(cast(int, **pc))) res = res*10 + (*(*pc)++) - '0';
+ return sig*res;
+}
+
+static const char *getname_aux (char *buff, const char **pc) {
+ int i = 0;
+ skip(pc);
+ while (**pc != '\0' && !strchr(delimits, **pc))
+ buff[i++] = *(*pc)++;
+ buff[i] = '\0';
+ return buff;
+}
+
+
+#define EQ(s1) (strcmp(s1, inst) == 0)
+
+#define getnum (getnum_aux(L, &pc))
+#define getname (getname_aux(buff, &pc))
+
+
+static int testC (lua_State *L) {
+ char buff[30];
+ const char *pc = luaL_checkstring(L, 1);
+ for (;;) {
+ const char *inst = getname;
+ if EQ("") return 0;
+ else if EQ("isnumber") {
+ lua_pushintegral(L, lua_isnumber(L, getnum));
+ }
+ else if EQ("isstring") {
+ lua_pushintegral(L, lua_isstring(L, getnum));
+ }
+ else if EQ("istable") {
+ lua_pushintegral(L, lua_istable(L, getnum));
+ }
+ else if EQ("iscfunction") {
+ lua_pushintegral(L, lua_iscfunction(L, getnum));
+ }
+ else if EQ("isfunction") {
+ lua_pushintegral(L, lua_isfunction(L, getnum));
+ }
+ else if EQ("isuserdata") {
+ lua_pushintegral(L, lua_isuserdata(L, getnum));
+ }
+ else if EQ("isudataval") {
+ lua_pushintegral(L, lua_islightuserdata(L, getnum));
+ }
+ else if EQ("isnil") {
+ lua_pushintegral(L, lua_isnil(L, getnum));
+ }
+ else if EQ("isnull") {
+ lua_pushintegral(L, lua_isnone(L, getnum));
+ }
+ else if EQ("tonumber") {
+ lua_pushnumber(L, lua_tonumber(L, getnum));
+ }
+ else if EQ("tostring") {
+ const char *s = lua_tostring(L, getnum);
+ lua_pushstring(L, s);
+ }
+ else if EQ("strlen") {
+ lua_pushintegral(L, lua_strlen(L, getnum));
+ }
+ else if EQ("tocfunction") {
+ lua_pushcfunction(L, lua_tocfunction(L, getnum));
+ }
+ else if EQ("return") {
+ return getnum;
+ }
+ else if EQ("gettop") {
+ lua_pushintegral(L, lua_gettop(L));
+ }
+ else if EQ("settop") {
+ lua_settop(L, getnum);
+ }
+ else if EQ("pop") {
+ lua_pop(L, getnum);
+ }
+ else if EQ("pushnum") {
+ lua_pushintegral(L, getnum);
+ }
+ else if EQ("pushnil") {
+ lua_pushnil(L);
+ }
+ else if EQ("pushbool") {
+ lua_pushboolean(L, getnum);
+ }
+ else if EQ("tobool") {
+ lua_pushintegral(L, lua_toboolean(L, getnum));
+ }
+ else if EQ("pushvalue") {
+ lua_pushvalue(L, getnum);
+ }
+ else if EQ("pushcclosure") {
+ lua_pushcclosure(L, testC, getnum);
+ }
+ else if EQ("pushupvalues") {
+ lua_pushupvalues(L);
+ }
+ else if EQ("remove") {
+ lua_remove(L, getnum);
+ }
+ else if EQ("insert") {
+ lua_insert(L, getnum);
+ }
+ else if EQ("replace") {
+ lua_replace(L, getnum);
+ }
+ else if EQ("gettable") {
+ lua_gettable(L, getnum);
+ }
+ else if EQ("settable") {
+ lua_settable(L, getnum);
+ }
+ else if EQ("next") {
+ lua_next(L, -2);
+ }
+ else if EQ("concat") {
+ lua_concat(L, getnum);
+ }
+ else if EQ("lessthan") {
+ int a = getnum;
+ lua_pushboolean(L, lua_lessthan(L, a, getnum));
+ }
+ else if EQ("equal") {
+ int a = getnum;
+ lua_pushboolean(L, lua_equal(L, a, getnum));
+ }
+ else if EQ("rawcall") {
+ int narg = getnum;
+ int nres = getnum;
+ lua_call(L, narg, nres);
+ }
+ else if EQ("call") {
+ int narg = getnum;
+ int nres = getnum;
+ lua_pcall(L, narg, nres, 0);
+ }
+ else if EQ("loadstring") {
+ size_t sl;
+ const char *s = luaL_checklstring(L, getnum, &sl);
+ luaL_loadbuffer(L, s, sl, s);
+ }
+ else if EQ("loadfile") {
+ luaL_loadfile(L, luaL_checkstring(L, getnum));
+ }
+ else if EQ("setmetatable") {
+ lua_setmetatable(L, getnum);
+ }
+ else if EQ("getmetatable") {
+ if (lua_getmetatable(L, getnum) == 0)
+ lua_pushnil(L);
+ }
+ else if EQ("type") {
+ lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
+ }
+ else if EQ("getn") {
+ int i = getnum;
+ lua_pushintegral(L, luaL_getn(L, i));
+ }
+ else if EQ("setn") {
+ int i = getnum;
+ int n = cast(int, lua_tonumber(L, -1));
+ luaL_setn(L, i, n);
+ lua_pop(L, 1);
+ }
+ else luaL_error(L, "unknown instruction %s", buff);
+ }
+ return 0;
+}
+
+/* }====================================================== */
+
+
+/*
+** {======================================================
+** tests for yield inside hooks
+** =======================================================
+*/
+
+static void yieldf (lua_State *L, lua_Debug *ar) {
+ lua_yield(L, 0);
+}
+
+static int setyhook (lua_State *L) {
+ if (lua_isnoneornil(L, 1))
+ lua_sethook(L, NULL, 0, 0); /* turn off hooks */
+ else {
+ const char *smask = luaL_checkstring(L, 1);
+ int count = luaL_optint(L, 2, 0);
+ int mask = 0;
+ if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
+ if (count > 0) mask |= LUA_MASKCOUNT;
+ lua_sethook(L, yieldf, mask, count);
+ }
+ return 0;
+}
+
+
+static int coresume (lua_State *L) {
+ int status;
+ lua_State *co = lua_tothread(L, 1);
+ luaL_argcheck(L, co, 1, "coroutine expected");
+ status = lua_resume(co, 0);
+ if (status != 0) {
+ lua_pushboolean(L, 0);
+ lua_insert(L, -2);
+ return 2; /* return false + error message */
+ }
+ else {
+ lua_pushboolean(L, 1);
+ return 1;
+ }
+}
+
+/* }====================================================== */
+
+
+
+static const struct luaL_reg tests_funcs[] = {
+ {"hash", hash_query},
+ {"limits", get_limits},
+ {"listcode", listcode},
+ {"listk", listk},
+ {"listlocals", listlocals},
+ {"loadlib", loadlib},
+ {"stacklevel", stacklevel},
+ {"querystr", string_query},
+ {"querytab", table_query},
+ {"doit", test_do},
+ {"testC", testC},
+ {"ref", tref},
+ {"getref", getref},
+ {"unref", unref},
+ {"d2s", d2s},
+ {"s2d", s2d},
+ {"metatable", metatable},
+ {"upvalue", upvalue},
+ {"newuserdata", newuserdata},
+ {"pushuserdata", pushuserdata},
+ {"udataval", udataval},
+ {"doonnewstack", doonnewstack},
+ {"newstate", newstate},
+ {"closestate", closestate},
+ {"doremote", doremote},
+ {"log2", log2_aux},
+ {"int2fb", int2fb_aux},
+ {"totalmem", mem_query},
+ {"resume", coresume},
+ {"setyhook", setyhook},
+ {NULL, NULL}
+};
+
+
+static void fim (void) {
+ if (!islocked)
+ lua_close(lua_state);
+ lua_assert(memdebug_numblocks == 0);
+ lua_assert(memdebug_total == 0);
+}
+
+
+static int l_panic (lua_State *L) {
+ UNUSED(L);
+ fprintf(stderr, "unable to recover; exiting\n");
+ return 0;
+}
+
+
+int luaB_opentests (lua_State *L) {
+ lua_atpanic(L, l_panic);
+ lua_userstateopen(L); /* init lock */
+ lua_state = L; /* keep first state to be opened */
+ luaL_openlib(L, "T", tests_funcs, 0);
+ atexit(fim);
+ return 0;
+}
+
+
+#undef main
+int main (int argc, char *argv[]) {
+ char *limit = getenv("MEMLIMIT");
+ if (limit)
+ memdebug_memlimit = strtoul(limit, NULL, 10);
+ l_main(argc, argv);
+ return 0;
+}
+
+#endif
diff --git a/lib/lua/src/ltm.c b/lib/lua/src/ltm.c
index 204bf46..5ad7858 100644
--- a/lib/lua/src/ltm.c
+++ b/lib/lua/src/ltm.c
@@ -1,70 +1,70 @@
-/*
-** $Id: ltm.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** Tag methods
-** See Copyright Notice in lua.h
-*/
-
-
-#include <string.h>
-
-#define ltm_c
-
-#include "lua.h"
-
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-
-
-
-const char *const luaT_typenames[] = {
- "nil", "boolean", "userdata", "number",
- "string", "table", "function", "userdata", "thread"
-};
-
-
-void luaT_init (lua_State *L) {
- static const char *const luaT_eventname[] = { /* ORDER TM */
- "__index", "__newindex",
- "__gc", "__mode", "__eq",
- "__add", "__sub", "__mul", "__div",
- "__pow", "__unm", "__lt", "__le",
- "__concat", "__call"
- };
- int i;
- for (i=0; i<TM_N; i++) {
- G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
- luaS_fix(G(L)->tmname[i]); /* never collect these names */
- }
-}
-
-
-/*
-** function to be used with macro "fasttm": optimized for absence of
-** tag methods
-*/
-const TObject *luaT_gettm (Table *events, TMS event, TString *ename) {
- const TObject *tm = luaH_getstr(events, ename);
- lua_assert(event <= TM_EQ);
- if (ttisnil(tm)) { /* no tag method? */
- events->flags |= cast(lu_byte, 1u<<event); /* cache this fact */
- return NULL;
- }
- else return tm;
-}
-
-
-const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event) {
- TString *ename = G(L)->tmname[event];
- switch (ttype(o)) {
- case LUA_TTABLE:
- return luaH_getstr(hvalue(o)->metatable, ename);
- case LUA_TUSERDATA:
- return luaH_getstr(uvalue(o)->uv.metatable, ename);
- default:
- return &luaO_nilobject;
- }
-}
-
+/*
+** $Id: ltm.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** Tag methods
+** See Copyright Notice in lua.h
+*/
+
+
+#include <string.h>
+
+#define ltm_c
+
+#include "lua.h"
+
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+
+
+
+const char *const luaT_typenames[] = {
+ "nil", "boolean", "userdata", "number",
+ "string", "table", "function", "userdata", "thread"
+};
+
+
+void luaT_init (lua_State *L) {
+ static const char *const luaT_eventname[] = { /* ORDER TM */
+ "__index", "__newindex",
+ "__gc", "__mode", "__eq",
+ "__add", "__sub", "__mul", "__div",
+ "__pow", "__unm", "__lt", "__le",
+ "__concat", "__call"
+ };
+ int i;
+ for (i=0; i<TM_N; i++) {
+ G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
+ luaS_fix(G(L)->tmname[i]); /* never collect these names */
+ }
+}
+
+
+/*
+** function to be used with macro "fasttm": optimized for absence of
+** tag methods
+*/
+const TObject *luaT_gettm (Table *events, TMS event, TString *ename) {
+ const TObject *tm = luaH_getstr(events, ename);
+ lua_assert(event <= TM_EQ);
+ if (ttisnil(tm)) { /* no tag method? */
+ events->flags |= cast(lu_byte, 1u<<event); /* cache this fact */
+ return NULL;
+ }
+ else return tm;
+}
+
+
+const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event) {
+ TString *ename = G(L)->tmname[event];
+ switch (ttype(o)) {
+ case LUA_TTABLE:
+ return luaH_getstr(hvalue(o)->metatable, ename);
+ case LUA_TUSERDATA:
+ return luaH_getstr(uvalue(o)->uv.metatable, ename);
+ default:
+ return &luaO_nilobject;
+ }
+}
+
diff --git a/lib/lua/src/luacomp.c b/lib/lua/src/luacomp.c
index bac561b..87372a2 100644
--- a/lib/lua/src/luacomp.c
+++ b/lib/lua/src/luacomp.c
@@ -1,82 +1,82 @@
-/*
- ** $Id: luacomp.c,v 1.5 2004-11-27 21:35:20 pixel Exp $
- ** Lua compiler (saves bytecodes to files; also list bytecodes)
- ** Highly hacked by Nicolas "Pixel" Noble to be transformed into a
- ** small form-factor LUA compiler.
- ** See Copyright Notice in lua.h
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "lua.h"
-#include "lauxlib.h"
-
-#include "lfunc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lstring.h"
-#include "lundump.h"
-
-#ifndef PROGNAME
-#define PROGNAME "luacomp" /* program name */
-#endif
-
-const char * progname = PROGNAME; /* actual program name */
-
-static Proto * toproto(lua_State * L, int i) {
- const Closure * c = (const Closure *) lua_topointer(L, i);
-
- return c->l.p;
-}
-
-static Proto * combine(lua_State * L, int n) {
- if (n == 1)
- return toproto(L, -1);
- else {
- int i, pc = 0;
- Proto * f = luaF_newproto(L);
-
- f->source = luaS_newliteral(L, "=(" PROGNAME ")");
- f->maxstacksize = 1;
- f->p = luaM_newvector(L, n, Proto *);
- f->sizep = n;
- f->sizecode = 2 * n + 1;
- f->code = luaM_newvector(L, f->sizecode, Instruction);
- for (i = 0; i < n; i++) {
- f->p[i] = toproto(L, i - n);
- f->code[pc++] = CREATE_ABx(OP_CLOSURE, 0, i);
- f->code[pc++] = CREATE_ABC(OP_CALL, 0, 1, 1);
- }
- f->code[pc++] = CREATE_ABC(OP_RETURN, 0, 1, 0);
- return f;
- }
-}
-
-static void strip(lua_State * L, Proto * f) {
- int i, n = f->sizep;
- luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
- luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
-
- luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
- f->lineinfo = NULL;
- f->sizelineinfo = 0;
- f->locvars = NULL;
- f->sizelocvars = 0;
- f->upvalues = NULL;
- f->sizeupvalues = 0;
- f->source = luaS_newliteral(L, "=(none)");
- for (i = 0; i < n; i++)
- strip(L, f->p[i]);
-}
-
-void luacmain(lua_State * L, int stripping, lua_Chunkwriter w, void *uD) {
- Proto * f;
-
- f = combine(L, lua_gettop(L));
- if (stripping)
- strip(L, f);
- luaU_dump(L, f, w, uD);
-}
+/*
+ ** $Id: luacomp.c,v 1.6 2004-11-27 21:46:07 pixel Exp $
+ ** Lua compiler (saves bytecodes to files; also list bytecodes)
+ ** Highly hacked by Nicolas "Pixel" Noble to be transformed into a
+ ** small form-factor LUA compiler.
+ ** See Copyright Notice in lua.h
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lua.h"
+#include "lauxlib.h"
+
+#include "lfunc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lstring.h"
+#include "lundump.h"
+
+#ifndef PROGNAME
+#define PROGNAME "luacomp" /* program name */
+#endif
+
+const char * progname = PROGNAME; /* actual program name */
+
+static Proto * toproto(lua_State * L, int i) {
+ const Closure * c = (const Closure *) lua_topointer(L, i);
+
+ return c->l.p;
+}
+
+static Proto * combine(lua_State * L, int n) {
+ if (n == 1)
+ return toproto(L, -1);
+ else {
+ int i, pc = 0;
+ Proto * f = luaF_newproto(L);
+
+ f->source = luaS_newliteral(L, "=(" PROGNAME ")");
+ f->maxstacksize = 1;
+ f->p = luaM_newvector(L, n, Proto *);
+ f->sizep = n;
+ f->sizecode = 2 * n + 1;
+ f->code = luaM_newvector(L, f->sizecode, Instruction);
+ for (i = 0; i < n; i++) {
+ f->p[i] = toproto(L, i - n);
+ f->code[pc++] = CREATE_ABx(OP_CLOSURE, 0, i);
+ f->code[pc++] = CREATE_ABC(OP_CALL, 0, 1, 1);
+ }
+ f->code[pc++] = CREATE_ABC(OP_RETURN, 0, 1, 0);
+ return f;
+ }
+}
+
+static void strip(lua_State * L, Proto * f) {
+ int i, n = f->sizep;
+ luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
+ luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
+
+ luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
+ f->lineinfo = NULL;
+ f->sizelineinfo = 0;
+ f->locvars = NULL;
+ f->sizelocvars = 0;
+ f->upvalues = NULL;
+ f->sizeupvalues = 0;
+ f->source = luaS_newliteral(L, "=(none)");
+ for (i = 0; i < n; i++)
+ strip(L, f->p[i]);
+}
+
+void luacmain(lua_State * L, int stripping, lua_Chunkwriter w, void *uD) {
+ Proto * f;
+
+ f = combine(L, lua_gettop(L));
+ if (stripping)
+ strip(L, f);
+ luaU_dump(L, f, w, uD);
+}
diff --git a/lib/lua/src/lundump.c b/lib/lua/src/lundump.c
index be2b586..7d9f031 100644
--- a/lib/lua/src/lundump.c
+++ b/lib/lua/src/lundump.c
@@ -1,286 +1,286 @@
-/*
-** $Id: lundump.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** load pre-compiled Lua chunks
-** See Copyright Notice in lua.h
-*/
-
-#define lundump_c
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "lfunc.h"
-#include "lmem.h"
-#include "lopcodes.h"
-#include "lstring.h"
-#include "lundump.h"
-#include "lzio.h"
-
-#define LoadByte (lu_byte) ezgetc
-
-typedef struct {
- lua_State* L;
- ZIO* Z;
- Mbuffer* b;
- int swap;
- const char* name;
-} LoadState;
-
-static void unexpectedEOZ (LoadState* S)
-{
- luaG_runerror(S->L,"unexpected end of file in %s",S->name);
-}
-
-static int ezgetc (LoadState* S)
-{
- int c=zgetc(S->Z);
- if (c==EOZ) unexpectedEOZ(S);
- return c;
-}
-
-static void ezread (LoadState* S, void* b, int n)
-{
- int r=luaZ_read(S->Z,b,n);
- if (r!=0) unexpectedEOZ(S);
-}
-
-static void LoadBlock (LoadState* S, void* b, size_t size)
-{
- if (S->swap)
- {
- char* p=(char*) b+size-1;
- int n=size;
- while (n--) *p--=(char)ezgetc(S);
- }
- else
- ezread(S,b,size);
-}
-
-static void LoadVector (LoadState* S, void* b, int m, size_t size)
-{
- if (S->swap)
- {
- char* q=(char*) b;
- while (m--)
- {
- char* p=q+size-1;
- int n=size;
- while (n--) *p--=(char)ezgetc(S);
- q+=size;
- }
- }
- else
- ezread(S,b,m*size);
-}
-
-static int LoadInt (LoadState* S)
-{
- int x;
- LoadBlock(S,&x,sizeof(x));
- if (x<0) luaG_runerror(S->L,"bad integer in %s",S->name);
- return x;
-}
-
-static size_t LoadSize (LoadState* S)
-{
- size_t x;
- LoadBlock(S,&x,sizeof(x));
- return x;
-}
-
-static lua_Number LoadNumber (LoadState* S)
-{
- lua_Number x;
- LoadBlock(S,&x,sizeof(x));
- return x;
-}
-
-static TString* LoadString (LoadState* S)
-{
- size_t size=LoadSize(S);
- if (size==0)
- return NULL;
- else
- {
- char* s=luaZ_openspace(S->L,S->b,size);
- ezread(S,s,size);
- return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
- }
-}
-
-static void LoadCode (LoadState* S, Proto* f)
-{
- int size=LoadInt(S);
- f->code=luaM_newvector(S->L,size,Instruction);
- f->sizecode=size;
- LoadVector(S,f->code,size,sizeof(*f->code));
-}
-
-static void LoadLocals (LoadState* S, Proto* f)
-{
- int i,n;
- n=LoadInt(S);
- f->locvars=luaM_newvector(S->L,n,LocVar);
- f->sizelocvars=n;
- for (i=0; i<n; i++)
- {
- f->locvars[i].varname=LoadString(S);
- f->locvars[i].startpc=LoadInt(S);
- f->locvars[i].endpc=LoadInt(S);
- }
-}
-
-static void LoadLines (LoadState* S, Proto* f)
-{
- int size=LoadInt(S);
- f->lineinfo=luaM_newvector(S->L,size,int);
- f->sizelineinfo=size;
- LoadVector(S,f->lineinfo,size,sizeof(*f->lineinfo));
-}
-
-static void LoadUpvalues (LoadState* S, Proto* f)
-{
- int i,n;
- n=LoadInt(S);
- if (n!=0 && n!=f->nups)
- luaG_runerror(S->L,"bad nupvalues in %s: read %d; expected %d",
- S->name,n,f->nups);
- f->upvalues=luaM_newvector(S->L,n,TString*);
- f->sizeupvalues=n;
- for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
-}
-
-static Proto* LoadFunction (LoadState* S, TString* p);
-
-static void LoadConstants (LoadState* S, Proto* f)
-{
- int i,n;
- n=LoadInt(S);
- f->k=luaM_newvector(S->L,n,TObject);
- f->sizek=n;
- for (i=0; i<n; i++)
- {
- TObject* o=&f->k[i];
- int t=LoadByte(S);
- switch (t)
- {
- case LUA_TNUMBER:
- setnvalue(o,LoadNumber(S));
- break;
- case LUA_TSTRING:
- setsvalue2n(o,LoadString(S));
- break;
- case LUA_TNIL:
- setnilvalue(o);
- break;
- default:
- luaG_runerror(S->L,"bad constant type (%d) in %s",t,S->name);
- break;
- }
- }
- n=LoadInt(S);
- f->p=luaM_newvector(S->L,n,Proto*);
- f->sizep=n;
- for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
-}
-
-static Proto* LoadFunction (LoadState* S, TString* p)
-{
- Proto* f=luaF_newproto(S->L);
- f->source=LoadString(S); if (f->source==NULL) f->source=p;
- f->lineDefined=LoadInt(S);
- f->nups=LoadByte(S);
- f->numparams=LoadByte(S);
- f->is_vararg=LoadByte(S);
- f->maxstacksize=LoadByte(S);
- LoadLines(S,f);
- LoadLocals(S,f);
- LoadUpvalues(S,f);
- LoadConstants(S,f);
- LoadCode(S,f);
-#ifndef TRUST_BINARIES
- if (!luaG_checkcode(f)) luaG_runerror(S->L,"bad code in %s",S->name);
-#endif
- return f;
-}
-
-static void LoadSignature (LoadState* S)
-{
- const char* s=LUA_SIGNATURE;
- while (*s!=0 && ezgetc(S)==*s)
- ++s;
- if (*s!=0) luaG_runerror(S->L,"bad signature in %s",S->name);
-}
-
-static void TestSize (LoadState* S, int s, const char* what)
-{
- int r=LoadByte(S);
- if (r!=s)
- luaG_runerror(S->L,"virtual machine mismatch in %s: "
- "size of %s is %d but read %d",S->name,what,s,r);
-}
-
-#define TESTSIZE(s,w) TestSize(S,s,w)
-#define V(v) v/16,v%16
-
-static void LoadHeader (LoadState* S)
-{
- int version;
- lua_Number x,tx=TEST_NUMBER;
- LoadSignature(S);
- version=LoadByte(S);
- if (version>VERSION)
- luaG_runerror(S->L,"%s too new: "
- "read version %d.%d; expected at most %d.%d",
- S->name,V(version),V(VERSION));
- if (version<VERSION0) /* check last major change */
- luaG_runerror(S->L,"%s too old: "
- "read version %d.%d; expected at least %d.%d",
- S->name,V(version),V(VERSION0));
- S->swap=(luaU_endianness()!=LoadByte(S)); /* need to swap bytes? */
- TESTSIZE(sizeof(int),"int");
- TESTSIZE(sizeof(size_t), "size_t");
- TESTSIZE(sizeof(Instruction), "Instruction");
- TESTSIZE(SIZE_OP, "OP");
- TESTSIZE(SIZE_A, "A");
- TESTSIZE(SIZE_B, "B");
- TESTSIZE(SIZE_C, "C");
- TESTSIZE(sizeof(lua_Number), "number");
- x=LoadNumber(S);
- if ((long)x!=(long)tx) /* disregard errors in last bits of fraction */
- luaG_runerror(S->L,"unknown number format in %s",S->name);
-}
-
-static Proto* LoadChunk (LoadState* S)
-{
- LoadHeader(S);
- return LoadFunction(S,NULL);
-}
-
-/*
-** load precompiled chunk
-*/
-Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff)
-{
- LoadState S;
- const char* s=zname(Z);
- if (*s=='@' || *s=='=')
- S.name=s+1;
- else if (*s==LUA_SIGNATURE[0])
- S.name="binary string";
- else
- S.name=s;
- S.L=L;
- S.Z=Z;
- S.b=buff;
- return LoadChunk(&S);
-}
-
-/*
-** find byte order
-*/
-int luaU_endianness (void)
-{
- int x=1;
- return *(char*)&x;
-}
+/*
+** $Id: lundump.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** load pre-compiled Lua chunks
+** See Copyright Notice in lua.h
+*/
+
+#define lundump_c
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "lfunc.h"
+#include "lmem.h"
+#include "lopcodes.h"
+#include "lstring.h"
+#include "lundump.h"
+#include "lzio.h"
+
+#define LoadByte (lu_byte) ezgetc
+
+typedef struct {
+ lua_State* L;
+ ZIO* Z;
+ Mbuffer* b;
+ int swap;
+ const char* name;
+} LoadState;
+
+static void unexpectedEOZ (LoadState* S)
+{
+ luaG_runerror(S->L,"unexpected end of file in %s",S->name);
+}
+
+static int ezgetc (LoadState* S)
+{
+ int c=zgetc(S->Z);
+ if (c==EOZ) unexpectedEOZ(S);
+ return c;
+}
+
+static void ezread (LoadState* S, void* b, int n)
+{
+ int r=luaZ_read(S->Z,b,n);
+ if (r!=0) unexpectedEOZ(S);
+}
+
+static void LoadBlock (LoadState* S, void* b, size_t size)
+{
+ if (S->swap)
+ {
+ char* p=(char*) b+size-1;
+ int n=size;
+ while (n--) *p--=(char)ezgetc(S);
+ }
+ else
+ ezread(S,b,size);
+}
+
+static void LoadVector (LoadState* S, void* b, int m, size_t size)
+{
+ if (S->swap)
+ {
+ char* q=(char*) b;
+ while (m--)
+ {
+ char* p=q+size-1;
+ int n=size;
+ while (n--) *p--=(char)ezgetc(S);
+ q+=size;
+ }
+ }
+ else
+ ezread(S,b,m*size);
+}
+
+static int LoadInt (LoadState* S)
+{
+ int x;
+ LoadBlock(S,&x,sizeof(x));
+ if (x<0) luaG_runerror(S->L,"bad integer in %s",S->name);
+ return x;
+}
+
+static size_t LoadSize (LoadState* S)
+{
+ size_t x;
+ LoadBlock(S,&x,sizeof(x));
+ return x;
+}
+
+static lua_Number LoadNumber (LoadState* S)
+{
+ lua_Number x;
+ LoadBlock(S,&x,sizeof(x));
+ return x;
+}
+
+static TString* LoadString (LoadState* S)
+{
+ size_t size=LoadSize(S);
+ if (size==0)
+ return NULL;
+ else
+ {
+ char* s=luaZ_openspace(S->L,S->b,size);
+ ezread(S,s,size);
+ return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
+ }
+}
+
+static void LoadCode (LoadState* S, Proto* f)
+{
+ int size=LoadInt(S);
+ f->code=luaM_newvector(S->L,size,Instruction);
+ f->sizecode=size;
+ LoadVector(S,f->code,size,sizeof(*f->code));
+}
+
+static void LoadLocals (LoadState* S, Proto* f)
+{
+ int i,n;
+ n=LoadInt(S);
+ f->locvars=luaM_newvector(S->L,n,LocVar);
+ f->sizelocvars=n;
+ for (i=0; i<n; i++)
+ {
+ f->locvars[i].varname=LoadString(S);
+ f->locvars[i].startpc=LoadInt(S);
+ f->locvars[i].endpc=LoadInt(S);
+ }
+}
+
+static void LoadLines (LoadState* S, Proto* f)
+{
+ int size=LoadInt(S);
+ f->lineinfo=luaM_newvector(S->L,size,int);
+ f->sizelineinfo=size;
+ LoadVector(S,f->lineinfo,size,sizeof(*f->lineinfo));
+}
+
+static void LoadUpvalues (LoadState* S, Proto* f)
+{
+ int i,n;
+ n=LoadInt(S);
+ if (n!=0 && n!=f->nups)
+ luaG_runerror(S->L,"bad nupvalues in %s: read %d; expected %d",
+ S->name,n,f->nups);
+ f->upvalues=luaM_newvector(S->L,n,TString*);
+ f->sizeupvalues=n;
+ for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
+}
+
+static Proto* LoadFunction (LoadState* S, TString* p);
+
+static void LoadConstants (LoadState* S, Proto* f)
+{
+ int i,n;
+ n=LoadInt(S);
+ f->k=luaM_newvector(S->L,n,TObject);
+ f->sizek=n;
+ for (i=0; i<n; i++)
+ {
+ TObject* o=&f->k[i];
+ int t=LoadByte(S);
+ switch (t)
+ {
+ case LUA_TNUMBER:
+ setnvalue(o,LoadNumber(S));
+ break;
+ case LUA_TSTRING:
+ setsvalue2n(o,LoadString(S));
+ break;
+ case LUA_TNIL:
+ setnilvalue(o);
+ break;
+ default:
+ luaG_runerror(S->L,"bad constant type (%d) in %s",t,S->name);
+ break;
+ }
+ }
+ n=LoadInt(S);
+ f->p=luaM_newvector(S->L,n,Proto*);
+ f->sizep=n;
+ for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
+}
+
+static Proto* LoadFunction (LoadState* S, TString* p)
+{
+ Proto* f=luaF_newproto(S->L);
+ f->source=LoadString(S); if (f->source==NULL) f->source=p;
+ f->lineDefined=LoadInt(S);
+ f->nups=LoadByte(S);
+ f->numparams=LoadByte(S);
+ f->is_vararg=LoadByte(S);
+ f->maxstacksize=LoadByte(S);
+ LoadLines(S,f);
+ LoadLocals(S,f);
+ LoadUpvalues(S,f);
+ LoadConstants(S,f);
+ LoadCode(S,f);
+#ifndef TRUST_BINARIES
+ if (!luaG_checkcode(f)) luaG_runerror(S->L,"bad code in %s",S->name);
+#endif
+ return f;
+}
+
+static void LoadSignature (LoadState* S)
+{
+ const char* s=LUA_SIGNATURE;
+ while (*s!=0 && ezgetc(S)==*s)
+ ++s;
+ if (*s!=0) luaG_runerror(S->L,"bad signature in %s",S->name);
+}
+
+static void TestSize (LoadState* S, int s, const char* what)
+{
+ int r=LoadByte(S);
+ if (r!=s)
+ luaG_runerror(S->L,"virtual machine mismatch in %s: "
+ "size of %s is %d but read %d",S->name,what,s,r);
+}
+
+#define TESTSIZE(s,w) TestSize(S,s,w)
+#define V(v) v/16,v%16
+
+static void LoadHeader (LoadState* S)
+{
+ int version;
+ lua_Number x,tx=TEST_NUMBER;
+ LoadSignature(S);
+ version=LoadByte(S);
+ if (version>VERSION)
+ luaG_runerror(S->L,"%s too new: "
+ "read version %d.%d; expected at most %d.%d",
+ S->name,V(version),V(VERSION));
+ if (version<VERSION0) /* check last major change */
+ luaG_runerror(S->L,"%s too old: "
+ "read version %d.%d; expected at least %d.%d",
+ S->name,V(version),V(VERSION0));
+ S->swap=(luaU_endianness()!=LoadByte(S)); /* need to swap bytes? */
+ TESTSIZE(sizeof(int),"int");
+ TESTSIZE(sizeof(size_t), "size_t");
+ TESTSIZE(sizeof(Instruction), "Instruction");
+ TESTSIZE(SIZE_OP, "OP");
+ TESTSIZE(SIZE_A, "A");
+ TESTSIZE(SIZE_B, "B");
+ TESTSIZE(SIZE_C, "C");
+ TESTSIZE(sizeof(lua_Number), "number");
+ x=LoadNumber(S);
+ if ((long)x!=(long)tx) /* disregard errors in last bits of fraction */
+ luaG_runerror(S->L,"unknown number format in %s",S->name);
+}
+
+static Proto* LoadChunk (LoadState* S)
+{
+ LoadHeader(S);
+ return LoadFunction(S,NULL);
+}
+
+/*
+** load precompiled chunk
+*/
+Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff)
+{
+ LoadState S;
+ const char* s=zname(Z);
+ if (*s=='@' || *s=='=')
+ S.name=s+1;
+ else if (*s==LUA_SIGNATURE[0])
+ S.name="binary string";
+ else
+ S.name=s;
+ S.L=L;
+ S.Z=Z;
+ S.b=buff;
+ return LoadChunk(&S);
+}
+
+/*
+** find byte order
+*/
+int luaU_endianness (void)
+{
+ int x=1;
+ return *(char*)&x;
+}
diff --git a/lib/lua/src/lvm.c b/lib/lua/src/lvm.c
index c22c258..6c07b0f 100644
--- a/lib/lua/src/lvm.c
+++ b/lib/lua/src/lvm.c
@@ -1,784 +1,784 @@
-/*
-** $Id: lvm.c,v 1.4 2004-11-27 21:35:20 pixel Exp $
-** Lua virtual machine
-** See Copyright Notice in lua.h
-*/
-
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* needed only when `lua_number2str' uses `sprintf' */
-#include <stdio.h>
-
-#define lvm_c
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-#include "lvm.h"
-
-
-
-/* function to convert a lua_Number to a string */
-#ifndef lua_number2str
-#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
-#endif
-
-
-/* limit for table tag-method chains (to avoid loops) */
-#define MAXTAGLOOP 100
-
-
-const TObject *luaV_tonumber (const TObject *obj, TObject *n) {
- lua_Number num;
- if (ttisnumber(obj)) return obj;
- if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
- setnvalue(n, num);
- return n;
- }
- else
- return NULL;
-}
-
-
-int luaV_tostring (lua_State *L, StkId obj) {
- if (!ttisnumber(obj))
- return 0;
- else {
- char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */
- lua_number2str(s, nvalue(obj));
- setsvalue2s(obj, luaS_new(L, s));
- return 1;
- }
-}
-
-
-static void traceexec (lua_State *L) {
- lu_byte mask = L->hookmask;
- if (mask > LUA_MASKLINE) { /* instruction-hook set? */
- if (L->hookcount == 0) {
- resethookcount(L);
- luaD_callhook(L, LUA_HOOKCOUNT, -1);
- return;
- }
- }
- if (mask & LUA_MASKLINE) {
- CallInfo *ci = L->ci;
- Proto *p = ci_func(ci)->l.p;
- int newline = getline(p, pcRel(*ci->u.l.pc, p));
- if (!L->hookinit) {
- luaG_inithooks(L);
- return;
- }
- lua_assert(ci->state & CI_HASFRAME);
- if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */
- ci->u.l.savedpc = *ci->u.l.pc; /* initialize `savedpc' */
- /* calls linehook when enters a new line or jumps back (loop) */
- if (*ci->u.l.pc <= ci->u.l.savedpc ||
- newline != getline(p, pcRel(ci->u.l.savedpc, p))) {
- luaD_callhook(L, LUA_HOOKLINE, newline);
- ci = L->ci; /* previous call may reallocate `ci' */
- }
- ci->u.l.savedpc = *ci->u.l.pc;
- }
-}
-
-
-static void callTMres (lua_State *L, const TObject *f,
- const TObject *p1, const TObject *p2) {
- setobj2s(L->top, f); /* push function */
- setobj2s(L->top+1, p1); /* 1st argument */
- setobj2s(L->top+2, p2); /* 2nd argument */
- luaD_checkstack(L, 3); /* cannot check before (could invalidate p1, p2) */
- L->top += 3;
- luaD_call(L, L->top - 3, 1);
- L->top--; /* result will be in L->top */
-}
-
-
-
-static void callTM (lua_State *L, const TObject *f,
- const TObject *p1, const TObject *p2, const TObject *p3) {
- setobj2s(L->top, f); /* push function */
- setobj2s(L->top+1, p1); /* 1st argument */
- setobj2s(L->top+2, p2); /* 2nd argument */
- setobj2s(L->top+3, p3); /* 3th argument */
- luaD_checkstack(L, 4); /* cannot check before (could invalidate p1...p3) */
- L->top += 4;
- luaD_call(L, L->top - 4, 0);
-}
-
-
-static const TObject *luaV_index (lua_State *L, const TObject *t,
- TObject *key, int loop) {
- const TObject *tm = fasttm(L, hvalue(t)->metatable, TM_INDEX);
- if (tm == NULL) return &luaO_nilobject; /* no TM */
- if (ttisfunction(tm)) {
- callTMres(L, tm, t, key);
- return L->top;
- }
- else return luaV_gettable(L, tm, key, loop);
-}
-
-static const TObject *luaV_getnotable (lua_State *L, const TObject *t,
- TObject *key, int loop) {
- const TObject *tm = luaT_gettmbyobj(L, t, TM_INDEX);
- if (ttisnil(tm))
- luaG_typeerror(L, t, "index");
- if (ttisfunction(tm)) {
- callTMres(L, tm, t, key);
- return L->top;
- }
- else return luaV_gettable(L, tm, key, loop);
-}
-
-
-/*
-** Function to index a table.
-** Receives the table at `t' and the key at `key'.
-** leaves the result at `res'.
-*/
-const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key,
- int loop) {
- if (loop > MAXTAGLOOP)
- luaG_runerror(L, "loop in gettable");
- if (ttistable(t)) { /* `t' is a table? */
- Table *h = hvalue(t);
- const TObject *v = luaH_get(h, key); /* do a primitive get */
- if (!ttisnil(v)) return v;
- else return luaV_index(L, t, key, loop+1);
- }
- else return luaV_getnotable(L, t, key, loop+1);
-}
-
-
-/*
-** Receives table at `t', key at `key' and value at `val'.
-*/
-void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val) {
- const TObject *tm;
- int loop = 0;
- do {
- if (ttistable(t)) { /* `t' is a table? */
- Table *h = hvalue(t);
- TObject *oldval = luaH_set(L, h, key); /* do a primitive set */
- if (!ttisnil(oldval) || /* result is no nil? */
- (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
- setobj2t(oldval, val); /* write barrier */
- return;
- }
- /* else will try the tag method */
- }
- else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
- luaG_typeerror(L, t, "index");
- if (ttisfunction(tm)) {
- callTM(L, tm, t, key, val);
- return;
- }
- t = tm; /* else repeat with `tm' */
- } while (++loop <= MAXTAGLOOP);
- luaG_runerror(L, "loop in settable");
-}
-
-
-static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
- StkId res, TMS event) {
- ptrdiff_t result = savestack(L, res);
- const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
- if (ttisnil(tm))
- tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
- if (!ttisfunction(tm)) return 0;
- callTMres(L, tm, p1, p2);
- res = restorestack(L, result); /* previous call may change stack */
- setobjs2s(res, L->top);
- return 1;
-}
-
-
-static const TObject *get_compTM (lua_State *L, Table *mt1, Table *mt2,
- TMS event) {
- const TObject *tm1 = fasttm(L, mt1, event);
- const TObject *tm2;
- if (tm1 == NULL) return NULL; /* no metamethod */
- if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
- tm2 = fasttm(L, mt2, event);
- if (tm2 == NULL) return NULL; /* no metamethod */
- if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
- return tm1;
- return NULL;
-}
-
-
-static int call_orderTM (lua_State *L, const TObject *p1, const TObject *p2,
- TMS event) {
- const TObject *tm1 = luaT_gettmbyobj(L, p1, event);
- const TObject *tm2;
- if (ttisnil(tm1)) return -1; /* no metamethod? */
- tm2 = luaT_gettmbyobj(L, p2, event);
- if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
- return -1;
- callTMres(L, tm1, p1, p2);
- return !l_isfalse(L->top);
-}
-
-
-static int luaV_strcmp (const TString *ls, const TString *rs) {
- const char *l = getstr(ls);
- size_t ll = ls->tsv.len;
- const char *r = getstr(rs);
- size_t lr = rs->tsv.len;
- for (;;) {
- int temp = strcoll(l, r);
- if (temp != 0) return temp;
- else { /* strings are equal up to a `\0' */
- size_t len = strlen(l); /* index of first `\0' in both strings */
- if (len == lr) /* r is finished? */
- return (len == ll) ? 0 : 1;
- else if (len == ll) /* l is finished? */
- return -1; /* l is smaller than r (because r is not finished) */
- /* both strings longer than `len'; go on comparing (after the `\0') */
- len++;
- l += len; ll -= len; r += len; lr -= len;
- }
- }
-}
-
-
-int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) {
- int res;
- if (ttype(l) != ttype(r))
- return luaG_ordererror(L, l, r);
- else if (ttisnumber(l))
- return nvalue(l) < nvalue(r);
- else if (ttisstring(l))
- return luaV_strcmp(tsvalue(l), tsvalue(r)) < 0;
- else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
- return res;
- return luaG_ordererror(L, l, r);
-}
-
-
-static int luaV_lessequal (lua_State *L, const TObject *l, const TObject *r) {
- int res;
- if (ttype(l) != ttype(r))
- return luaG_ordererror(L, l, r);
- else if (ttisnumber(l))
- return nvalue(l) <= nvalue(r);
- else if (ttisstring(l))
- return luaV_strcmp(tsvalue(l), tsvalue(r)) <= 0;
- else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
- return res;
- else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
- return !res;
- return luaG_ordererror(L, l, r);
-}
-
-
-int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2) {
- const TObject *tm;
- lua_assert(ttype(t1) == ttype(t2));
- switch (ttype(t1)) {
- case LUA_TNIL: return 1;
- case LUA_TNUMBER: return nvalue(t1) == nvalue(t2);
- case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
- case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
- case LUA_TUSERDATA: {
- if (uvalue(t1) == uvalue(t2)) return 1;
- tm = get_compTM(L, uvalue(t1)->uv.metatable, uvalue(t2)->uv.metatable,
- TM_EQ);
- break; /* will try TM */
- }
- case LUA_TTABLE: {
- if (hvalue(t1) == hvalue(t2)) return 1;
- tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
- break; /* will try TM */
- }
- default: return gcvalue(t1) == gcvalue(t2);
- }
- if (tm == NULL) return 0; /* no TM? */
- callTMres(L, tm, t1, t2); /* call TM */
- return !l_isfalse(L->top);
-}
-
-
-void luaV_concat (lua_State *L, int total, int last) {
- do {
- StkId top = L->base + last + 1;
- int n = 2; /* number of elements handled in this pass (at least 2) */
- if (!tostring(L, top-2) || !tostring(L, top-1)) {
- if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
- luaG_concaterror(L, top-2, top-1);
- } else if (tsvalue(top-1)->tsv.len > 0) { /* if len=0, do nothing */
- /* at least two string values; get as many as possible */
- lu_mem tl = cast(lu_mem, tsvalue(top-1)->tsv.len) +
- cast(lu_mem, tsvalue(top-2)->tsv.len);
- char *buffer;
- int i;
- while (n < total && tostring(L, top-n-1)) { /* collect total length */
- tl += tsvalue(top-n-1)->tsv.len;
- n++;
- }
- if (tl > MAX_SIZET) luaG_runerror(L, "string size overflow");
- buffer = luaZ_openspace(L, &G(L)->buff, tl);
- tl = 0;
- for (i=n; i>0; i--) { /* concat all strings */
- size_t l = tsvalue(top-i)->tsv.len;
- memcpy(buffer+tl, svalue(top-i), l);
- tl += l;
- }
- setsvalue2s(top-n, luaS_newlstr(L, buffer, tl));
- }
- total -= n-1; /* got `n' strings to create 1 new */
- last -= n-1;
- } while (total > 1); /* repeat until only 1 result left */
-}
-
-
-static void Arith (lua_State *L, StkId ra,
- const TObject *rb, const TObject *rc, TMS op) {
- TObject tempb, tempc;
- const TObject *b, *c;
- if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
- (c = luaV_tonumber(rc, &tempc)) != NULL) {
- switch (op) {
- case TM_ADD: setnvalue(ra, nvalue(b) + nvalue(c)); break;
- case TM_SUB: setnvalue(ra, nvalue(b) - nvalue(c)); break;
- case TM_MUL: setnvalue(ra, nvalue(b) * nvalue(c)); break;
- case TM_DIV: setnvalue(ra, nvalue(b) / nvalue(c)); break;
- case TM_POW: {
- const TObject *f = luaH_getstr(hvalue(gt(L)), G(L)->tmname[TM_POW]);
- ptrdiff_t res = savestack(L, ra);
- if (!ttisfunction(f))
- luaG_runerror(L, "`__pow' (`^' operator) is not a function");
- callTMres(L, f, b, c);
- ra = restorestack(L, res); /* previous call may change stack */
- setobjs2s(ra, L->top);
- break;
- }
- default: lua_assert(0); break;
- }
- }
- else if (!call_binTM(L, rb, rc, ra, op))
- luaG_aritherror(L, rb, rc);
-}
-
-
-
-/*
-** some macros for common tasks in `luaV_execute'
-*/
-
-#define runtime_check(L, c) { if (!(c)) return 0; }
-
-#define RA(i) (base+GETARG_A(i))
-/* to be used after possible stack reallocation */
-#define XRA(i) (L->base+GETARG_A(i))
-#define RB(i) (base+GETARG_B(i))
-#define RKB(i) ((GETARG_B(i) < MAXSTACK) ? RB(i) : k+GETARG_B(i)-MAXSTACK)
-#define RC(i) (base+GETARG_C(i))
-#define RKC(i) ((GETARG_C(i) < MAXSTACK) ? RC(i) : k+GETARG_C(i)-MAXSTACK)
-#define KBx(i) (k+GETARG_Bx(i))
-
-
-#define dojump(pc, i) ((pc) += (i))
-
-
-StkId luaV_execute (lua_State *L) {
- LClosure *cl;
- TObject *k;
- const Instruction *pc;
- callentry: /* entry point when calling new functions */
- L->ci->u.l.pc = &pc;
- if (L->hookmask & LUA_MASKCALL)
- luaD_callhook(L, LUA_HOOKCALL, -1);
- retentry: /* entry point when returning to old functions */
- lua_assert(L->ci->state == CI_SAVEDPC ||
- L->ci->state == (CI_SAVEDPC | CI_CALLING));
- L->ci->state = CI_HASFRAME; /* activate frame */
- pc = L->ci->u.l.savedpc;
- cl = &clvalue(L->base - 1)->l;
- k = cl->p->k;
- /* main loop of interpreter */
- for (;;) {
- const Instruction i = *pc++;
- StkId base, ra;
- if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
- (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
- traceexec(L);
- if (L->ci->state & CI_YIELD) { /* did hook yield? */
- L->ci->u.l.savedpc = pc - 1;
- L->ci->state = CI_YIELD | CI_SAVEDPC;
- return NULL;
- }
- if (L->ci->state & CI_BREAK) { /* did hook break? */
- luaG_runerror(L, "breaking");
- L->ci->state &= ~CI_BREAK;
- }
- }
- /* warning!! several calls may realloc the stack and invalidate `ra' */
- base = L->base;
- ra = RA(i);
- lua_assert(L->ci->state & CI_HASFRAME);
- lua_assert(base == L->ci->base);
- lua_assert(L->top <= L->stack + L->stacksize && L->top >= base);
- lua_assert(L->top == L->ci->top ||
- GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
- GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO);
- switch (GET_OPCODE(i)) {
- case OP_MOVE: {
- setobjs2s(ra, RB(i));
- break;
- }
- case OP_LOADK: {
- setobj2s(ra, KBx(i));
- break;
- }
- case OP_LOADBOOL: {
- setbvalue(ra, GETARG_B(i));
- if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
- break;
- }
- case OP_LOADNIL: {
- TObject *rb = RB(i);
- do {
- setnilvalue(rb--);
- } while (rb >= ra);
- break;
- }
- case OP_GETUPVAL: {
- int b = GETARG_B(i);
- setobj2s(ra, cl->upvals[b]->v);
- break;
- }
- case OP_GETGLOBAL: {
- TObject *rb = KBx(i);
- const TObject *v;
- lua_assert(ttisstring(rb) && ttistable(&cl->g));
- v = luaH_getstr(hvalue(&cl->g), tsvalue(rb));
- if (!ttisnil(v)) { setobj2s(ra, v); }
- else
- setobj2s(XRA(i), luaV_index(L, &cl->g, rb, 0));
- break;
- }
- case OP_GETTABLE: {
- StkId rb = RB(i);
- TObject *rc = RKC(i);
- if (ttistable(rb)) {
- const TObject *v = luaH_get(hvalue(rb), rc);
- if (!ttisnil(v)) { setobj2s(ra, v); }
- else
- setobj2s(XRA(i), luaV_index(L, rb, rc, 0));
- }
- else
- setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0));
- break;
- }
- case OP_SETGLOBAL: {
- lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g));
- luaV_settable(L, &cl->g, KBx(i), ra);
- break;
- }
- case OP_SETUPVAL: {
- int b = GETARG_B(i);
- setobj(cl->upvals[b]->v, ra); /* write barrier */
- break;
- }
- case OP_SETTABLE: {
- luaV_settable(L, ra, RKB(i), RKC(i));
- break;
- }
- case OP_NEWTABLE: {
- int b = GETARG_B(i);
- b = fb2int(b);
- sethvalue(ra, luaH_new(L, b, GETARG_C(i)));
- luaC_checkGC(L);
- break;
- }
- case OP_SELF: {
- StkId rb = RB(i);
- TObject *rc = RKC(i);
- runtime_check(L, ttisstring(rc));
- setobjs2s(ra+1, rb);
- if (ttistable(rb)) {
- const TObject *v = luaH_getstr(hvalue(rb), tsvalue(rc));
- if (!ttisnil(v)) { setobj2s(ra, v); }
- else
- setobj2s(XRA(i), luaV_index(L, rb, rc, 0));
- }
- else
- setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0));
- break;
- }
- case OP_ADD: {
- TObject *rb = RKB(i);
- TObject *rc = RKC(i);
- if (ttisnumber(rb) && ttisnumber(rc)) {
- setnvalue(ra, nvalue(rb) + nvalue(rc));
- }
- else
- Arith(L, ra, rb, rc, TM_ADD);
- break;
- }
- case OP_SUB: {
- TObject *rb = RKB(i);
- TObject *rc = RKC(i);
- if (ttisnumber(rb) && ttisnumber(rc)) {
- setnvalue(ra, nvalue(rb) - nvalue(rc));
- }
- else
- Arith(L, ra, rb, rc, TM_SUB);
- break;
- }
- case OP_MUL: {
- TObject *rb = RKB(i);
- TObject *rc = RKC(i);
- if (ttisnumber(rb) && ttisnumber(rc)) {
- setnvalue(ra, nvalue(rb) * nvalue(rc));
- }
- else
- Arith(L, ra, rb, rc, TM_MUL);
- break;
- }
- case OP_DIV: {
- TObject *rb = RKB(i);
- TObject *rc = RKC(i);
- if (ttisnumber(rb) && ttisnumber(rc)) {
- setnvalue(ra, nvalue(rb) / nvalue(rc));
- }
- else
- Arith(L, ra, rb, rc, TM_DIV);
- break;
- }
- case OP_POW: {
- Arith(L, ra, RKB(i), RKC(i), TM_POW);
- break;
- }
- case OP_UNM: {
- const TObject *rb = RB(i);
- TObject temp;
- if (tonumber(rb, &temp)) {
- setnvalue(ra, -nvalue(rb));
- }
- else {
- setnilvalue(&temp);
- if (!call_binTM(L, RB(i), &temp, ra, TM_UNM))
- luaG_aritherror(L, RB(i), &temp);
- }
- break;
- }
- case OP_NOT: {
- int res = l_isfalse(RB(i)); /* next assignment may change this value */
- setbvalue(ra, res);
- break;
- }
- case OP_CONCAT: {
- int b = GETARG_B(i);
- int c = GETARG_C(i);
- luaV_concat(L, c-b+1, c); /* may change `base' (and `ra') */
- base = L->base;
- setobjs2s(RA(i), base+b);
- luaC_checkGC(L);
- break;
- }
- case OP_JMP: {
- dojump(pc, GETARG_sBx(i));
- break;
- }
- case OP_EQ: {
- if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
- else dojump(pc, GETARG_sBx(*pc) + 1);
- break;
- }
- case OP_LT: {
- if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
- else dojump(pc, GETARG_sBx(*pc) + 1);
- break;
- }
- case OP_LE: {
- if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
- else dojump(pc, GETARG_sBx(*pc) + 1);
- break;
- }
- case OP_TEST: {
- TObject *rb = RB(i);
- if (l_isfalse(rb) == GETARG_C(i)) pc++;
- else {
- setobjs2s(ra, rb);
- dojump(pc, GETARG_sBx(*pc) + 1);
- }
- break;
- }
- case OP_CALL:
- case OP_TAILCALL: {
- StkId firstResult;
- int b = GETARG_B(i);
- int nresults;
- if (b != 0) L->top = ra+b; /* else previous instruction set top */
- nresults = GETARG_C(i) - 1;
- firstResult = luaD_precall(L, ra);
- if (firstResult) {
- if (firstResult > L->top) { /* yield? */
- lua_assert(L->ci->state == (CI_C | CI_YIELD));
- (L->ci - 1)->u.l.savedpc = pc;
- (L->ci - 1)->state = CI_SAVEDPC;
- return NULL;
- }
- /* it was a C function (`precall' called it); adjust results */
- luaD_poscall(L, nresults, firstResult);
- if (nresults >= 0) L->top = L->ci->top;
- }
- else { /* it is a Lua function */
- if (GET_OPCODE(i) == OP_CALL) { /* regular call? */
- (L->ci-1)->u.l.savedpc = pc; /* save `pc' to return later */
- (L->ci-1)->state = (CI_SAVEDPC | CI_CALLING);
- }
- else { /* tail call: put new frame in place of previous one */
- int aux;
- base = (L->ci - 1)->base; /* `luaD_precall' may change the stack */
- ra = RA(i);
- if (L->openupval) luaF_close(L, base);
- for (aux = 0; ra+aux < L->top; aux++) /* move frame down */
- setobjs2s(base+aux-1, ra+aux);
- (L->ci - 1)->top = L->top = base+aux; /* correct top */
- lua_assert(L->ci->state & CI_SAVEDPC);
- (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;
- (L->ci - 1)->u.l.tailcalls++; /* one more call lost */
- (L->ci - 1)->state = CI_SAVEDPC;
- L->ci--; /* remove new frame */
- L->base = L->ci->base;
- }
- goto callentry;
- }
- break;
- }
- case OP_RETURN: {
- CallInfo *ci = L->ci - 1; /* previous function frame */
- int b = GETARG_B(i);
- if (b != 0) L->top = ra+b-1;
- lua_assert(L->ci->state & CI_HASFRAME);
- if (L->openupval) luaF_close(L, base);
- L->ci->state = CI_SAVEDPC; /* deactivate current function */
- L->ci->u.l.savedpc = pc;
- /* previous function was running `here'? */
- if (!(ci->state & CI_CALLING)) {
- lua_assert((ci->state & CI_C) || ci->u.l.pc != &pc);
- return ra; /* no: return */
- }
- else { /* yes: continue its execution */
- int nresults;
- lua_assert(ci->u.l.pc == &pc &&
- ttisfunction(ci->base - 1) &&
- (ci->state & CI_SAVEDPC));
- lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);
- nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1;
- luaD_poscall(L, nresults, ra);
- if (nresults >= 0) L->top = L->ci->top;
- goto retentry;
- }
- }
- case OP_FORLOOP: {
- lua_Number step, idx, limit;
- const TObject *plimit = ra+1;
- const TObject *pstep = ra+2;
- if (!ttisnumber(ra))
- luaG_runerror(L, "`for' initial value must be a number");
- if (!tonumber(plimit, ra+1))
- luaG_runerror(L, "`for' limit must be a number");
- if (!tonumber(pstep, ra+2))
- luaG_runerror(L, "`for' step must be a number");
- step = nvalue(pstep);
- idx = nvalue(ra) + step; /* increment index */
- limit = nvalue(plimit);
- if (step > 0 ? idx <= limit : idx >= limit) {
- dojump(pc, GETARG_sBx(i)); /* jump back */
- chgnvalue(ra, idx); /* update index */
- }
- break;
- }
- case OP_TFORLOOP: {
- int nvar = GETARG_C(i) + 1;
- StkId cb = ra + nvar + 2; /* call base */
- setobjs2s(cb, ra);
- setobjs2s(cb+1, ra+1);
- setobjs2s(cb+2, ra+2);
- L->top = cb+3; /* func. + 2 args (state and index) */
- luaD_call(L, cb, nvar);
- L->top = L->ci->top;
- ra = XRA(i) + 2; /* final position of first result */
- cb = ra + nvar;
- do { /* move results to proper positions */
- nvar--;
- setobjs2s(ra+nvar, cb+nvar);
- } while (nvar > 0);
- if (ttisnil(ra)) /* break loop? */
- pc++; /* skip jump (break loop) */
- else
- dojump(pc, GETARG_sBx(*pc) + 1); /* jump back */
- break;
- }
- case OP_TFORPREP: { /* for compatibility only */
- if (ttistable(ra)) {
- setobjs2s(ra+1, ra);
- setobj2s(ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next")));
- }
- dojump(pc, GETARG_sBx(i));
- break;
- }
- case OP_SETLIST:
- case OP_SETLISTO: {
- int bc;
- int n;
- Table *h;
- runtime_check(L, ttistable(ra));
- h = hvalue(ra);
- bc = GETARG_Bx(i);
- if (GET_OPCODE(i) == OP_SETLIST)
- n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;
- else {
- n = L->top - ra - 1;
- L->top = L->ci->top;
- }
- bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */
- for (; n > 0; n--)
- setobj2t(luaH_setnum(L, h, bc+n), ra+n); /* write barrier */
- break;
- }
- case OP_CLOSE: {
- luaF_close(L, ra);
- break;
- }
- case OP_CLOSURE: {
- Proto *p;
- Closure *ncl;
- int nup, j;
- p = cl->p->p[GETARG_Bx(i)];
- nup = p->nups;
- ncl = luaF_newLclosure(L, nup, &cl->g);
- ncl->l.p = p;
- for (j=0; j<nup; j++, pc++) {
- if (GET_OPCODE(*pc) == OP_GETUPVAL)
- ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
- else {
- lua_assert(GET_OPCODE(*pc) == OP_MOVE);
- ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
- }
- }
- setclvalue(ra, ncl);
- luaC_checkGC(L);
- break;
- }
- }
- }
-}
-
+/*
+** $Id: lvm.c,v 1.5 2004-11-27 21:46:07 pixel Exp $
+** Lua virtual machine
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* needed only when `lua_number2str' uses `sprintf' */
+#include <stdio.h>
+
+#define lvm_c
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+#include "lvm.h"
+
+
+
+/* function to convert a lua_Number to a string */
+#ifndef lua_number2str
+#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
+#endif
+
+
+/* limit for table tag-method chains (to avoid loops) */
+#define MAXTAGLOOP 100
+
+
+const TObject *luaV_tonumber (const TObject *obj, TObject *n) {
+ lua_Number num;
+ if (ttisnumber(obj)) return obj;
+ if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
+ setnvalue(n, num);
+ return n;
+ }
+ else
+ return NULL;
+}
+
+
+int luaV_tostring (lua_State *L, StkId obj) {
+ if (!ttisnumber(obj))
+ return 0;
+ else {
+ char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */
+ lua_number2str(s, nvalue(obj));
+ setsvalue2s(obj, luaS_new(L, s));
+ return 1;
+ }
+}
+
+
+static void traceexec (lua_State *L) {
+ lu_byte mask = L->hookmask;
+ if (mask > LUA_MASKLINE) { /* instruction-hook set? */
+ if (L->hookcount == 0) {
+ resethookcount(L);
+ luaD_callhook(L, LUA_HOOKCOUNT, -1);
+ return;
+ }
+ }
+ if (mask & LUA_MASKLINE) {
+ CallInfo *ci = L->ci;
+ Proto *p = ci_func(ci)->l.p;
+ int newline = getline(p, pcRel(*ci->u.l.pc, p));
+ if (!L->hookinit) {
+ luaG_inithooks(L);
+ return;
+ }
+ lua_assert(ci->state & CI_HASFRAME);
+ if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */
+ ci->u.l.savedpc = *ci->u.l.pc; /* initialize `savedpc' */
+ /* calls linehook when enters a new line or jumps back (loop) */
+ if (*ci->u.l.pc <= ci->u.l.savedpc ||
+ newline != getline(p, pcRel(ci->u.l.savedpc, p))) {
+ luaD_callhook(L, LUA_HOOKLINE, newline);
+ ci = L->ci; /* previous call may reallocate `ci' */
+ }
+ ci->u.l.savedpc = *ci->u.l.pc;
+ }
+}
+
+
+static void callTMres (lua_State *L, const TObject *f,
+ const TObject *p1, const TObject *p2) {
+ setobj2s(L->top, f); /* push function */
+ setobj2s(L->top+1, p1); /* 1st argument */
+ setobj2s(L->top+2, p2); /* 2nd argument */
+ luaD_checkstack(L, 3); /* cannot check before (could invalidate p1, p2) */
+ L->top += 3;
+ luaD_call(L, L->top - 3, 1);
+ L->top--; /* result will be in L->top */
+}
+
+
+
+static void callTM (lua_State *L, const TObject *f,
+ const TObject *p1, const TObject *p2, const TObject *p3) {
+ setobj2s(L->top, f); /* push function */
+ setobj2s(L->top+1, p1); /* 1st argument */
+ setobj2s(L->top+2, p2); /* 2nd argument */
+ setobj2s(L->top+3, p3); /* 3th argument */
+ luaD_checkstack(L, 4); /* cannot check before (could invalidate p1...p3) */
+ L->top += 4;
+ luaD_call(L, L->top - 4, 0);
+}
+
+
+static const TObject *luaV_index (lua_State *L, const TObject *t,
+ TObject *key, int loop) {
+ const TObject *tm = fasttm(L, hvalue(t)->metatable, TM_INDEX);
+ if (tm == NULL) return &luaO_nilobject; /* no TM */
+ if (ttisfunction(tm)) {
+ callTMres(L, tm, t, key);
+ return L->top;
+ }
+ else return luaV_gettable(L, tm, key, loop);
+}
+
+static const TObject *luaV_getnotable (lua_State *L, const TObject *t,
+ TObject *key, int loop) {
+ const TObject *tm = luaT_gettmbyobj(L, t, TM_INDEX);
+ if (ttisnil(tm))
+ luaG_typeerror(L, t, "index");
+ if (ttisfunction(tm)) {
+ callTMres(L, tm, t, key);
+ return L->top;
+ }
+ else return luaV_gettable(L, tm, key, loop);
+}
+
+
+/*
+** Function to index a table.
+** Receives the table at `t' and the key at `key'.
+** leaves the result at `res'.
+*/
+const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key,
+ int loop) {
+ if (loop > MAXTAGLOOP)
+ luaG_runerror(L, "loop in gettable");
+ if (ttistable(t)) { /* `t' is a table? */
+ Table *h = hvalue(t);
+ const TObject *v = luaH_get(h, key); /* do a primitive get */
+ if (!ttisnil(v)) return v;
+ else return luaV_index(L, t, key, loop+1);
+ }
+ else return luaV_getnotable(L, t, key, loop+1);
+}
+
+
+/*
+** Receives table at `t', key at `key' and value at `val'.
+*/
+void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val) {
+ const TObject *tm;
+ int loop = 0;
+ do {
+ if (ttistable(t)) { /* `t' is a table? */
+ Table *h = hvalue(t);
+ TObject *oldval = luaH_set(L, h, key); /* do a primitive set */
+ if (!ttisnil(oldval) || /* result is no nil? */
+ (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
+ setobj2t(oldval, val); /* write barrier */
+ return;
+ }
+ /* else will try the tag method */
+ }
+ else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
+ luaG_typeerror(L, t, "index");
+ if (ttisfunction(tm)) {
+ callTM(L, tm, t, key, val);
+ return;
+ }
+ t = tm; /* else repeat with `tm' */
+ } while (++loop <= MAXTAGLOOP);
+ luaG_runerror(L, "loop in settable");
+}
+
+
+static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
+ StkId res, TMS event) {
+ ptrdiff_t result = savestack(L, res);
+ const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
+ if (ttisnil(tm))
+ tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
+ if (!ttisfunction(tm)) return 0;
+ callTMres(L, tm, p1, p2);
+ res = restorestack(L, result); /* previous call may change stack */
+ setobjs2s(res, L->top);
+ return 1;
+}
+
+
+static const TObject *get_compTM (lua_State *L, Table *mt1, Table *mt2,
+ TMS event) {
+ const TObject *tm1 = fasttm(L, mt1, event);
+ const TObject *tm2;
+ if (tm1 == NULL) return NULL; /* no metamethod */
+ if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
+ tm2 = fasttm(L, mt2, event);
+ if (tm2 == NULL) return NULL; /* no metamethod */
+ if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
+ return tm1;
+ return NULL;
+}
+
+
+static int call_orderTM (lua_State *L, const TObject *p1, const TObject *p2,
+ TMS event) {
+ const TObject *tm1 = luaT_gettmbyobj(L, p1, event);
+ const TObject *tm2;
+ if (ttisnil(tm1)) return -1; /* no metamethod? */
+ tm2 = luaT_gettmbyobj(L, p2, event);
+ if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
+ return -1;
+ callTMres(L, tm1, p1, p2);
+ return !l_isfalse(L->top);
+}
+
+
+static int luaV_strcmp (const TString *ls, const TString *rs) {
+ const char *l = getstr(ls);
+ size_t ll = ls->tsv.len;
+ const char *r = getstr(rs);
+ size_t lr = rs->tsv.len;
+ for (;;) {
+ int temp = strcoll(l, r);
+ if (temp != 0) return temp;
+ else { /* strings are equal up to a `\0' */
+ size_t len = strlen(l); /* index of first `\0' in both strings */
+ if (len == lr) /* r is finished? */
+ return (len == ll) ? 0 : 1;
+ else if (len == ll) /* l is finished? */
+ return -1; /* l is smaller than r (because r is not finished) */
+ /* both strings longer than `len'; go on comparing (after the `\0') */
+ len++;
+ l += len; ll -= len; r += len; lr -= len;
+ }
+ }
+}
+
+
+int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) {
+ int res;
+ if (ttype(l) != ttype(r))
+ return luaG_ordererror(L, l, r);
+ else if (ttisnumber(l))
+ return nvalue(l) < nvalue(r);
+ else if (ttisstring(l))
+ return luaV_strcmp(tsvalue(l), tsvalue(r)) < 0;
+ else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
+ return res;
+ return luaG_ordererror(L, l, r);
+}
+
+
+static int luaV_lessequal (lua_State *L, const TObject *l, const TObject *r) {
+ int res;
+ if (ttype(l) != ttype(r))
+ return luaG_ordererror(L, l, r);
+ else if (ttisnumber(l))
+ return nvalue(l) <= nvalue(r);
+ else if (ttisstring(l))
+ return luaV_strcmp(tsvalue(l), tsvalue(r)) <= 0;
+ else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
+ return res;
+ else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
+ return !res;
+ return luaG_ordererror(L, l, r);
+}
+
+
+int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2) {
+ const TObject *tm;
+ lua_assert(ttype(t1) == ttype(t2));
+ switch (ttype(t1)) {
+ case LUA_TNIL: return 1;
+ case LUA_TNUMBER: return nvalue(t1) == nvalue(t2);
+ case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
+ case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
+ case LUA_TUSERDATA: {
+ if (uvalue(t1) == uvalue(t2)) return 1;
+ tm = get_compTM(L, uvalue(t1)->uv.metatable, uvalue(t2)->uv.metatable,
+ TM_EQ);
+ break; /* will try TM */
+ }
+ case LUA_TTABLE: {
+ if (hvalue(t1) == hvalue(t2)) return 1;
+ tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
+ break; /* will try TM */
+ }
+ default: return gcvalue(t1) == gcvalue(t2);
+ }
+ if (tm == NULL) return 0; /* no TM? */
+ callTMres(L, tm, t1, t2); /* call TM */
+ return !l_isfalse(L->top);
+}
+
+
+void luaV_concat (lua_State *L, int total, int last) {
+ do {
+ StkId top = L->base + last + 1;
+ int n = 2; /* number of elements handled in this pass (at least 2) */
+ if (!tostring(L, top-2) || !tostring(L, top-1)) {
+ if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
+ luaG_concaterror(L, top-2, top-1);
+ } else if (tsvalue(top-1)->tsv.len > 0) { /* if len=0, do nothing */
+ /* at least two string values; get as many as possible */
+ lu_mem tl = cast(lu_mem, tsvalue(top-1)->tsv.len) +
+ cast(lu_mem, tsvalue(top-2)->tsv.len);
+ char *buffer;
+ int i;
+ while (n < total && tostring(L, top-n-1)) { /* collect total length */
+ tl += tsvalue(top-n-1)->tsv.len;
+ n++;
+ }
+ if (tl > MAX_SIZET) luaG_runerror(L, "string size overflow");
+ buffer = luaZ_openspace(L, &G(L)->buff, tl);
+ tl = 0;
+ for (i=n; i>0; i--) { /* concat all strings */
+ size_t l = tsvalue(top-i)->tsv.len;
+ memcpy(buffer+tl, svalue(top-i), l);
+ tl += l;
+ }
+ setsvalue2s(top-n, luaS_newlstr(L, buffer, tl));
+ }
+ total -= n-1; /* got `n' strings to create 1 new */
+ last -= n-1;
+ } while (total > 1); /* repeat until only 1 result left */
+}
+
+
+static void Arith (lua_State *L, StkId ra,
+ const TObject *rb, const TObject *rc, TMS op) {
+ TObject tempb, tempc;
+ const TObject *b, *c;
+ if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
+ (c = luaV_tonumber(rc, &tempc)) != NULL) {
+ switch (op) {
+ case TM_ADD: setnvalue(ra, nvalue(b) + nvalue(c)); break;
+ case TM_SUB: setnvalue(ra, nvalue(b) - nvalue(c)); break;
+ case TM_MUL: setnvalue(ra, nvalue(b) * nvalue(c)); break;
+ case TM_DIV: setnvalue(ra, nvalue(b) / nvalue(c)); break;
+ case TM_POW: {
+ const TObject *f = luaH_getstr(hvalue(gt(L)), G(L)->tmname[TM_POW]);
+ ptrdiff_t res = savestack(L, ra);
+ if (!ttisfunction(f))
+ luaG_runerror(L, "`__pow' (`^' operator) is not a function");
+ callTMres(L, f, b, c);
+ ra = restorestack(L, res); /* previous call may change stack */
+ setobjs2s(ra, L->top);
+ break;
+ }
+ default: lua_assert(0); break;
+ }
+ }
+ else if (!call_binTM(L, rb, rc, ra, op))
+ luaG_aritherror(L, rb, rc);
+}
+
+
+
+/*
+** some macros for common tasks in `luaV_execute'
+*/
+
+#define runtime_check(L, c) { if (!(c)) return 0; }
+
+#define RA(i) (base+GETARG_A(i))
+/* to be used after possible stack reallocation */
+#define XRA(i) (L->base+GETARG_A(i))
+#define RB(i) (base+GETARG_B(i))
+#define RKB(i) ((GETARG_B(i) < MAXSTACK) ? RB(i) : k+GETARG_B(i)-MAXSTACK)
+#define RC(i) (base+GETARG_C(i))
+#define RKC(i) ((GETARG_C(i) < MAXSTACK) ? RC(i) : k+GETARG_C(i)-MAXSTACK)
+#define KBx(i) (k+GETARG_Bx(i))
+
+
+#define dojump(pc, i) ((pc) += (i))
+
+
+StkId luaV_execute (lua_State *L) {
+ LClosure *cl;
+ TObject *k;
+ const Instruction *pc;
+ callentry: /* entry point when calling new functions */
+ L->ci->u.l.pc = &pc;
+ if (L->hookmask & LUA_MASKCALL)
+ luaD_callhook(L, LUA_HOOKCALL, -1);
+ retentry: /* entry point when returning to old functions */
+ lua_assert(L->ci->state == CI_SAVEDPC ||
+ L->ci->state == (CI_SAVEDPC | CI_CALLING));
+ L->ci->state = CI_HASFRAME; /* activate frame */
+ pc = L->ci->u.l.savedpc;
+ cl = &clvalue(L->base - 1)->l;
+ k = cl->p->k;
+ /* main loop of interpreter */
+ for (;;) {
+ const Instruction i = *pc++;
+ StkId base, ra;
+ if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
+ (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
+ traceexec(L);
+ if (L->ci->state & CI_YIELD) { /* did hook yield? */
+ L->ci->u.l.savedpc = pc - 1;
+ L->ci->state = CI_YIELD | CI_SAVEDPC;
+ return NULL;
+ }
+ if (L->ci->state & CI_BREAK) { /* did hook break? */
+ luaG_runerror(L, "breaking");
+ L->ci->state &= ~CI_BREAK;
+ }
+ }
+ /* warning!! several calls may realloc the stack and invalidate `ra' */
+ base = L->base;
+ ra = RA(i);
+ lua_assert(L->ci->state & CI_HASFRAME);
+ lua_assert(base == L->ci->base);
+ lua_assert(L->top <= L->stack + L->stacksize && L->top >= base);
+ lua_assert(L->top == L->ci->top ||
+ GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
+ GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO);
+ switch (GET_OPCODE(i)) {
+ case OP_MOVE: {
+ setobjs2s(ra, RB(i));
+ break;
+ }
+ case OP_LOADK: {
+ setobj2s(ra, KBx(i));
+ break;
+ }
+ case OP_LOADBOOL: {
+ setbvalue(ra, GETARG_B(i));
+ if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
+ break;
+ }
+ case OP_LOADNIL: {
+ TObject *rb = RB(i);
+ do {
+ setnilvalue(rb--);
+ } while (rb >= ra);
+ break;
+ }
+ case OP_GETUPVAL: {
+ int b = GETARG_B(i);
+ setobj2s(ra, cl->upvals[b]->v);
+ break;
+ }
+ case OP_GETGLOBAL: {
+ TObject *rb = KBx(i);
+ const TObject *v;
+ lua_assert(ttisstring(rb) && ttistable(&cl->g));
+ v = luaH_getstr(hvalue(&cl->g), tsvalue(rb));
+ if (!ttisnil(v)) { setobj2s(ra, v); }
+ else
+ setobj2s(XRA(i), luaV_index(L, &cl->g, rb, 0));
+ break;
+ }
+ case OP_GETTABLE: {
+ StkId rb = RB(i);
+ TObject *rc = RKC(i);
+ if (ttistable(rb)) {
+ const TObject *v = luaH_get(hvalue(rb), rc);
+ if (!ttisnil(v)) { setobj2s(ra, v); }
+ else
+ setobj2s(XRA(i), luaV_index(L, rb, rc, 0));
+ }
+ else
+ setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0));
+ break;
+ }
+ case OP_SETGLOBAL: {
+ lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g));
+ luaV_settable(L, &cl->g, KBx(i), ra);
+ break;
+ }
+ case OP_SETUPVAL: {
+ int b = GETARG_B(i);
+ setobj(cl->upvals[b]->v, ra); /* write barrier */
+ break;
+ }
+ case OP_SETTABLE: {
+ luaV_settable(L, ra, RKB(i), RKC(i));
+ break;
+ }
+ case OP_NEWTABLE: {
+ int b = GETARG_B(i);
+ b = fb2int(b);
+ sethvalue(ra, luaH_new(L, b, GETARG_C(i)));
+ luaC_checkGC(L);
+ break;
+ }
+ case OP_SELF: {
+ StkId rb = RB(i);
+ TObject *rc = RKC(i);
+ runtime_check(L, ttisstring(rc));
+ setobjs2s(ra+1, rb);
+ if (ttistable(rb)) {
+ const TObject *v = luaH_getstr(hvalue(rb), tsvalue(rc));
+ if (!ttisnil(v)) { setobj2s(ra, v); }
+ else
+ setobj2s(XRA(i), luaV_index(L, rb, rc, 0));
+ }
+ else
+ setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0));
+ break;
+ }
+ case OP_ADD: {
+ TObject *rb = RKB(i);
+ TObject *rc = RKC(i);
+ if (ttisnumber(rb) && ttisnumber(rc)) {
+ setnvalue(ra, nvalue(rb) + nvalue(rc));
+ }
+ else
+ Arith(L, ra, rb, rc, TM_ADD);
+ break;
+ }
+ case OP_SUB: {
+ TObject *rb = RKB(i);
+ TObject *rc = RKC(i);
+ if (ttisnumber(rb) && ttisnumber(rc)) {
+ setnvalue(ra, nvalue(rb) - nvalue(rc));
+ }
+ else
+ Arith(L, ra, rb, rc, TM_SUB);
+ break;
+ }
+ case OP_MUL: {
+ TObject *rb = RKB(i);
+ TObject *rc = RKC(i);
+ if (ttisnumber(rb) && ttisnumber(rc)) {
+ setnvalue(ra, nvalue(rb) * nvalue(rc));
+ }
+ else
+ Arith(L, ra, rb, rc, TM_MUL);
+ break;
+ }
+ case OP_DIV: {
+ TObject *rb = RKB(i);
+ TObject *rc = RKC(i);
+ if (ttisnumber(rb) && ttisnumber(rc)) {
+ setnvalue(ra, nvalue(rb) / nvalue(rc));
+ }
+ else
+ Arith(L, ra, rb, rc, TM_DIV);
+ break;
+ }
+ case OP_POW: {
+ Arith(L, ra, RKB(i), RKC(i), TM_POW);
+ break;
+ }
+ case OP_UNM: {
+ const TObject *rb = RB(i);
+ TObject temp;
+ if (tonumber(rb, &temp)) {
+ setnvalue(ra, -nvalue(rb));
+ }
+ else {
+ setnilvalue(&temp);
+ if (!call_binTM(L, RB(i), &temp, ra, TM_UNM))
+ luaG_aritherror(L, RB(i), &temp);
+ }
+ break;
+ }
+ case OP_NOT: {
+ int res = l_isfalse(RB(i)); /* next assignment may change this value */
+ setbvalue(ra, res);
+ break;
+ }
+ case OP_CONCAT: {
+ int b = GETARG_B(i);
+ int c = GETARG_C(i);
+ luaV_concat(L, c-b+1, c); /* may change `base' (and `ra') */
+ base = L->base;
+ setobjs2s(RA(i), base+b);
+ luaC_checkGC(L);
+ break;
+ }
+ case OP_JMP: {
+ dojump(pc, GETARG_sBx(i));
+ break;
+ }
+ case OP_EQ: {
+ if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
+ else dojump(pc, GETARG_sBx(*pc) + 1);
+ break;
+ }
+ case OP_LT: {
+ if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
+ else dojump(pc, GETARG_sBx(*pc) + 1);
+ break;
+ }
+ case OP_LE: {
+ if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
+ else dojump(pc, GETARG_sBx(*pc) + 1);
+ break;
+ }
+ case OP_TEST: {
+ TObject *rb = RB(i);
+ if (l_isfalse(rb) == GETARG_C(i)) pc++;
+ else {
+ setobjs2s(ra, rb);
+ dojump(pc, GETARG_sBx(*pc) + 1);
+ }
+ break;
+ }
+ case OP_CALL:
+ case OP_TAILCALL: {
+ StkId firstResult;
+ int b = GETARG_B(i);
+ int nresults;
+ if (b != 0) L->top = ra+b; /* else previous instruction set top */
+ nresults = GETARG_C(i) - 1;
+ firstResult = luaD_precall(L, ra);
+ if (firstResult) {
+ if (firstResult > L->top) { /* yield? */
+ lua_assert(L->ci->state == (CI_C | CI_YIELD));
+ (L->ci - 1)->u.l.savedpc = pc;
+ (L->ci - 1)->state = CI_SAVEDPC;
+ return NULL;
+ }
+ /* it was a C function (`precall' called it); adjust results */
+ luaD_poscall(L, nresults, firstResult);
+ if (nresults >= 0) L->top = L->ci->top;
+ }
+ else { /* it is a Lua function */
+ if (GET_OPCODE(i) == OP_CALL) { /* regular call? */
+ (L->ci-1)->u.l.savedpc = pc; /* save `pc' to return later */
+ (L->ci-1)->state = (CI_SAVEDPC | CI_CALLING);
+ }
+ else { /* tail call: put new frame in place of previous one */
+ int aux;
+ base = (L->ci - 1)->base; /* `luaD_precall' may change the stack */
+ ra = RA(i);
+ if (L->openupval) luaF_close(L, base);
+ for (aux = 0; ra+aux < L->top; aux++) /* move frame down */
+ setobjs2s(base+aux-1, ra+aux);
+ (L->ci - 1)->top = L->top = base+aux; /* correct top */
+ lua_assert(L->ci->state & CI_SAVEDPC);
+ (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;
+ (L->ci - 1)->u.l.tailcalls++; /* one more call lost */
+ (L->ci - 1)->state = CI_SAVEDPC;
+ L->ci--; /* remove new frame */
+ L->base = L->ci->base;
+ }
+ goto callentry;
+ }
+ break;
+ }
+ case OP_RETURN: {
+ CallInfo *ci = L->ci - 1; /* previous function frame */
+ int b = GETARG_B(i);
+ if (b != 0) L->top = ra+b-1;
+ lua_assert(L->ci->state & CI_HASFRAME);
+ if (L->openupval) luaF_close(L, base);
+ L->ci->state = CI_SAVEDPC; /* deactivate current function */
+ L->ci->u.l.savedpc = pc;
+ /* previous function was running `here'? */
+ if (!(ci->state & CI_CALLING)) {
+ lua_assert((ci->state & CI_C) || ci->u.l.pc != &pc);
+ return ra; /* no: return */
+ }
+ else { /* yes: continue its execution */
+ int nresults;
+ lua_assert(ci->u.l.pc == &pc &&
+ ttisfunction(ci->base - 1) &&
+ (ci->state & CI_SAVEDPC));
+ lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);
+ nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1;
+ luaD_poscall(L, nresults, ra);
+ if (nresults >= 0) L->top = L->ci->top;
+ goto retentry;
+ }
+ }
+ case OP_FORLOOP: {
+ lua_Number step, idx, limit;
+ const TObject *plimit = ra+1;
+ const TObject *pstep = ra+2;
+ if (!ttisnumber(ra))
+ luaG_runerror(L, "`for' initial value must be a number");
+ if (!tonumber(plimit, ra+1))
+ luaG_runerror(L, "`for' limit must be a number");
+ if (!tonumber(pstep, ra+2))
+ luaG_runerror(L, "`for' step must be a number");
+ step = nvalue(pstep);
+ idx = nvalue(ra) + step; /* increment index */
+ limit = nvalue(plimit);
+ if (step > 0 ? idx <= limit : idx >= limit) {
+ dojump(pc, GETARG_sBx(i)); /* jump back */
+ chgnvalue(ra, idx); /* update index */
+ }
+ break;
+ }
+ case OP_TFORLOOP: {
+ int nvar = GETARG_C(i) + 1;
+ StkId cb = ra + nvar + 2; /* call base */
+ setobjs2s(cb, ra);
+ setobjs2s(cb+1, ra+1);
+ setobjs2s(cb+2, ra+2);
+ L->top = cb+3; /* func. + 2 args (state and index) */
+ luaD_call(L, cb, nvar);
+ L->top = L->ci->top;
+ ra = XRA(i) + 2; /* final position of first result */
+ cb = ra + nvar;
+ do { /* move results to proper positions */
+ nvar--;
+ setobjs2s(ra+nvar, cb+nvar);
+ } while (nvar > 0);
+ if (ttisnil(ra)) /* break loop? */
+ pc++; /* skip jump (break loop) */
+ else
+ dojump(pc, GETARG_sBx(*pc) + 1); /* jump back */
+ break;
+ }
+ case OP_TFORPREP: { /* for compatibility only */
+ if (ttistable(ra)) {
+ setobjs2s(ra+1, ra);
+ setobj2s(ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next")));
+ }
+ dojump(pc, GETARG_sBx(i));
+ break;
+ }
+ case OP_SETLIST:
+ case OP_SETLISTO: {
+ int bc;
+ int n;
+ Table *h;
+ runtime_check(L, ttistable(ra));
+ h = hvalue(ra);
+ bc = GETARG_Bx(i);
+ if (GET_OPCODE(i) == OP_SETLIST)
+ n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;
+ else {
+ n = L->top - ra - 1;
+ L->top = L->ci->top;
+ }
+ bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */
+ for (; n > 0; n--)
+ setobj2t(luaH_setnum(L, h, bc+n), ra+n); /* write barrier */
+ break;
+ }
+ case OP_CLOSE: {
+ luaF_close(L, ra);
+ break;
+ }
+ case OP_CLOSURE: {
+ Proto *p;
+ Closure *ncl;
+ int nup, j;
+ p = cl->p->p[GETARG_Bx(i)];
+ nup = p->nups;
+ ncl = luaF_newLclosure(L, nup, &cl->g);
+ ncl->l.p = p;
+ for (j=0; j<nup; j++, pc++) {
+ if (GET_OPCODE(*pc) == OP_GETUPVAL)
+ ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
+ else {
+ lua_assert(GET_OPCODE(*pc) == OP_MOVE);
+ ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
+ }
+ }
+ setclvalue(ra, ncl);
+ luaC_checkGC(L);
+ break;
+ }
+ }
+ }
+}
+
diff --git a/lib/lua/src/lzio.c b/lib/lua/src/lzio.c
index e3aefa0..277a656 100644
--- a/lib/lua/src/lzio.c
+++ b/lib/lua/src/lzio.c
@@ -1,81 +1,81 @@
-/*
-** $Id: lzio.c,v 1.3 2004-11-27 21:35:20 pixel Exp $
-** a generic input stream interface
-** See Copyright Notice in lua.h
-*/
-
-
-#include <string.h>
-
-#define lzio_c
-
-#include "lua.h"
-
-#include "llimits.h"
-#include "lmem.h"
-#include "lzio.h"
-
-
-int luaZ_fill (ZIO *z) {
- size_t size;
- const char *buff = z->reader(NULL, z->data, &size);
- if (buff == NULL || size == 0) return EOZ;
- z->n = size - 1;
- z->p = buff;
- return char2int(*(z->p++));
-}
-
-
-int luaZ_lookahead (ZIO *z) {
- if (z->n == 0) {
- int c = luaZ_fill(z);
- if (c == EOZ) return c;
- z->n++;
- z->p--;
- }
- return char2int(*z->p);
-}
-
-
-void luaZ_init (ZIO *z, lua_Chunkreader reader, void *data, const char *name) {
- z->reader = reader;
- z->data = data;
- z->name = name;
- z->n = 0;
- z->p = NULL;
-}
-
-
-/* --------------------------------------------------------------- read --- */
-size_t luaZ_read (ZIO *z, void *b, size_t n) {
- while (n) {
- size_t m;
- if (z->n == 0) {
- if (luaZ_fill(z) == EOZ)
- return n; /* return number of missing bytes */
- else {
- ++z->n; /* filbuf removed first byte; put back it */
- --z->p;
- }
- }
- m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
- memcpy(b, z->p, m);
- z->n -= m;
- z->p += m;
- b = (char *)b + m;
- n -= m;
- }
- return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
- if (n > buff->buffsize) {
- if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
- luaM_reallocvector(L, buff->buffer, buff->buffsize, n, char);
- buff->buffsize = n;
- }
- return buff->buffer;
-}
-
-
+/*
+** $Id: lzio.c,v 1.4 2004-11-27 21:46:07 pixel Exp $
+** a generic input stream interface
+** See Copyright Notice in lua.h
+*/
+
+
+#include <string.h>
+
+#define lzio_c
+
+#include "lua.h"
+
+#include "llimits.h"
+#include "lmem.h"
+#include "lzio.h"
+
+
+int luaZ_fill (ZIO *z) {
+ size_t size;
+ const char *buff = z->reader(NULL, z->data, &size);
+ if (buff == NULL || size == 0) return EOZ;
+ z->n = size - 1;
+ z->p = buff;
+ return char2int(*(z->p++));
+}
+
+
+int luaZ_lookahead (ZIO *z) {
+ if (z->n == 0) {
+ int c = luaZ_fill(z);
+ if (c == EOZ) return c;
+ z->n++;
+ z->p--;
+ }
+ return char2int(*z->p);
+}
+
+
+void luaZ_init (ZIO *z, lua_Chunkreader reader, void *data, const char *name) {
+ z->reader = reader;
+ z->data = data;
+ z->name = name;
+ z->n = 0;
+ z->p = NULL;
+}
+
+
+/* --------------------------------------------------------------- read --- */
+size_t luaZ_read (ZIO *z, void *b, size_t n) {
+ while (n) {
+ size_t m;
+ if (z->n == 0) {
+ if (luaZ_fill(z) == EOZ)
+ return n; /* return number of missing bytes */
+ else {
+ ++z->n; /* filbuf removed first byte; put back it */
+ --z->p;
+ }
+ }
+ m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
+ memcpy(b, z->p, m);
+ z->n -= m;
+ z->p += m;
+ b = (char *)b + m;
+ n -= m;
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
+ if (n > buff->buffsize) {
+ if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
+ luaM_reallocvector(L, buff->buffer, buff->buffsize, n, char);
+ buff->buffsize = n;
+ }
+ return buff->buffer;
+}
+
+
diff --git a/lib/zlib/include/deflate.h b/lib/zlib/include/deflate.h
index 0630d9f..3259981 100644
--- a/lib/zlib/include/deflate.h
+++ b/lib/zlib/include/deflate.h
@@ -1,318 +1,318 @@
-/* deflate.h -- internal compression state
- * Copyright (C) 1995-2002 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id: deflate.h,v 1.2 2004-11-27 21:43:51 pixel Exp $ */
-
-#ifndef _DEFLATE_H
-#define _DEFLATE_H
-
-#include "zutil.h"
-
-/* ===========================================================================
- * Internal compression state.
- */
-
-#define LENGTH_CODES 29
-/* number of length codes, not counting the special END_BLOCK code */
-
-#define LITERALS 256
-/* number of literal bytes 0..255 */
-
-#define L_CODES (LITERALS+1+LENGTH_CODES)
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-#define D_CODES 30
-/* number of distance codes */
-
-#define BL_CODES 19
-/* number of codes used to transfer the bit lengths */
-
-#define HEAP_SIZE (2*L_CODES+1)
-/* maximum heap size */
-
-#define MAX_BITS 15
-/* All codes must not exceed MAX_BITS bits */
-
-#define INIT_STATE 42
-#define BUSY_STATE 113
-#define FINISH_STATE 666
-/* Stream status */
-
-
-/* Data structure describing a single value and its code string. */
-typedef struct ct_data_s {
- union {
- ush freq; /* frequency count */
- ush code; /* bit string */
- } fc;
- union {
- ush dad; /* father node in Huffman tree */
- ush len; /* length of bit string */
- } dl;
-} FAR ct_data;
-
-#define Freq fc.freq
-#define Code fc.code
-#define Dad dl.dad
-#define Len dl.len
-
-typedef struct static_tree_desc_s static_tree_desc;
-
-typedef struct tree_desc_s {
- ct_data *dyn_tree; /* the dynamic tree */
- int max_code; /* largest code with non zero frequency */
- static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
-
-typedef ush Pos;
-typedef Pos FAR Posf;
-typedef unsigned IPos;
-
-/* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-typedef struct internal_state {
- z_streamp strm; /* pointer back to this zlib stream */
- int status; /* as the name implies */
- Bytef *pending_buf; /* output still pending */
- ulg pending_buf_size; /* size of pending_buf */
- Bytef *pending_out; /* next pending byte to output to the stream */
- int pending; /* nb of bytes in the pending buffer */
- int noheader; /* suppress zlib header and adler32 */
- Byte data_type; /* UNKNOWN, BINARY or ASCII */
- Byte method; /* STORED (for zip only) or DEFLATED */
- int last_flush; /* value of flush param for previous deflate call */
-
- /* used by deflate.c: */
-
- uInt w_size; /* LZ77 window size (32K by default) */
- uInt w_bits; /* log2(w_size) (8..16) */
- uInt w_mask; /* w_size - 1 */
-
- Bytef *window;
- /* Sliding window. Input bytes are read into the second half of the window,
- * and move to the first half later to keep a dictionary of at least wSize
- * bytes. With this organization, matches are limited to a distance of
- * wSize-MAX_MATCH bytes, but this ensures that IO is always
- * performed with a length multiple of the block size. Also, it limits
- * the window size to 64K, which is quite useful on MSDOS.
- * To do: use the user input buffer as sliding window.
- */
-
- ulg window_size;
- /* Actual size of window: 2*wSize, except when the user input buffer
- * is directly used as sliding window.
- */
-
- Posf *prev;
- /* Link to older string with same hash index. To limit the size of this
- * array to 64K, this link is maintained only for the last 32K strings.
- * An index in this array is thus a window index modulo 32K.
- */
-
- Posf *head; /* Heads of the hash chains or NIL. */
-
- uInt ins_h; /* hash index of string to be inserted */
- uInt hash_size; /* number of elements in hash table */
- uInt hash_bits; /* log2(hash_size) */
- uInt hash_mask; /* hash_size-1 */
-
- uInt hash_shift;
- /* Number of bits by which ins_h must be shifted at each input
- * step. It must be such that after MIN_MATCH steps, the oldest
- * byte no longer takes part in the hash key, that is:
- * hash_shift * MIN_MATCH >= hash_bits
- */
-
- long block_start;
- /* Window position at the beginning of the current output block. Gets
- * negative when the window is moved backwards.
- */
-
- uInt match_length; /* length of best match */
- IPos prev_match; /* previous match */
- int match_available; /* set if previous match exists */
- uInt strstart; /* start of string to insert */
- uInt match_start; /* start of matching string */
- uInt lookahead; /* number of valid bytes ahead in window */
-
- uInt prev_length;
- /* Length of the best match at previous step. Matches not greater than this
- * are discarded. This is used in the lazy match evaluation.
- */
-
- uInt max_chain_length;
- /* To speed up deflation, hash chains are never searched beyond this
- * length. A higher limit improves compression ratio but degrades the
- * speed.
- */
-
- uInt max_lazy_match;
- /* Attempt to find a better match only when the current match is strictly
- * smaller than this value. This mechanism is used only for compression
- * levels >= 4.
- */
-# define max_insert_length max_lazy_match
- /* Insert new strings in the hash table only if the match length is not
- * greater than this length. This saves time but degrades compression.
- * max_insert_length is used only for compression levels <= 3.
- */
-
- int level; /* compression level (1..9) */
- int strategy; /* favor or force Huffman coding*/
-
- uInt good_match;
- /* Use a faster search when the previous match is longer than this */
-
- int nice_match; /* Stop searching when current match exceeds this */
-
- /* used by trees.c: */
- /* Didn't use ct_data typedef below to supress compiler warning */
- struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
- struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
- struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
-
- struct tree_desc_s l_desc; /* desc. for literal tree */
- struct tree_desc_s d_desc; /* desc. for distance tree */
- struct tree_desc_s bl_desc; /* desc. for bit length tree */
-
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
- int heap_len; /* number of elements in the heap */
- int heap_max; /* element of largest frequency */
- /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
- * The same heap array is used to build all trees.
- */
-
- uch depth[2*L_CODES+1];
- /* Depth of each subtree used as tie breaker for trees of equal frequency
- */
-
- uchf *l_buf; /* buffer for literals or lengths */
-
- uInt lit_bufsize;
- /* Size of match buffer for literals/lengths. There are 4 reasons for
- * limiting lit_bufsize to 64K:
- * - frequencies can be kept in 16 bit counters
- * - if compression is not successful for the first block, all input
- * data is still in the window so we can still emit a stored block even
- * when input comes from standard input. (This can also be done for
- * all blocks if lit_bufsize is not greater than 32K.)
- * - if compression is not successful for a file smaller than 64K, we can
- * even emit a stored file instead of a stored block (saving 5 bytes).
- * This is applicable only for zip (not gzip or zlib).
- * - creating new Huffman trees less frequently may not provide fast
- * adaptation to changes in the input data statistics. (Take for
- * example a binary file with poorly compressible code followed by
- * a highly compressible string table.) Smaller buffer sizes give
- * fast adaptation but have of course the overhead of transmitting
- * trees more frequently.
- * - I can't count above 4
- */
-
- uInt last_lit; /* running index in l_buf */
-
- ushf *d_buf;
- /* Buffer for distances. To simplify the code, d_buf and l_buf have
- * the same number of elements. To use different lengths, an extra flag
- * array would be necessary.
- */
-
- ulg opt_len; /* bit length of current block with optimal trees */
- ulg static_len; /* bit length of current block with static trees */
- uInt matches; /* number of string matches in current block */
- int last_eob_len; /* bit length of EOB code for last block */
-
-#ifdef DEBUG
- ulg compressed_len; /* total bit length of compressed file mod 2^32 */
- ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
-#endif
-
- ush bi_buf;
- /* Output buffer. bits are inserted starting at the bottom (least
- * significant bits).
- */
- int bi_valid;
- /* Number of valid bits in bi_buf. All bits above the last valid bit
- * are always zero.
- */
-
-} FAR deflate_state;
-
-/* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
-/* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
- /* in trees.c */
-void _tr_init OF((deflate_state *s));
-int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-void _tr_align OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-
-#define d_code(dist) \
- ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
-/* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. _dist_code[256] and _dist_code[257] are never
- * used.
- */
-
-#ifndef DEBUG
-/* Inline versions of _tr_tally for speed: */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
- extern uch _length_code[];
- extern uch _dist_code[];
-#else
- extern const uch _length_code[];
- extern const uch _dist_code[];
-#endif
-
-# define _tr_tally_lit(s, c, flush) \
- { uch cc = (c); \
- s->d_buf[s->last_lit] = 0; \
- s->l_buf[s->last_lit++] = cc; \
- s->dyn_ltree[cc].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-# define _tr_tally_dist(s, distance, length, flush) \
- { uch len = (length); \
- ush dist = (distance); \
- s->d_buf[s->last_lit] = dist; \
- s->l_buf[s->last_lit++] = len; \
- dist--; \
- s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
- s->dyn_dtree[d_code(dist)].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-#else
-# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
-# define _tr_tally_dist(s, distance, length, flush) \
- flush = _tr_tally(s, distance, length)
-#endif
-
-#endif
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2002 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id: deflate.h,v 1.3 2004-11-27 21:46:12 pixel Exp $ */
+
+#ifndef _DEFLATE_H
+#define _DEFLATE_H
+
+#include "zutil.h"
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS 256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES 30
+/* number of distance codes */
+
+#define BL_CODES 19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE 42
+#define BUSY_STATE 113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+ union {
+ ush freq; /* frequency count */
+ ush code; /* bit string */
+ } fc;
+ union {
+ ush dad; /* father node in Huffman tree */
+ ush len; /* length of bit string */
+ } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad dl.dad
+#define Len dl.len
+
+typedef struct static_tree_desc_s static_tree_desc;
+
+typedef struct tree_desc_s {
+ ct_data *dyn_tree; /* the dynamic tree */
+ int max_code; /* largest code with non zero frequency */
+ static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+ z_streamp strm; /* pointer back to this zlib stream */
+ int status; /* as the name implies */
+ Bytef *pending_buf; /* output still pending */
+ ulg pending_buf_size; /* size of pending_buf */
+ Bytef *pending_out; /* next pending byte to output to the stream */
+ int pending; /* nb of bytes in the pending buffer */
+ int noheader; /* suppress zlib header and adler32 */
+ Byte data_type; /* UNKNOWN, BINARY or ASCII */
+ Byte method; /* STORED (for zip only) or DEFLATED */
+ int last_flush; /* value of flush param for previous deflate call */
+
+ /* used by deflate.c: */
+
+ uInt w_size; /* LZ77 window size (32K by default) */
+ uInt w_bits; /* log2(w_size) (8..16) */
+ uInt w_mask; /* w_size - 1 */
+
+ Bytef *window;
+ /* Sliding window. Input bytes are read into the second half of the window,
+ * and move to the first half later to keep a dictionary of at least wSize
+ * bytes. With this organization, matches are limited to a distance of
+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
+ * performed with a length multiple of the block size. Also, it limits
+ * the window size to 64K, which is quite useful on MSDOS.
+ * To do: use the user input buffer as sliding window.
+ */
+
+ ulg window_size;
+ /* Actual size of window: 2*wSize, except when the user input buffer
+ * is directly used as sliding window.
+ */
+
+ Posf *prev;
+ /* Link to older string with same hash index. To limit the size of this
+ * array to 64K, this link is maintained only for the last 32K strings.
+ * An index in this array is thus a window index modulo 32K.
+ */
+
+ Posf *head; /* Heads of the hash chains or NIL. */
+
+ uInt ins_h; /* hash index of string to be inserted */
+ uInt hash_size; /* number of elements in hash table */
+ uInt hash_bits; /* log2(hash_size) */
+ uInt hash_mask; /* hash_size-1 */
+
+ uInt hash_shift;
+ /* Number of bits by which ins_h must be shifted at each input
+ * step. It must be such that after MIN_MATCH steps, the oldest
+ * byte no longer takes part in the hash key, that is:
+ * hash_shift * MIN_MATCH >= hash_bits
+ */
+
+ long block_start;
+ /* Window position at the beginning of the current output block. Gets
+ * negative when the window is moved backwards.
+ */
+
+ uInt match_length; /* length of best match */
+ IPos prev_match; /* previous match */
+ int match_available; /* set if previous match exists */
+ uInt strstart; /* start of string to insert */
+ uInt match_start; /* start of matching string */
+ uInt lookahead; /* number of valid bytes ahead in window */
+
+ uInt prev_length;
+ /* Length of the best match at previous step. Matches not greater than this
+ * are discarded. This is used in the lazy match evaluation.
+ */
+
+ uInt max_chain_length;
+ /* To speed up deflation, hash chains are never searched beyond this
+ * length. A higher limit improves compression ratio but degrades the
+ * speed.
+ */
+
+ uInt max_lazy_match;
+ /* Attempt to find a better match only when the current match is strictly
+ * smaller than this value. This mechanism is used only for compression
+ * levels >= 4.
+ */
+# define max_insert_length max_lazy_match
+ /* Insert new strings in the hash table only if the match length is not
+ * greater than this length. This saves time but degrades compression.
+ * max_insert_length is used only for compression levels <= 3.
+ */
+
+ int level; /* compression level (1..9) */
+ int strategy; /* favor or force Huffman coding*/
+
+ uInt good_match;
+ /* Use a faster search when the previous match is longer than this */
+
+ int nice_match; /* Stop searching when current match exceeds this */
+
+ /* used by trees.c: */
+ /* Didn't use ct_data typedef below to supress compiler warning */
+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
+
+ struct tree_desc_s l_desc; /* desc. for literal tree */
+ struct tree_desc_s d_desc; /* desc. for distance tree */
+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
+
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
+ int heap_len; /* number of elements in the heap */
+ int heap_max; /* element of largest frequency */
+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+ * The same heap array is used to build all trees.
+ */
+
+ uch depth[2*L_CODES+1];
+ /* Depth of each subtree used as tie breaker for trees of equal frequency
+ */
+
+ uchf *l_buf; /* buffer for literals or lengths */
+
+ uInt lit_bufsize;
+ /* Size of match buffer for literals/lengths. There are 4 reasons for
+ * limiting lit_bufsize to 64K:
+ * - frequencies can be kept in 16 bit counters
+ * - if compression is not successful for the first block, all input
+ * data is still in the window so we can still emit a stored block even
+ * when input comes from standard input. (This can also be done for
+ * all blocks if lit_bufsize is not greater than 32K.)
+ * - if compression is not successful for a file smaller than 64K, we can
+ * even emit a stored file instead of a stored block (saving 5 bytes).
+ * This is applicable only for zip (not gzip or zlib).
+ * - creating new Huffman trees less frequently may not provide fast
+ * adaptation to changes in the input data statistics. (Take for
+ * example a binary file with poorly compressible code followed by
+ * a highly compressible string table.) Smaller buffer sizes give
+ * fast adaptation but have of course the overhead of transmitting
+ * trees more frequently.
+ * - I can't count above 4
+ */
+
+ uInt last_lit; /* running index in l_buf */
+
+ ushf *d_buf;
+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
+ * the same number of elements. To use different lengths, an extra flag
+ * array would be necessary.
+ */
+
+ ulg opt_len; /* bit length of current block with optimal trees */
+ ulg static_len; /* bit length of current block with static trees */
+ uInt matches; /* number of string matches in current block */
+ int last_eob_len; /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
+#endif
+
+ ush bi_buf;
+ /* Output buffer. bits are inserted starting at the bottom (least
+ * significant bits).
+ */
+ int bi_valid;
+ /* Number of valid bits in bi_buf. All bits above the last valid bit
+ * are always zero.
+ */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+ /* in trees.c */
+void _tr_init OF((deflate_state *s));
+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+void _tr_align OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+
+#define d_code(dist) \
+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+ extern uch _length_code[];
+ extern uch _dist_code[];
+#else
+ extern const uch _length_code[];
+ extern const uch _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+ { uch cc = (c); \
+ s->d_buf[s->last_lit] = 0; \
+ s->l_buf[s->last_lit++] = cc; \
+ s->dyn_ltree[cc].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+# define _tr_tally_dist(s, distance, length, flush) \
+ { uch len = (length); \
+ ush dist = (distance); \
+ s->d_buf[s->last_lit] = dist; \
+ s->l_buf[s->last_lit++] = len; \
+ dist--; \
+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+ s->dyn_dtree[d_code(dist)].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+ flush = _tr_tally(s, distance, length)
+#endif
+
+#endif
diff --git a/lib/zlib/include/infblock.h b/lib/zlib/include/infblock.h
index 4cf0fa9..173b226 100644
--- a/lib/zlib/include/infblock.h
+++ b/lib/zlib/include/infblock.h
@@ -1,39 +1,39 @@
-/* infblock.h -- header to use infblock.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_blocks_state;
-typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-
-extern inflate_blocks_statef * inflate_blocks_new OF((
- z_streamp z,
- check_func c, /* check function */
- uInt w)); /* window size */
-
-extern int inflate_blocks OF((
- inflate_blocks_statef *,
- z_streamp ,
- int)); /* initial return code */
-
-extern void inflate_blocks_reset OF((
- inflate_blocks_statef *,
- z_streamp ,
- uLongf *)); /* check value on output */
-
-extern int inflate_blocks_free OF((
- inflate_blocks_statef *,
- z_streamp));
-
-extern void inflate_set_dictionary OF((
- inflate_blocks_statef *s,
- const Bytef *d, /* dictionary */
- uInt n)); /* dictionary length */
-
-extern int inflate_blocks_sync_point OF((
- inflate_blocks_statef *s));
+/* infblock.h -- header to use infblock.c
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_blocks_state;
+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
+
+extern inflate_blocks_statef * inflate_blocks_new OF((
+ z_streamp z,
+ check_func c, /* check function */
+ uInt w)); /* window size */
+
+extern int inflate_blocks OF((
+ inflate_blocks_statef *,
+ z_streamp ,
+ int)); /* initial return code */
+
+extern void inflate_blocks_reset OF((
+ inflate_blocks_statef *,
+ z_streamp ,
+ uLongf *)); /* check value on output */
+
+extern int inflate_blocks_free OF((
+ inflate_blocks_statef *,
+ z_streamp));
+
+extern void inflate_set_dictionary OF((
+ inflate_blocks_statef *s,
+ const Bytef *d, /* dictionary */
+ uInt n)); /* dictionary length */
+
+extern int inflate_blocks_sync_point OF((
+ inflate_blocks_statef *s));
diff --git a/lib/zlib/include/infcodes.h b/lib/zlib/include/infcodes.h
index 531d419..46821a0 100644
--- a/lib/zlib/include/infcodes.h
+++ b/lib/zlib/include/infcodes.h
@@ -1,27 +1,27 @@
-/* infcodes.h -- header to use infcodes.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_codes_state;
-typedef struct inflate_codes_state FAR inflate_codes_statef;
-
-extern inflate_codes_statef *inflate_codes_new OF((
- uInt, uInt,
- inflate_huft *, inflate_huft *,
- z_streamp ));
-
-extern int inflate_codes OF((
- inflate_blocks_statef *,
- z_streamp ,
- int));
-
-extern void inflate_codes_free OF((
- inflate_codes_statef *,
- z_streamp ));
-
+/* infcodes.h -- header to use infcodes.c
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_codes_state;
+typedef struct inflate_codes_state FAR inflate_codes_statef;
+
+extern inflate_codes_statef *inflate_codes_new OF((
+ uInt, uInt,
+ inflate_huft *, inflate_huft *,
+ z_streamp ));
+
+extern int inflate_codes OF((
+ inflate_blocks_statef *,
+ z_streamp ,
+ int));
+
+extern void inflate_codes_free OF((
+ inflate_codes_statef *,
+ z_streamp ));
+
diff --git a/lib/zlib/include/inffast.h b/lib/zlib/include/inffast.h
index ac643b3..a31a4bb 100644
--- a/lib/zlib/include/inffast.h
+++ b/lib/zlib/include/inffast.h
@@ -1,17 +1,17 @@
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-extern int inflate_fast OF((
- uInt,
- uInt,
- inflate_huft *,
- inflate_huft *,
- inflate_blocks_statef *,
- z_streamp ));
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+extern int inflate_fast OF((
+ uInt,
+ uInt,
+ inflate_huft *,
+ inflate_huft *,
+ inflate_blocks_statef *,
+ z_streamp ));
diff --git a/lib/zlib/include/inffixed.h b/lib/zlib/include/inffixed.h
index e997507..77f7e76 100644
--- a/lib/zlib/include/inffixed.h
+++ b/lib/zlib/include/inffixed.h
@@ -1,151 +1,151 @@
-/* inffixed.h -- table for decoding fixed codes
- * Generated automatically by the maketree.c program
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-local uInt fixed_bl = 9;
-local uInt fixed_bd = 5;
-local inflate_huft fixed_tl[] = {
- {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
- {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
- {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
- {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
- {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
- {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
- {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
- {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
- {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
- {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
- {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
- {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
- {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
- {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
- {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
- {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
- {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
- {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
- {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
- {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
- {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
- {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
- {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
- {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
- {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
- {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
- {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
- {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
- {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
- {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
- {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
- {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
- {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
- {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
- {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
- {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
- {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
- {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
- {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
- {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
- {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
- {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
- {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
- {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
- {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
- {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
- {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
- {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
- {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
- {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
- {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
- {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
- {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
- {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
- {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
- {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
- {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
- {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
- {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
- {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
- {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
- {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
- {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
- {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
- {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
- {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
- {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
- {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
- {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
- {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
- {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
- {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
- {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
- {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
- {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
- {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
- {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
- {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
- {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
- {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
- {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
- {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
- {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
- {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
- {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
- {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
- {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
- {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
- {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
- {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
- {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
- {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
- {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
- {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
- {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
- {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
- {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
- {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
- {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
- {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
- {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
- {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
- {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
- {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
- {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
- {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
- {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
- {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
- {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
- {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
- {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
- {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
- {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
- {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
- {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
- {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
- {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
- {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
- {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
- {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
- {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
- {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
- {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
- {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
- {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
- {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
- {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
- {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
- };
-local inflate_huft fixed_td[] = {
- {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
- {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
- {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
- {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
- {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
- {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
- {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
- {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
- };
+/* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by the maketree.c program
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+local uInt fixed_bl = 9;
+local uInt fixed_bd = 5;
+local inflate_huft fixed_tl[] = {
+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
+ };
+local inflate_huft fixed_td[] = {
+ {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
+ {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
+ {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
+ {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
+ {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
+ {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
+ {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
+ {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
+ };
diff --git a/lib/zlib/include/inftrees.h b/lib/zlib/include/inftrees.h
index affbb3b..04b73b7 100644
--- a/lib/zlib/include/inftrees.h
+++ b/lib/zlib/include/inftrees.h
@@ -1,58 +1,58 @@
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* Huffman code lookup table entry--this entry is four bytes for machines
- that have 16-bit pointers (e.g. PC's in the small or medium model). */
-
-typedef struct inflate_huft_s FAR inflate_huft;
-
-struct inflate_huft_s {
- union {
- struct {
- Byte Exop; /* number of extra bits or operation */
- Byte Bits; /* number of bits in this code or subcode */
- } what;
- uInt pad; /* pad structure to a power of 2 (4 bytes for */
- } word; /* 16-bit, 8 bytes for 32-bit int's) */
- uInt base; /* literal, length base, distance base,
- or table offset */
-};
-
-/* Maximum size of dynamic tree. The maximum found in a long but non-
- exhaustive search was 1004 huft structures (850 for length/literals
- and 154 for distances, the latter actually the result of an
- exhaustive search). The actual maximum is not known, but the
- value below is more than safe. */
-#define MANY 1440
-
-extern int inflate_trees_bits OF((
- uIntf *, /* 19 code lengths */
- uIntf *, /* bits tree desired/actual depth */
- inflate_huft * FAR *, /* bits tree result */
- inflate_huft *, /* space for trees */
- z_streamp)); /* for messages */
-
-extern int inflate_trees_dynamic OF((
- uInt, /* number of literal/length codes */
- uInt, /* number of distance codes */
- uIntf *, /* that many (total) code lengths */
- uIntf *, /* literal desired/actual bit depth */
- uIntf *, /* distance desired/actual bit depth */
- inflate_huft * FAR *, /* literal/length tree result */
- inflate_huft * FAR *, /* distance tree result */
- inflate_huft *, /* space for trees */
- z_streamp)); /* for messages */
-
-extern int inflate_trees_fixed OF((
- uIntf *, /* literal desired/actual bit depth */
- uIntf *, /* distance desired/actual bit depth */
- inflate_huft * FAR *, /* literal/length tree result */
- inflate_huft * FAR *, /* distance tree result */
- z_streamp)); /* for memory allocation */
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+ that have 16-bit pointers (e.g. PC's in the small or medium model). */
+
+typedef struct inflate_huft_s FAR inflate_huft;
+
+struct inflate_huft_s {
+ union {
+ struct {
+ Byte Exop; /* number of extra bits or operation */
+ Byte Bits; /* number of bits in this code or subcode */
+ } what;
+ uInt pad; /* pad structure to a power of 2 (4 bytes for */
+ } word; /* 16-bit, 8 bytes for 32-bit int's) */
+ uInt base; /* literal, length base, distance base,
+ or table offset */
+};
+
+/* Maximum size of dynamic tree. The maximum found in a long but non-
+ exhaustive search was 1004 huft structures (850 for length/literals
+ and 154 for distances, the latter actually the result of an
+ exhaustive search). The actual maximum is not known, but the
+ value below is more than safe. */
+#define MANY 1440
+
+extern int inflate_trees_bits OF((
+ uIntf *, /* 19 code lengths */
+ uIntf *, /* bits tree desired/actual depth */
+ inflate_huft * FAR *, /* bits tree result */
+ inflate_huft *, /* space for trees */
+ z_streamp)); /* for messages */
+
+extern int inflate_trees_dynamic OF((
+ uInt, /* number of literal/length codes */
+ uInt, /* number of distance codes */
+ uIntf *, /* that many (total) code lengths */
+ uIntf *, /* literal desired/actual bit depth */
+ uIntf *, /* distance desired/actual bit depth */
+ inflate_huft * FAR *, /* literal/length tree result */
+ inflate_huft * FAR *, /* distance tree result */
+ inflate_huft *, /* space for trees */
+ z_streamp)); /* for messages */
+
+extern int inflate_trees_fixed OF((
+ uIntf *, /* literal desired/actual bit depth */
+ uIntf *, /* distance desired/actual bit depth */
+ inflate_huft * FAR *, /* literal/length tree result */
+ inflate_huft * FAR *, /* distance tree result */
+ z_streamp)); /* for memory allocation */
diff --git a/lib/zlib/include/infutil.h b/lib/zlib/include/infutil.h
index 0c0ace3..4401df8 100644
--- a/lib/zlib/include/infutil.h
+++ b/lib/zlib/include/infutil.h
@@ -1,98 +1,98 @@
-/* infutil.h -- types and macros common to blocks and codes
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-#ifndef _INFUTIL_H
-#define _INFUTIL_H
-
-typedef enum {
- TYPE, /* get type bits (3, including end bit) */
- LENS, /* get lengths for stored */
- STORED, /* processing stored block */
- TABLE, /* get table lengths */
- BTREE, /* get bit lengths tree for a dynamic block */
- DTREE, /* get length, distance trees for a dynamic block */
- CODES, /* processing fixed or dynamic block */
- DRY, /* output remaining window bytes */
- DONE, /* finished last block, done */
- BAD} /* got a data error--stuck here */
-inflate_block_mode;
-
-/* inflate blocks semi-private state */
-struct inflate_blocks_state {
-
- /* mode */
- inflate_block_mode mode; /* current inflate_block mode */
-
- /* mode dependent information */
- union {
- uInt left; /* if STORED, bytes left to copy */
- struct {
- uInt table; /* table lengths (14 bits) */
- uInt index; /* index into blens (or border) */
- uIntf *blens; /* bit lengths of codes */
- uInt bb; /* bit length tree depth */
- inflate_huft *tb; /* bit length decoding tree */
- } trees; /* if DTREE, decoding info for trees */
- struct {
- inflate_codes_statef
- *codes;
- } decode; /* if CODES, current state */
- } sub; /* submode */
- uInt last; /* true if this block is the last block */
-
- /* mode independent information */
- uInt bitk; /* bits in bit buffer */
- uLong bitb; /* bit buffer */
- inflate_huft *hufts; /* single malloc for tree space */
- Bytef *window; /* sliding window */
- Bytef *end; /* one byte after sliding window */
- Bytef *read; /* window read pointer */
- Bytef *write; /* window write pointer */
- check_func checkfn; /* check function */
- uLong check; /* check on output */
-
-};
-
-
-/* defines for inflate input/output */
-/* update pointers and return */
-#define UPDBITS {s->bitb=b;s->bitk=k;}
-#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-#define UPDOUT {s->write=q;}
-#define UPDATE {UPDBITS UPDIN UPDOUT}
-#define LEAVE {UPDATE return inflate_flush(s,z,r);}
-/* get bytes and bits */
-#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-#define NEXTBYTE (n--,*p++)
-#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define DUMPBITS(j) {b>>=(j);k-=(j);}
-/* output bytes */
-#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
-#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
-#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
-#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
-#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
-#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-/* load local pointers */
-#define LOAD {LOADIN LOADOUT}
-
-/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
-extern uInt inflate_mask[17];
-
-/* copy as much as possible from the sliding window to the output area */
-extern int inflate_flush OF((
- inflate_blocks_statef *,
- z_streamp ,
- int));
-
-struct internal_state {int dummy;}; /* for buggy compilers */
-
-#endif
+/* infutil.h -- types and macros common to blocks and codes
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+#ifndef _INFUTIL_H
+#define _INFUTIL_H
+
+typedef enum {
+ TYPE, /* get type bits (3, including end bit) */
+ LENS, /* get lengths for stored */
+ STORED, /* processing stored block */
+ TABLE, /* get table lengths */
+ BTREE, /* get bit lengths tree for a dynamic block */
+ DTREE, /* get length, distance trees for a dynamic block */
+ CODES, /* processing fixed or dynamic block */
+ DRY, /* output remaining window bytes */
+ DONE, /* finished last block, done */
+ BAD} /* got a data error--stuck here */
+inflate_block_mode;
+
+/* inflate blocks semi-private state */
+struct inflate_blocks_state {
+
+ /* mode */
+ inflate_block_mode mode; /* current inflate_block mode */
+
+ /* mode dependent information */
+ union {
+ uInt left; /* if STORED, bytes left to copy */
+ struct {
+ uInt table; /* table lengths (14 bits) */
+ uInt index; /* index into blens (or border) */
+ uIntf *blens; /* bit lengths of codes */
+ uInt bb; /* bit length tree depth */
+ inflate_huft *tb; /* bit length decoding tree */
+ } trees; /* if DTREE, decoding info for trees */
+ struct {
+ inflate_codes_statef
+ *codes;
+ } decode; /* if CODES, current state */
+ } sub; /* submode */
+ uInt last; /* true if this block is the last block */
+
+ /* mode independent information */
+ uInt bitk; /* bits in bit buffer */
+ uLong bitb; /* bit buffer */
+ inflate_huft *hufts; /* single malloc for tree space */
+ Bytef *window; /* sliding window */
+ Bytef *end; /* one byte after sliding window */
+ Bytef *read; /* window read pointer */
+ Bytef *write; /* window write pointer */
+ check_func checkfn; /* check function */
+ uLong check; /* check on output */
+
+};
+
+
+/* defines for inflate input/output */
+/* update pointers and return */
+#define UPDBITS {s->bitb=b;s->bitk=k;}
+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
+#define UPDOUT {s->write=q;}
+#define UPDATE {UPDBITS UPDIN UPDOUT}
+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
+/* get bytes and bits */
+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
+#define NEXTBYTE (n--,*p++)
+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define DUMPBITS(j) {b>>=(j);k-=(j);}
+/* output bytes */
+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
+/* load local pointers */
+#define LOAD {LOADIN LOADOUT}
+
+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
+extern uInt inflate_mask[17];
+
+/* copy as much as possible from the sliding window to the output area */
+extern int inflate_flush OF((
+ inflate_blocks_statef *,
+ z_streamp ,
+ int));
+
+struct internal_state {int dummy;}; /* for buggy compilers */
+
+#endif
diff --git a/lib/zlib/include/trees.h b/lib/zlib/include/trees.h
index 1ca868b..72facf9 100644
--- a/lib/zlib/include/trees.h
+++ b/lib/zlib/include/trees.h
@@ -1,128 +1,128 @@
-/* header created automatically with -DGEN_TREES_H */
-
-local const ct_data static_ltree[L_CODES+2] = {
-{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
-{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
-{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
-{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
-{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
-{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
-{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
-{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
-{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
-{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
-{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
-{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
-{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
-{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
-{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
-{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
-{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
-{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
-{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
-{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
-{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
-{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
-{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
-{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
-{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
-{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
-{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
-{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
-{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
-{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
-{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
-{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
-{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
-{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
-{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
-{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
-{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
-{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
-{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
-{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
-{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
-{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
-{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
-{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
-{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
-{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
-{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
-{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
-{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
-{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
-{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
-{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
-{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
-{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
-{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
-{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
-{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
-{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
-};
-
-local const ct_data static_dtree[D_CODES] = {
-{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
-{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
-{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
-{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
-{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
-{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
-};
-
-const uch _dist_code[DIST_CODE_LEN] = {
- 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
- 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
-10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
-18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
-};
-
-const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
-13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
-17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
-19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
-22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
-};
-
-local const int base_length[LENGTH_CODES] = {
-0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
-64, 80, 96, 112, 128, 160, 192, 224, 0
-};
-
-local const int base_dist[D_CODES] = {
- 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
- 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
- 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
-};
-
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch _dist_code[DIST_CODE_LEN] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
+};
+
diff --git a/lib/zlib/include/zconf.h b/lib/zlib/include/zconf.h
index 0a87ed0..458a72b 100644
--- a/lib/zlib/include/zconf.h
+++ b/lib/zlib/include/zconf.h
@@ -1,283 +1,283 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: zconf.h,v 1.2 2004-11-27 21:43:51 pixel Exp $ */
-
-#ifndef _ZCONF_H
-#define _ZCONF_H
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- */
-#ifdef Z_PREFIX
-# define deflateInit_ z_deflateInit_
-# define deflate z_deflate
-# define deflateEnd z_deflateEnd
-# define inflateInit_ z_inflateInit_
-# define inflate z_inflate
-# define inflateEnd z_inflateEnd
-# define deflateInit2_ z_deflateInit2_
-# define deflateSetDictionary z_deflateSetDictionary
-# define deflateCopy z_deflateCopy
-# define deflateReset z_deflateReset
-# define deflateParams z_deflateParams
-# define inflateInit2_ z_inflateInit2_
-# define inflateSetDictionary z_inflateSetDictionary
-# define inflateSync z_inflateSync
-# define inflateSyncPoint z_inflateSyncPoint
-# define inflateReset z_inflateReset
-# define compress z_compress
-# define compress2 z_compress2
-# define uncompress z_uncompress
-# define adler32 z_adler32
-# define crc32 z_crc32
-# define get_crc_table z_get_crc_table
-
-# define Byte z_Byte
-# define uInt z_uInt
-# define uLong z_uLong
-# define Bytef z_Bytef
-# define charf z_charf
-# define intf z_intf
-# define uIntf z_uIntf
-# define uLongf z_uLongf
-# define voidpf z_voidpf
-# define voidp z_voidp
-#endif
-
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-# define WIN32
-#endif
-#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
-# ifndef __32BIT__
-# define __32BIT__
-# endif
-#endif
-#if defined(__MSDOS__) && !defined(MSDOS)
-# define MSDOS
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#if defined(MSDOS) && !defined(__32BIT__)
-# define MAXSEG_64K
-#endif
-#ifdef MSDOS
-# define UNALIGNED_OK
-#endif
-
-#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
-# define STDC
-#endif
-#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
-# ifndef STDC
-# define STDC
-# endif
-#endif
-
-#ifndef STDC
-# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-# define const
-# endif
-#endif
-
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
-# define NO_DUMMY_DECL
-#endif
-
-/* Old Borland C incorrectly complains about missing returns: */
-#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
-# define NEED_DUMMY_RETURN
-#endif
-
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- (1 << (windowBits+2)) + (1 << (memLevel+9))
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
- /* MSC small or medium model */
-# define SMALL_MEDIUM
-# ifdef _MSC_VER
-# define FAR _far
-# else
-# define FAR far
-# endif
-#endif
-#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
-# ifndef __32BIT__
-# define SMALL_MEDIUM
-# define FAR _far
-# endif
-#endif
-
-/* Compile with -DZLIB_DLL for Windows DLL support */
-#if defined(ZLIB_DLL)
-# if defined(_WINDOWS) || defined(WINDOWS)
-# ifdef FAR
-# undef FAR
-# endif
-# include <windows.h>
-# define ZEXPORT WINAPI
-# ifdef WIN32
-# define ZEXPORTVA WINAPIV
-# else
-# define ZEXPORTVA FAR _cdecl _export
-# endif
-# endif
-# if defined (__BORLANDC__)
-# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
-# include <windows.h>
-# define ZEXPORT __declspec(dllexport) WINAPI
-# define ZEXPORTRVA __declspec(dllexport) WINAPIV
-# else
-# if defined (_Windows) && defined (__DLL__)
-# define ZEXPORT _export
-# define ZEXPORTVA _export
-# endif
-# endif
-# endif
-#endif
-
-#if defined (__BEOS__)
-# if defined (ZLIB_DLL)
-# define ZEXTERN extern __declspec(dllexport)
-# else
-# define ZEXTERN extern __declspec(dllimport)
-# endif
-#endif
-
-#ifndef ZEXPORT
-# define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-# define ZEXPORTVA
-#endif
-#ifndef ZEXTERN
-# define ZEXTERN extern
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-#if !defined(MACOS) && !defined(TARGET_OS_MAC)
-typedef unsigned char Byte; /* 8 bits */
-#endif
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-#ifdef SMALL_MEDIUM
- /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-# define Bytef Byte FAR
-#else
- typedef Byte FAR Bytef;
-#endif
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void FAR *voidpf;
- typedef void *voidp;
- typedef const void FAR *cvoidpf;
- typedef const void *cvoidp;
-#else
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
- typedef const Byte FAR *cvoidpf;
- typedef const Byte *cvoidp;
-#endif
-
-#ifdef HAVE_UNISTD_H
-# include <sys/types.h> /* for off_t */
-# include <unistd.h> /* for SEEK_* and off_t */
-# define z_off_t off_t
-#endif
-#ifndef SEEK_SET
-# define SEEK_SET 0 /* Seek from beginning of file. */
-# define SEEK_CUR 1 /* Seek from current position. */
-# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-#endif
-#ifndef z_off_t
-# define z_off_t long
-#endif
-
-/* MVS linker does not support external names larger than 8 bytes */
-#if defined(__MVS__)
-# pragma map(deflateInit_,"DEIN")
-# pragma map(deflateInit2_,"DEIN2")
-# pragma map(deflateEnd,"DEEND")
-# pragma map(inflateInit_,"ININ")
-# pragma map(inflateInit2_,"ININ2")
-# pragma map(inflateEnd,"INEND")
-# pragma map(inflateSync,"INSY")
-# pragma map(inflateSetDictionary,"INSEDI")
-# pragma map(inflate_blocks,"INBL")
-# pragma map(inflate_blocks_new,"INBLNE")
-# pragma map(inflate_blocks_free,"INBLFR")
-# pragma map(inflate_blocks_reset,"INBLRE")
-# pragma map(inflate_codes_free,"INCOFR")
-# pragma map(inflate_codes,"INCO")
-# pragma map(inflate_fast,"INFA")
-# pragma map(inflate_flush,"INFLU")
-# pragma map(inflate_mask,"INMA")
-# pragma map(inflate_set_dictionary,"INSEDI2")
-# pragma map(inflate_copyright,"INCOPY")
-# pragma map(inflate_trees_bits,"INTRBI")
-# pragma map(inflate_trees_dynamic,"INTRDY")
-# pragma map(inflate_trees_fixed,"INTRFI")
-# pragma map(inflate_trees_free,"INTRFR")
-#endif
-
-#endif /* _ZCONF_H */
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id: zconf.h,v 1.3 2004-11-27 21:46:12 pixel Exp $ */
+
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+# define deflateInit_ z_deflateInit_
+# define deflate z_deflate
+# define deflateEnd z_deflateEnd
+# define inflateInit_ z_inflateInit_
+# define inflate z_inflate
+# define inflateEnd z_inflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateCopy z_deflateCopy
+# define deflateReset z_deflateReset
+# define deflateParams z_deflateParams
+# define inflateInit2_ z_inflateInit2_
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateReset z_inflateReset
+# define compress z_compress
+# define compress2 z_compress2
+# define uncompress z_uncompress
+# define adler32 z_adler32
+# define crc32 z_crc32
+# define get_crc_table z_get_crc_table
+
+# define Byte z_Byte
+# define uInt z_uInt
+# define uLong z_uLong
+# define Bytef z_Bytef
+# define charf z_charf
+# define intf z_intf
+# define uIntf z_uIntf
+# define uLongf z_uLongf
+# define voidpf z_voidpf
+# define voidp z_voidp
+#endif
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+# define WIN32
+#endif
+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
+# ifndef __32BIT__
+# define __32BIT__
+# endif
+#endif
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#if defined(MSDOS) && !defined(__32BIT__)
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
+# define STDC
+#endif
+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
+# ifndef STDC
+# define STDC
+# endif
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const
+# endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Old Borland C incorrectly complains about missing returns: */
+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
+# define NEED_DUMMY_RETURN
+#endif
+
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+#endif
+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
+# ifndef __32BIT__
+# define SMALL_MEDIUM
+# define FAR _far
+# endif
+#endif
+
+/* Compile with -DZLIB_DLL for Windows DLL support */
+#if defined(ZLIB_DLL)
+# if defined(_WINDOWS) || defined(WINDOWS)
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR _cdecl _export
+# endif
+# endif
+# if defined (__BORLANDC__)
+# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
+# include <windows.h>
+# define ZEXPORT __declspec(dllexport) WINAPI
+# define ZEXPORTRVA __declspec(dllexport) WINAPIV
+# else
+# if defined (_Windows) && defined (__DLL__)
+# define ZEXPORT _export
+# define ZEXPORTVA _export
+# endif
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# if defined (ZLIB_DLL)
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+#endif
+
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+ typedef const void FAR *cvoidpf;
+ typedef const void *cvoidp;
+#else
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+ typedef const Byte FAR *cvoidpf;
+ typedef const Byte *cvoidp;
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <sys/types.h> /* for off_t */
+# include <unistd.h> /* for SEEK_* and off_t */
+# define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+# pragma map(deflateInit_,"DEIN")
+# pragma map(deflateInit2_,"DEIN2")
+# pragma map(deflateEnd,"DEEND")
+# pragma map(inflateInit_,"ININ")
+# pragma map(inflateInit2_,"ININ2")
+# pragma map(inflateEnd,"INEND")
+# pragma map(inflateSync,"INSY")
+# pragma map(inflateSetDictionary,"INSEDI")
+# pragma map(inflate_blocks,"INBL")
+# pragma map(inflate_blocks_new,"INBLNE")
+# pragma map(inflate_blocks_free,"INBLFR")
+# pragma map(inflate_blocks_reset,"INBLRE")
+# pragma map(inflate_codes_free,"INCOFR")
+# pragma map(inflate_codes,"INCO")
+# pragma map(inflate_fast,"INFA")
+# pragma map(inflate_flush,"INFLU")
+# pragma map(inflate_mask,"INMA")
+# pragma map(inflate_set_dictionary,"INSEDI2")
+# pragma map(inflate_copyright,"INCOPY")
+# pragma map(inflate_trees_bits,"INTRBI")
+# pragma map(inflate_trees_dynamic,"INTRDY")
+# pragma map(inflate_trees_fixed,"INTRFI")
+# pragma map(inflate_trees_free,"INTRFR")
+#endif
+
+#endif /* _ZCONF_H */
diff --git a/lib/zlib/include/zlib.h b/lib/zlib/include/zlib.h
index fc81811..b2f0ef0 100644
--- a/lib/zlib/include/zlib.h
+++ b/lib/zlib/include/zlib.h
@@ -1,893 +1,893 @@
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.1.4, March 11th, 2002
-
- Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- jloup@gzip.org madler@alumni.caltech.edu
-
-
- The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
- (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-*/
-
-#ifndef _ZLIB_H
-#define _ZLIB_H
-
-#include "zconf.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ZLIB_VERSION "1.1.4"
-
-/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms will be added later and will have the same
- stream interface.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
- (providing more output space) before each call.
-
- The library also supports reading and writing files in gzip (.gz) format
- with an interface similar to that of stdio.
-
- The library does not install any signal handler. The decoder checks
- the consistency of the compressed data, so the library should never
- crash even in case of corrupted input.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void (*free_func) OF((voidpf opaque, voidpf address));
-
-struct internal_state;
-
-typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
-
- char *msg; /* last error message, NULL if no error */
- struct internal_state FAR *state; /* not visible by applications */
-
- alloc_func zalloc; /* used to allocate the internal state */
- free_func zfree; /* used to free the internal state */
- voidpf opaque; /* private data object passed to zalloc and zfree */
-
- int data_type; /* best guess about the data type: ascii or binary */
- uLong adler; /* adler32 value of the uncompressed data */
- uLong reserved; /* reserved for future use */
-} z_stream;
-
-typedef z_stream FAR *z_streamp;
-
-/*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- opaque value.
-
- zalloc must return Z_NULL if there is not enough memory for the object.
- If zlib is used in a multi-threaded application, zalloc and zfree must be
- thread safe.
-
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
-*/
-
- /* constants */
-
-#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
-#define Z_SYNC_FLUSH 2
-#define Z_FULL_FLUSH 3
-#define Z_FINISH 4
-/* Allowed flush values; see deflate() below for details */
-
-#define Z_OK 0
-#define Z_STREAM_END 1
-#define Z_NEED_DICT 2
-#define Z_ERRNO (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR (-3)
-#define Z_MEM_ERROR (-4)
-#define Z_BUF_ERROR (-5)
-#define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
-#define Z_NO_COMPRESSION 0
-#define Z_BEST_SPEED 1
-#define Z_BEST_COMPRESSION 9
-#define Z_DEFAULT_COMPRESSION (-1)
-/* compression levels */
-
-#define Z_FILTERED 1
-#define Z_HUFFMAN_ONLY 2
-#define Z_DEFAULT_STRATEGY 0
-/* compression strategy; see deflateInit2() below for details */
-
-#define Z_BINARY 0
-#define Z_ASCII 1
-#define Z_UNKNOWN 2
-/* Possible values of the data_type field */
-
-#define Z_DEFLATED 8
-/* The deflate compression method (the only one supported in this version) */
-
-#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-#define zlib_version zlibVersion()
-/* for compatibility with versions < 1.0.2 */
-
- /* basic functions */
-
-ZEXTERN const char * ZEXPORT zlibVersion OF((void));
-/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- This check is automatically made by deflateInit and inflateInit.
- */
-
-/*
-ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
-
- Initializes the internal stream state for compression. The fields
- zalloc, zfree and opaque must be initialized before by the caller.
- If zalloc and zfree are set to Z_NULL, deflateInit updates them to
- use default allocation functions.
-
- The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
- 1 gives best speed, 9 gives best compression, 0 gives no compression at
- all (the input data is simply copied a block at a time).
- Z_DEFAULT_COMPRESSION requests a default compromise between speed and
- compression (currently equivalent to level 6).
-
- deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if level is not a valid compression level,
- Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
- with the version assumed by the caller (ZLIB_VERSION).
- msg is set to null if there is no error message. deflateInit does not
- perform any compression: this will be done by deflate().
-*/
-
-
-ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
-/*
- deflate compresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce some
- output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. deflate performs one or both of the
- following actions:
-
- - Compress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in and avail_in are updated and
- processing will resume at this point for the next call of deflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. This action is forced if the parameter flush is non zero.
- Forcing flush frequently degrades the compression ratio, so this parameter
- should be set only when necessary (in interactive applications).
- Some output may be provided even if flush is not set.
-
- Before the call of deflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating avail_in or avail_out accordingly; avail_out
- should never be zero before the call. The application can consume the
- compressed output when it wants, for example when the output buffer is full
- (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
- and with zero avail_out, it must be called again after making room in the
- output buffer because there might be more output pending.
-
- If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
- flushed to the output buffer and the output is aligned on a byte boundary, so
- that the decompressor can get all input data available so far. (In particular
- avail_in is zero after the call if enough output space has been provided
- before the call.) Flushing may degrade compression for some compression
- algorithms and so it should be used only when necessary.
-
- If flush is set to Z_FULL_FLUSH, all output is flushed as with
- Z_SYNC_FLUSH, and the compression state is reset so that decompression can
- restart from this point if previous compressed data has been damaged or if
- random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
- the compression.
-
- If deflate returns with avail_out == 0, this function must be called again
- with the same value of the flush parameter and more output space (updated
- avail_out), until the flush is complete (deflate returns with non-zero
- avail_out).
-
- If the parameter flush is set to Z_FINISH, pending input is processed,
- pending output is flushed and deflate returns with Z_STREAM_END if there
- was enough output space; if deflate returns with Z_OK, this function must be
- called again with Z_FINISH and more output space (updated avail_out) but no
- more input data, until it returns with Z_STREAM_END or an error. After
- deflate has returned Z_STREAM_END, the only possible operations on the
- stream are deflateReset or deflateEnd.
-
- Z_FINISH can be used immediately after deflateInit if all the compression
- is to be done in a single step. In this case, avail_out must be at least
- 0.1% larger than avail_in plus 12 bytes. If deflate does not return
- Z_STREAM_END, then it must be called again as described above.
-
- deflate() sets strm->adler to the adler32 checksum of all input read
- so far (that is, total_in bytes).
-
- deflate() may update data_type if it can make a good guess about
- the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
- binary. This field is only for information purposes and does not affect
- the compression algorithm in any manner.
-
- deflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if all input has been
- consumed and all output has been produced (only when flush is set to
- Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
- if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
- (for example avail_in or avail_out was zero).
-*/
-
-
-ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
- stream state was inconsistent, Z_DATA_ERROR if the stream was freed
- prematurely (some input or output was discarded). In the error case,
- msg may be set but then points to a static string (which must not be
- deallocated).
-*/
-
-
-/*
-ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
-
- Initializes the internal stream state for decompression. The fields
- next_in, avail_in, zalloc, zfree and opaque must be initialized before by
- the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
- value depends on the compression method), inflateInit determines the
- compression method from the zlib header and allocates all data structures
- accordingly; otherwise the allocation will be deferred to the first call of
- inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
- use default allocation functions.
-
- inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
- version assumed by the caller. msg is set to null if there is no error
- message. inflateInit does not perform any decompression apart from reading
- the zlib header if present: this will be done by inflate(). (So next_in and
- avail_in may be modified, but next_out and avail_out are unchanged.)
-*/
-
-
-ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
-/*
- inflate decompresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may some
- introduce some output latency (reading input without producing any output)
- except when forced to flush.
-
- The detailed semantics are as follows. inflate performs one or both of the
- following actions:
-
- - Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() provides as much output as possible, until there
- is no more input data or no more space in the output buffer (see below
- about the flush parameter).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate(). If inflate returns Z_OK and with zero avail_out, it
- must be called again after making room in the output buffer because there
- might be more output pending.
-
- If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
- output as possible to the output buffer. The flushing behavior of inflate is
- not specified for values of the flush parameter other than Z_SYNC_FLUSH
- and Z_FINISH, but the current implementation actually flushes as much output
- as possible anyway.
-
- inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster routine
- may be used for the single inflate() call.
-
- If a preset dictionary is needed at this point (see inflateSetDictionary
- below), inflate sets strm-adler to the adler32 checksum of the
- dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
- it sets strm->adler to the adler32 checksum of all output produced
- so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
- an error code as described below. At the end of the stream, inflate()
- checks that its computed adler32 checksum is equal to that saved by the
- compressor and returns Z_STREAM_END only if the checksum is correct.
-
- inflate() returns Z_OK if some progress has been made (more input processed
- or more output produced), Z_STREAM_END if the end of the compressed data has
- been reached and all uncompressed output has been produced, Z_NEED_DICT if a
- preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
- corrupted (input stream not conforming to the zlib format or incorrect
- adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
- (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if no progress is possible or if there was not
- enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
- case, the application may then call inflateSync to look for a good
- compression block.
-*/
-
-
-ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
-*/
-
- /* Advanced functions */
-
-/*
- The following functions are needed only in some special applications.
-*/
-
-/*
-ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
- int level,
- int method,
- int windowBits,
- int memLevel,
- int strategy));
-
- This is another version of deflateInit with more compression options. The
- fields next_in, zalloc, zfree and opaque must be initialized before by
- the caller.
-
- The method parameter is the compression method. It must be Z_DEFLATED in
- this version of the library.
-
- The windowBits parameter is the base two logarithm of the window size
- (the size of the history buffer). It should be in the range 8..15 for this
- version of the library. Larger values of this parameter result in better
- compression at the expense of memory usage. The default value is 15 if
- deflateInit is used instead.
-
- The memLevel parameter specifies how much memory should be allocated
- for the internal compression state. memLevel=1 uses minimum memory but
- is slow and reduces compression ratio; memLevel=9 uses maximum memory
- for optimal speed. The default value is 8. See zconf.h for total memory
- usage as a function of windowBits and memLevel.
-
- The strategy parameter is used to tune the compression algorithm. Use the
- value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
- filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
- string match). Filtered data consists mostly of small values with a
- somewhat random distribution. In this case, the compression algorithm is
- tuned to compress them better. The effect of Z_FILTERED is to force more
- Huffman coding and less string matching; it is somewhat intermediate
- between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
- the compression ratio but not the correctness of the compressed output even
- if it is not set appropriately.
-
- deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
- method). msg is set to null if there is no error message. deflateInit2 does
- not perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the compression dictionary from the given byte sequence
- without producing any compressed output. This function must be called
- immediately after deflateInit, deflateInit2 or deflateReset, before any
- call of deflate. The compressor and decompressor must use exactly the same
- dictionary (see inflateSetDictionary).
-
- The dictionary should consist of strings (byte sequences) that are likely
- to be encountered later in the data to be compressed, with the most commonly
- used strings preferably put towards the end of the dictionary. Using a
- dictionary is most useful when the data to be compressed is short and can be
- predicted with good accuracy; the data can then be compressed better than
- with the default empty dictionary.
-
- Depending on the size of the compression data structures selected by
- deflateInit or deflateInit2, a part of the dictionary may in effect be
- discarded, for example if the dictionary is larger than the window size in
- deflate or deflate2. Thus the strings most likely to be useful should be
- put at the end of the dictionary, not at the front.
-
- Upon return of this function, strm->adler is set to the Adler32 value
- of the dictionary; the decompressor may later use this value to determine
- which dictionary has been used by the compressor. (The Adler32 value
- applies to the whole dictionary even if only a subset of the dictionary is
- actually used by the compressor.)
-
- deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent (for example if deflate has already been called for this stream
- or if the compression method is bsort). deflateSetDictionary does not
- perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
- z_streamp source));
-/*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when several compression strategies will be
- tried, for example when there are several ways of pre-processing the input
- data with a filter. The streams that will be discarded should then be freed
- by calling deflateEnd. Note that deflateCopy duplicates the internal
- compression state which can be quite large, so this strategy is slow and
- can consume lots of memory.
-
- deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
-*/
-
-ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
-/*
- This function is equivalent to deflateEnd followed by deflateInit,
- but does not free and reallocate all the internal compression state.
- The stream will keep the same compression level and any other attributes
- that may have been set by deflateInit2.
-
- deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
- int level,
- int strategy));
-/*
- Dynamically update the compression level and compression strategy. The
- interpretation of level and strategy is as in deflateInit2. This can be
- used to switch between compression and straight copy of the input data, or
- to switch to a different kind of input data requiring a different
- strategy. If the compression level is changed, the input available so far
- is compressed with the old level (and may be flushed); the new level will
- take effect only at the next call of deflate().
-
- Before the call of deflateParams, the stream state must be set as for
- a call of deflate(), since the currently available input may have to
- be compressed and flushed. In particular, strm->avail_out must be non-zero.
-
- deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
- stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
- if strm->avail_out was zero.
-*/
-
-/*
-ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
- int windowBits));
-
- This is another version of inflateInit with an extra parameter. The
- fields next_in, avail_in, zalloc, zfree and opaque must be initialized
- before by the caller.
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library. The default value is 15 if inflateInit is used
- instead. If a compressed stream with a larger window size is given as
- input, inflate() will return with the error code Z_DATA_ERROR instead of
- trying to allocate a larger window.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
- memLevel). msg is set to null if there is no error message. inflateInit2
- does not perform any decompression apart from reading the zlib header if
- present: this will be done by inflate(). (So next_in and avail_in may be
- modified, but next_out and avail_out are unchanged.)
-*/
-
-ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the decompression dictionary from the given uncompressed byte
- sequence. This function must be called immediately after a call of inflate
- if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
- can be determined from the Adler32 value returned by this call of
- inflate. The compressor and decompressor must use exactly the same
- dictionary (see deflateSetDictionary).
-
- inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
- expected one (incorrect Adler32 value). inflateSetDictionary does not
- perform any decompression: this will be done by subsequent calls of
- inflate().
-*/
-
-ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
-/*
- Skips invalid compressed data until a full flush point (see above the
- description of deflate with Z_FULL_FLUSH) can be found, or until all
- available input is skipped. No output is provided.
-
- inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no flush point has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
-*/
-
-ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
-/*
- This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
-
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-
- /* utility functions */
-
-/*
- The following utility functions are implemented on top of the
- basic stream-oriented functions. To simplify the interface, some
- default options are assumed (compression level and memory usage,
- standard memory allocation functions). The source code of these
- utility functions can easily be modified if you need special options.
-*/
-
-ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Compresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be at least 0.1% larger than
- sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
- compressed buffer.
- This function can be used to compress a whole file at once if the
- input file is mmap'ed.
- compress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer.
-*/
-
-ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen,
- int level));
-/*
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least 0.1% larger than sourceLen plus
- 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-
-ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted.
-*/
-
-
-typedef voidp gzFile;
-
-ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
-/*
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb") but can also include a compression level
- ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
- Huffman only compression as in "wb1h". (See the description
- of deflateInit2 for more information about the strategy parameter.)
-
- gzopen can be used to read a file which is not in gzip format; in this
- case gzread will directly read from the file without decompression.
-
- gzopen returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR). */
-
-ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
-/*
- gzdopen() associates a gzFile with the file descriptor fd. File
- descriptors are obtained from calls like open, dup, creat, pipe or
- fileno (in the file has been previously opened with fopen).
- The mode parameter is as in gzopen.
- The next call of gzclose on the returned gzFile will also close the
- file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
- descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
- gzdopen returns NULL if there was insufficient memory to allocate
- the (de)compression state.
-*/
-
-ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
-/*
- Dynamically update the compression level or strategy. See the description
- of deflateInit2 for the meaning of these parameters.
- gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
- opened for writing.
-*/
-
-ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
-/*
- Reads the given number of uncompressed bytes from the compressed file.
- If the input file was not in gzip format, gzread copies the given number
- of bytes into the buffer.
- gzread returns the number of uncompressed bytes actually read (0 for
- end of file, -1 for error). */
-
-ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
- cvoidp buf, unsigned len));
-/*
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of uncompressed bytes actually written
- (0 in case of error).
-*/
-
-ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
-/*
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error).
-*/
-
-ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
-/*
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-
-ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
-/*
- Reads bytes from the compressed file until len-1 characters are read, or
- a newline character is read and transferred to buf, or an end-of-file
- condition is encountered. The string is then terminated with a null
- character.
- gzgets returns buf, or Z_NULL in case of error.
-*/
-
-ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
-/*
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-
-ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
-/*
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-
-ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
-/*
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function. The return value is the zlib
- error number (see function gzerror below). gzflush returns Z_OK if
- the flush parameter is Z_FINISH and all output could be flushed.
- gzflush should be called only when strictly necessary because it can
- degrade compression.
-*/
-
-ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
- z_off_t offset, int whence));
-/*
- Sets the starting position for the next gzread or gzwrite on the
- given compressed file. The offset represents a number of bytes in the
- uncompressed data stream. The whence parameter is defined as in lseek(2);
- the value SEEK_END is not supported.
- If the file is opened for reading, this function is emulated but can be
- extremely slow. If the file is opened for writing, only forward seeks are
- supported; gzseek then compresses a sequence of zeroes up to the new
- starting position.
-
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error, in
- particular if the file is opened for writing and the new starting position
- would be before the current position.
-*/
-
-ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
-/*
- Rewinds the given file. This function is supported only for reading.
-
- gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
-*/
-
-ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
-/*
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-
- gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
-*/
-
-ZEXTERN int ZEXPORT gzeof OF((gzFile file));
-/*
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-
-ZEXTERN int ZEXPORT gzclose OF((gzFile file));
-/*
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state. The return value is the zlib
- error number (see function gzerror below).
-*/
-
-ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
-/*
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-
- /* checksum functions */
-
-/*
- These functions are not related to compression but are exported
- anyway because they might be useful in applications using the
- compression library.
-*/
-
-ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-
-ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
-/*
- Update a running crc with the bytes buf[0..len-1] and return the updated
- crc. If buf is NULL, this function returns the required initial value
- for the crc. Pre- and post-conditioning (one's complement) is performed
- within this function so it shouldn't be done by the application.
- Usage example:
-
- uLong crc = crc32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- crc = crc32(crc, buffer, length);
- }
- if (crc != original_crc) error();
-*/
-
-
- /* various hacks, don't look :) */
-
-/* deflateInit and inflateInit are macros to allow checking the zlib version
- * and the compiler's view of z_stream:
- */
-ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
- int windowBits, int memLevel,
- int strategy, const char *version,
- int stream_size));
-ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
- const char *version, int stream_size));
-#define deflateInit(strm, level) \
- deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit(strm) \
- inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
- deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
- (strategy), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit2(strm, windowBits) \
- inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-
-
-#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
- struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-ZEXTERN const char * ZEXPORT zError OF((int err));
-ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
-ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ZLIB_H */
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.1.4, March 11th, 2002
+
+ Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.1.4"
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed
+ data. This version of the library supports only one compression method
+ (deflation) but other algorithms will be added later and will have the same
+ stream interface.
+
+ Compression can be done in a single step if the buffers are large
+ enough (for example if an input file is mmap'ed), or can be done by
+ repeated calls of the compression function. In the latter case, the
+ application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never
+ crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total nb of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total nb of bytes output so far */
+
+ char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: ascii or binary */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ The application must update next_in and avail_in when avail_in has
+ dropped to zero. It must update next_out and avail_out when avail_out
+ has dropped to zero. The application must initialize zalloc, zfree and
+ opaque before calling the init function. All other fields are set by the
+ compression library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this
+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
+ have their offset normalized to zero. The default allocation function
+ provided by this library ensures this (see zutil.c). To reduce memory
+ requirements and avoid any allocation of 64K objects, at the expense of
+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or
+ progress reports. After compression, total_in holds the total size of
+ the uncompressed data and may be saved for use in the decompressor
+ (particularly if the decompressor wants to decompress everything in
+ a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+/* Allowed flush values; see deflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_ASCII 1
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is
+ not compatible with the zlib.h header file used by the application.
+ This check is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller.
+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+ use default allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
+ all (the input data is simply copied a block at a time).
+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+ compression (currently equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION).
+ msg is set to null if there is no error message. deflateInit does not
+ perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce some
+ output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications).
+ Some output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating avail_in or avail_out accordingly; avail_out
+ should never be zero before the call. The application can consume the
+ compressed output when it wants, for example when the output buffer is full
+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+ and with zero avail_out, it must be called again after making room in the
+ output buffer because there might be more output pending.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In particular
+ avail_in is zero after the call if enough output space has been provided
+ before the call.) Flushing may degrade compression for some compression
+ algorithms and so it should be used only when necessary.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ the compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out).
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there
+ was enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the
+ stream are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least
+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return
+ Z_STREAM_END, then it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update data_type if it can make a good guess about
+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect
+ the compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero).
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case,
+ msg may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+ value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller. msg is set to null if there is no error
+ message. inflateInit does not perform any decompression apart from reading
+ the zlib header if present: this will be done by inflate(). (So next_in and
+ avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may some
+ introduce some output latency (reading input without producing any output)
+ except when forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing
+ will resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there
+ is no more input data or no more space in the output buffer (see below
+ about the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating the next_* and avail_* values accordingly.
+ The application can consume the uncompressed output when it wants, for
+ example when the output buffer is full (avail_out == 0), or after each
+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+ must be called again after making room in the output buffer because there
+ might be more output pending.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
+ output as possible to the output buffer. The flushing behavior of inflate is
+ not specified for values of the flush parameter other than Z_SYNC_FLUSH
+ and Z_FINISH, but the current implementation actually flushes as much output
+ as possible anyway.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step
+ (a single call of inflate), the parameter flush should be set to
+ Z_FINISH. In this case all pending input is processed and all pending
+ output is flushed; avail_out must be large enough to hold all the
+ uncompressed data. (The size of the uncompressed data may have been saved
+ by the compressor for this purpose.) The next operation on this stream must
+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+ is never required, but can be used to inform inflate that a faster routine
+ may be used for the single inflate() call.
+
+ If a preset dictionary is needed at this point (see inflateSetDictionary
+ below), inflate sets strm-adler to the adler32 checksum of the
+ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
+ it sets strm->adler to the adler32 checksum of all output produced
+ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
+ an error code as described below. At the end of the stream, inflate()
+ checks that its computed adler32 checksum is equal to that saved by the
+ compressor and returns Z_STREAM_END only if the checksum is correct.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect
+ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
+ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if no progress is possible or if there was not
+ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
+ case, the application may then call inflateSync to look for a good
+ compression block.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by
+ the caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but
+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
+ for optimal speed. The default value is 8. See zconf.h for total memory
+ usage as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match). Filtered data consists mostly of small values with a
+ somewhat random distribution. In this case, the compression algorithm is
+ tuned to compress them better. The effect of Z_FILTERED is to force more
+ Huffman coding and less string matching; it is somewhat intermediate
+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
+ the compression ratio but not the correctness of the compressed output even
+ if it is not set appropriately.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+ method). msg is set to null if there is no error message. deflateInit2 does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. This function must be called
+ immediately after deflateInit, deflateInit2 or deflateReset, before any
+ call of deflate. The compressor and decompressor must use exactly the same
+ dictionary (see inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size in
+ deflate or deflate2. Thus the strings most likely to be useful should be
+ put at the end of the dictionary, not at the front.
+
+ Upon return of this function, strm->adler is set to the Adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The Adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.)
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if the compression method is bsort). deflateSetDictionary does not
+ perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and
+ can consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state.
+ The stream will keep the same compression level and any other attributes
+ that may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different
+ strategy. If the compression level is changed, the input available so far
+ is compressed with the old level (and may be flushed); the new level will
+ take effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to
+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+ if strm->avail_out was zero.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. If a compressed stream with a larger window size is given as
+ input, inflate() will return with the error code Z_DATA_ERROR instead of
+ trying to allocate a larger window.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
+ memLevel). msg is set to null if there is no error message. inflateInit2
+ does not perform any decompression apart from reading the zlib header if
+ present: this will be done by inflate(). (So next_in and avail_in may be
+ modified, but next_out and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate
+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the Adler32 value returned by this call of
+ inflate. The compressor and decompressor must use exactly the same
+ dictionary (see deflateSetDictionary).
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect Adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a full flush point (see above the
+ description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+ case, the application may save the current current value of total_in which
+ indicates where valid compressed data was found. In the error case, the
+ application may repeatedly call inflateSync, providing more input each time,
+ until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state.
+ The stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the
+ basic stream-oriented functions. To simplify the interface, some
+ default options are assumed (compression level and memory usage,
+ standard memory allocation functions). The source code of these
+ utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be at least 0.1% larger than
+ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
+ compressed buffer.
+ This function can be used to compress a whole file at once if the
+ input file is mmap'ed.
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+/*
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
+ is as in fopen ("rb" or "wb") but can also include a compression level
+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+ Huffman only compression as in "wb1h". (See the description
+ of deflateInit2 for more information about the strategy parameter.)
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression.
+
+ gzopen returns NULL if the file could not be opened or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR). */
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen() associates a gzFile with the file descriptor fd. File
+ descriptors are obtained from calls like open, dup, creat, pipe or
+ fileno (in the file has been previously opened with fopen).
+ The mode parameter is as in gzopen.
+ The next call of gzclose on the returned gzFile will also close the
+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+ gzdopen returns NULL if there was insufficient memory to allocate
+ the (de)compression state.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file.
+ If the input file was not in gzip format, gzread copies the given number
+ of bytes into the buffer.
+ gzread returns the number of uncompressed bytes actually read (0 for
+ end of file, -1 for error). */
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ cvoidp buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes actually written
+ (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or
+ a newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. The string is then terminated with a null
+ character.
+ gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file.
+ gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte
+ or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter
+ flush is as in the deflate() function. The return value is the zlib
+ error number (see function gzerror below). gzflush returns Z_OK if
+ the flush parameter is Z_FINISH and all output could be flushed.
+ gzflush should be called only when strictly necessary because it can
+ degrade compression.
+*/
+
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+/*
+ Sets the starting position for the next gzread or gzwrite on the
+ given compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+/*
+ Returns the starting position for the next gzread or gzwrite on the
+ given compressed file. This position represents a number of bytes in the
+ uncompressed data stream.
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state. The return value is the zlib
+ error number (see function gzerror below).
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the
+ given compressed file. errnum is set to zlib error number. If an
+ error occurred in the file system and not in the compression library,
+ errnum is set to Z_ERRNO and the application may consult errno
+ to get the exact error code.
+*/
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the
+ compression library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is NULL, this function returns
+ the required initial value for the checksum.
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster. Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running crc with the bytes buf[0..len-1] and return the updated
+ crc. If buf is NULL, this function returns the required initial value
+ for the crc. Pre- and post-conditioning (one's complement) is performed
+ within this function so it shouldn't be done by the application.
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char * ZEXPORT zError OF((int err));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZLIB_H */
diff --git a/lib/zlib/include/zutil.h b/lib/zlib/include/zutil.h
index 300a4c1..eed3624 100644
--- a/lib/zlib/include/zutil.h
+++ b/lib/zlib/include/zutil.h
@@ -1,220 +1,220 @@
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id: zutil.h,v 1.2 2004-11-27 21:43:51 pixel Exp $ */
-
-#ifndef _Z_UTIL_H
-#define _Z_UTIL_H
-
-#include "zlib.h"
-
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
-#else
-# include <errno.h>
-#endif
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-typedef unsigned char uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long ulg;
-
-extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
-/* (size given to avoid silly warnings with Visual C++) */
-
-#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-
-#define ERR_RETURN(strm,err) \
- return (strm->msg = (char*)ERR_MSG(err), (err))
-/* To be used only when the state is known to be valid */
-
- /* common constants */
-
-#ifndef DEF_WBITS
-# define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES 2
-/* The three kinds of block type */
-
-#define MIN_MATCH 3
-#define MAX_MATCH 258
-/* The minimum and maximum match lengths */
-
-#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
- /* target dependencies */
-
-#ifdef MSDOS
-# define OS_CODE 0x00
-# if defined(__TURBOC__) || defined(__BORLANDC__)
-# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
- /* Allow compilation with ANSI keywords only enabled */
- void _Cdecl farfree( void *block );
- void *_Cdecl farmalloc( unsigned long nbytes );
-# else
-# include <alloc.h>
-# endif
-# else /* MSC or DJGPP */
-# include <malloc.h>
-# endif
-#endif
-
-#ifdef OS2
-# define OS_CODE 0x06
-#endif
-
-#ifdef WIN32 /* Window 95 & Windows NT */
-# define OS_CODE 0x0b
-#endif
-
-#if defined(VAXC) || defined(VMS)
-# define OS_CODE 0x02
-# define F_OPEN(name, mode) \
- fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-#endif
-
-#ifdef AMIGA
-# define OS_CODE 0x01
-#endif
-
-#if defined(ATARI) || defined(atarist)
-# define OS_CODE 0x05
-#endif
-
-#if defined(MACOS) || defined(TARGET_OS_MAC)
-# define OS_CODE 0x07
-# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-# include <unix.h> /* for fdopen */
-# else
-# ifndef fdopen
-# define fdopen(fd,mode) NULL /* No fdopen() */
-# endif
-# endif
-#endif
-
-#ifdef __50SERIES /* Prime/PRIMOS */
-# define OS_CODE 0x0F
-#endif
-
-#ifdef TOPS20
-# define OS_CODE 0x0a
-#endif
-
-#if defined(_BEOS_) || defined(RISCOS)
-# define fdopen(fd,mode) NULL /* No fdopen() */
-#endif
-
-#if (defined(_MSC_VER) && (_MSC_VER > 600))
-# define fdopen(fd,type) _fdopen(fd,type)
-#endif
-
-
- /* Common defaults */
-
-#ifndef OS_CODE
-# define OS_CODE 0x03 /* assume Unix */
-#endif
-
-#ifndef F_OPEN
-# define F_OPEN(name, mode) fopen((name), (mode))
-#endif
-
- /* functions */
-
-#ifdef HAVE_STRERROR
- extern char *strerror OF((int));
-# define zstrerror(errnum) strerror(errnum)
-#else
-# define zstrerror(errnum) ""
-#endif
-
-#if defined(pyr)
-# define NO_MEMCPY
-#endif
-#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
- /* Use our own functions for small and medium model with MSC <= 5.0.
- * You may have to use the same strategy for Borland C (untested).
- * The __SC__ check is for Symantec.
- */
-# define NO_MEMCPY
-#endif
-#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-# define HAVE_MEMCPY
-#endif
-#ifdef HAVE_MEMCPY
-# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-# define zmemcpy _fmemcpy
-# define zmemcmp _fmemcmp
-# define zmemzero(dest, len) _fmemset(dest, 0, len)
-# else
-# define zmemcpy memcpy
-# define zmemcmp memcmp
-# define zmemzero(dest, len) memset(dest, 0, len)
-# endif
-#else
- extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
- extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
- extern void zmemzero OF((Bytef* dest, uInt len));
-#endif
-
-/* Diagnostic functions */
-#ifdef DEBUG
-# include <stdio.h>
- extern int z_verbose;
- extern void z_error OF((char *m));
-# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-# define Trace(x) {if (z_verbose>=0) fprintf x ;}
-# define Tracev(x) {if (z_verbose>0) fprintf x ;}
-# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-#else
-# define Assert(cond,msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
-#endif
-
-
-typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
- uInt len));
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-void zcfree OF((voidpf opaque, voidpf ptr));
-
-#define ZALLOC(strm, items, size) \
- (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-
-#endif /* _Z_UTIL_H */
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id: zutil.h,v 1.3 2004-11-27 21:46:12 pixel Exp $ */
+
+#ifndef _Z_UTIL_H
+#define _Z_UTIL_H
+
+#include "zlib.h"
+
+#ifdef STDC
+# include <stddef.h>
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+ extern int errno;
+#else
+# include <errno.h>
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+ return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+ /* common constants */
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+ /* target dependencies */
+
+#ifdef MSDOS
+# define OS_CODE 0x00
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include <alloc.h>
+# endif
+# else /* MSC or DJGPP */
+# include <malloc.h>
+# endif
+#endif
+
+#ifdef OS2
+# define OS_CODE 0x06
+#endif
+
+#ifdef WIN32 /* Window 95 & Windows NT */
+# define OS_CODE 0x0b
+#endif
+
+#if defined(VAXC) || defined(VMS)
+# define OS_CODE 0x02
+# define F_OPEN(name, mode) \
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#ifdef AMIGA
+# define OS_CODE 0x01
+#endif
+
+#if defined(ATARI) || defined(atarist)
+# define OS_CODE 0x05
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+# define OS_CODE 0x07
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
+# endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+# define OS_CODE 0x0F
+#endif
+
+#ifdef TOPS20
+# define OS_CODE 0x0a
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600))
+# define fdopen(fd,type) _fdopen(fd,type)
+#endif
+
+
+ /* Common defaults */
+
+#ifndef OS_CODE
+# define OS_CODE 0x03 /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+# define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+ /* functions */
+
+#ifdef HAVE_STRERROR
+ extern char *strerror OF((int));
+# define zstrerror(errnum) strerror(errnum)
+#else
+# define zstrerror(errnum) ""
+#endif
+
+#if defined(pyr)
+# define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+ * You may have to use the same strategy for Borland C (untested).
+ * The __SC__ check is for Symantec.
+ */
+# define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+# define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+# define zmemcpy _fmemcpy
+# define zmemcmp _fmemcmp
+# define zmemzero(dest, len) _fmemset(dest, 0, len)
+# else
+# define zmemcpy memcpy
+# define zmemcmp memcmp
+# define zmemzero(dest, len) memset(dest, 0, len)
+# endif
+#else
+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# include <stdio.h>
+ extern int z_verbose;
+ extern void z_error OF((char *m));
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+
+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
+ uInt len));
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void zcfree OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* _Z_UTIL_H */
diff --git a/lib/zlib/src/adler32.c b/lib/zlib/src/adler32.c
index eeffe9b..e19806c 100644
--- a/lib/zlib/src/adler32.c
+++ b/lib/zlib/src/adler32.c
@@ -1,48 +1,48 @@
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: adler32.c,v 1.2 2004-11-27 21:35:22 pixel Exp $ */
-
-#include "zlib.h"
-
-#define BASE 65521L /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
-#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf) DO8(buf,0); DO8(buf,8);
-
-/* ========================================================================= */
-uLong ZEXPORT adler32(adler, buf, len)
- uLong adler;
- const Bytef *buf;
- uInt len;
-{
- unsigned long s1 = adler & 0xffff;
- unsigned long s2 = (adler >> 16) & 0xffff;
- int k;
-
- if (buf == Z_NULL) return 1L;
-
- while (len > 0) {
- k = len < NMAX ? len : NMAX;
- len -= k;
- while (k >= 16) {
- DO16(buf);
- buf += 16;
- k -= 16;
- }
- if (k != 0) do {
- s1 += *buf++;
- s2 += s1;
- } while (--k);
- s1 %= BASE;
- s2 %= BASE;
- }
- return (s2 << 16) | s1;
-}
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id: adler32.c,v 1.3 2004-11-27 21:46:13 pixel Exp $ */
+
+#include "zlib.h"
+
+#define BASE 65521L /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ uInt len;
+{
+ unsigned long s1 = adler & 0xffff;
+ unsigned long s2 = (adler >> 16) & 0xffff;
+ int k;
+
+ if (buf == Z_NULL) return 1L;
+
+ while (len > 0) {
+ k = len < NMAX ? len : NMAX;
+ len -= k;
+ while (k >= 16) {
+ DO16(buf);
+ buf += 16;
+ k -= 16;
+ }
+ if (k != 0) do {
+ s1 += *buf++;
+ s2 += s1;
+ } while (--k);
+ s1 %= BASE;
+ s2 %= BASE;
+ }
+ return (s2 << 16) | s1;
+}
diff --git a/lib/zlib/src/compress.c b/lib/zlib/src/compress.c
index d5e2d4b..439c5e1 100644
--- a/lib/zlib/src/compress.c
+++ b/lib/zlib/src/compress.c
@@ -1,68 +1,68 @@
-/* compress.c -- compress a memory buffer
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: compress.c,v 1.2 2004-11-27 21:35:22 pixel Exp $ */
-
-#include "zlib.h"
-
-/* ===========================================================================
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least 0.1% larger than sourceLen plus
- 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
- int level;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
-#ifdef MAXSEG_64K
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-#endif
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
-
- err = deflateInit(&stream, level);
- if (err != Z_OK) return err;
-
- err = deflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- deflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = deflateEnd(&stream);
- return err;
-}
-
-/* ===========================================================================
- */
-int ZEXPORT compress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
-}
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id: compress.c,v 1.3 2004-11-27 21:46:13 pixel Exp $ */
+
+#include "zlib.h"
+
+/* ===========================================================================
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+ int level;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = deflateInit(&stream, level);
+ if (err != Z_OK) return err;
+
+ err = deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ deflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out;
+
+ err = deflateEnd(&stream);
+ return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
diff --git a/lib/zlib/src/crc32.c b/lib/zlib/src/crc32.c
index 434d6f9..0059f3d 100644
--- a/lib/zlib/src/crc32.c
+++ b/lib/zlib/src/crc32.c
@@ -1,162 +1,162 @@
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: crc32.c,v 1.2 2004-11-27 21:35:22 pixel Exp $ */
-
-#include "zlib.h"
-
-#define local static
-
-#ifdef DYNAMIC_CRC_TABLE
-
-local int crc_table_empty = 1;
-local uLongf crc_table[256];
-local void make_crc_table OF((void));
-
-/*
- Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
- x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-
- Polynomials over GF(2) are represented in binary, one bit per coefficient,
- with the lowest powers in the most significant bit. Then adding polynomials
- is just exclusive-or, and multiplying a polynomial by x is a right shift by
- one. If we call the above polynomial p, and represent a byte as the
- polynomial q, also with the lowest power in the most significant bit (so the
- byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
- where a mod b means the remainder after dividing a by b.
-
- This calculation is done using the shift-register method of multiplying and
- taking the remainder. The register is initialized to zero, and for each
- incoming bit, x^32 is added mod p to the register if the bit is a one (where
- x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
- x (which is shifting right by one and adding x^32 mod p if the bit shifted
- out is a one). We start with the highest power (least significant bit) of
- q and repeat for all eight bits of q.
-
- The table is simply the CRC of all possible eight bit values. This is all
- the information needed to generate CRC's on data a byte at a time for all
- combinations of CRC register values and incoming bytes.
-*/
-local void make_crc_table()
-{
- uLong c;
- int n, k;
- uLong poly; /* polynomial exclusive-or pattern */
- /* terms of polynomial defining this crc (except x^32): */
- static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
- /* make exclusive-or pattern from polynomial (0xedb88320L) */
- poly = 0L;
- for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
- poly |= 1L << (31 - p[n]);
-
- for (n = 0; n < 256; n++)
- {
- c = (uLong)n;
- for (k = 0; k < 8; k++)
- c = c & 1 ? poly ^ (c >> 1) : c >> 1;
- crc_table[n] = c;
- }
- crc_table_empty = 0;
-}
-#else
-/* ========================================================================
- * Table of CRC-32's of all single-byte values (made by make_crc_table)
- */
-local const uLongf crc_table[256] = {
- 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
- 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
- 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
- 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
- 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
- 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
- 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
- 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
- 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
- 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
- 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
- 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
- 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
- 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
- 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
- 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
- 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
- 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
- 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
- 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
- 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
- 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
- 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
- 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
- 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
- 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
- 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
- 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
- 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
- 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
- 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
- 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
- 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
- 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
- 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
- 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
- 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
- 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
- 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
- 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
- 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
- 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
- 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
- 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
- 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
- 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
- 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
- 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
- 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
- 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
- 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
- 0x2d02ef8dL
-};
-#endif
-
-/* =========================================================================
- * This function can be used by asm versions of crc32()
- */
-const uLongf * ZEXPORT get_crc_table()
-{
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty) make_crc_table();
-#endif
- return (const uLongf *)crc_table;
-}
-
-/* ========================================================================= */
-#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
-#define DO2(buf) DO1(buf); DO1(buf);
-#define DO4(buf) DO2(buf); DO2(buf);
-#define DO8(buf) DO4(buf); DO4(buf);
-
-/* ========================================================================= */
-uLong ZEXPORT crc32(crc, buf, len)
- uLong crc;
- const Bytef *buf;
- uInt len;
-{
- if (buf == Z_NULL) return 0L;
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif
- crc = crc ^ 0xffffffffL;
- while (len >= 8)
- {
- DO8(buf);
- len -= 8;
- }
- if (len) do {
- DO1(buf);
- } while (--len);
- return crc ^ 0xffffffffL;
-}
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id: crc32.c,v 1.3 2004-11-27 21:46:13 pixel Exp $ */
+
+#include "zlib.h"
+
+#define local static
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local int crc_table_empty = 1;
+local uLongf crc_table[256];
+local void make_crc_table OF((void));
+
+/*
+ Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ out is a one). We start with the highest power (least significant bit) of
+ q and repeat for all eight bits of q.
+
+ The table is simply the CRC of all possible eight bit values. This is all
+ the information needed to generate CRC's on data a byte at a time for all
+ combinations of CRC register values and incoming bytes.
+*/
+local void make_crc_table()
+{
+ uLong c;
+ int n, k;
+ uLong poly; /* polynomial exclusive-or pattern */
+ /* terms of polynomial defining this crc (except x^32): */
+ static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* make exclusive-or pattern from polynomial (0xedb88320L) */
+ poly = 0L;
+ for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
+ poly |= 1L << (31 - p[n]);
+
+ for (n = 0; n < 256; n++)
+ {
+ c = (uLong)n;
+ for (k = 0; k < 8; k++)
+ c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+ crc_table[n] = c;
+ }
+ crc_table_empty = 0;
+}
+#else
+/* ========================================================================
+ * Table of CRC-32's of all single-byte values (made by make_crc_table)
+ */
+local const uLongf crc_table[256] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+ 0x2d02ef8dL
+};
+#endif
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const uLongf * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty) make_crc_table();
+#endif
+ return (const uLongf *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO2(buf) DO1(buf); DO1(buf);
+#define DO4(buf) DO2(buf); DO2(buf);
+#define DO8(buf) DO4(buf); DO4(buf);
+
+/* ========================================================================= */
+uLong ZEXPORT crc32(crc, buf, len)
+ uLong crc;
+ const Bytef *buf;
+ uInt len;
+{
+ if (buf == Z_NULL) return 0L;
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif
+ crc = crc ^ 0xffffffffL;
+ while (len >= 8)
+ {
+ DO8(buf);
+ len -= 8;
+ }
+ if (len) do {
+ DO1(buf);
+ } while (--len);
+ return crc ^ 0xffffffffL;
+}
diff --git a/lib/zlib/src/deflate.c b/lib/zlib/src/deflate.c
index a891418..7f60791 100644
--- a/lib/zlib/src/deflate.c
+++ b/lib/zlib/src/deflate.c
@@ -1,1350 +1,1350 @@
-/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process depends on being able to identify portions
- * of the input text which are identical to earlier input (within a
- * sliding window trailing behind the input currently being processed).
- *
- * The most straightforward technique turns out to be the fastest for
- * most input files: try all possible matches and select the longest.
- * The key feature of this algorithm is that insertions into the string
- * dictionary are very simple and thus fast, and deletions are avoided
- * completely. Insertions are performed at each input character, whereas
- * string matches are performed only when the previous match ends. So it
- * is preferable to spend more time in matches to allow very fast string
- * insertions and avoid deletions. The matching algorithm for small
- * strings is inspired from that of Rabin & Karp. A brute force approach
- * is used to find longer strings when a small match has been found.
- * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
- * (by Leonid Broukhis).
- * A previous version of this file used a more sophisticated algorithm
- * (by Fiala and Greene) which is guaranteed to run in linear amortized
- * time, but has a larger average cost, uses more memory and is patented.
- * However the F&G algorithm may be faster for some highly redundant
- * files if the parameter max_chain_length (described below) is too large.
- *
- * ACKNOWLEDGEMENTS
- *
- * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
- * I found it in 'freeze' written by Leonid Broukhis.
- * Thanks to many people for bug reports and testing.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- * Available in ftp://ds.internic.net/rfc/rfc1951.txt
- *
- * A description of the Rabin and Karp algorithm is given in the book
- * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
- *
- * Fiala,E.R., and Greene,D.H.
- * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
- *
- */
-
-/* @(#) $Id: deflate.c,v 1.2 2004-11-27 21:35:22 pixel Exp $ */
-
-#include "deflate.h"
-
-const char deflate_copyright[] =
- " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/* ===========================================================================
- * Function prototypes.
- */
-typedef enum {
- need_more, /* block not completed, need more input or more output */
- block_done, /* block flush performed */
- finish_started, /* finish started, need only more output at next deflate */
- finish_done /* finish done, accept no more input or output */
-} block_state;
-
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-/* Compression function. Returns the block state after the call. */
-
-local void fill_window OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast OF((deflate_state *s, int flush));
-local block_state deflate_slow OF((deflate_state *s, int flush));
-local void lm_init OF((deflate_state *s));
-local void putShortMSB OF((deflate_state *s, uInt b));
-local void flush_pending OF((z_streamp strm));
-local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-#ifdef ASMV
- void match_init OF((void)); /* asm code initialization */
- uInt longest_match OF((deflate_state *s, IPos cur_match));
-#else
-local uInt longest_match OF((deflate_state *s, IPos cur_match));
-#endif
-
-#ifdef DEBUG
-local void check_match OF((deflate_state *s, IPos start, IPos match,
- int length));
-#endif
-
-/* ===========================================================================
- * Local data
- */
-
-#define NIL 0
-/* Tail of hash chains */
-
-#ifndef TOO_FAR
-# define TOO_FAR 4096
-#endif
-/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-/* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
-typedef struct config_s {
- ush good_length; /* reduce lazy search above this match length */
- ush max_lazy; /* do not perform lazy search above this match length */
- ush nice_length; /* quit search above this match length */
- ush max_chain;
- compress_func func;
-} config;
-
-local const config configuration_table[10] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
-/* 2 */ {4, 5, 16, 8, deflate_fast},
-/* 3 */ {4, 6, 32, 32, deflate_fast},
-
-/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
-/* 5 */ {8, 16, 32, 32, deflate_slow},
-/* 6 */ {8, 16, 128, 128, deflate_slow},
-/* 7 */ {8, 32, 128, 256, deflate_slow},
-/* 8 */ {32, 128, 258, 1024, deflate_slow},
-/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
-
-/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
- * meaning.
- */
-
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-
-/* ===========================================================================
- * Update a hash value with the given input byte
- * IN assertion: all calls to to UPDATE_HASH are made with consecutive
- * input characters, so that a running hash key can be computed from the
- * previous key instead of complete recalculation each time.
- */
-#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-
-
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * If this file is compiled with -DFASTEST, the compression level is forced
- * to 1, and no hash chains are maintained.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
- */
-#ifdef FASTEST
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#else
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#endif
-
-/* ===========================================================================
- * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
- * prev[] will be initialized on the fly.
- */
-#define CLEAR_HASH(s) \
- s->head[s->hash_size-1] = NIL; \
- zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
-/* ========================================================================= */
-int ZEXPORT deflateInit_(strm, level, version, stream_size)
- z_streamp strm;
- int level;
- const char *version;
- int stream_size;
-{
- return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, version, stream_size);
- /* To do: ignore strm->next_in if we use it as window */
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- version, stream_size)
- z_streamp strm;
- int level;
- int method;
- int windowBits;
- int memLevel;
- int strategy;
- const char *version;
- int stream_size;
-{
- deflate_state *s;
- int noheader = 0;
- static const char* my_version = ZLIB_VERSION;
-
- ushf *overlay;
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
- * output size for (length,distance) codes is <= 24 bits.
- */
-
- if (version == Z_NULL || version[0] != my_version[0] ||
- stream_size != sizeof(z_stream)) {
- return Z_VERSION_ERROR;
- }
- if (strm == Z_NULL) return Z_STREAM_ERROR;
-
- strm->msg = Z_NULL;
- if (strm->zalloc == Z_NULL) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == Z_NULL) strm->zfree = zcfree;
-
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#ifdef FASTEST
- level = 1;
-#endif
-
- if (windowBits < 0) { /* undocumented feature: suppress zlib header */
- noheader = 1;
- windowBits = -windowBits;
- }
- if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
- windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
- strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
- return Z_STREAM_ERROR;
- }
- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
- if (s == Z_NULL) return Z_MEM_ERROR;
- strm->state = (struct internal_state FAR *)s;
- s->strm = strm;
-
- s->noheader = noheader;
- s->w_bits = windowBits;
- s->w_size = 1 << s->w_bits;
- s->w_mask = s->w_size - 1;
-
- s->hash_bits = memLevel + 7;
- s->hash_size = 1 << s->hash_bits;
- s->hash_mask = s->hash_size - 1;
- s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
- s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
- s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-
- s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
- s->pending_buf = (uchf *) overlay;
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
- if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
- s->pending_buf == Z_NULL) {
- strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
- deflateEnd (strm);
- return Z_MEM_ERROR;
- }
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
- s->level = level;
- s->strategy = strategy;
- s->method = (Byte)method;
-
- return deflateReset(strm);
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
- z_streamp strm;
- const Bytef *dictionary;
- uInt dictLength;
-{
- deflate_state *s;
- uInt length = dictLength;
- uInt n;
- IPos hash_head = 0;
-
- if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
- strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
-
- s = strm->state;
- strm->adler = adler32(strm->adler, dictionary, dictLength);
-
- if (length < MIN_MATCH) return Z_OK;
- if (length > MAX_DIST(s)) {
- length = MAX_DIST(s);
-#ifndef USE_DICT_HEAD
- dictionary += dictLength - length; /* use the tail of the dictionary */
-#endif
- }
- zmemcpy(s->window, dictionary, length);
- s->strstart = length;
- s->block_start = (long)length;
-
- /* Insert all strings in the hash table (except for the last two bytes).
- * s->lookahead stays null, so s->ins_h will be recomputed at the next
- * call of fill_window.
- */
- s->ins_h = s->window[0];
- UPDATE_HASH(s, s->ins_h, s->window[1]);
- for (n = 0; n <= length - MIN_MATCH; n++) {
- INSERT_STRING(s, n, hash_head);
- }
- if (hash_head) hash_head = 0; /* to make compiler happy */
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateReset (strm)
- z_streamp strm;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
-
- strm->total_in = strm->total_out = 0;
- strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
- strm->data_type = Z_UNKNOWN;
-
- s = (deflate_state *)strm->state;
- s->pending = 0;
- s->pending_out = s->pending_buf;
-
- if (s->noheader < 0) {
- s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
- }
- s->status = s->noheader ? BUSY_STATE : INIT_STATE;
- strm->adler = 1;
- s->last_flush = Z_NO_FLUSH;
-
- _tr_init(s);
- lm_init(s);
-
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateParams(strm, level, strategy)
- z_streamp strm;
- int level;
- int strategy;
-{
- deflate_state *s;
- compress_func func;
- int err = Z_OK;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
-
- if (level == Z_DEFAULT_COMPRESSION) {
- level = 6;
- }
- if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
- return Z_STREAM_ERROR;
- }
- func = configuration_table[s->level].func;
-
- if (func != configuration_table[level].func && strm->total_in != 0) {
- /* Flush the last buffer: */
- err = deflate(strm, Z_PARTIAL_FLUSH);
- }
- if (s->level != level) {
- s->level = level;
- s->max_lazy_match = configuration_table[level].max_lazy;
- s->good_match = configuration_table[level].good_length;
- s->nice_match = configuration_table[level].nice_length;
- s->max_chain_length = configuration_table[level].max_chain;
- }
- s->strategy = strategy;
- return err;
-}
-
-/* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
-local void putShortMSB (s, b)
- deflate_state *s;
- uInt b;
-{
- put_byte(s, (Byte)(b >> 8));
- put_byte(s, (Byte)(b & 0xff));
-}
-
-/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
- */
-local void flush_pending(strm)
- z_streamp strm;
-{
- unsigned len = strm->state->pending;
-
- if (len > strm->avail_out) len = strm->avail_out;
- if (len == 0) return;
-
- zmemcpy(strm->next_out, strm->state->pending_out, len);
- strm->next_out += len;
- strm->state->pending_out += len;
- strm->total_out += len;
- strm->avail_out -= len;
- strm->state->pending -= len;
- if (strm->state->pending == 0) {
- strm->state->pending_out = strm->state->pending_buf;
- }
-}
-
-/* ========================================================================= */
-int ZEXPORT deflate (strm, flush)
- z_streamp strm;
- int flush;
-{
- int old_flush; /* value of flush param for previous deflate call */
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- flush > Z_FINISH || flush < 0) {
- return Z_STREAM_ERROR;
- }
- s = strm->state;
-
- if (strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0) ||
- (s->status == FINISH_STATE && flush != Z_FINISH)) {
- ERR_RETURN(strm, Z_STREAM_ERROR);
- }
- if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
- s->strm = strm; /* just in case */
- old_flush = s->last_flush;
- s->last_flush = flush;
-
- /* Write the zlib header */
- if (s->status == INIT_STATE) {
-
- uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
- uInt level_flags = (s->level-1) >> 1;
-
- if (level_flags > 3) level_flags = 3;
- header |= (level_flags << 6);
- if (s->strstart != 0) header |= PRESET_DICT;
- header += 31 - (header % 31);
-
- s->status = BUSY_STATE;
- putShortMSB(s, header);
-
- /* Save the adler32 of the preset dictionary: */
- if (s->strstart != 0) {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- strm->adler = 1L;
- }
-
- /* Flush as much pending output as possible */
- if (s->pending != 0) {
- flush_pending(strm);
- if (strm->avail_out == 0) {
- /* Since avail_out is 0, deflate will be called again with
- * more output space, but possibly with both pending and
- * avail_in equal to zero. There won't be anything to do,
- * but this is not an error situation so make sure we
- * return OK instead of BUF_ERROR at next call of deflate:
- */
- s->last_flush = -1;
- return Z_OK;
- }
-
- /* Make sure there is something to do and avoid duplicate consecutive
- * flushes. For repeated and useless calls with Z_FINISH, we keep
- * returning Z_STREAM_END instead of Z_BUFF_ERROR.
- */
- } else if (strm->avail_in == 0 && flush <= old_flush &&
- flush != Z_FINISH) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* User must not provide more input after the first FINISH: */
- if (s->status == FINISH_STATE && strm->avail_in != 0) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* Start a new block or continue the current one.
- */
- if (strm->avail_in != 0 || s->lookahead != 0 ||
- (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
- block_state bstate;
-
- bstate = (*(configuration_table[s->level].func))(s, flush);
-
- if (bstate == finish_started || bstate == finish_done) {
- s->status = FINISH_STATE;
- }
- if (bstate == need_more || bstate == finish_started) {
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
- }
- return Z_OK;
- /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
- * of deflate should use the same flush parameter to make sure
- * that the flush is complete. So we don't have to output an
- * empty block here, this will be done at next call. This also
- * ensures that for a very small output buffer, we emit at most
- * one empty block.
- */
- }
- if (bstate == block_done) {
- if (flush == Z_PARTIAL_FLUSH) {
- _tr_align(s);
- } else { /* FULL_FLUSH or SYNC_FLUSH */
- _tr_stored_block(s, (char*)0, 0L, 0);
- /* For a full flush, this empty block will be recognized
- * as a special marker by inflate_sync().
- */
- if (flush == Z_FULL_FLUSH) {
- CLEAR_HASH(s); /* forget history */
- }
- }
- flush_pending(strm);
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
- return Z_OK;
- }
- }
- }
- Assert(strm->avail_out > 0, "bug2");
-
- if (flush != Z_FINISH) return Z_OK;
- if (s->noheader) return Z_STREAM_END;
-
- /* Write the zlib trailer (adler32) */
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- flush_pending(strm);
- /* If avail_out is zero, the application will call deflate again
- * to flush the rest.
- */
- s->noheader = -1; /* write the trailer only once! */
- return s->pending != 0 ? Z_OK : Z_STREAM_END;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateEnd (strm)
- z_streamp strm;
-{
- int status;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-
- status = strm->state->status;
- if (status != INIT_STATE && status != BUSY_STATE &&
- status != FINISH_STATE) {
- return Z_STREAM_ERROR;
- }
-
- /* Deallocate in reverse order of allocations: */
- TRY_FREE(strm, strm->state->pending_buf);
- TRY_FREE(strm, strm->state->head);
- TRY_FREE(strm, strm->state->prev);
- TRY_FREE(strm, strm->state->window);
-
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
-
- return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-}
-
-/* =========================================================================
- * Copy the source state to the destination state.
- * To simplify the source, this is not supported for 16-bit MSDOS (which
- * doesn't have enough memory anyway to duplicate compression states).
- */
-int ZEXPORT deflateCopy (dest, source)
- z_streamp dest;
- z_streamp source;
-{
-#ifdef MAXSEG_64K
- return Z_STREAM_ERROR;
-#else
- deflate_state *ds;
- deflate_state *ss;
- ushf *overlay;
-
-
- if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
- return Z_STREAM_ERROR;
- }
-
- ss = source->state;
-
- *dest = *source;
-
- ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
- if (ds == Z_NULL) return Z_MEM_ERROR;
- dest->state = (struct internal_state FAR *) ds;
- *ds = *ss;
- ds->strm = dest;
-
- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
- ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
- ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
- ds->pending_buf = (uchf *) overlay;
-
- if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
- ds->pending_buf == Z_NULL) {
- deflateEnd (dest);
- return Z_MEM_ERROR;
- }
- /* following zmemcpy do not work for 16-bit MSDOS */
- zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
- zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
- zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
- zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-
- ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-
- ds->l_desc.dyn_tree = ds->dyn_ltree;
- ds->d_desc.dyn_tree = ds->dyn_dtree;
- ds->bl_desc.dyn_tree = ds->bl_tree;
-
- return Z_OK;
-#endif
-}
-
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read. All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
-local int read_buf(strm, buf, size)
- z_streamp strm;
- Bytef *buf;
- unsigned size;
-{
- unsigned len = strm->avail_in;
-
- if (len > size) len = size;
- if (len == 0) return 0;
-
- strm->avail_in -= len;
-
- if (!strm->state->noheader) {
- strm->adler = adler32(strm->adler, strm->next_in, len);
- }
- zmemcpy(buf, strm->next_in, len);
- strm->next_in += len;
- strm->total_in += len;
-
- return (int)len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init (s)
- deflate_state *s;
-{
- s->window_size = (ulg)2L*s->w_size;
-
- CLEAR_HASH(s);
-
- /* Set the default configuration parameters:
- */
- s->max_lazy_match = configuration_table[s->level].max_lazy;
- s->good_match = configuration_table[s->level].good_length;
- s->nice_match = configuration_table[s->level].nice_length;
- s->max_chain_length = configuration_table[s->level].max_chain;
-
- s->strstart = 0;
- s->block_start = 0L;
- s->lookahead = 0;
- s->match_length = s->prev_length = MIN_MATCH-1;
- s->match_available = 0;
- s->ins_h = 0;
-#ifdef ASMV
- match_init(); /* initialize the asm code */
-#endif
-}
-
-/* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
-#ifndef ASMV
-/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
-#ifndef FASTEST
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
-#else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
-#endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2:
- */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- /* It is not necessary to compare scan[2] and match[2] since they are
- * always equal when the other bytes match, given that the hash keys
- * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
- * strstart+3, +5, ... up to strstart+257. We check for insufficient
- * lookahead only every 4th comparison; the 128th check will be made
- * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
- * necessary to put more guard bytes at the end of the window, or
- * to check more often for insufficient lookahead.
- */
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
-#else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
-#endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
-}
-
-#else /* FASTEST */
-/* ---------------------------------------------------------------------------
- * Optimized version for level == 1 only
- */
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- Assert(cur_match < s->strstart, "no future");
-
- match = s->window + cur_match;
-
- /* Return failure if the match length is less than 2:
- */
- if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match += 2;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
-
- if (len < MIN_MATCH) return MIN_MATCH - 1;
-
- s->match_start = cur_match;
- return len <= s->lookahead ? len : s->lookahead;
-}
-#endif /* FASTEST */
-#endif /* ASMV */
-
-#ifdef DEBUG
-/* ===========================================================================
- * Check that the match at match_start is indeed a match.
- */
-local void check_match(s, start, match, length)
- deflate_state *s;
- IPos start, match;
- int length;
-{
- /* check that the match is indeed a match */
- if (zmemcmp(s->window + match,
- s->window + start, length) != EQUAL) {
- fprintf(stderr, " start %u, match %u, length %d\n",
- start, match, length);
- do {
- fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
- } while (--length != 0);
- z_error("invalid match");
- }
- if (z_verbose > 1) {
- fprintf(stderr,"\\[%d,%d]", start-match, length);
- do { putc(s->window[start++], stderr); } while (--length != 0);
- }
-}
-#else
-# define check_match(s, start, match, length)
-#endif
-
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- * At least one byte has been read, or avail_in == 0; reads are
- * performed for at least two bytes (required for the zip translate_eol
- * option -- not supported here).
- */
-local void fill_window(s)
- deflate_state *s;
-{
- register unsigned n, m;
- register Posf *p;
- unsigned more; /* Amount of free space at the end of the window. */
- uInt wsize = s->w_size;
-
- do {
- more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
- /* Deal with !@#$% 64K limit: */
- if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
- more = wsize;
-
- } else if (more == (unsigned)(-1)) {
- /* Very unlikely, but possible on 16 bit machine if strstart == 0
- * and lookahead == 1 (input done one byte at time)
- */
- more--;
-
- /* If the window is almost full and there is insufficient lookahead,
- * move the upper half to the lower one to make room in the upper half.
- */
- } else if (s->strstart >= wsize+MAX_DIST(s)) {
-
- zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
- s->match_start -= wsize;
- s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
- s->block_start -= (long) wsize;
-
- /* Slide the hash table (could be avoided with 32 bit values
- at the expense of memory usage). We slide even when level == 0
- to keep the hash table consistent if we switch back to level > 0
- later. (Using level 0 permanently is not an optimal usage of
- zlib, so we don't care about this pathological case.)
- */
- n = s->hash_size;
- p = &s->head[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- } while (--n);
-
- n = wsize;
-#ifndef FASTEST
- p = &s->prev[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- /* If n is not on any hash chain, prev[n] is garbage but
- * its value will never be used.
- */
- } while (--n);
-#endif
- more += wsize;
- }
- if (s->strm->avail_in == 0) return;
-
- /* If there was no sliding:
- * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
- * more == window_size - lookahead - strstart
- * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
- * => more >= window_size - 2*WSIZE + 2
- * In the BIG_MEM or MMAP case (not yet supported),
- * window_size == input_size + MIN_LOOKAHEAD &&
- * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
- * Otherwise, window_size == 2*WSIZE so more >= 2.
- * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
- */
- Assert(more >= 2, "more < 2");
-
- n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
- s->lookahead += n;
-
- /* Initialize the hash value now that we have some input: */
- if (s->lookahead >= MIN_MATCH) {
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- }
- /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
- * but this is not important since only literal bytes will be emitted.
- */
-
- } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-}
-
-/* ===========================================================================
- * Flush the current block, with given end-of-file flag.
- * IN assertion: strstart is set to the end of the current match.
- */
-#define FLUSH_BLOCK_ONLY(s, eof) { \
- _tr_flush_block(s, (s->block_start >= 0L ? \
- (charf *)&s->window[(unsigned)s->block_start] : \
- (charf *)Z_NULL), \
- (ulg)((long)s->strstart - s->block_start), \
- (eof)); \
- s->block_start = s->strstart; \
- flush_pending(s->strm); \
- Tracev((stderr,"[FLUSH]")); \
-}
-
-/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, eof) { \
- FLUSH_BLOCK_ONLY(s, eof); \
- if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
-}
-
-/* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
-local block_state deflate_stored(s, flush)
- deflate_state *s;
- int flush;
-{
- /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
- * to pending_buf_size, and each stored block has a 5 byte header:
- */
- ulg max_block_size = 0xffff;
- ulg max_start;
-
- if (max_block_size > s->pending_buf_size - 5) {
- max_block_size = s->pending_buf_size - 5;
- }
-
- /* Copy as much as possible from input to output: */
- for (;;) {
- /* Fill the window as much as possible: */
- if (s->lookahead <= 1) {
-
- Assert(s->strstart < s->w_size+MAX_DIST(s) ||
- s->block_start >= (long)s->w_size, "slide too late");
-
- fill_window(s);
- if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-
- if (s->lookahead == 0) break; /* flush the current block */
- }
- Assert(s->block_start >= 0L, "block gone");
-
- s->strstart += s->lookahead;
- s->lookahead = 0;
-
- /* Emit a stored block if pending_buf will be full: */
- max_start = s->block_start + max_block_size;
- if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
- /* strstart == 0 is possible when wraparound on 16-bit machine */
- s->lookahead = (uInt)(s->strstart - max_start);
- s->strstart = (uInt)max_start;
- FLUSH_BLOCK(s, 0);
- }
- /* Flush if we may have to slide, otherwise block_start may become
- * negative and the data will be gone:
- */
- if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
- FLUSH_BLOCK(s, 0);
- }
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
-local block_state deflate_fast(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of the hash chain */
- int bflush; /* set if current block must be flushed */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- * At this point we have always match_length < MIN_MATCH
- */
- if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- if (s->strategy != Z_HUFFMAN_ONLY) {
- s->match_length = longest_match (s, hash_head);
- }
- /* longest_match() sets match_start */
- }
- if (s->match_length >= MIN_MATCH) {
- check_match(s, s->strstart, s->match_start, s->match_length);
-
- _tr_tally_dist(s, s->strstart - s->match_start,
- s->match_length - MIN_MATCH, bflush);
-
- s->lookahead -= s->match_length;
-
- /* Insert new strings in the hash table only if the match length
- * is not too large. This saves time but degrades compression.
- */
-#ifndef FASTEST
- if (s->match_length <= s->max_insert_length &&
- s->lookahead >= MIN_MATCH) {
- s->match_length--; /* string at strstart already in hash table */
- do {
- s->strstart++;
- INSERT_STRING(s, s->strstart, hash_head);
- /* strstart never exceeds WSIZE-MAX_MATCH, so there are
- * always MIN_MATCH bytes ahead.
- */
- } while (--s->match_length != 0);
- s->strstart++;
- } else
-#endif
- {
- s->strstart += s->match_length;
- s->match_length = 0;
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
- * matter since it will be recomputed at next deflate call.
- */
- }
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
-local block_state deflate_slow(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of hash chain */
- int bflush; /* set if current block must be flushed */
-
- /* Process the input block. */
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- */
- s->prev_length = s->match_length, s->prev_match = s->match_start;
- s->match_length = MIN_MATCH-1;
-
- if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
- s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- if (s->strategy != Z_HUFFMAN_ONLY) {
- s->match_length = longest_match (s, hash_head);
- }
- /* longest_match() sets match_start */
-
- if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
- (s->match_length == MIN_MATCH &&
- s->strstart - s->match_start > TOO_FAR))) {
-
- /* If prev_match is also MIN_MATCH, match_start is garbage
- * but we will ignore the current match anyway.
- */
- s->match_length = MIN_MATCH-1;
- }
- }
- /* If there was a match at the previous step and the current
- * match is not better, output the previous match:
- */
- if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
- uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
- /* Do not insert strings in hash table beyond this. */
-
- check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
- _tr_tally_dist(s, s->strstart -1 - s->prev_match,
- s->prev_length - MIN_MATCH, bflush);
-
- /* Insert in hash table all strings up to the end of the match.
- * strstart-1 and strstart are already inserted. If there is not
- * enough lookahead, the last two strings are not inserted in
- * the hash table.
- */
- s->lookahead -= s->prev_length-1;
- s->prev_length -= 2;
- do {
- if (++s->strstart <= max_insert) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
- } while (--s->prev_length != 0);
- s->match_available = 0;
- s->match_length = MIN_MATCH-1;
- s->strstart++;
-
- if (bflush) FLUSH_BLOCK(s, 0);
-
- } else if (s->match_available) {
- /* If there was no match at the previous position, output a
- * single literal. If there was a match but the current match
- * is longer, truncate the previous match to a single literal.
- */
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- if (bflush) {
- FLUSH_BLOCK_ONLY(s, 0);
- }
- s->strstart++;
- s->lookahead--;
- if (s->strm->avail_out == 0) return need_more;
- } else {
- /* There is no previous match to compare with, wait for
- * the next step to decide.
- */
- s->match_available = 1;
- s->strstart++;
- s->lookahead--;
- }
- }
- Assert (flush != Z_NO_FLUSH, "no flush?");
- if (s->match_available) {
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- s->match_available = 0;
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process depends on being able to identify portions
+ * of the input text which are identical to earlier input (within a
+ * sliding window trailing behind the input currently being processed).
+ *
+ * The most straightforward technique turns out to be the fastest for
+ * most input files: try all possible matches and select the longest.
+ * The key feature of this algorithm is that insertions into the string
+ * dictionary are very simple and thus fast, and deletions are avoided
+ * completely. Insertions are performed at each input character, whereas
+ * string matches are performed only when the previous match ends. So it
+ * is preferable to spend more time in matches to allow very fast string
+ * insertions and avoid deletions. The matching algorithm for small
+ * strings is inspired from that of Rabin & Karp. A brute force approach
+ * is used to find longer strings when a small match has been found.
+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ * (by Leonid Broukhis).
+ * A previous version of this file used a more sophisticated algorithm
+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
+ * time, but has a larger average cost, uses more memory and is patented.
+ * However the F&G algorithm may be faster for some highly redundant
+ * files if the parameter max_chain_length (described below) is too large.
+ *
+ * ACKNOWLEDGEMENTS
+ *
+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ * I found it in 'freeze' written by Leonid Broukhis.
+ * Thanks to many people for bug reports and testing.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ * Available in ftp://ds.internic.net/rfc/rfc1951.txt
+ *
+ * A description of the Rabin and Karp algorithm is given in the book
+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ * Fiala,E.R., and Greene,D.H.
+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id: deflate.c,v 1.3 2004-11-27 21:46:13 pixel Exp $ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+ " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ * Function prototypes.
+ */
+typedef enum {
+ need_more, /* block not completed, need more input or more output */
+ block_done, /* block flush performed */
+ finish_started, /* finish started, need only more output at next deflate */
+ finish_done /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast OF((deflate_state *s, int flush));
+local block_state deflate_slow OF((deflate_state *s, int flush));
+local void lm_init OF((deflate_state *s));
+local void putShortMSB OF((deflate_state *s, uInt b));
+local void flush_pending OF((z_streamp strm));
+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+ void match_init OF((void)); /* asm code initialization */
+ uInt longest_match OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef DEBUG
+local void check_match OF((deflate_state *s, IPos start, IPos match,
+ int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+# define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+ ush good_length; /* reduce lazy search above this match length */
+ ush max_lazy; /* do not perform lazy search above this match length */
+ ush nice_length; /* quit search above this match length */
+ ush max_chain;
+ compress_func func;
+} config;
+
+local const config configuration_table[10] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
+/* 2 */ {4, 5, 16, 8, deflate_fast},
+/* 3 */ {4, 6, 32, 32, deflate_fast},
+
+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
+/* 5 */ {8, 16, 32, 32, deflate_slow},
+/* 6 */ {8, 16, 128, 128, deflate_slow},
+/* 7 */ {8, 32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
+ * input characters, so that a running hash key can be computed from the
+ * previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
+ * input characters and the first MIN_MATCH bytes of str are valid
+ * (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+ s->head[s->hash_size-1] = NIL; \
+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+ z_streamp strm;
+ int level;
+ const char *version;
+ int stream_size;
+{
+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+ Z_DEFAULT_STRATEGY, version, stream_size);
+ /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+ version, stream_size)
+ z_streamp strm;
+ int level;
+ int method;
+ int windowBits;
+ int memLevel;
+ int strategy;
+ const char *version;
+ int stream_size;
+{
+ deflate_state *s;
+ int noheader = 0;
+ static const char* my_version = ZLIB_VERSION;
+
+ ushf *overlay;
+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
+ * output size for (length,distance) codes is <= 24 bits.
+ */
+
+ if (version == Z_NULL || version[0] != my_version[0] ||
+ stream_size != sizeof(z_stream)) {
+ return Z_VERSION_ERROR;
+ }
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+ strm->msg = Z_NULL;
+ if (strm->zalloc == Z_NULL) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == Z_NULL) strm->zfree = zcfree;
+
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#ifdef FASTEST
+ level = 1;
+#endif
+
+ if (windowBits < 0) { /* undocumented feature: suppress zlib header */
+ noheader = 1;
+ windowBits = -windowBits;
+ }
+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+ windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
+ strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+ return Z_STREAM_ERROR;
+ }
+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+ if (s == Z_NULL) return Z_MEM_ERROR;
+ strm->state = (struct internal_state FAR *)s;
+ s->strm = strm;
+
+ s->noheader = noheader;
+ s->w_bits = windowBits;
+ s->w_size = 1 << s->w_bits;
+ s->w_mask = s->w_size - 1;
+
+ s->hash_bits = memLevel + 7;
+ s->hash_size = 1 << s->hash_bits;
+ s->hash_mask = s->hash_size - 1;
+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+ s->pending_buf = (uchf *) overlay;
+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+ s->pending_buf == Z_NULL) {
+ strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+ deflateEnd (strm);
+ return Z_MEM_ERROR;
+ }
+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+ s->level = level;
+ s->strategy = strategy;
+ s->method = (Byte)method;
+
+ return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+ z_streamp strm;
+ const Bytef *dictionary;
+ uInt dictLength;
+{
+ deflate_state *s;
+ uInt length = dictLength;
+ uInt n;
+ IPos hash_head = 0;
+
+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+ strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
+
+ s = strm->state;
+ strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+ if (length < MIN_MATCH) return Z_OK;
+ if (length > MAX_DIST(s)) {
+ length = MAX_DIST(s);
+#ifndef USE_DICT_HEAD
+ dictionary += dictLength - length; /* use the tail of the dictionary */
+#endif
+ }
+ zmemcpy(s->window, dictionary, length);
+ s->strstart = length;
+ s->block_start = (long)length;
+
+ /* Insert all strings in the hash table (except for the last two bytes).
+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
+ * call of fill_window.
+ */
+ s->ins_h = s->window[0];
+ UPDATE_HASH(s, s->ins_h, s->window[1]);
+ for (n = 0; n <= length - MIN_MATCH; n++) {
+ INSERT_STRING(s, n, hash_head);
+ }
+ if (hash_head) hash_head = 0; /* to make compiler happy */
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
+
+ strm->total_in = strm->total_out = 0;
+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+ strm->data_type = Z_UNKNOWN;
+
+ s = (deflate_state *)strm->state;
+ s->pending = 0;
+ s->pending_out = s->pending_buf;
+
+ if (s->noheader < 0) {
+ s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
+ }
+ s->status = s->noheader ? BUSY_STATE : INIT_STATE;
+ strm->adler = 1;
+ s->last_flush = Z_NO_FLUSH;
+
+ _tr_init(s);
+ lm_init(s);
+
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+ z_streamp strm;
+ int level;
+ int strategy;
+{
+ deflate_state *s;
+ compress_func func;
+ int err = Z_OK;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+
+ if (level == Z_DEFAULT_COMPRESSION) {
+ level = 6;
+ }
+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+ return Z_STREAM_ERROR;
+ }
+ func = configuration_table[s->level].func;
+
+ if (func != configuration_table[level].func && strm->total_in != 0) {
+ /* Flush the last buffer: */
+ err = deflate(strm, Z_PARTIAL_FLUSH);
+ }
+ if (s->level != level) {
+ s->level = level;
+ s->max_lazy_match = configuration_table[level].max_lazy;
+ s->good_match = configuration_table[level].good_length;
+ s->nice_match = configuration_table[level].nice_length;
+ s->max_chain_length = configuration_table[level].max_chain;
+ }
+ s->strategy = strategy;
+ return err;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+ deflate_state *s;
+ uInt b;
+{
+ put_byte(s, (Byte)(b >> 8));
+ put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+ z_streamp strm;
+{
+ unsigned len = strm->state->pending;
+
+ if (len > strm->avail_out) len = strm->avail_out;
+ if (len == 0) return;
+
+ zmemcpy(strm->next_out, strm->state->pending_out, len);
+ strm->next_out += len;
+ strm->state->pending_out += len;
+ strm->total_out += len;
+ strm->avail_out -= len;
+ strm->state->pending -= len;
+ if (strm->state->pending == 0) {
+ strm->state->pending_out = strm->state->pending_buf;
+ }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+ z_streamp strm;
+ int flush;
+{
+ int old_flush; /* value of flush param for previous deflate call */
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ flush > Z_FINISH || flush < 0) {
+ return Z_STREAM_ERROR;
+ }
+ s = strm->state;
+
+ if (strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
+ ERR_RETURN(strm, Z_STREAM_ERROR);
+ }
+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+ s->strm = strm; /* just in case */
+ old_flush = s->last_flush;
+ s->last_flush = flush;
+
+ /* Write the zlib header */
+ if (s->status == INIT_STATE) {
+
+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+ uInt level_flags = (s->level-1) >> 1;
+
+ if (level_flags > 3) level_flags = 3;
+ header |= (level_flags << 6);
+ if (s->strstart != 0) header |= PRESET_DICT;
+ header += 31 - (header % 31);
+
+ s->status = BUSY_STATE;
+ putShortMSB(s, header);
+
+ /* Save the adler32 of the preset dictionary: */
+ if (s->strstart != 0) {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ strm->adler = 1L;
+ }
+
+ /* Flush as much pending output as possible */
+ if (s->pending != 0) {
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ /* Since avail_out is 0, deflate will be called again with
+ * more output space, but possibly with both pending and
+ * avail_in equal to zero. There won't be anything to do,
+ * but this is not an error situation so make sure we
+ * return OK instead of BUF_ERROR at next call of deflate:
+ */
+ s->last_flush = -1;
+ return Z_OK;
+ }
+
+ /* Make sure there is something to do and avoid duplicate consecutive
+ * flushes. For repeated and useless calls with Z_FINISH, we keep
+ * returning Z_STREAM_END instead of Z_BUFF_ERROR.
+ */
+ } else if (strm->avail_in == 0 && flush <= old_flush &&
+ flush != Z_FINISH) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* User must not provide more input after the first FINISH: */
+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* Start a new block or continue the current one.
+ */
+ if (strm->avail_in != 0 || s->lookahead != 0 ||
+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+ block_state bstate;
+
+ bstate = (*(configuration_table[s->level].func))(s, flush);
+
+ if (bstate == finish_started || bstate == finish_done) {
+ s->status = FINISH_STATE;
+ }
+ if (bstate == need_more || bstate == finish_started) {
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+ }
+ return Z_OK;
+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+ * of deflate should use the same flush parameter to make sure
+ * that the flush is complete. So we don't have to output an
+ * empty block here, this will be done at next call. This also
+ * ensures that for a very small output buffer, we emit at most
+ * one empty block.
+ */
+ }
+ if (bstate == block_done) {
+ if (flush == Z_PARTIAL_FLUSH) {
+ _tr_align(s);
+ } else { /* FULL_FLUSH or SYNC_FLUSH */
+ _tr_stored_block(s, (char*)0, 0L, 0);
+ /* For a full flush, this empty block will be recognized
+ * as a special marker by inflate_sync().
+ */
+ if (flush == Z_FULL_FLUSH) {
+ CLEAR_HASH(s); /* forget history */
+ }
+ }
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+ return Z_OK;
+ }
+ }
+ }
+ Assert(strm->avail_out > 0, "bug2");
+
+ if (flush != Z_FINISH) return Z_OK;
+ if (s->noheader) return Z_STREAM_END;
+
+ /* Write the zlib trailer (adler32) */
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ flush_pending(strm);
+ /* If avail_out is zero, the application will call deflate again
+ * to flush the rest.
+ */
+ s->noheader = -1; /* write the trailer only once! */
+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+ z_streamp strm;
+{
+ int status;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+ status = strm->state->status;
+ if (status != INIT_STATE && status != BUSY_STATE &&
+ status != FINISH_STATE) {
+ return Z_STREAM_ERROR;
+ }
+
+ /* Deallocate in reverse order of allocations: */
+ TRY_FREE(strm, strm->state->pending_buf);
+ TRY_FREE(strm, strm->state->head);
+ TRY_FREE(strm, strm->state->prev);
+ TRY_FREE(strm, strm->state->window);
+
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+
+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+ z_streamp dest;
+ z_streamp source;
+{
+#ifdef MAXSEG_64K
+ return Z_STREAM_ERROR;
+#else
+ deflate_state *ds;
+ deflate_state *ss;
+ ushf *overlay;
+
+
+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+ return Z_STREAM_ERROR;
+ }
+
+ ss = source->state;
+
+ *dest = *source;
+
+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+ if (ds == Z_NULL) return Z_MEM_ERROR;
+ dest->state = (struct internal_state FAR *) ds;
+ *ds = *ss;
+ ds->strm = dest;
+
+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+ ds->pending_buf = (uchf *) overlay;
+
+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+ ds->pending_buf == Z_NULL) {
+ deflateEnd (dest);
+ return Z_MEM_ERROR;
+ }
+ /* following zmemcpy do not work for 16-bit MSDOS */
+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+ ds->l_desc.dyn_tree = ds->dyn_ltree;
+ ds->d_desc.dyn_tree = ds->dyn_dtree;
+ ds->bl_desc.dyn_tree = ds->bl_tree;
+
+ return Z_OK;
+#endif
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read. All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+ z_streamp strm;
+ Bytef *buf;
+ unsigned size;
+{
+ unsigned len = strm->avail_in;
+
+ if (len > size) len = size;
+ if (len == 0) return 0;
+
+ strm->avail_in -= len;
+
+ if (!strm->state->noheader) {
+ strm->adler = adler32(strm->adler, strm->next_in, len);
+ }
+ zmemcpy(buf, strm->next_in, len);
+ strm->next_in += len;
+ strm->total_in += len;
+
+ return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+ deflate_state *s;
+{
+ s->window_size = (ulg)2L*s->w_size;
+
+ CLEAR_HASH(s);
+
+ /* Set the default configuration parameters:
+ */
+ s->max_lazy_match = configuration_table[s->level].max_lazy;
+ s->good_match = configuration_table[s->level].good_length;
+ s->nice_match = configuration_table[s->level].nice_length;
+ s->max_chain_length = configuration_table[s->level].max_chain;
+
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->lookahead = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ s->ins_h = 0;
+#ifdef ASMV
+ match_init(); /* initialize the asm code */
+#endif
+}
+
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+#ifndef FASTEST
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ int best_len = s->prev_length; /* best match length so far */
+ int nice_match = s->nice_match; /* stop if match long enough */
+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+ s->strstart - (IPos)MAX_DIST(s) : NIL;
+ /* Stop when cur_match becomes <= limit. To simplify the code,
+ * we prevent matches with the string of window index 0.
+ */
+ Posf *prev = s->prev;
+ uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+ /* Compare two bytes at a time. Note: this is not always beneficial.
+ * Try with and without -DUNALIGNED_OK to check.
+ */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+ register ush scan_start = *(ushf*)scan;
+ register ush scan_end = *(ushf*)(scan+best_len-1);
+#else
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+ register Byte scan_end1 = scan[best_len-1];
+ register Byte scan_end = scan[best_len];
+#endif
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ /* Do not waste too much time if we already have a good match: */
+ if (s->prev_length >= s->good_match) {
+ chain_length >>= 2;
+ }
+ /* Do not look for matches beyond the end of the input. This is necessary
+ * to make deflate deterministic.
+ */
+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ do {
+ Assert(cur_match < s->strstart, "no future");
+ match = s->window + cur_match;
+
+ /* Skip to next match if the match length cannot increase
+ * or if the match length is less than 2:
+ */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+ /* This code assumes sizeof(unsigned short) == 2. Do not use
+ * UNALIGNED_OK if your compiler uses a different size.
+ */
+ if (*(ushf*)(match+best_len-1) != scan_end ||
+ *(ushf*)match != scan_start) continue;
+
+ /* It is not necessary to compare scan[2] and match[2] since they are
+ * always equal when the other bytes match, given that the hash keys
+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
+ * lookahead only every 4th comparison; the 128th check will be made
+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+ * necessary to put more guard bytes at the end of the window, or
+ * to check more often for insufficient lookahead.
+ */
+ Assert(scan[2] == match[2], "scan[2]?");
+ scan++, match++;
+ do {
+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ scan < strend);
+ /* The funny "do {}" generates better code on most compilers */
+
+ /* Here, scan <= window+strstart+257 */
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+ if (*scan == *match) scan++;
+
+ len = (MAX_MATCH - 1) - (int)(strend-scan);
+ scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+ if (match[best_len] != scan_end ||
+ match[best_len-1] != scan_end1 ||
+ *match != *scan ||
+ *++match != scan[1]) continue;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match++;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+ scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+ if (len > best_len) {
+ s->match_start = cur_match;
+ best_len = len;
+ if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+ scan_end = *(ushf*)(scan+best_len-1);
+#else
+ scan_end1 = scan[best_len-1];
+ scan_end = scan[best_len];
+#endif
+ }
+ } while ((cur_match = prev[cur_match & wmask]) > limit
+ && --chain_length != 0);
+
+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+ return s->lookahead;
+}
+
+#else /* FASTEST */
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 only
+ */
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ Assert(cur_match < s->strstart, "no future");
+
+ match = s->window + cur_match;
+
+ /* Return failure if the match length is less than 2:
+ */
+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match += 2;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+
+ if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+ s->match_start = cur_match;
+ return len <= s->lookahead ? len : s->lookahead;
+}
+#endif /* FASTEST */
+#endif /* ASMV */
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+ deflate_state *s;
+ IPos start, match;
+ int length;
+{
+ /* check that the match is indeed a match */
+ if (zmemcmp(s->window + match,
+ s->window + start, length) != EQUAL) {
+ fprintf(stderr, " start %u, match %u, length %d\n",
+ start, match, length);
+ do {
+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+ } while (--length != 0);
+ z_error("invalid match");
+ }
+ if (z_verbose > 1) {
+ fprintf(stderr,"\\[%d,%d]", start-match, length);
+ do { putc(s->window[start++], stderr); } while (--length != 0);
+ }
+}
+#else
+# define check_match(s, start, match, length)
+#endif
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ * At least one byte has been read, or avail_in == 0; reads are
+ * performed for at least two bytes (required for the zip translate_eol
+ * option -- not supported here).
+ */
+local void fill_window(s)
+ deflate_state *s;
+{
+ register unsigned n, m;
+ register Posf *p;
+ unsigned more; /* Amount of free space at the end of the window. */
+ uInt wsize = s->w_size;
+
+ do {
+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+ /* Deal with !@#$% 64K limit: */
+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+ more = wsize;
+
+ } else if (more == (unsigned)(-1)) {
+ /* Very unlikely, but possible on 16 bit machine if strstart == 0
+ * and lookahead == 1 (input done one byte at time)
+ */
+ more--;
+
+ /* If the window is almost full and there is insufficient lookahead,
+ * move the upper half to the lower one to make room in the upper half.
+ */
+ } else if (s->strstart >= wsize+MAX_DIST(s)) {
+
+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+ s->match_start -= wsize;
+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
+ s->block_start -= (long) wsize;
+
+ /* Slide the hash table (could be avoided with 32 bit values
+ at the expense of memory usage). We slide even when level == 0
+ to keep the hash table consistent if we switch back to level > 0
+ later. (Using level 0 permanently is not an optimal usage of
+ zlib, so we don't care about this pathological case.)
+ */
+ n = s->hash_size;
+ p = &s->head[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ } while (--n);
+
+ n = wsize;
+#ifndef FASTEST
+ p = &s->prev[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ /* If n is not on any hash chain, prev[n] is garbage but
+ * its value will never be used.
+ */
+ } while (--n);
+#endif
+ more += wsize;
+ }
+ if (s->strm->avail_in == 0) return;
+
+ /* If there was no sliding:
+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+ * more == window_size - lookahead - strstart
+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+ * => more >= window_size - 2*WSIZE + 2
+ * In the BIG_MEM or MMAP case (not yet supported),
+ * window_size == input_size + MIN_LOOKAHEAD &&
+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+ * Otherwise, window_size == 2*WSIZE so more >= 2.
+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+ */
+ Assert(more >= 2, "more < 2");
+
+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+ s->lookahead += n;
+
+ /* Initialize the hash value now that we have some input: */
+ if (s->lookahead >= MIN_MATCH) {
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ }
+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+ * but this is not important since only literal bytes will be emitted.
+ */
+
+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+ _tr_flush_block(s, (s->block_start >= 0L ? \
+ (charf *)&s->window[(unsigned)s->block_start] : \
+ (charf *)Z_NULL), \
+ (ulg)((long)s->strstart - s->block_start), \
+ (eof)); \
+ s->block_start = s->strstart; \
+ flush_pending(s->strm); \
+ Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+ FLUSH_BLOCK_ONLY(s, eof); \
+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+ * to pending_buf_size, and each stored block has a 5 byte header:
+ */
+ ulg max_block_size = 0xffff;
+ ulg max_start;
+
+ if (max_block_size > s->pending_buf_size - 5) {
+ max_block_size = s->pending_buf_size - 5;
+ }
+
+ /* Copy as much as possible from input to output: */
+ for (;;) {
+ /* Fill the window as much as possible: */
+ if (s->lookahead <= 1) {
+
+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+ s->block_start >= (long)s->w_size, "slide too late");
+
+ fill_window(s);
+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+ Assert(s->block_start >= 0L, "block gone");
+
+ s->strstart += s->lookahead;
+ s->lookahead = 0;
+
+ /* Emit a stored block if pending_buf will be full: */
+ max_start = s->block_start + max_block_size;
+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+ /* strstart == 0 is possible when wraparound on 16-bit machine */
+ s->lookahead = (uInt)(s->strstart - max_start);
+ s->strstart = (uInt)max_start;
+ FLUSH_BLOCK(s, 0);
+ }
+ /* Flush if we may have to slide, otherwise block_start may become
+ * negative and the data will be gone:
+ */
+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+ FLUSH_BLOCK(s, 0);
+ }
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head = NIL; /* head of the hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ * At this point we have always match_length < MIN_MATCH
+ */
+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ if (s->strategy != Z_HUFFMAN_ONLY) {
+ s->match_length = longest_match (s, hash_head);
+ }
+ /* longest_match() sets match_start */
+ }
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->match_start, s->match_length);
+
+ _tr_tally_dist(s, s->strstart - s->match_start,
+ s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+
+ /* Insert new strings in the hash table only if the match length
+ * is not too large. This saves time but degrades compression.
+ */
+#ifndef FASTEST
+ if (s->match_length <= s->max_insert_length &&
+ s->lookahead >= MIN_MATCH) {
+ s->match_length--; /* string at strstart already in hash table */
+ do {
+ s->strstart++;
+ INSERT_STRING(s, s->strstart, hash_head);
+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+ * always MIN_MATCH bytes ahead.
+ */
+ } while (--s->match_length != 0);
+ s->strstart++;
+ } else
+#endif
+ {
+ s->strstart += s->match_length;
+ s->match_length = 0;
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+ * matter since it will be recomputed at next deflate call.
+ */
+ }
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head = NIL; /* head of hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ /* Process the input block. */
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ */
+ s->prev_length = s->match_length, s->prev_match = s->match_start;
+ s->match_length = MIN_MATCH-1;
+
+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+ s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ if (s->strategy != Z_HUFFMAN_ONLY) {
+ s->match_length = longest_match (s, hash_head);
+ }
+ /* longest_match() sets match_start */
+
+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
+ (s->match_length == MIN_MATCH &&
+ s->strstart - s->match_start > TOO_FAR))) {
+
+ /* If prev_match is also MIN_MATCH, match_start is garbage
+ * but we will ignore the current match anyway.
+ */
+ s->match_length = MIN_MATCH-1;
+ }
+ }
+ /* If there was a match at the previous step and the current
+ * match is not better, output the previous match:
+ */
+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+ /* Do not insert strings in hash table beyond this. */
+
+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+ s->prev_length - MIN_MATCH, bflush);
+
+ /* Insert in hash table all strings up to the end of the match.
+ * strstart-1 and strstart are already inserted. If there is not
+ * enough lookahead, the last two strings are not inserted in
+ * the hash table.
+ */
+ s->lookahead -= s->prev_length-1;
+ s->prev_length -= 2;
+ do {
+ if (++s->strstart <= max_insert) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+ } while (--s->prev_length != 0);
+ s->match_available = 0;
+ s->match_length = MIN_MATCH-1;
+ s->strstart++;
+
+ if (bflush) FLUSH_BLOCK(s, 0);
+
+ } else if (s->match_available) {
+ /* If there was no match at the previous position, output a
+ * single literal. If there was a match but the current match
+ * is longer, truncate the previous match to a single literal.
+ */
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ if (bflush) {
+ FLUSH_BLOCK_ONLY(s, 0);
+ }
+ s->strstart++;
+ s->lookahead--;
+ if (s->strm->avail_out == 0) return need_more;
+ } else {
+ /* There is no previous match to compare with, wait for
+ * the next step to decide.
+ */
+ s->match_available = 1;
+ s->strstart++;
+ s->lookahead--;
+ }
+ }
+ Assert (flush != Z_NO_FLUSH, "no flush?");
+ if (s->match_available) {
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ s->match_available = 0;
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
diff --git a/lib/zlib/src/gzio.c b/lib/zlib/src/gzio.c
index 4e5a432..3f534f6 100644
--- a/lib/zlib/src/gzio.c
+++ b/lib/zlib/src/gzio.c
@@ -1,879 +1,879 @@
-/* gzio.c -- IO on .gz files
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Compile this file with -DNO_DEFLATE to avoid the compression code.
- */
-
-/* @(#) $Id: gzio.c,v 1.4 2004-11-27 21:35:22 pixel Exp $ */
-
-#include <stdio.h>
-
-#include "zutil.h"
-
-struct internal_state {int dummy;}; /* for buggy compilers */
-
-#ifndef Z_BUFSIZE
-# ifdef MAXSEG_64K
-# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
-# else
-# define Z_BUFSIZE 16384
-# endif
-#endif
-#ifndef Z_PRINTF_BUFSIZE
-# define Z_PRINTF_BUFSIZE 4096
-#endif
-
-#define ALLOC(size) malloc(size)
-#define TRYFREE(p) {if (p) free(p);}
-
-static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define RESERVED 0xE0 /* bits 5..7: reserved */
-
-typedef struct gz_stream {
- z_stream stream;
- int z_err; /* error code for last stream operation */
- int z_eof; /* set if end of input file */
- FILE *file; /* .gz file */
- Byte *inbuf; /* input buffer */
- Byte *outbuf; /* output buffer */
- uLong crc; /* crc32 of uncompressed data */
- char *msg; /* error message */
- char *path; /* path name for debugging only */
- int transparent; /* 1 if input file is not a .gz file */
- char mode; /* 'w' or 'r' */
- long startpos; /* start of compressed data in file (header skipped) */
-} gz_stream;
-
-
-local gzFile gz_open OF((const char *path, const char *mode, int fd));
-local int do_flush OF((gzFile file, int flush));
-local int get_byte OF((gz_stream *s));
-local void check_header OF((gz_stream *s));
-local int destroy OF((gz_stream *s));
-local void putLong OF((FILE *file, uLong x));
-local uLong getLong OF((gz_stream *s));
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb"). The file is given either by file descriptor
- or path name (if fd == -1).
- gz_open return NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR).
-*/
-local gzFile gz_open (path, mode, fd)
- const char *path;
- const char *mode;
- int fd;
-{
- int err;
- int level = Z_DEFAULT_COMPRESSION; /* compression level */
- int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
- char *p = (char*)mode;
- gz_stream *s;
- char fmode[80]; /* copy of mode, without the compression level */
- char *m = fmode;
-
- if (!path || !mode) return Z_NULL;
-
- s = (gz_stream *)ALLOC(sizeof(gz_stream));
- if (!s) return Z_NULL;
-
- s->stream.zalloc = (alloc_func)0;
- s->stream.zfree = (free_func)0;
- s->stream.opaque = (voidpf)0;
- s->stream.next_in = s->inbuf = Z_NULL;
- s->stream.next_out = s->outbuf = Z_NULL;
- s->stream.avail_in = s->stream.avail_out = 0;
- s->file = NULL;
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->crc = crc32(0L, Z_NULL, 0);
- s->msg = NULL;
- s->transparent = 0;
-
- s->path = (char*)ALLOC(strlen(path)+1);
- if (s->path == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- strcpy(s->path, path); /* do this early for debugging */
-
- s->mode = '\0';
- do {
- if (*p == 'r') s->mode = 'r';
- if (*p == 'w' || *p == 'a') s->mode = 'w';
- if (*p >= '0' && *p <= '9') {
- level = *p - '0';
- } else if (*p == 'f') {
- strategy = Z_FILTERED;
- } else if (*p == 'h') {
- strategy = Z_HUFFMAN_ONLY;
- } else {
- *m++ = *p; /* copy the mode */
- }
- } while (*p++ && m != fmode + sizeof(fmode));
- if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
-
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- err = Z_STREAM_ERROR;
-#else
- err = deflateInit2(&(s->stream), level,
- Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
- /* windowBits is passed < 0 to suppress zlib header */
-
- s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
-#endif
- if (err != Z_OK || s->outbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- } else {
- s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
-
- err = inflateInit2(&(s->stream), -MAX_WBITS);
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
- * present after the compressed stream.
- */
- if (err != Z_OK || s->inbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- }
- s->stream.avail_out = Z_BUFSIZE;
-
- errno = 0;
- s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
-
- if (s->file == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- if (s->mode == 'w') {
- /* Write a very simple .gz header:
- */
- fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
- Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
- s->startpos = 10L;
- /* We use 10L instead of ftell(s->file) to because ftell causes an
- * fflush on some systems. This version of the library doesn't use
- * startpos anyway in write mode, so this initialization is not
- * necessary.
- */
- } else {
- check_header(s); /* skip the .gz header */
- s->startpos = (ftell(s->file) - s->stream.avail_in);
- }
-
- return (gzFile)s;
-}
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing.
-*/
-gzFile ZEXPORT gzopen (path, mode)
- const char *path;
- const char *mode;
-{
- return gz_open (path, mode, -1);
-}
-
-/* ===========================================================================
- Associate a gzFile with the file descriptor fd. fd is not dup'ed here
- to mimic the behavio(u)r of fdopen.
-*/
-gzFile ZEXPORT gzdopen (fd, mode)
- int fd;
- const char *mode;
-{
- char name[20];
-
- if (fd < 0) return (gzFile)Z_NULL;
- sprintf(name, "<fd:%d>", fd); /* for debugging */
-
- return gz_open (name, mode, fd);
-}
-
-/* ===========================================================================
- * Update the compression level and strategy
- */
-int ZEXPORT gzsetparams (file, level, strategy)
- gzFile file;
- int level;
- int strategy;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- /* Make room to allow flushing */
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
-
- return deflateParams (&(s->stream), level, strategy);
-}
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-local int get_byte(s)
- gz_stream *s;
-{
- if (s->z_eof) return EOF;
- if (s->stream.avail_in == 0) {
- errno = 0;
- s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) s->z_err = Z_ERRNO;
- return EOF;
- }
- s->stream.next_in = s->inbuf;
- }
- s->stream.avail_in--;
- return *(s->stream.next_in)++;
-}
-
-/* ===========================================================================
- Check the gzip header of a gz_stream opened for reading. Set the stream
- mode to transparent if the gzip magic header is not present; set s->err
- to Z_DATA_ERROR if the magic header is present but the rest of the header
- is incorrect.
- IN assertion: the stream s has already been created sucessfully;
- s->stream.avail_in is zero for the first time, but may be non-zero
- for concatenated .gz files.
-*/
-local void check_header(s)
- gz_stream *s;
-{
- int method; /* method byte */
- int flags; /* flags byte */
- uInt len;
- int c;
-
- /* Check the gzip magic header */
- for (len = 0; len < 2; len++) {
- c = get_byte(s);
- if (c != gz_magic[len]) {
- if (len != 0) s->stream.avail_in++, s->stream.next_in--;
- if (c != EOF) {
- s->stream.avail_in++, s->stream.next_in--;
- s->transparent = 1;
- }
- s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
- return;
- }
- }
- method = get_byte(s);
- flags = get_byte(s);
- if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
- s->z_err = Z_DATA_ERROR;
- return;
- }
-
- /* Discard time, xflags and OS code: */
- for (len = 0; len < 6; len++) (void)get_byte(s);
-
- if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
- len = (uInt)get_byte(s);
- len += ((uInt)get_byte(s))<<8;
- /* len is garbage if EOF but the loop below will quit anyway */
- while (len-- != 0 && get_byte(s) != EOF) ;
- }
- if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
- for (len = 0; len < 2; len++) (void)get_byte(s);
- }
- s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
-}
-
- /* ===========================================================================
- * Cleanup then free the given gz_stream. Return a zlib error code.
- Try freeing in the reverse order of allocations.
- */
-local int destroy (s)
- gz_stream *s;
-{
- int err = Z_OK;
-
- if (!s) return Z_STREAM_ERROR;
-
- TRYFREE(s->msg);
-
- if (s->stream.state != NULL) {
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- err = Z_STREAM_ERROR;
-#else
- err = deflateEnd(&(s->stream));
-#endif
- } else if (s->mode == 'r') {
- err = inflateEnd(&(s->stream));
- }
- }
- if (s->file != NULL && fclose(s->file)) {
-#ifdef ESPIPE
- if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
-#endif
- err = Z_ERRNO;
- }
- if (s->z_err < 0) err = s->z_err;
-
- TRYFREE(s->inbuf);
- TRYFREE(s->outbuf);
- TRYFREE(s->path);
- TRYFREE(s);
- return err;
-}
-
-/* ===========================================================================
- Reads the given number of uncompressed bytes from the compressed file.
- gzread returns the number of bytes actually read (0 for end of file).
-*/
-int ZEXPORT gzread (file, buf, len)
- gzFile file;
- voidp buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
- Bytef *start = (Bytef*)buf; /* starting point for crc computation */
- Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
-
- if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
-
- if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
- if (s->z_err == Z_STREAM_END) return 0; /* EOF */
-
- next_out = (Byte*)buf;
- s->stream.next_out = (Bytef*)buf;
- s->stream.avail_out = len;
-
- while (s->stream.avail_out != 0) {
-
- if (s->transparent) {
- /* Copy first the lookahead bytes: */
- uInt n = s->stream.avail_in;
- if (n > s->stream.avail_out) n = s->stream.avail_out;
- if (n > 0) {
- zmemcpy(s->stream.next_out, s->stream.next_in, n);
- next_out += n;
- s->stream.next_out = next_out;
- s->stream.next_in += n;
- s->stream.avail_out -= n;
- s->stream.avail_in -= n;
- }
- if (s->stream.avail_out > 0) {
- s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
- s->file);
- }
- len -= s->stream.avail_out;
- s->stream.total_in += (uLong)len;
- s->stream.total_out += (uLong)len;
- if (len == 0) s->z_eof = 1;
- return (int)len;
- }
- if (s->stream.avail_in == 0 && !s->z_eof) {
-
- errno = 0;
- s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) {
- s->z_err = Z_ERRNO;
- break;
- }
- }
- s->stream.next_in = s->inbuf;
- }
- s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
-
- if (s->z_err == Z_STREAM_END) {
- /* Check CRC and original size */
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
- start = s->stream.next_out;
-
- if (getLong(s) != s->crc) {
- s->z_err = Z_DATA_ERROR;
- } else {
- (void)getLong(s);
- /* The uncompressed length returned by above getlong() may
- * be different from s->stream.total_out) in case of
- * concatenated .gz files. Check for such files:
- */
- check_header(s);
- if (s->z_err == Z_OK) {
- uLong total_in = s->stream.total_in;
- uLong total_out = s->stream.total_out;
-
- inflateReset(&(s->stream));
- s->stream.total_in = total_in;
- s->stream.total_out = total_out;
- s->crc = crc32(0L, Z_NULL, 0);
- }
- }
- }
- if (s->z_err != Z_OK || s->z_eof) break;
- }
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
-
- return (int)(len - s->stream.avail_out);
-}
-
-
-/* ===========================================================================
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-int ZEXPORT gzgetc(file)
- gzFile file;
-{
- unsigned char c;
-
- return gzread(file, &c, 1) == 1 ? c : -1;
-}
-
-
-/* ===========================================================================
- Reads bytes from the compressed file until len-1 characters are
- read, or a newline character is read and transferred to buf, or an
- end-of-file condition is encountered. The string is then terminated
- with a null character.
- gzgets returns buf, or Z_NULL in case of error.
-
- The current implementation is not optimized at all.
-*/
-char * ZEXPORT gzgets(file, buf, len)
- gzFile file;
- char *buf;
- int len;
-{
- char *b = buf;
- if (buf == Z_NULL || len <= 0) return Z_NULL;
-
- while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
- *buf = '\0';
- return b == buf && len > 0 ? Z_NULL : b;
-}
-
-
-#ifndef NO_DEFLATE
-/* ===========================================================================
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of bytes actually written (0 in case of error).
-*/
-int ZEXPORT gzwrite (file, buf, len)
- gzFile file;
- cvoidp buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.next_in = (Bytef*)buf;
- s->stream.avail_in = len;
-
- while (s->stream.avail_in != 0) {
-
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- break;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
- s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
- if (s->z_err != Z_OK) break;
- }
- s->crc = crc32(s->crc, (const Bytef *)buf, len);
-
- return (int)(len - s->stream.avail_in);
-}
-
-/* ===========================================================================
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error).
-*/
-#ifdef STDC
-#include <stdarg.h>
-
-int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
-{
- char buf[Z_PRINTF_BUFSIZE];
- va_list va;
- int len;
-
- va_start(va, format);
-#ifdef HAS_vsnprintf
- (void)vsnprintf(buf, sizeof(buf), format, va);
-#else
- (void)vsprintf(buf, format, va);
-#endif
- va_end(va);
- len = strlen(buf); /* some *sprintf don't return the nb of bytes written */
- if (len <= 0) return 0;
-
- return gzwrite(file, buf, (unsigned)len);
-}
-#else /* not ANSI C */
-
-int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
- gzFile file;
- const char *format;
- int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
-{
- char buf[Z_PRINTF_BUFSIZE];
- int len;
-
-#ifdef HAS_snprintf
- snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-#else
- sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-#endif
- len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */
- if (len <= 0) return 0;
-
- return gzwrite(file, buf, len);
-}
-#endif
-
-/* ===========================================================================
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-int ZEXPORT gzputc(file, c)
- gzFile file;
- int c;
-{
- unsigned char cc = (unsigned char) c; /* required for big endian systems */
-
- return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
-}
-
-
-/* ===========================================================================
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-int ZEXPORT gzputs(file, s)
- gzFile file;
- const char *s;
-{
- return gzwrite(file, (char*)s, (unsigned)strlen(s));
-}
-
-
-/* ===========================================================================
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function.
-*/
-local int do_flush (file, flush)
- gzFile file;
- int flush;
-{
- uInt len;
- int done = 0;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL)
- return Z_STREAM_ERROR;
- else
- if (s->mode != 'w')
- return Z_STREAM_ERROR;
-
- s->stream.avail_in = 0; /* should be zero already anyway */
-
- for (;;) {
- len = Z_BUFSIZE - s->stream.avail_out;
-
- if (len != 0) {
- if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
- s->z_err = Z_ERRNO;
- return Z_ERRNO;
- }
- s->stream.next_out = s->outbuf;
- s->stream.avail_out = Z_BUFSIZE;
- }
- if (done) break;
- s->z_err = deflate(&(s->stream), flush);
-
- /* Ignore the second of two consecutive flushes: */
- if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
-
- /* deflate has finished flushing only when it hasn't used up
- * all the available space in the output buffer:
- */
- done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
-
- if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
- }
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-
-int ZEXPORT gzflush (file, flush)
- gzFile file;
- int flush;
-{
- gz_stream *s = (gz_stream*)file;
- int err = do_flush (file, flush);
-
- if (err) return err;
- fflush(s->file);
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-#endif /* NO_DEFLATE */
-
-/* ===========================================================================
- Sets the starting position for the next gzread or gzwrite on the given
- compressed file. The offset represents a number of bytes in the
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error.
- SEEK_END is not implemented, returns error.
- In this version of the library, gzseek can be extremely slow.
-*/
-z_off_t ZEXPORT gzseek (file, offset, whence)
- gzFile file;
- z_off_t offset;
- int whence;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || whence == SEEK_END ||
- s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
- return -1L;
- }
-
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- return -1L;
-#else
- if (whence == SEEK_SET) {
- offset -= s->stream.total_in;
- }
- if (offset < 0) return -1L;
-
- /* At this point, offset is the number of zero bytes to write. */
- if (s->inbuf == Z_NULL) {
- s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
- zmemzero(s->inbuf, Z_BUFSIZE);
- }
- while (offset > 0) {
- uInt size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (uInt)offset;
-
- size = gzwrite(file, s->inbuf, size);
- if (size == 0) return -1L;
-
- offset -= size;
- }
- return (z_off_t)s->stream.total_in;
-#endif
- }
- /* Rest of function is for reading only */
-
- /* compute absolute position */
- if (whence == SEEK_CUR) {
- offset += s->stream.total_out;
- }
- if (offset < 0) return -1L;
-
- if (s->transparent) {
- /* map to fseek */
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
-
- s->stream.total_in = s->stream.total_out = (uLong)offset;
- return offset;
- }
-
- /* For a negative seek, rewind and use positive seek */
- if ((uLong)offset >= s->stream.total_out) {
- offset -= s->stream.total_out;
- } else if (gzrewind(file) < 0) {
- return -1L;
- }
- /* offset is now the number of bytes to skip. */
-
- if (offset != 0 && s->outbuf == Z_NULL) {
- s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
- }
- while (offset > 0) {
- int size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (int)offset;
-
- size = gzread(file, s->outbuf, (uInt)size);
- if (size <= 0) return -1L;
- offset -= size;
- }
- return (z_off_t)s->stream.total_out;
-}
-
-/* ===========================================================================
- Rewinds input file.
-*/
-int ZEXPORT gzrewind (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return -1;
-
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- s->crc = crc32(0L, Z_NULL, 0);
-
- if (s->startpos == 0) { /* not a compressed file */
- rewind(s->file);
- return 0;
- }
-
- (void) inflateReset(&s->stream);
- return fseek(s->file, s->startpos, SEEK_SET);
-}
-
-/* ===========================================================================
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-*/
-z_off_t ZEXPORT gztell (file)
- gzFile file;
-{
- return gzseek(file, 0L, SEEK_CUR);
-}
-
-/* ===========================================================================
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-int ZEXPORT gzeof (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- return (s == NULL || s->mode != 'r') ? 0 : s->z_eof;
-}
-
-/* ===========================================================================
- Outputs a long in LSB order to the given file
-*/
-local void putLong (file, x)
- FILE *file;
- uLong x;
-{
- int n;
- for (n = 0; n < 4; n++) {
- fputc((int)(x & 0xff), file);
- x >>= 8;
- }
-}
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets z_err in case
- of error.
-*/
-local uLong getLong (s)
- gz_stream *s;
-{
- uLong x = (uLong)get_byte(s);
- int c;
-
- x += ((uLong)get_byte(s))<<8;
- x += ((uLong)get_byte(s))<<16;
- c = get_byte(s);
- if (c == EOF) s->z_err = Z_DATA_ERROR;
- x += ((uLong)c)<<24;
- return x;
-}
-
-/* ===========================================================================
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state.
-*/
-int ZEXPORT gzclose (file)
- gzFile file;
-{
- int err;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return Z_STREAM_ERROR;
-
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- return Z_STREAM_ERROR;
-#else
- err = do_flush (file, Z_FINISH);
- if (err != Z_OK) return destroy((gz_stream*)file);
-
- putLong (s->file, s->crc);
- putLong (s->file, s->stream.total_in);
-#endif
- }
- return destroy((gz_stream*)file);
-}
-
-/* ===========================================================================
- Returns the error message for the last error which occured on the
- given compressed file. errnum is set to zlib error number. If an
- error occured in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-const char* ZEXPORT gzerror (file, errnum)
- gzFile file;
- int *errnum;
-{
- char *m;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) {
- *errnum = Z_STREAM_ERROR;
- return (const char*)ERR_MSG(Z_STREAM_ERROR);
- }
- *errnum = s->z_err;
- if (*errnum == Z_OK) return (const char*)"";
-
- m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
-
- if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
-
- TRYFREE(s->msg);
- s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
- strcpy(s->msg, s->path);
- strcat(s->msg, ": ");
- strcat(s->msg, m);
- return (const char*)s->msg;
-}
+/* gzio.c -- IO on .gz files
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Compile this file with -DNO_DEFLATE to avoid the compression code.
+ */
+
+/* @(#) $Id: gzio.c,v 1.5 2004-11-27 21:46:13 pixel Exp $ */
+
+#include <stdio.h>
+
+#include "zutil.h"
+
+struct internal_state {int dummy;}; /* for buggy compilers */
+
+#ifndef Z_BUFSIZE
+# ifdef MAXSEG_64K
+# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
+# else
+# define Z_BUFSIZE 16384
+# endif
+#endif
+#ifndef Z_PRINTF_BUFSIZE
+# define Z_PRINTF_BUFSIZE 4096
+#endif
+
+#define ALLOC(size) malloc(size)
+#define TRYFREE(p) {if (p) free(p);}
+
+static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define RESERVED 0xE0 /* bits 5..7: reserved */
+
+typedef struct gz_stream {
+ z_stream stream;
+ int z_err; /* error code for last stream operation */
+ int z_eof; /* set if end of input file */
+ FILE *file; /* .gz file */
+ Byte *inbuf; /* input buffer */
+ Byte *outbuf; /* output buffer */
+ uLong crc; /* crc32 of uncompressed data */
+ char *msg; /* error message */
+ char *path; /* path name for debugging only */
+ int transparent; /* 1 if input file is not a .gz file */
+ char mode; /* 'w' or 'r' */
+ long startpos; /* start of compressed data in file (header skipped) */
+} gz_stream;
+
+
+local gzFile gz_open OF((const char *path, const char *mode, int fd));
+local int do_flush OF((gzFile file, int flush));
+local int get_byte OF((gz_stream *s));
+local void check_header OF((gz_stream *s));
+local int destroy OF((gz_stream *s));
+local void putLong OF((FILE *file, uLong x));
+local uLong getLong OF((gz_stream *s));
+
+/* ===========================================================================
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
+ is as in fopen ("rb" or "wb"). The file is given either by file descriptor
+ or path name (if fd == -1).
+ gz_open return NULL if the file could not be opened or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR).
+*/
+local gzFile gz_open (path, mode, fd)
+ const char *path;
+ const char *mode;
+ int fd;
+{
+ int err;
+ int level = Z_DEFAULT_COMPRESSION; /* compression level */
+ int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
+ char *p = (char*)mode;
+ gz_stream *s;
+ char fmode[80]; /* copy of mode, without the compression level */
+ char *m = fmode;
+
+ if (!path || !mode) return Z_NULL;
+
+ s = (gz_stream *)ALLOC(sizeof(gz_stream));
+ if (!s) return Z_NULL;
+
+ s->stream.zalloc = (alloc_func)0;
+ s->stream.zfree = (free_func)0;
+ s->stream.opaque = (voidpf)0;
+ s->stream.next_in = s->inbuf = Z_NULL;
+ s->stream.next_out = s->outbuf = Z_NULL;
+ s->stream.avail_in = s->stream.avail_out = 0;
+ s->file = NULL;
+ s->z_err = Z_OK;
+ s->z_eof = 0;
+ s->crc = crc32(0L, Z_NULL, 0);
+ s->msg = NULL;
+ s->transparent = 0;
+
+ s->path = (char*)ALLOC(strlen(path)+1);
+ if (s->path == NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ strcpy(s->path, path); /* do this early for debugging */
+
+ s->mode = '\0';
+ do {
+ if (*p == 'r') s->mode = 'r';
+ if (*p == 'w' || *p == 'a') s->mode = 'w';
+ if (*p >= '0' && *p <= '9') {
+ level = *p - '0';
+ } else if (*p == 'f') {
+ strategy = Z_FILTERED;
+ } else if (*p == 'h') {
+ strategy = Z_HUFFMAN_ONLY;
+ } else {
+ *m++ = *p; /* copy the mode */
+ }
+ } while (*p++ && m != fmode + sizeof(fmode));
+ if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
+
+ if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+ err = Z_STREAM_ERROR;
+#else
+ err = deflateInit2(&(s->stream), level,
+ Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
+ /* windowBits is passed < 0 to suppress zlib header */
+
+ s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+#endif
+ if (err != Z_OK || s->outbuf == Z_NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ } else {
+ s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
+
+ err = inflateInit2(&(s->stream), -MAX_WBITS);
+ /* windowBits is passed < 0 to tell that there is no zlib header.
+ * Note that in this case inflate *requires* an extra "dummy" byte
+ * after the compressed stream in order to complete decompression and
+ * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
+ * present after the compressed stream.
+ */
+ if (err != Z_OK || s->inbuf == Z_NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+
+ errno = 0;
+ s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
+
+ if (s->file == NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ if (s->mode == 'w') {
+ /* Write a very simple .gz header:
+ */
+ fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
+ Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
+ s->startpos = 10L;
+ /* We use 10L instead of ftell(s->file) to because ftell causes an
+ * fflush on some systems. This version of the library doesn't use
+ * startpos anyway in write mode, so this initialization is not
+ * necessary.
+ */
+ } else {
+ check_header(s); /* skip the .gz header */
+ s->startpos = (ftell(s->file) - s->stream.avail_in);
+ }
+
+ return (gzFile)s;
+}
+
+/* ===========================================================================
+ Opens a gzip (.gz) file for reading or writing.
+*/
+gzFile ZEXPORT gzopen (path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open (path, mode, -1);
+}
+
+/* ===========================================================================
+ Associate a gzFile with the file descriptor fd. fd is not dup'ed here
+ to mimic the behavio(u)r of fdopen.
+*/
+gzFile ZEXPORT gzdopen (fd, mode)
+ int fd;
+ const char *mode;
+{
+ char name[20];
+
+ if (fd < 0) return (gzFile)Z_NULL;
+ sprintf(name, "<fd:%d>", fd); /* for debugging */
+
+ return gz_open (name, mode, fd);
+}
+
+/* ===========================================================================
+ * Update the compression level and strategy
+ */
+int ZEXPORT gzsetparams (file, level, strategy)
+ gzFile file;
+ int level;
+ int strategy;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ /* Make room to allow flushing */
+ if (s->stream.avail_out == 0) {
+
+ s->stream.next_out = s->outbuf;
+ if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+ s->z_err = Z_ERRNO;
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+
+ return deflateParams (&(s->stream), level, strategy);
+}
+
+/* ===========================================================================
+ Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+ for end of file.
+ IN assertion: the stream s has been sucessfully opened for reading.
+*/
+local int get_byte(s)
+ gz_stream *s;
+{
+ if (s->z_eof) return EOF;
+ if (s->stream.avail_in == 0) {
+ errno = 0;
+ s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+ if (s->stream.avail_in == 0) {
+ s->z_eof = 1;
+ if (ferror(s->file)) s->z_err = Z_ERRNO;
+ return EOF;
+ }
+ s->stream.next_in = s->inbuf;
+ }
+ s->stream.avail_in--;
+ return *(s->stream.next_in)++;
+}
+
+/* ===========================================================================
+ Check the gzip header of a gz_stream opened for reading. Set the stream
+ mode to transparent if the gzip magic header is not present; set s->err
+ to Z_DATA_ERROR if the magic header is present but the rest of the header
+ is incorrect.
+ IN assertion: the stream s has already been created sucessfully;
+ s->stream.avail_in is zero for the first time, but may be non-zero
+ for concatenated .gz files.
+*/
+local void check_header(s)
+ gz_stream *s;
+{
+ int method; /* method byte */
+ int flags; /* flags byte */
+ uInt len;
+ int c;
+
+ /* Check the gzip magic header */
+ for (len = 0; len < 2; len++) {
+ c = get_byte(s);
+ if (c != gz_magic[len]) {
+ if (len != 0) s->stream.avail_in++, s->stream.next_in--;
+ if (c != EOF) {
+ s->stream.avail_in++, s->stream.next_in--;
+ s->transparent = 1;
+ }
+ s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
+ return;
+ }
+ }
+ method = get_byte(s);
+ flags = get_byte(s);
+ if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+ s->z_err = Z_DATA_ERROR;
+ return;
+ }
+
+ /* Discard time, xflags and OS code: */
+ for (len = 0; len < 6; len++) (void)get_byte(s);
+
+ if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+ len = (uInt)get_byte(s);
+ len += ((uInt)get_byte(s))<<8;
+ /* len is garbage if EOF but the loop below will quit anyway */
+ while (len-- != 0 && get_byte(s) != EOF) ;
+ }
+ if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+ while ((c = get_byte(s)) != 0 && c != EOF) ;
+ }
+ if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
+ while ((c = get_byte(s)) != 0 && c != EOF) ;
+ }
+ if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
+ for (len = 0; len < 2; len++) (void)get_byte(s);
+ }
+ s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
+}
+
+ /* ===========================================================================
+ * Cleanup then free the given gz_stream. Return a zlib error code.
+ Try freeing in the reverse order of allocations.
+ */
+local int destroy (s)
+ gz_stream *s;
+{
+ int err = Z_OK;
+
+ if (!s) return Z_STREAM_ERROR;
+
+ TRYFREE(s->msg);
+
+ if (s->stream.state != NULL) {
+ if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+ err = Z_STREAM_ERROR;
+#else
+ err = deflateEnd(&(s->stream));
+#endif
+ } else if (s->mode == 'r') {
+ err = inflateEnd(&(s->stream));
+ }
+ }
+ if (s->file != NULL && fclose(s->file)) {
+#ifdef ESPIPE
+ if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
+#endif
+ err = Z_ERRNO;
+ }
+ if (s->z_err < 0) err = s->z_err;
+
+ TRYFREE(s->inbuf);
+ TRYFREE(s->outbuf);
+ TRYFREE(s->path);
+ TRYFREE(s);
+ return err;
+}
+
+/* ===========================================================================
+ Reads the given number of uncompressed bytes from the compressed file.
+ gzread returns the number of bytes actually read (0 for end of file).
+*/
+int ZEXPORT gzread (file, buf, len)
+ gzFile file;
+ voidp buf;
+ unsigned len;
+{
+ gz_stream *s = (gz_stream*)file;
+ Bytef *start = (Bytef*)buf; /* starting point for crc computation */
+ Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
+
+ if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
+
+ if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
+ if (s->z_err == Z_STREAM_END) return 0; /* EOF */
+
+ next_out = (Byte*)buf;
+ s->stream.next_out = (Bytef*)buf;
+ s->stream.avail_out = len;
+
+ while (s->stream.avail_out != 0) {
+
+ if (s->transparent) {
+ /* Copy first the lookahead bytes: */
+ uInt n = s->stream.avail_in;
+ if (n > s->stream.avail_out) n = s->stream.avail_out;
+ if (n > 0) {
+ zmemcpy(s->stream.next_out, s->stream.next_in, n);
+ next_out += n;
+ s->stream.next_out = next_out;
+ s->stream.next_in += n;
+ s->stream.avail_out -= n;
+ s->stream.avail_in -= n;
+ }
+ if (s->stream.avail_out > 0) {
+ s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
+ s->file);
+ }
+ len -= s->stream.avail_out;
+ s->stream.total_in += (uLong)len;
+ s->stream.total_out += (uLong)len;
+ if (len == 0) s->z_eof = 1;
+ return (int)len;
+ }
+ if (s->stream.avail_in == 0 && !s->z_eof) {
+
+ errno = 0;
+ s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+ if (s->stream.avail_in == 0) {
+ s->z_eof = 1;
+ if (ferror(s->file)) {
+ s->z_err = Z_ERRNO;
+ break;
+ }
+ }
+ s->stream.next_in = s->inbuf;
+ }
+ s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
+
+ if (s->z_err == Z_STREAM_END) {
+ /* Check CRC and original size */
+ s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+ start = s->stream.next_out;
+
+ if (getLong(s) != s->crc) {
+ s->z_err = Z_DATA_ERROR;
+ } else {
+ (void)getLong(s);
+ /* The uncompressed length returned by above getlong() may
+ * be different from s->stream.total_out) in case of
+ * concatenated .gz files. Check for such files:
+ */
+ check_header(s);
+ if (s->z_err == Z_OK) {
+ uLong total_in = s->stream.total_in;
+ uLong total_out = s->stream.total_out;
+
+ inflateReset(&(s->stream));
+ s->stream.total_in = total_in;
+ s->stream.total_out = total_out;
+ s->crc = crc32(0L, Z_NULL, 0);
+ }
+ }
+ }
+ if (s->z_err != Z_OK || s->z_eof) break;
+ }
+ s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+
+ return (int)(len - s->stream.avail_out);
+}
+
+
+/* ===========================================================================
+ Reads one byte from the compressed file. gzgetc returns this byte
+ or -1 in case of end of file or error.
+*/
+int ZEXPORT gzgetc(file)
+ gzFile file;
+{
+ unsigned char c;
+
+ return gzread(file, &c, 1) == 1 ? c : -1;
+}
+
+
+/* ===========================================================================
+ Reads bytes from the compressed file until len-1 characters are
+ read, or a newline character is read and transferred to buf, or an
+ end-of-file condition is encountered. The string is then terminated
+ with a null character.
+ gzgets returns buf, or Z_NULL in case of error.
+
+ The current implementation is not optimized at all.
+*/
+char * ZEXPORT gzgets(file, buf, len)
+ gzFile file;
+ char *buf;
+ int len;
+{
+ char *b = buf;
+ if (buf == Z_NULL || len <= 0) return Z_NULL;
+
+ while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
+ *buf = '\0';
+ return b == buf && len > 0 ? Z_NULL : b;
+}
+
+
+#ifndef NO_DEFLATE
+/* ===========================================================================
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of bytes actually written (0 in case of error).
+*/
+int ZEXPORT gzwrite (file, buf, len)
+ gzFile file;
+ cvoidp buf;
+ unsigned len;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ s->stream.next_in = (Bytef*)buf;
+ s->stream.avail_in = len;
+
+ while (s->stream.avail_in != 0) {
+
+ if (s->stream.avail_out == 0) {
+
+ s->stream.next_out = s->outbuf;
+ if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+ s->z_err = Z_ERRNO;
+ break;
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+ s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
+ if (s->z_err != Z_OK) break;
+ }
+ s->crc = crc32(s->crc, (const Bytef *)buf, len);
+
+ return (int)(len - s->stream.avail_in);
+}
+
+/* ===========================================================================
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error).
+*/
+#ifdef STDC
+#include <stdarg.h>
+
+int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
+{
+ char buf[Z_PRINTF_BUFSIZE];
+ va_list va;
+ int len;
+
+ va_start(va, format);
+#ifdef HAS_vsnprintf
+ (void)vsnprintf(buf, sizeof(buf), format, va);
+#else
+ (void)vsprintf(buf, format, va);
+#endif
+ va_end(va);
+ len = strlen(buf); /* some *sprintf don't return the nb of bytes written */
+ if (len <= 0) return 0;
+
+ return gzwrite(file, buf, (unsigned)len);
+}
+#else /* not ANSI C */
+
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+ gzFile file;
+ const char *format;
+ int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+ char buf[Z_PRINTF_BUFSIZE];
+ int len;
+
+#ifdef HAS_snprintf
+ snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#else
+ sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#endif
+ len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */
+ if (len <= 0) return 0;
+
+ return gzwrite(file, buf, len);
+}
+#endif
+
+/* ===========================================================================
+ Writes c, converted to an unsigned char, into the compressed file.
+ gzputc returns the value that was written, or -1 in case of error.
+*/
+int ZEXPORT gzputc(file, c)
+ gzFile file;
+ int c;
+{
+ unsigned char cc = (unsigned char) c; /* required for big endian systems */
+
+ return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
+}
+
+
+/* ===========================================================================
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+int ZEXPORT gzputs(file, s)
+ gzFile file;
+ const char *s;
+{
+ return gzwrite(file, (char*)s, (unsigned)strlen(s));
+}
+
+
+/* ===========================================================================
+ Flushes all pending output into the compressed file. The parameter
+ flush is as in the deflate() function.
+*/
+local int do_flush (file, flush)
+ gzFile file;
+ int flush;
+{
+ uInt len;
+ int done = 0;
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL)
+ return Z_STREAM_ERROR;
+ else
+ if (s->mode != 'w')
+ return Z_STREAM_ERROR;
+
+ s->stream.avail_in = 0; /* should be zero already anyway */
+
+ for (;;) {
+ len = Z_BUFSIZE - s->stream.avail_out;
+
+ if (len != 0) {
+ if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
+ s->z_err = Z_ERRNO;
+ return Z_ERRNO;
+ }
+ s->stream.next_out = s->outbuf;
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+ if (done) break;
+ s->z_err = deflate(&(s->stream), flush);
+
+ /* Ignore the second of two consecutive flushes: */
+ if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
+
+ /* deflate has finished flushing only when it hasn't used up
+ * all the available space in the output buffer:
+ */
+ done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
+
+ if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
+ }
+ return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+
+int ZEXPORT gzflush (file, flush)
+ gzFile file;
+ int flush;
+{
+ gz_stream *s = (gz_stream*)file;
+ int err = do_flush (file, flush);
+
+ if (err) return err;
+ fflush(s->file);
+ return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+#endif /* NO_DEFLATE */
+
+/* ===========================================================================
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error.
+ SEEK_END is not implemented, returns error.
+ In this version of the library, gzseek can be extremely slow.
+*/
+z_off_t ZEXPORT gzseek (file, offset, whence)
+ gzFile file;
+ z_off_t offset;
+ int whence;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || whence == SEEK_END ||
+ s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
+ return -1L;
+ }
+
+ if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+ return -1L;
+#else
+ if (whence == SEEK_SET) {
+ offset -= s->stream.total_in;
+ }
+ if (offset < 0) return -1L;
+
+ /* At this point, offset is the number of zero bytes to write. */
+ if (s->inbuf == Z_NULL) {
+ s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
+ zmemzero(s->inbuf, Z_BUFSIZE);
+ }
+ while (offset > 0) {
+ uInt size = Z_BUFSIZE;
+ if (offset < Z_BUFSIZE) size = (uInt)offset;
+
+ size = gzwrite(file, s->inbuf, size);
+ if (size == 0) return -1L;
+
+ offset -= size;
+ }
+ return (z_off_t)s->stream.total_in;
+#endif
+ }
+ /* Rest of function is for reading only */
+
+ /* compute absolute position */
+ if (whence == SEEK_CUR) {
+ offset += s->stream.total_out;
+ }
+ if (offset < 0) return -1L;
+
+ if (s->transparent) {
+ /* map to fseek */
+ s->stream.avail_in = 0;
+ s->stream.next_in = s->inbuf;
+ if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
+
+ s->stream.total_in = s->stream.total_out = (uLong)offset;
+ return offset;
+ }
+
+ /* For a negative seek, rewind and use positive seek */
+ if ((uLong)offset >= s->stream.total_out) {
+ offset -= s->stream.total_out;
+ } else if (gzrewind(file) < 0) {
+ return -1L;
+ }
+ /* offset is now the number of bytes to skip. */
+
+ if (offset != 0 && s->outbuf == Z_NULL) {
+ s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+ }
+ while (offset > 0) {
+ int size = Z_BUFSIZE;
+ if (offset < Z_BUFSIZE) size = (int)offset;
+
+ size = gzread(file, s->outbuf, (uInt)size);
+ if (size <= 0) return -1L;
+ offset -= size;
+ }
+ return (z_off_t)s->stream.total_out;
+}
+
+/* ===========================================================================
+ Rewinds input file.
+*/
+int ZEXPORT gzrewind (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'r') return -1;
+
+ s->z_err = Z_OK;
+ s->z_eof = 0;
+ s->stream.avail_in = 0;
+ s->stream.next_in = s->inbuf;
+ s->crc = crc32(0L, Z_NULL, 0);
+
+ if (s->startpos == 0) { /* not a compressed file */
+ rewind(s->file);
+ return 0;
+ }
+
+ (void) inflateReset(&s->stream);
+ return fseek(s->file, s->startpos, SEEK_SET);
+}
+
+/* ===========================================================================
+ Returns the starting position for the next gzread or gzwrite on the
+ given compressed file. This position represents a number of bytes in the
+ uncompressed data stream.
+*/
+z_off_t ZEXPORT gztell (file)
+ gzFile file;
+{
+ return gzseek(file, 0L, SEEK_CUR);
+}
+
+/* ===========================================================================
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+int ZEXPORT gzeof (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ return (s == NULL || s->mode != 'r') ? 0 : s->z_eof;
+}
+
+/* ===========================================================================
+ Outputs a long in LSB order to the given file
+*/
+local void putLong (file, x)
+ FILE *file;
+ uLong x;
+{
+ int n;
+ for (n = 0; n < 4; n++) {
+ fputc((int)(x & 0xff), file);
+ x >>= 8;
+ }
+}
+
+/* ===========================================================================
+ Reads a long in LSB order from the given gz_stream. Sets z_err in case
+ of error.
+*/
+local uLong getLong (s)
+ gz_stream *s;
+{
+ uLong x = (uLong)get_byte(s);
+ int c;
+
+ x += ((uLong)get_byte(s))<<8;
+ x += ((uLong)get_byte(s))<<16;
+ c = get_byte(s);
+ if (c == EOF) s->z_err = Z_DATA_ERROR;
+ x += ((uLong)c)<<24;
+ return x;
+}
+
+/* ===========================================================================
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state.
+*/
+int ZEXPORT gzclose (file)
+ gzFile file;
+{
+ int err;
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL) return Z_STREAM_ERROR;
+
+ if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+ return Z_STREAM_ERROR;
+#else
+ err = do_flush (file, Z_FINISH);
+ if (err != Z_OK) return destroy((gz_stream*)file);
+
+ putLong (s->file, s->crc);
+ putLong (s->file, s->stream.total_in);
+#endif
+ }
+ return destroy((gz_stream*)file);
+}
+
+/* ===========================================================================
+ Returns the error message for the last error which occured on the
+ given compressed file. errnum is set to zlib error number. If an
+ error occured in the file system and not in the compression library,
+ errnum is set to Z_ERRNO and the application may consult errno
+ to get the exact error code.
+*/
+const char* ZEXPORT gzerror (file, errnum)
+ gzFile file;
+ int *errnum;
+{
+ char *m;
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL) {
+ *errnum = Z_STREAM_ERROR;
+ return (const char*)ERR_MSG(Z_STREAM_ERROR);
+ }
+ *errnum = s->z_err;
+ if (*errnum == Z_OK) return (const char*)"";
+
+ m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
+
+ if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
+
+ TRYFREE(s->msg);
+ s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
+ strcpy(s->msg, s->path);
+ strcat(s->msg, ": ");
+ strcat(s->msg, m);
+ return (const char*)s->msg;
+}
diff --git a/lib/zlib/src/infblock.c b/lib/zlib/src/infblock.c
index 943e849..dd7a6d4 100644
--- a/lib/zlib/src/infblock.c
+++ b/lib/zlib/src/infblock.c
@@ -1,403 +1,403 @@
-/* infblock.c -- interpret and process block types to last block
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "infblock.h"
-#include "inftrees.h"
-#include "infcodes.h"
-#include "infutil.h"
-
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* Table for deflate from PKZIP's appnote.txt. */
-local const uInt border[] = { /* Order of the bit length code lengths */
- 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-/*
- Notes beyond the 1.93a appnote.txt:
-
- 1. Distance pointers never point before the beginning of the output
- stream.
- 2. Distance pointers can point back across blocks, up to 32k away.
- 3. There is an implied maximum of 7 bits for the bit length table and
- 15 bits for the actual data.
- 4. If only one code exists, then it is encoded using one bit. (Zero
- would be more efficient, but perhaps a little confusing.) If two
- codes exist, they are coded using one bit each (0 and 1).
- 5. There is no way of sending zero distance codes--a dummy must be
- sent if there are none. (History: a pre 2.0 version of PKZIP would
- store blocks with no distance codes, but this was discovered to be
- too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
- zero distance codes, which is sent as one code of zero bits in
- length.
- 6. There are up to 286 literal/length codes. Code 256 represents the
- end-of-block. Note however that the static length tree defines
- 288 codes just to fill out the Huffman codes. Codes 286 and 287
- cannot be used though, since there is no length base or extra bits
- defined for them. Similarily, there are up to 30 distance codes.
- However, static trees define 32 codes (all 5 bits) to fill out the
- Huffman codes, but the last two had better not show up in the data.
- 7. Unzip can check dynamic Huffman blocks for complete code sets.
- The exception is that a single code would not be complete (see #4).
- 8. The five bits following the block type is really the number of
- literal codes sent minus 257.
- 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
- (1+6+6). Therefore, to output three times the length, you output
- three codes (1+1+1), whereas to output four times the same length,
- you only need two codes (1+3). Hmm.
- 10. In the tree reconstruction algorithm, Code = Code + Increment
- only if BitLength(i) is not zero. (Pretty obvious.)
- 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
- 12. Note: length code 284 can represent 227-258, but length code 285
- really is 258. The last length deserves its own, short code
- since it gets used a lot in very redundant files. The length
- 258 is special since 258 - 3 (the min match length) is 255.
- 13. The literal/length and distance code bit lengths are read as a
- single stream of lengths. It is possible (and advantageous) for
- a repeat code (16, 17, or 18) to go across the boundary between
- the two sets of lengths.
- */
-
-
-void inflate_blocks_reset(s, z, c)
-inflate_blocks_statef *s;
-z_streamp z;
-uLongf *c;
-{
- if (c != Z_NULL)
- *c = s->check;
- if (s->mode == BTREE || s->mode == DTREE)
- ZFREE(z, s->sub.trees.blens);
- if (s->mode == CODES)
- inflate_codes_free(s->sub.decode.codes, z);
- s->mode = TYPE;
- s->bitk = 0;
- s->bitb = 0;
- s->read = s->write = s->window;
- if (s->checkfn != Z_NULL)
- z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
- Tracev((stderr, "inflate: blocks reset\n"));
-}
-
-
-inflate_blocks_statef *inflate_blocks_new(z, c, w)
-z_streamp z;
-check_func c;
-uInt w;
-{
- inflate_blocks_statef *s;
-
- if ((s = (inflate_blocks_statef *)ZALLOC
- (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
- return s;
- if ((s->hufts =
- (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
- {
- ZFREE(z, s);
- return Z_NULL;
- }
- if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
- {
- ZFREE(z, s->hufts);
- ZFREE(z, s);
- return Z_NULL;
- }
- s->end = s->window + w;
- s->checkfn = c;
- s->mode = TYPE;
- Tracev((stderr, "inflate: blocks allocated\n"));
- inflate_blocks_reset(s, z, Z_NULL);
- return s;
-}
-
-
-int inflate_blocks(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
- uInt t; /* temporary storage */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
-
- /* copy input/output information to locals (UPDATE macro restores) */
- LOAD
-
- /* process input based on current state */
- while (1) switch (s->mode)
- {
- case TYPE:
- NEEDBITS(3)
- t = (uInt)b & 7;
- s->last = t & 1;
- switch (t >> 1)
- {
- case 0: /* stored */
- Tracev((stderr, "inflate: stored block%s\n",
- s->last ? " (last)" : ""));
- DUMPBITS(3)
- t = k & 7; /* go to byte boundary */
- DUMPBITS(t)
- s->mode = LENS; /* get length of stored block */
- break;
- case 1: /* fixed */
- Tracev((stderr, "inflate: fixed codes block%s\n",
- s->last ? " (last)" : ""));
- {
- uInt bl, bd;
- inflate_huft *tl, *td;
-
- inflate_trees_fixed(&bl, &bd, &tl, &td, z);
- s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
- if (s->sub.decode.codes == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- }
- DUMPBITS(3)
- s->mode = CODES;
- break;
- case 2: /* dynamic */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- s->last ? " (last)" : ""));
- DUMPBITS(3)
- s->mode = TABLE;
- break;
- case 3: /* illegal */
- DUMPBITS(3)
- s->mode = BAD;
- z->msg = (char*)"invalid block type";
- r = Z_DATA_ERROR;
- LEAVE
- }
- break;
- case LENS:
- NEEDBITS(32)
- if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
- {
- s->mode = BAD;
- z->msg = (char*)"invalid stored block lengths";
- r = Z_DATA_ERROR;
- LEAVE
- }
- s->sub.left = (uInt)b & 0xffff;
- b = k = 0; /* dump bits */
- Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
- s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
- break;
- case STORED:
- if (n == 0)
- LEAVE
- NEEDOUT
- t = s->sub.left;
- if (t > n) t = n;
- if (t > m) t = m;
- zmemcpy(q, p, t);
- p += t; n -= t;
- q += t; m -= t;
- if ((s->sub.left -= t) != 0)
- break;
- Tracev((stderr, "inflate: stored end, %lu total out\n",
- z->total_out + (q >= s->read ? q - s->read :
- (s->end - s->read) + (q - s->window))));
- s->mode = s->last ? DRY : TYPE;
- break;
- case TABLE:
- NEEDBITS(14)
- s->sub.trees.table = t = (uInt)b & 0x3fff;
-#ifndef PKZIP_BUG_WORKAROUND
- if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
- {
- s->mode = BAD;
- z->msg = (char*)"too many length or distance symbols";
- r = Z_DATA_ERROR;
- LEAVE
- }
-#endif
- t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
- if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- DUMPBITS(14)
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: table sizes ok\n"));
- s->mode = BTREE;
- case BTREE:
- while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
- {
- NEEDBITS(3)
- s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
- DUMPBITS(3)
- }
- while (s->sub.trees.index < 19)
- s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
- s->sub.trees.bb = 7;
- t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
- &s->sub.trees.tb, s->hufts, z);
- if (t != Z_OK)
- {
- r = t;
- if (r == Z_DATA_ERROR)
- {
- ZFREE(z, s->sub.trees.blens);
- s->mode = BAD;
- }
- LEAVE
- }
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: bits tree ok\n"));
- s->mode = DTREE;
- case DTREE:
- while (t = s->sub.trees.table,
- s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
- {
- inflate_huft *h;
- uInt i, j, c;
-
- t = s->sub.trees.bb;
- NEEDBITS(t)
- h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
- t = h->bits;
- c = h->base;
- if (c < 16)
- {
- DUMPBITS(t)
- s->sub.trees.blens[s->sub.trees.index++] = c;
- }
- else /* c == 16..18 */
- {
- i = c == 18 ? 7 : c - 14;
- j = c == 18 ? 11 : 3;
- NEEDBITS(t + i)
- DUMPBITS(t)
- j += (uInt)b & inflate_mask[i];
- DUMPBITS(i)
- i = s->sub.trees.index;
- t = s->sub.trees.table;
- if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
- (c == 16 && i < 1))
- {
- ZFREE(z, s->sub.trees.blens);
- s->mode = BAD;
- z->msg = (char*)"invalid bit length repeat";
- r = Z_DATA_ERROR;
- LEAVE
- }
- c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
- do {
- s->sub.trees.blens[i++] = c;
- } while (--j);
- s->sub.trees.index = i;
- }
- }
- s->sub.trees.tb = Z_NULL;
- {
- uInt bl, bd;
- inflate_huft *tl, *td;
- inflate_codes_statef *c;
-
- bl = 9; /* must be <= 9 for lookahead assumptions */
- bd = 6; /* must be <= 9 for lookahead assumptions */
- t = s->sub.trees.table;
- t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
- s->sub.trees.blens, &bl, &bd, &tl, &td,
- s->hufts, z);
- if (t != Z_OK)
- {
- if (t == (uInt)Z_DATA_ERROR)
- {
- ZFREE(z, s->sub.trees.blens);
- s->mode = BAD;
- }
- r = t;
- LEAVE
- }
- Tracev((stderr, "inflate: trees ok\n"));
- if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
- {
- r = Z_MEM_ERROR;
- LEAVE
- }
- s->sub.decode.codes = c;
- }
- ZFREE(z, s->sub.trees.blens);
- s->mode = CODES;
- case CODES:
- UPDATE
- if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
- return inflate_flush(s, z, r);
- r = Z_OK;
- inflate_codes_free(s->sub.decode.codes, z);
- LOAD
- Tracev((stderr, "inflate: codes end, %lu total out\n",
- z->total_out + (q >= s->read ? q - s->read :
- (s->end - s->read) + (q - s->window))));
- if (!s->last)
- {
- s->mode = TYPE;
- break;
- }
- s->mode = DRY;
- case DRY:
- FLUSH
- if (s->read != s->write)
- LEAVE
- s->mode = DONE;
- case DONE:
- r = Z_STREAM_END;
- LEAVE
- case BAD:
- r = Z_DATA_ERROR;
- LEAVE
- default:
- r = Z_STREAM_ERROR;
- LEAVE
- }
-}
-
-
-int inflate_blocks_free(s, z)
-inflate_blocks_statef *s;
-z_streamp z;
-{
- inflate_blocks_reset(s, z, Z_NULL);
- ZFREE(z, s->window);
- ZFREE(z, s->hufts);
- ZFREE(z, s);
- Tracev((stderr, "inflate: blocks freed\n"));
- return Z_OK;
-}
-
-
-void inflate_set_dictionary(s, d, n)
-inflate_blocks_statef *s;
-const Bytef *d;
-uInt n;
-{
- zmemcpy(s->window, d, n);
- s->read = s->write = s->window + n;
-}
-
-
-/* Returns true if inflate is currently at the end of a block generated
- * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
- * IN assertion: s != Z_NULL
- */
-int inflate_blocks_sync_point(s)
-inflate_blocks_statef *s;
-{
- return s->mode == LENS;
-}
+/* infblock.c -- interpret and process block types to last block
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+#include "inftrees.h"
+#include "infcodes.h"
+#include "infutil.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* Table for deflate from PKZIP's appnote.txt. */
+local const uInt border[] = { /* Order of the bit length code lengths */
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+/*
+ Notes beyond the 1.93a appnote.txt:
+
+ 1. Distance pointers never point before the beginning of the output
+ stream.
+ 2. Distance pointers can point back across blocks, up to 32k away.
+ 3. There is an implied maximum of 7 bits for the bit length table and
+ 15 bits for the actual data.
+ 4. If only one code exists, then it is encoded using one bit. (Zero
+ would be more efficient, but perhaps a little confusing.) If two
+ codes exist, they are coded using one bit each (0 and 1).
+ 5. There is no way of sending zero distance codes--a dummy must be
+ sent if there are none. (History: a pre 2.0 version of PKZIP would
+ store blocks with no distance codes, but this was discovered to be
+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
+ zero distance codes, which is sent as one code of zero bits in
+ length.
+ 6. There are up to 286 literal/length codes. Code 256 represents the
+ end-of-block. Note however that the static length tree defines
+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
+ cannot be used though, since there is no length base or extra bits
+ defined for them. Similarily, there are up to 30 distance codes.
+ However, static trees define 32 codes (all 5 bits) to fill out the
+ Huffman codes, but the last two had better not show up in the data.
+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
+ The exception is that a single code would not be complete (see #4).
+ 8. The five bits following the block type is really the number of
+ literal codes sent minus 257.
+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+ (1+6+6). Therefore, to output three times the length, you output
+ three codes (1+1+1), whereas to output four times the same length,
+ you only need two codes (1+3). Hmm.
+ 10. In the tree reconstruction algorithm, Code = Code + Increment
+ only if BitLength(i) is not zero. (Pretty obvious.)
+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
+ 12. Note: length code 284 can represent 227-258, but length code 285
+ really is 258. The last length deserves its own, short code
+ since it gets used a lot in very redundant files. The length
+ 258 is special since 258 - 3 (the min match length) is 255.
+ 13. The literal/length and distance code bit lengths are read as a
+ single stream of lengths. It is possible (and advantageous) for
+ a repeat code (16, 17, or 18) to go across the boundary between
+ the two sets of lengths.
+ */
+
+
+void inflate_blocks_reset(s, z, c)
+inflate_blocks_statef *s;
+z_streamp z;
+uLongf *c;
+{
+ if (c != Z_NULL)
+ *c = s->check;
+ if (s->mode == BTREE || s->mode == DTREE)
+ ZFREE(z, s->sub.trees.blens);
+ if (s->mode == CODES)
+ inflate_codes_free(s->sub.decode.codes, z);
+ s->mode = TYPE;
+ s->bitk = 0;
+ s->bitb = 0;
+ s->read = s->write = s->window;
+ if (s->checkfn != Z_NULL)
+ z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
+ Tracev((stderr, "inflate: blocks reset\n"));
+}
+
+
+inflate_blocks_statef *inflate_blocks_new(z, c, w)
+z_streamp z;
+check_func c;
+uInt w;
+{
+ inflate_blocks_statef *s;
+
+ if ((s = (inflate_blocks_statef *)ZALLOC
+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
+ return s;
+ if ((s->hufts =
+ (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
+ {
+ ZFREE(z, s);
+ return Z_NULL;
+ }
+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
+ {
+ ZFREE(z, s->hufts);
+ ZFREE(z, s);
+ return Z_NULL;
+ }
+ s->end = s->window + w;
+ s->checkfn = c;
+ s->mode = TYPE;
+ Tracev((stderr, "inflate: blocks allocated\n"));
+ inflate_blocks_reset(s, z, Z_NULL);
+ return s;
+}
+
+
+int inflate_blocks(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+ uInt t; /* temporary storage */
+ uLong b; /* bit buffer */
+ uInt k; /* bits in bit buffer */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+
+ /* copy input/output information to locals (UPDATE macro restores) */
+ LOAD
+
+ /* process input based on current state */
+ while (1) switch (s->mode)
+ {
+ case TYPE:
+ NEEDBITS(3)
+ t = (uInt)b & 7;
+ s->last = t & 1;
+ switch (t >> 1)
+ {
+ case 0: /* stored */
+ Tracev((stderr, "inflate: stored block%s\n",
+ s->last ? " (last)" : ""));
+ DUMPBITS(3)
+ t = k & 7; /* go to byte boundary */
+ DUMPBITS(t)
+ s->mode = LENS; /* get length of stored block */
+ break;
+ case 1: /* fixed */
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ s->last ? " (last)" : ""));
+ {
+ uInt bl, bd;
+ inflate_huft *tl, *td;
+
+ inflate_trees_fixed(&bl, &bd, &tl, &td, z);
+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
+ if (s->sub.decode.codes == Z_NULL)
+ {
+ r = Z_MEM_ERROR;
+ LEAVE
+ }
+ }
+ DUMPBITS(3)
+ s->mode = CODES;
+ break;
+ case 2: /* dynamic */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ s->last ? " (last)" : ""));
+ DUMPBITS(3)
+ s->mode = TABLE;
+ break;
+ case 3: /* illegal */
+ DUMPBITS(3)
+ s->mode = BAD;
+ z->msg = (char*)"invalid block type";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+ break;
+ case LENS:
+ NEEDBITS(32)
+ if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
+ {
+ s->mode = BAD;
+ z->msg = (char*)"invalid stored block lengths";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+ s->sub.left = (uInt)b & 0xffff;
+ b = k = 0; /* dump bits */
+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
+ s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
+ break;
+ case STORED:
+ if (n == 0)
+ LEAVE
+ NEEDOUT
+ t = s->sub.left;
+ if (t > n) t = n;
+ if (t > m) t = m;
+ zmemcpy(q, p, t);
+ p += t; n -= t;
+ q += t; m -= t;
+ if ((s->sub.left -= t) != 0)
+ break;
+ Tracev((stderr, "inflate: stored end, %lu total out\n",
+ z->total_out + (q >= s->read ? q - s->read :
+ (s->end - s->read) + (q - s->window))));
+ s->mode = s->last ? DRY : TYPE;
+ break;
+ case TABLE:
+ NEEDBITS(14)
+ s->sub.trees.table = t = (uInt)b & 0x3fff;
+#ifndef PKZIP_BUG_WORKAROUND
+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+ {
+ s->mode = BAD;
+ z->msg = (char*)"too many length or distance symbols";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+#endif
+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
+ {
+ r = Z_MEM_ERROR;
+ LEAVE
+ }
+ DUMPBITS(14)
+ s->sub.trees.index = 0;
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ s->mode = BTREE;
+ case BTREE:
+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
+ {
+ NEEDBITS(3)
+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
+ DUMPBITS(3)
+ }
+ while (s->sub.trees.index < 19)
+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
+ s->sub.trees.bb = 7;
+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
+ &s->sub.trees.tb, s->hufts, z);
+ if (t != Z_OK)
+ {
+ r = t;
+ if (r == Z_DATA_ERROR)
+ {
+ ZFREE(z, s->sub.trees.blens);
+ s->mode = BAD;
+ }
+ LEAVE
+ }
+ s->sub.trees.index = 0;
+ Tracev((stderr, "inflate: bits tree ok\n"));
+ s->mode = DTREE;
+ case DTREE:
+ while (t = s->sub.trees.table,
+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
+ {
+ inflate_huft *h;
+ uInt i, j, c;
+
+ t = s->sub.trees.bb;
+ NEEDBITS(t)
+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
+ t = h->bits;
+ c = h->base;
+ if (c < 16)
+ {
+ DUMPBITS(t)
+ s->sub.trees.blens[s->sub.trees.index++] = c;
+ }
+ else /* c == 16..18 */
+ {
+ i = c == 18 ? 7 : c - 14;
+ j = c == 18 ? 11 : 3;
+ NEEDBITS(t + i)
+ DUMPBITS(t)
+ j += (uInt)b & inflate_mask[i];
+ DUMPBITS(i)
+ i = s->sub.trees.index;
+ t = s->sub.trees.table;
+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+ (c == 16 && i < 1))
+ {
+ ZFREE(z, s->sub.trees.blens);
+ s->mode = BAD;
+ z->msg = (char*)"invalid bit length repeat";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
+ do {
+ s->sub.trees.blens[i++] = c;
+ } while (--j);
+ s->sub.trees.index = i;
+ }
+ }
+ s->sub.trees.tb = Z_NULL;
+ {
+ uInt bl, bd;
+ inflate_huft *tl, *td;
+ inflate_codes_statef *c;
+
+ bl = 9; /* must be <= 9 for lookahead assumptions */
+ bd = 6; /* must be <= 9 for lookahead assumptions */
+ t = s->sub.trees.table;
+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
+ s->sub.trees.blens, &bl, &bd, &tl, &td,
+ s->hufts, z);
+ if (t != Z_OK)
+ {
+ if (t == (uInt)Z_DATA_ERROR)
+ {
+ ZFREE(z, s->sub.trees.blens);
+ s->mode = BAD;
+ }
+ r = t;
+ LEAVE
+ }
+ Tracev((stderr, "inflate: trees ok\n"));
+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
+ {
+ r = Z_MEM_ERROR;
+ LEAVE
+ }
+ s->sub.decode.codes = c;
+ }
+ ZFREE(z, s->sub.trees.blens);
+ s->mode = CODES;
+ case CODES:
+ UPDATE
+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
+ return inflate_flush(s, z, r);
+ r = Z_OK;
+ inflate_codes_free(s->sub.decode.codes, z);
+ LOAD
+ Tracev((stderr, "inflate: codes end, %lu total out\n",
+ z->total_out + (q >= s->read ? q - s->read :
+ (s->end - s->read) + (q - s->window))));
+ if (!s->last)
+ {
+ s->mode = TYPE;
+ break;
+ }
+ s->mode = DRY;
+ case DRY:
+ FLUSH
+ if (s->read != s->write)
+ LEAVE
+ s->mode = DONE;
+ case DONE:
+ r = Z_STREAM_END;
+ LEAVE
+ case BAD:
+ r = Z_DATA_ERROR;
+ LEAVE
+ default:
+ r = Z_STREAM_ERROR;
+ LEAVE
+ }
+}
+
+
+int inflate_blocks_free(s, z)
+inflate_blocks_statef *s;
+z_streamp z;
+{
+ inflate_blocks_reset(s, z, Z_NULL);
+ ZFREE(z, s->window);
+ ZFREE(z, s->hufts);
+ ZFREE(z, s);
+ Tracev((stderr, "inflate: blocks freed\n"));
+ return Z_OK;
+}
+
+
+void inflate_set_dictionary(s, d, n)
+inflate_blocks_statef *s;
+const Bytef *d;
+uInt n;
+{
+ zmemcpy(s->window, d, n);
+ s->read = s->write = s->window + n;
+}
+
+
+/* Returns true if inflate is currently at the end of a block generated
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
+ * IN assertion: s != Z_NULL
+ */
+int inflate_blocks_sync_point(s)
+inflate_blocks_statef *s;
+{
+ return s->mode == LENS;
+}
diff --git a/lib/zlib/src/infcodes.c b/lib/zlib/src/infcodes.c
index aa7b3a0..9abe541 100644
--- a/lib/zlib/src/infcodes.c
+++ b/lib/zlib/src/infcodes.c
@@ -1,251 +1,251 @@
-/* infcodes.c -- process literals and length/distance pairs
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "infblock.h"
-#include "infcodes.h"
-#include "infutil.h"
-#include "inffast.h"
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
- START, /* x: set up for LEN */
- LEN, /* i: get length/literal/eob next */
- LENEXT, /* i: getting length extra (have base) */
- DIST, /* i: get distance next */
- DISTEXT, /* i: getting distance extra */
- COPY, /* o: copying bytes in window, waiting for space */
- LIT, /* o: got literal, waiting for output space */
- WASH, /* o: got eob, possibly still output waiting */
- END, /* x: got eob and all data flushed */
- BADCODE} /* x: got error */
-inflate_codes_mode;
-
-/* inflate codes private state */
-struct inflate_codes_state {
-
- /* mode */
- inflate_codes_mode mode; /* current inflate_codes mode */
-
- /* mode dependent information */
- uInt len;
- union {
- struct {
- inflate_huft *tree; /* pointer into tree */
- uInt need; /* bits needed */
- } code; /* if LEN or DIST, where in tree */
- uInt lit; /* if LIT, literal */
- struct {
- uInt get; /* bits to get for extra */
- uInt dist; /* distance back to copy from */
- } copy; /* if EXT or COPY, where and how much */
- } sub; /* submode */
-
- /* mode independent information */
- Byte lbits; /* ltree bits decoded per branch */
- Byte dbits; /* dtree bits decoder per branch */
- inflate_huft *ltree; /* literal/length/eob tree */
- inflate_huft *dtree; /* distance tree */
-
-};
-
-
-inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
-uInt bl, bd;
-inflate_huft *tl;
-inflate_huft *td; /* need separate declaration for Borland C++ */
-z_streamp z;
-{
- inflate_codes_statef *c;
-
- if ((c = (inflate_codes_statef *)
- ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
- {
- c->mode = START;
- c->lbits = (Byte)bl;
- c->dbits = (Byte)bd;
- c->ltree = tl;
- c->dtree = td;
- Tracev((stderr, "inflate: codes new\n"));
- }
- return c;
-}
-
-
-int inflate_codes(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
- uInt j; /* temporary storage */
- inflate_huft *t; /* temporary pointer */
- uInt e; /* extra bits or operation */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
- Bytef *f; /* pointer to copy strings from */
- inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
-
- /* copy input/output information to locals (UPDATE macro restores) */
- LOAD
-
- /* process input and output based on current state */
- while (1) switch (c->mode)
- { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
- case START: /* x: set up for LEN */
-#ifndef SLOW
- if (m >= 258 && n >= 10)
- {
- UPDATE
- r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
- LOAD
- if (r != Z_OK)
- {
- c->mode = r == Z_STREAM_END ? WASH : BADCODE;
- break;
- }
- }
-#endif /* !SLOW */
- c->sub.code.need = c->lbits;
- c->sub.code.tree = c->ltree;
- c->mode = LEN;
- case LEN: /* i: get length/literal/eob next */
- j = c->sub.code.need;
- NEEDBITS(j)
- t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
- DUMPBITS(t->bits)
- e = (uInt)(t->exop);
- if (e == 0) /* literal */
- {
- c->sub.lit = t->base;
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", t->base));
- c->mode = LIT;
- break;
- }
- if (e & 16) /* length */
- {
- c->sub.copy.get = e & 15;
- c->len = t->base;
- c->mode = LENEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = t + t->base;
- break;
- }
- if (e & 32) /* end of block */
- {
- Tracevv((stderr, "inflate: end of block\n"));
- c->mode = WASH;
- break;
- }
- c->mode = BADCODE; /* invalid code */
- z->msg = (char*)"invalid literal/length code";
- r = Z_DATA_ERROR;
- LEAVE
- case LENEXT: /* i: getting length extra (have base) */
- j = c->sub.copy.get;
- NEEDBITS(j)
- c->len += (uInt)b & inflate_mask[j];
- DUMPBITS(j)
- c->sub.code.need = c->dbits;
- c->sub.code.tree = c->dtree;
- Tracevv((stderr, "inflate: length %u\n", c->len));
- c->mode = DIST;
- case DIST: /* i: get distance next */
- j = c->sub.code.need;
- NEEDBITS(j)
- t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
- DUMPBITS(t->bits)
- e = (uInt)(t->exop);
- if (e & 16) /* distance */
- {
- c->sub.copy.get = e & 15;
- c->sub.copy.dist = t->base;
- c->mode = DISTEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = t + t->base;
- break;
- }
- c->mode = BADCODE; /* invalid code */
- z->msg = (char*)"invalid distance code";
- r = Z_DATA_ERROR;
- LEAVE
- case DISTEXT: /* i: getting distance extra */
- j = c->sub.copy.get;
- NEEDBITS(j)
- c->sub.copy.dist += (uInt)b & inflate_mask[j];
- DUMPBITS(j)
- Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
- c->mode = COPY;
- case COPY: /* o: copying bytes in window, waiting for space */
- f = q - c->sub.copy.dist;
- while (f < s->window) /* modulo window size-"while" instead */
- f += s->end - s->window; /* of "if" handles invalid distances */
- while (c->len)
- {
- NEEDOUT
- OUTBYTE(*f++)
- if (f == s->end)
- f = s->window;
- c->len--;
- }
- c->mode = START;
- break;
- case LIT: /* o: got literal, waiting for output space */
- NEEDOUT
- OUTBYTE(c->sub.lit)
- c->mode = START;
- break;
- case WASH: /* o: got eob, possibly more output */
- if (k > 7) /* return unused byte, if any */
- {
- Assert(k < 16, "inflate_codes grabbed too many bytes")
- k -= 8;
- n++;
- p--; /* can always return one */
- }
- FLUSH
- if (s->read != s->write)
- LEAVE
- c->mode = END;
- case END:
- r = Z_STREAM_END;
- LEAVE
- case BADCODE: /* x: got error */
- r = Z_DATA_ERROR;
- LEAVE
- default:
- r = Z_STREAM_ERROR;
- LEAVE
- }
-#ifdef NEED_DUMMY_RETURN
- return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
-#endif
-}
-
-
-void inflate_codes_free(c, z)
-inflate_codes_statef *c;
-z_streamp z;
-{
- ZFREE(z, c);
- Tracev((stderr, "inflate: codes free\n"));
-}
+/* infcodes.c -- process literals and length/distance pairs
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "infblock.h"
+#include "infcodes.h"
+#include "infutil.h"
+#include "inffast.h"
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+ START, /* x: set up for LEN */
+ LEN, /* i: get length/literal/eob next */
+ LENEXT, /* i: getting length extra (have base) */
+ DIST, /* i: get distance next */
+ DISTEXT, /* i: getting distance extra */
+ COPY, /* o: copying bytes in window, waiting for space */
+ LIT, /* o: got literal, waiting for output space */
+ WASH, /* o: got eob, possibly still output waiting */
+ END, /* x: got eob and all data flushed */
+ BADCODE} /* x: got error */
+inflate_codes_mode;
+
+/* inflate codes private state */
+struct inflate_codes_state {
+
+ /* mode */
+ inflate_codes_mode mode; /* current inflate_codes mode */
+
+ /* mode dependent information */
+ uInt len;
+ union {
+ struct {
+ inflate_huft *tree; /* pointer into tree */
+ uInt need; /* bits needed */
+ } code; /* if LEN or DIST, where in tree */
+ uInt lit; /* if LIT, literal */
+ struct {
+ uInt get; /* bits to get for extra */
+ uInt dist; /* distance back to copy from */
+ } copy; /* if EXT or COPY, where and how much */
+ } sub; /* submode */
+
+ /* mode independent information */
+ Byte lbits; /* ltree bits decoded per branch */
+ Byte dbits; /* dtree bits decoder per branch */
+ inflate_huft *ltree; /* literal/length/eob tree */
+ inflate_huft *dtree; /* distance tree */
+
+};
+
+
+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+z_streamp z;
+{
+ inflate_codes_statef *c;
+
+ if ((c = (inflate_codes_statef *)
+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
+ {
+ c->mode = START;
+ c->lbits = (Byte)bl;
+ c->dbits = (Byte)bd;
+ c->ltree = tl;
+ c->dtree = td;
+ Tracev((stderr, "inflate: codes new\n"));
+ }
+ return c;
+}
+
+
+int inflate_codes(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+ uInt j; /* temporary storage */
+ inflate_huft *t; /* temporary pointer */
+ uInt e; /* extra bits or operation */
+ uLong b; /* bit buffer */
+ uInt k; /* bits in bit buffer */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+ Bytef *f; /* pointer to copy strings from */
+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
+
+ /* copy input/output information to locals (UPDATE macro restores) */
+ LOAD
+
+ /* process input and output based on current state */
+ while (1) switch (c->mode)
+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+ case START: /* x: set up for LEN */
+#ifndef SLOW
+ if (m >= 258 && n >= 10)
+ {
+ UPDATE
+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
+ LOAD
+ if (r != Z_OK)
+ {
+ c->mode = r == Z_STREAM_END ? WASH : BADCODE;
+ break;
+ }
+ }
+#endif /* !SLOW */
+ c->sub.code.need = c->lbits;
+ c->sub.code.tree = c->ltree;
+ c->mode = LEN;
+ case LEN: /* i: get length/literal/eob next */
+ j = c->sub.code.need;
+ NEEDBITS(j)
+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+ DUMPBITS(t->bits)
+ e = (uInt)(t->exop);
+ if (e == 0) /* literal */
+ {
+ c->sub.lit = t->base;
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", t->base));
+ c->mode = LIT;
+ break;
+ }
+ if (e & 16) /* length */
+ {
+ c->sub.copy.get = e & 15;
+ c->len = t->base;
+ c->mode = LENEXT;
+ break;
+ }
+ if ((e & 64) == 0) /* next table */
+ {
+ c->sub.code.need = e;
+ c->sub.code.tree = t + t->base;
+ break;
+ }
+ if (e & 32) /* end of block */
+ {
+ Tracevv((stderr, "inflate: end of block\n"));
+ c->mode = WASH;
+ break;
+ }
+ c->mode = BADCODE; /* invalid code */
+ z->msg = (char*)"invalid literal/length code";
+ r = Z_DATA_ERROR;
+ LEAVE
+ case LENEXT: /* i: getting length extra (have base) */
+ j = c->sub.copy.get;
+ NEEDBITS(j)
+ c->len += (uInt)b & inflate_mask[j];
+ DUMPBITS(j)
+ c->sub.code.need = c->dbits;
+ c->sub.code.tree = c->dtree;
+ Tracevv((stderr, "inflate: length %u\n", c->len));
+ c->mode = DIST;
+ case DIST: /* i: get distance next */
+ j = c->sub.code.need;
+ NEEDBITS(j)
+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+ DUMPBITS(t->bits)
+ e = (uInt)(t->exop);
+ if (e & 16) /* distance */
+ {
+ c->sub.copy.get = e & 15;
+ c->sub.copy.dist = t->base;
+ c->mode = DISTEXT;
+ break;
+ }
+ if ((e & 64) == 0) /* next table */
+ {
+ c->sub.code.need = e;
+ c->sub.code.tree = t + t->base;
+ break;
+ }
+ c->mode = BADCODE; /* invalid code */
+ z->msg = (char*)"invalid distance code";
+ r = Z_DATA_ERROR;
+ LEAVE
+ case DISTEXT: /* i: getting distance extra */
+ j = c->sub.copy.get;
+ NEEDBITS(j)
+ c->sub.copy.dist += (uInt)b & inflate_mask[j];
+ DUMPBITS(j)
+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
+ c->mode = COPY;
+ case COPY: /* o: copying bytes in window, waiting for space */
+ f = q - c->sub.copy.dist;
+ while (f < s->window) /* modulo window size-"while" instead */
+ f += s->end - s->window; /* of "if" handles invalid distances */
+ while (c->len)
+ {
+ NEEDOUT
+ OUTBYTE(*f++)
+ if (f == s->end)
+ f = s->window;
+ c->len--;
+ }
+ c->mode = START;
+ break;
+ case LIT: /* o: got literal, waiting for output space */
+ NEEDOUT
+ OUTBYTE(c->sub.lit)
+ c->mode = START;
+ break;
+ case WASH: /* o: got eob, possibly more output */
+ if (k > 7) /* return unused byte, if any */
+ {
+ Assert(k < 16, "inflate_codes grabbed too many bytes")
+ k -= 8;
+ n++;
+ p--; /* can always return one */
+ }
+ FLUSH
+ if (s->read != s->write)
+ LEAVE
+ c->mode = END;
+ case END:
+ r = Z_STREAM_END;
+ LEAVE
+ case BADCODE: /* x: got error */
+ r = Z_DATA_ERROR;
+ LEAVE
+ default:
+ r = Z_STREAM_ERROR;
+ LEAVE
+ }
+#ifdef NEED_DUMMY_RETURN
+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
+#endif
+}
+
+
+void inflate_codes_free(c, z)
+inflate_codes_statef *c;
+z_streamp z;
+{
+ ZFREE(z, c);
+ Tracev((stderr, "inflate: codes free\n"));
+}
diff --git a/lib/zlib/src/inffast.c b/lib/zlib/src/inffast.c
index 655eaf0..aa7f1d4 100644
--- a/lib/zlib/src/inffast.c
+++ b/lib/zlib/src/inffast.c
@@ -1,183 +1,183 @@
-/* inffast.c -- process literals and length/distance pairs fast
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "infblock.h"
-#include "infcodes.h"
-#include "infutil.h"
-#include "inffast.h"
-
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* macros for bit input with no checking and for returning unused bytes */
-#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
-
-/* Called with number of bytes left to write in window at least 258
- (the maximum string length) and number of input bytes available
- at least ten. The ten bytes are six bytes for the longest length/
- distance pair plus four bytes for overloading the bit buffer. */
-
-int inflate_fast(bl, bd, tl, td, s, z)
-uInt bl, bd;
-inflate_huft *tl;
-inflate_huft *td; /* need separate declaration for Borland C++ */
-inflate_blocks_statef *s;
-z_streamp z;
-{
- inflate_huft *t; /* temporary pointer */
- uInt e; /* extra bits or operation */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
- uInt ml; /* mask for literal/length tree */
- uInt md; /* mask for distance tree */
- uInt c; /* bytes to copy */
- uInt d; /* distance back to copy from */
- Bytef *r; /* copy source pointer */
-
- /* load input, output, bit values */
- LOAD
-
- /* initialize masks */
- ml = inflate_mask[bl];
- md = inflate_mask[bd];
-
- /* do until not enough input or output space for fast loop */
- do { /* assume called with m >= 258 && n >= 10 */
- /* get literal/length code */
- GRABBITS(20) /* max bits for literal/length code */
- if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
- {
- DUMPBITS(t->bits)
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: * literal '%c'\n" :
- "inflate: * literal 0x%02x\n", t->base));
- *q++ = (Byte)t->base;
- m--;
- continue;
- }
- do {
- DUMPBITS(t->bits)
- if (e & 16)
- {
- /* get extra bits for length */
- e &= 15;
- c = t->base + ((uInt)b & inflate_mask[e]);
- DUMPBITS(e)
- Tracevv((stderr, "inflate: * length %u\n", c));
-
- /* decode distance base of block to copy */
- GRABBITS(15); /* max bits for distance code */
- e = (t = td + ((uInt)b & md))->exop;
- do {
- DUMPBITS(t->bits)
- if (e & 16)
- {
- /* get extra bits to add to distance base */
- e &= 15;
- GRABBITS(e) /* get extra bits (up to 13) */
- d = t->base + ((uInt)b & inflate_mask[e]);
- DUMPBITS(e)
- Tracevv((stderr, "inflate: * distance %u\n", d));
-
- /* do the copy */
- m -= c;
- r = q - d;
- if (r < s->window) /* wrap if needed */
- {
- do {
- r += s->end - s->window; /* force pointer in window */
- } while (r < s->window); /* covers invalid distances */
- e = s->end - r;
- if (c > e)
- {
- c -= e; /* wrapped copy */
- do {
- *q++ = *r++;
- } while (--e);
- r = s->window;
- do {
- *q++ = *r++;
- } while (--c);
- }
- else /* normal copy */
- {
- *q++ = *r++; c--;
- *q++ = *r++; c--;
- do {
- *q++ = *r++;
- } while (--c);
- }
- }
- else /* normal copy */
- {
- *q++ = *r++; c--;
- *q++ = *r++; c--;
- do {
- *q++ = *r++;
- } while (--c);
- }
- break;
- }
- else if ((e & 64) == 0)
- {
- t += t->base;
- e = (t += ((uInt)b & inflate_mask[e]))->exop;
- }
- else
- {
- z->msg = (char*)"invalid distance code";
- UNGRAB
- UPDATE
- return Z_DATA_ERROR;
- }
- } while (1);
- break;
- }
- if ((e & 64) == 0)
- {
- t += t->base;
- if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
- {
- DUMPBITS(t->bits)
- Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
- "inflate: * literal '%c'\n" :
- "inflate: * literal 0x%02x\n", t->base));
- *q++ = (Byte)t->base;
- m--;
- break;
- }
- }
- else if (e & 32)
- {
- Tracevv((stderr, "inflate: * end of block\n"));
- UNGRAB
- UPDATE
- return Z_STREAM_END;
- }
- else
- {
- z->msg = (char*)"invalid literal/length code";
- UNGRAB
- UPDATE
- return Z_DATA_ERROR;
- }
- } while (1);
- } while (m >= 258 && n >= 10);
-
- /* not enough input or output--restore pointers and return */
- UNGRAB
- UPDATE
- return Z_OK;
-}
+/* inffast.c -- process literals and length/distance pairs fast
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "infblock.h"
+#include "infcodes.h"
+#include "infutil.h"
+#include "inffast.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* macros for bit input with no checking and for returning unused bytes */
+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
+
+/* Called with number of bytes left to write in window at least 258
+ (the maximum string length) and number of input bytes available
+ at least ten. The ten bytes are six bytes for the longest length/
+ distance pair plus four bytes for overloading the bit buffer. */
+
+int inflate_fast(bl, bd, tl, td, s, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+inflate_blocks_statef *s;
+z_streamp z;
+{
+ inflate_huft *t; /* temporary pointer */
+ uInt e; /* extra bits or operation */
+ uLong b; /* bit buffer */
+ uInt k; /* bits in bit buffer */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+ uInt ml; /* mask for literal/length tree */
+ uInt md; /* mask for distance tree */
+ uInt c; /* bytes to copy */
+ uInt d; /* distance back to copy from */
+ Bytef *r; /* copy source pointer */
+
+ /* load input, output, bit values */
+ LOAD
+
+ /* initialize masks */
+ ml = inflate_mask[bl];
+ md = inflate_mask[bd];
+
+ /* do until not enough input or output space for fast loop */
+ do { /* assume called with m >= 258 && n >= 10 */
+ /* get literal/length code */
+ GRABBITS(20) /* max bits for literal/length code */
+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
+ {
+ DUMPBITS(t->bits)
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+ "inflate: * literal '%c'\n" :
+ "inflate: * literal 0x%02x\n", t->base));
+ *q++ = (Byte)t->base;
+ m--;
+ continue;
+ }
+ do {
+ DUMPBITS(t->bits)
+ if (e & 16)
+ {
+ /* get extra bits for length */
+ e &= 15;
+ c = t->base + ((uInt)b & inflate_mask[e]);
+ DUMPBITS(e)
+ Tracevv((stderr, "inflate: * length %u\n", c));
+
+ /* decode distance base of block to copy */
+ GRABBITS(15); /* max bits for distance code */
+ e = (t = td + ((uInt)b & md))->exop;
+ do {
+ DUMPBITS(t->bits)
+ if (e & 16)
+ {
+ /* get extra bits to add to distance base */
+ e &= 15;
+ GRABBITS(e) /* get extra bits (up to 13) */
+ d = t->base + ((uInt)b & inflate_mask[e]);
+ DUMPBITS(e)
+ Tracevv((stderr, "inflate: * distance %u\n", d));
+
+ /* do the copy */
+ m -= c;
+ r = q - d;
+ if (r < s->window) /* wrap if needed */
+ {
+ do {
+ r += s->end - s->window; /* force pointer in window */
+ } while (r < s->window); /* covers invalid distances */
+ e = s->end - r;
+ if (c > e)
+ {
+ c -= e; /* wrapped copy */
+ do {
+ *q++ = *r++;
+ } while (--e);
+ r = s->window;
+ do {
+ *q++ = *r++;
+ } while (--c);
+ }
+ else /* normal copy */
+ {
+ *q++ = *r++; c--;
+ *q++ = *r++; c--;
+ do {
+ *q++ = *r++;
+ } while (--c);
+ }
+ }
+ else /* normal copy */
+ {
+ *q++ = *r++; c--;
+ *q++ = *r++; c--;
+ do {
+ *q++ = *r++;
+ } while (--c);
+ }
+ break;
+ }
+ else if ((e & 64) == 0)
+ {
+ t += t->base;
+ e = (t += ((uInt)b & inflate_mask[e]))->exop;
+ }
+ else
+ {
+ z->msg = (char*)"invalid distance code";
+ UNGRAB
+ UPDATE
+ return Z_DATA_ERROR;
+ }
+ } while (1);
+ break;
+ }
+ if ((e & 64) == 0)
+ {
+ t += t->base;
+ if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
+ {
+ DUMPBITS(t->bits)
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+ "inflate: * literal '%c'\n" :
+ "inflate: * literal 0x%02x\n", t->base));
+ *q++ = (Byte)t->base;
+ m--;
+ break;
+ }
+ }
+ else if (e & 32)
+ {
+ Tracevv((stderr, "inflate: * end of block\n"));
+ UNGRAB
+ UPDATE
+ return Z_STREAM_END;
+ }
+ else
+ {
+ z->msg = (char*)"invalid literal/length code";
+ UNGRAB
+ UPDATE
+ return Z_DATA_ERROR;
+ }
+ } while (1);
+ } while (m >= 258 && n >= 10);
+
+ /* not enough input or output--restore pointers and return */
+ UNGRAB
+ UPDATE
+ return Z_OK;
+}
diff --git a/lib/zlib/src/inflate.c b/lib/zlib/src/inflate.c
index 5577e02..dfb2e86 100644
--- a/lib/zlib/src/inflate.c
+++ b/lib/zlib/src/inflate.c
@@ -1,366 +1,366 @@
-/* inflate.c -- zlib interface to inflate modules
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "infblock.h"
-
-struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
-
-typedef enum {
- METHOD, /* waiting for method byte */
- FLAG, /* waiting for flag byte */
- DICT4, /* four dictionary check bytes to go */
- DICT3, /* three dictionary check bytes to go */
- DICT2, /* two dictionary check bytes to go */
- DICT1, /* one dictionary check byte to go */
- DICT0, /* waiting for inflateSetDictionary */
- BLOCKS, /* decompressing blocks */
- CHECK4, /* four check bytes to go */
- CHECK3, /* three check bytes to go */
- CHECK2, /* two check bytes to go */
- CHECK1, /* one check byte to go */
- DONE, /* finished check, done */
- BAD} /* got an error--stay here */
-inflate_mode;
-
-/* inflate private state */
-struct internal_state {
-
- /* mode */
- inflate_mode mode; /* current inflate mode */
-
- /* mode dependent information */
- union {
- uInt method; /* if FLAGS, method byte */
- struct {
- uLong was; /* computed check value */
- uLong need; /* stream check value */
- } check; /* if CHECK, check values to compare */
- uInt marker; /* if BAD, inflateSync's marker bytes count */
- } sub; /* submode */
-
- /* mode independent information */
- int nowrap; /* flag for no wrapper */
- uInt wbits; /* log2(window size) (8..15, defaults to 15) */
- inflate_blocks_statef
- *blocks; /* current inflate_blocks state */
-
-};
-
-
-int ZEXPORT inflateReset(z)
-z_streamp z;
-{
- if (z == Z_NULL || z->state == Z_NULL)
- return Z_STREAM_ERROR;
- z->total_in = z->total_out = 0;
- z->msg = Z_NULL;
- z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
- inflate_blocks_reset(z->state->blocks, z, Z_NULL);
- Tracev((stderr, "inflate: reset\n"));
- return Z_OK;
-}
-
-
-int ZEXPORT inflateEnd(z)
-z_streamp z;
-{
- if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
- return Z_STREAM_ERROR;
- if (z->state->blocks != Z_NULL)
- inflate_blocks_free(z->state->blocks, z);
- ZFREE(z, z->state);
- z->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
-}
-
-
-int ZEXPORT inflateInit2_(z, w, version, stream_size)
-z_streamp z;
-int w;
-const char *version;
-int stream_size;
-{
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != sizeof(z_stream))
- return Z_VERSION_ERROR;
-
- /* initialize state */
- if (z == Z_NULL)
- return Z_STREAM_ERROR;
- z->msg = Z_NULL;
- if (z->zalloc == Z_NULL)
- {
- z->zalloc = zcalloc;
- z->opaque = (voidpf)0;
- }
- if (z->zfree == Z_NULL) z->zfree = zcfree;
- if ((z->state = (struct internal_state FAR *)
- ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
- return Z_MEM_ERROR;
- z->state->blocks = Z_NULL;
-
- /* handle undocumented nowrap option (no zlib header or check) */
- z->state->nowrap = 0;
- if (w < 0)
- {
- w = - w;
- z->state->nowrap = 1;
- }
-
- /* set window size */
- if (w < 8 || w > 15)
- {
- inflateEnd(z);
- return Z_STREAM_ERROR;
- }
- z->state->wbits = (uInt)w;
-
- /* create inflate_blocks state */
- if ((z->state->blocks =
- inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
- == Z_NULL)
- {
- inflateEnd(z);
- return Z_MEM_ERROR;
- }
- Tracev((stderr, "inflate: allocated\n"));
-
- /* reset state */
- inflateReset(z);
- return Z_OK;
-}
-
-
-int ZEXPORT inflateInit_(z, version, stream_size)
-z_streamp z;
-const char *version;
-int stream_size;
-{
- return inflateInit2_(z, DEF_WBITS, version, stream_size);
-}
-
-
-#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
-#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-
-int ZEXPORT inflate(z, f)
-z_streamp z;
-int f;
-{
- int r;
- uInt b;
-
- if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
- return Z_STREAM_ERROR;
- f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
- r = Z_BUF_ERROR;
- while (1) switch (z->state->mode)
- {
- case METHOD:
- NEEDBYTE
- if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
- {
- z->state->mode = BAD;
- z->msg = (char*)"unknown compression method";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
- {
- z->state->mode = BAD;
- z->msg = (char*)"invalid window size";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- z->state->mode = FLAG;
- case FLAG:
- NEEDBYTE
- b = NEXTBYTE;
- if (((z->state->sub.method << 8) + b) % 31)
- {
- z->state->mode = BAD;
- z->msg = (char*)"incorrect header check";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- Tracev((stderr, "inflate: zlib header ok\n"));
- if (!(b & PRESET_DICT))
- {
- z->state->mode = BLOCKS;
- break;
- }
- z->state->mode = DICT4;
- case DICT4:
- NEEDBYTE
- z->state->sub.check.need = (uLong)NEXTBYTE << 24;
- z->state->mode = DICT3;
- case DICT3:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 16;
- z->state->mode = DICT2;
- case DICT2:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 8;
- z->state->mode = DICT1;
- case DICT1:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE;
- z->adler = z->state->sub.check.need;
- z->state->mode = DICT0;
- return Z_NEED_DICT;
- case DICT0:
- z->state->mode = BAD;
- z->msg = (char*)"need dictionary";
- z->state->sub.marker = 0; /* can try inflateSync */
- return Z_STREAM_ERROR;
- case BLOCKS:
- r = inflate_blocks(z->state->blocks, z, r);
- if (r == Z_DATA_ERROR)
- {
- z->state->mode = BAD;
- z->state->sub.marker = 0; /* can try inflateSync */
- break;
- }
- if (r == Z_OK)
- r = f;
- if (r != Z_STREAM_END)
- return r;
- r = f;
- inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
- if (z->state->nowrap)
- {
- z->state->mode = DONE;
- break;
- }
- z->state->mode = CHECK4;
- case CHECK4:
- NEEDBYTE
- z->state->sub.check.need = (uLong)NEXTBYTE << 24;
- z->state->mode = CHECK3;
- case CHECK3:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 16;
- z->state->mode = CHECK2;
- case CHECK2:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE << 8;
- z->state->mode = CHECK1;
- case CHECK1:
- NEEDBYTE
- z->state->sub.check.need += (uLong)NEXTBYTE;
-
- if (z->state->sub.check.was != z->state->sub.check.need)
- {
- z->state->mode = BAD;
- z->msg = (char*)"incorrect data check";
- z->state->sub.marker = 5; /* can't try inflateSync */
- break;
- }
- Tracev((stderr, "inflate: zlib check ok\n"));
- z->state->mode = DONE;
- case DONE:
- return Z_STREAM_END;
- case BAD:
- return Z_DATA_ERROR;
- default:
- return Z_STREAM_ERROR;
- }
-#ifdef NEED_DUMMY_RETURN
- return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
-#endif
-}
-
-
-int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
-z_streamp z;
-const Bytef *dictionary;
-uInt dictLength;
-{
- uInt length = dictLength;
-
- if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
- return Z_STREAM_ERROR;
-
- if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
- z->adler = 1L;
-
- if (length >= ((uInt)1<<z->state->wbits))
- {
- length = (1<<z->state->wbits)-1;
- dictionary += dictLength - length;
- }
- inflate_set_dictionary(z->state->blocks, dictionary, length);
- z->state->mode = BLOCKS;
- return Z_OK;
-}
-
-
-int ZEXPORT inflateSync(z)
-z_streamp z;
-{
- uInt n; /* number of bytes to look at */
- Bytef *p; /* pointer to bytes */
- uInt m; /* number of marker bytes found in a row */
- uLong r, w; /* temporaries to save total_in and total_out */
-
- /* set up */
- if (z == Z_NULL || z->state == Z_NULL)
- return Z_STREAM_ERROR;
- if (z->state->mode != BAD)
- {
- z->state->mode = BAD;
- z->state->sub.marker = 0;
- }
- if ((n = z->avail_in) == 0)
- return Z_BUF_ERROR;
- p = z->next_in;
- m = z->state->sub.marker;
-
- /* search */
- while (n && m < 4)
- {
- static const Byte mark[4] = {0, 0, 0xff, 0xff};
- if (*p == mark[m])
- m++;
- else if (*p)
- m = 0;
- else
- m = 4 - m;
- p++, n--;
- }
-
- /* restore */
- z->total_in += p - z->next_in;
- z->next_in = p;
- z->avail_in = n;
- z->state->sub.marker = m;
-
- /* return no joy or set up to restart on a new block */
- if (m != 4)
- return Z_DATA_ERROR;
- r = z->total_in; w = z->total_out;
- inflateReset(z);
- z->total_in = r; z->total_out = w;
- z->state->mode = BLOCKS;
- return Z_OK;
-}
-
-
-/* Returns true if inflate is currently at the end of a block generated
- * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
- * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
- * but removes the length bytes of the resulting empty stored block. When
- * decompressing, PPP checks that at the end of input packet, inflate is
- * waiting for these length bytes.
- */
-int ZEXPORT inflateSyncPoint(z)
-z_streamp z;
-{
- if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
- return Z_STREAM_ERROR;
- return inflate_blocks_sync_point(z->state->blocks);
-}
+/* inflate.c -- zlib interface to inflate modules
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+
+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
+
+typedef enum {
+ METHOD, /* waiting for method byte */
+ FLAG, /* waiting for flag byte */
+ DICT4, /* four dictionary check bytes to go */
+ DICT3, /* three dictionary check bytes to go */
+ DICT2, /* two dictionary check bytes to go */
+ DICT1, /* one dictionary check byte to go */
+ DICT0, /* waiting for inflateSetDictionary */
+ BLOCKS, /* decompressing blocks */
+ CHECK4, /* four check bytes to go */
+ CHECK3, /* three check bytes to go */
+ CHECK2, /* two check bytes to go */
+ CHECK1, /* one check byte to go */
+ DONE, /* finished check, done */
+ BAD} /* got an error--stay here */
+inflate_mode;
+
+/* inflate private state */
+struct internal_state {
+
+ /* mode */
+ inflate_mode mode; /* current inflate mode */
+
+ /* mode dependent information */
+ union {
+ uInt method; /* if FLAGS, method byte */
+ struct {
+ uLong was; /* computed check value */
+ uLong need; /* stream check value */
+ } check; /* if CHECK, check values to compare */
+ uInt marker; /* if BAD, inflateSync's marker bytes count */
+ } sub; /* submode */
+
+ /* mode independent information */
+ int nowrap; /* flag for no wrapper */
+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */
+ inflate_blocks_statef
+ *blocks; /* current inflate_blocks state */
+
+};
+
+
+int ZEXPORT inflateReset(z)
+z_streamp z;
+{
+ if (z == Z_NULL || z->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ z->total_in = z->total_out = 0;
+ z->msg = Z_NULL;
+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
+ inflate_blocks_reset(z->state->blocks, z, Z_NULL);
+ Tracev((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+
+int ZEXPORT inflateEnd(z)
+z_streamp z;
+{
+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
+ return Z_STREAM_ERROR;
+ if (z->state->blocks != Z_NULL)
+ inflate_blocks_free(z->state->blocks, z);
+ ZFREE(z, z->state);
+ z->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
+
+
+int ZEXPORT inflateInit2_(z, w, version, stream_size)
+z_streamp z;
+int w;
+const char *version;
+int stream_size;
+{
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != sizeof(z_stream))
+ return Z_VERSION_ERROR;
+
+ /* initialize state */
+ if (z == Z_NULL)
+ return Z_STREAM_ERROR;
+ z->msg = Z_NULL;
+ if (z->zalloc == Z_NULL)
+ {
+ z->zalloc = zcalloc;
+ z->opaque = (voidpf)0;
+ }
+ if (z->zfree == Z_NULL) z->zfree = zcfree;
+ if ((z->state = (struct internal_state FAR *)
+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
+ return Z_MEM_ERROR;
+ z->state->blocks = Z_NULL;
+
+ /* handle undocumented nowrap option (no zlib header or check) */
+ z->state->nowrap = 0;
+ if (w < 0)
+ {
+ w = - w;
+ z->state->nowrap = 1;
+ }
+
+ /* set window size */
+ if (w < 8 || w > 15)
+ {
+ inflateEnd(z);
+ return Z_STREAM_ERROR;
+ }
+ z->state->wbits = (uInt)w;
+
+ /* create inflate_blocks state */
+ if ((z->state->blocks =
+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
+ == Z_NULL)
+ {
+ inflateEnd(z);
+ return Z_MEM_ERROR;
+ }
+ Tracev((stderr, "inflate: allocated\n"));
+
+ /* reset state */
+ inflateReset(z);
+ return Z_OK;
+}
+
+
+int ZEXPORT inflateInit_(z, version, stream_size)
+z_streamp z;
+const char *version;
+int stream_size;
+{
+ return inflateInit2_(z, DEF_WBITS, version, stream_size);
+}
+
+
+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
+
+int ZEXPORT inflate(z, f)
+z_streamp z;
+int f;
+{
+ int r;
+ uInt b;
+
+ if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
+ return Z_STREAM_ERROR;
+ f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
+ r = Z_BUF_ERROR;
+ while (1) switch (z->state->mode)
+ {
+ case METHOD:
+ NEEDBYTE
+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
+ {
+ z->state->mode = BAD;
+ z->msg = (char*)"unknown compression method";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
+ {
+ z->state->mode = BAD;
+ z->msg = (char*)"invalid window size";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ z->state->mode = FLAG;
+ case FLAG:
+ NEEDBYTE
+ b = NEXTBYTE;
+ if (((z->state->sub.method << 8) + b) % 31)
+ {
+ z->state->mode = BAD;
+ z->msg = (char*)"incorrect header check";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ Tracev((stderr, "inflate: zlib header ok\n"));
+ if (!(b & PRESET_DICT))
+ {
+ z->state->mode = BLOCKS;
+ break;
+ }
+ z->state->mode = DICT4;
+ case DICT4:
+ NEEDBYTE
+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+ z->state->mode = DICT3;
+ case DICT3:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+ z->state->mode = DICT2;
+ case DICT2:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+ z->state->mode = DICT1;
+ case DICT1:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE;
+ z->adler = z->state->sub.check.need;
+ z->state->mode = DICT0;
+ return Z_NEED_DICT;
+ case DICT0:
+ z->state->mode = BAD;
+ z->msg = (char*)"need dictionary";
+ z->state->sub.marker = 0; /* can try inflateSync */
+ return Z_STREAM_ERROR;
+ case BLOCKS:
+ r = inflate_blocks(z->state->blocks, z, r);
+ if (r == Z_DATA_ERROR)
+ {
+ z->state->mode = BAD;
+ z->state->sub.marker = 0; /* can try inflateSync */
+ break;
+ }
+ if (r == Z_OK)
+ r = f;
+ if (r != Z_STREAM_END)
+ return r;
+ r = f;
+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
+ if (z->state->nowrap)
+ {
+ z->state->mode = DONE;
+ break;
+ }
+ z->state->mode = CHECK4;
+ case CHECK4:
+ NEEDBYTE
+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+ z->state->mode = CHECK3;
+ case CHECK3:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+ z->state->mode = CHECK2;
+ case CHECK2:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+ z->state->mode = CHECK1;
+ case CHECK1:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE;
+
+ if (z->state->sub.check.was != z->state->sub.check.need)
+ {
+ z->state->mode = BAD;
+ z->msg = (char*)"incorrect data check";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ Tracev((stderr, "inflate: zlib check ok\n"));
+ z->state->mode = DONE;
+ case DONE:
+ return Z_STREAM_END;
+ case BAD:
+ return Z_DATA_ERROR;
+ default:
+ return Z_STREAM_ERROR;
+ }
+#ifdef NEED_DUMMY_RETURN
+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
+#endif
+}
+
+
+int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
+z_streamp z;
+const Bytef *dictionary;
+uInt dictLength;
+{
+ uInt length = dictLength;
+
+ if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
+ return Z_STREAM_ERROR;
+
+ if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
+ z->adler = 1L;
+
+ if (length >= ((uInt)1<<z->state->wbits))
+ {
+ length = (1<<z->state->wbits)-1;
+ dictionary += dictLength - length;
+ }
+ inflate_set_dictionary(z->state->blocks, dictionary, length);
+ z->state->mode = BLOCKS;
+ return Z_OK;
+}
+
+
+int ZEXPORT inflateSync(z)
+z_streamp z;
+{
+ uInt n; /* number of bytes to look at */
+ Bytef *p; /* pointer to bytes */
+ uInt m; /* number of marker bytes found in a row */
+ uLong r, w; /* temporaries to save total_in and total_out */
+
+ /* set up */
+ if (z == Z_NULL || z->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ if (z->state->mode != BAD)
+ {
+ z->state->mode = BAD;
+ z->state->sub.marker = 0;
+ }
+ if ((n = z->avail_in) == 0)
+ return Z_BUF_ERROR;
+ p = z->next_in;
+ m = z->state->sub.marker;
+
+ /* search */
+ while (n && m < 4)
+ {
+ static const Byte mark[4] = {0, 0, 0xff, 0xff};
+ if (*p == mark[m])
+ m++;
+ else if (*p)
+ m = 0;
+ else
+ m = 4 - m;
+ p++, n--;
+ }
+
+ /* restore */
+ z->total_in += p - z->next_in;
+ z->next_in = p;
+ z->avail_in = n;
+ z->state->sub.marker = m;
+
+ /* return no joy or set up to restart on a new block */
+ if (m != 4)
+ return Z_DATA_ERROR;
+ r = z->total_in; w = z->total_out;
+ inflateReset(z);
+ z->total_in = r; z->total_out = w;
+ z->state->mode = BLOCKS;
+ return Z_OK;
+}
+
+
+/* Returns true if inflate is currently at the end of a block generated
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
+ * but removes the length bytes of the resulting empty stored block. When
+ * decompressing, PPP checks that at the end of input packet, inflate is
+ * waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(z)
+z_streamp z;
+{
+ if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
+ return Z_STREAM_ERROR;
+ return inflate_blocks_sync_point(z->state->blocks);
+}
diff --git a/lib/zlib/src/inftrees.c b/lib/zlib/src/inftrees.c
index f89e801..4c32ca3 100644
--- a/lib/zlib/src/inftrees.c
+++ b/lib/zlib/src/inftrees.c
@@ -1,454 +1,454 @@
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-
-#if !defined(BUILDFIXED) && !defined(STDC)
-# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
-#endif
-
-const char inflate_copyright[] =
- " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-struct internal_state {int dummy;}; /* for buggy compilers */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-
-local int huft_build OF((
- uIntf *, /* code lengths in bits */
- uInt, /* number of codes */
- uInt, /* number of "simple" codes */
- const uIntf *, /* list of base values for non-simple codes */
- const uIntf *, /* list of extra bits for non-simple codes */
- inflate_huft * FAR*,/* result: starting table */
- uIntf *, /* maximum lookup bits (returns actual) */
- inflate_huft *, /* space for trees */
- uInt *, /* hufts used in space */
- uIntf * )); /* space for values */
-
-/* Tables for deflate from PKZIP's appnote.txt. */
-local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
- /* see note #13 above about 258 */
-local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
- 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
-local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577};
-local const uInt cpdext[30] = { /* Extra bits for distance codes */
- 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
- 12, 12, 13, 13};
-
-/*
- Huffman code decoding is performed using a multi-level table lookup.
- The fastest way to decode is to simply build a lookup table whose
- size is determined by the longest code. However, the time it takes
- to build this table can also be a factor if the data being decoded
- is not very long. The most common codes are necessarily the
- shortest codes, so those codes dominate the decoding time, and hence
- the speed. The idea is you can have a shorter table that decodes the
- shorter, more probable codes, and then point to subsidiary tables for
- the longer codes. The time it costs to decode the longer codes is
- then traded against the time it takes to make longer tables.
-
- This results of this trade are in the variables lbits and dbits
- below. lbits is the number of bits the first level table for literal/
- length codes can decode in one step, and dbits is the same thing for
- the distance codes. Subsequent tables are also less than or equal to
- those sizes. These values may be adjusted either when all of the
- codes are shorter than that, in which case the longest code length in
- bits is used, or when the shortest code is *longer* than the requested
- table size, in which case the length of the shortest code in bits is
- used.
-
- There are two different values for the two tables, since they code a
- different number of possibilities each. The literal/length table
- codes 286 possible values, or in a flat code, a little over eight
- bits. The distance table codes 30 possible values, or a little less
- than five bits, flat. The optimum values for speed end up being
- about one bit more than those, so lbits is 8+1 and dbits is 5+1.
- The optimum values may differ though from machine to machine, and
- possibly even between compilers. Your mileage may vary.
- */
-
-
-/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-#define BMAX 15 /* maximum bit length of any code */
-
-local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
-uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
-uInt n; /* number of codes (assumed <= 288) */
-uInt s; /* number of simple-valued codes (0..s-1) */
-const uIntf *d; /* list of base values for non-simple codes */
-const uIntf *e; /* list of extra bits for non-simple codes */
-inflate_huft * FAR *t; /* result: starting table */
-uIntf *m; /* maximum lookup bits, returns actual */
-inflate_huft *hp; /* space for trees */
-uInt *hn; /* hufts used in space */
-uIntf *v; /* working area: values in order of bit length */
-/* Given a list of code lengths and a maximum table size, make a set of
- tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
- if the given code set is incomplete (the tables are still built in this
- case), or Z_DATA_ERROR if the input is invalid. */
-{
-
- uInt a; /* counter for codes of length k */
- uInt c[BMAX+1]; /* bit length count table */
- uInt f; /* i repeats in table every f entries */
- int g; /* maximum code length */
- int h; /* table level */
- register uInt i; /* counter, current code */
- register uInt j; /* counter */
- register int k; /* number of bits in current code */
- int l; /* bits per table (returned in m) */
- uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
- register uIntf *p; /* pointer into c[], b[], or v[] */
- inflate_huft *q; /* points to current table */
- struct inflate_huft_s r; /* table entry for structure assignment */
- inflate_huft *u[BMAX]; /* table stack */
- register int w; /* bits before this table == (l * h) */
- uInt x[BMAX+1]; /* bit offsets, then code stack */
- uIntf *xp; /* pointer into x */
- int y; /* number of dummy codes added */
- uInt z; /* number of entries in current table */
-
-
- /* Generate counts for each bit length */
- p = c;
-#define C0 *p++ = 0;
-#define C2 C0 C0 C0 C0
-#define C4 C2 C2 C2 C2
- C4 /* clear c[]--assume BMAX+1 is 16 */
- p = b; i = n;
- do {
- c[*p++]++; /* assume all entries <= BMAX */
- } while (--i);
- if (c[0] == n) /* null input--all zero length codes */
- {
- *t = (inflate_huft *)Z_NULL;
- *m = 0;
- return Z_OK;
- }
-
-
- /* Find minimum and maximum length, bound *m by those */
- l = *m;
- for (j = 1; j <= BMAX; j++)
- if (c[j])
- break;
- k = j; /* minimum code length */
- if ((uInt)l < j)
- l = j;
- for (i = BMAX; i; i--)
- if (c[i])
- break;
- g = i; /* maximum code length */
- if ((uInt)l > i)
- l = i;
- *m = l;
-
-
- /* Adjust last length count to fill out codes, if needed */
- for (y = 1 << j; j < i; j++, y <<= 1)
- if ((y -= c[j]) < 0)
- return Z_DATA_ERROR;
- if ((y -= c[i]) < 0)
- return Z_DATA_ERROR;
- c[i] += y;
-
-
- /* Generate starting offsets into the value table for each length */
- x[1] = j = 0;
- p = c + 1; xp = x + 2;
- while (--i) { /* note that i == g from above */
- *xp++ = (j += *p++);
- }
-
-
- /* Make a table of values in order of bit lengths */
- p = b; i = 0;
- do {
- if ((j = *p++) != 0)
- v[x[j]++] = i;
- } while (++i < n);
- n = x[g]; /* set n to length of v */
-
-
- /* Generate the Huffman codes and for each, make the table entries */
- x[0] = i = 0; /* first Huffman code is zero */
- p = v; /* grab values in bit order */
- h = -1; /* no tables yet--level -1 */
- w = -l; /* bits decoded == (l * h) */
- u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
- q = (inflate_huft *)Z_NULL; /* ditto */
- z = 0; /* ditto */
-
- /* go through the bit lengths (k already is bits in shortest code) */
- for (; k <= g; k++)
- {
- a = c[k];
- while (a--)
- {
- /* here i is the Huffman code of length k bits for value *p */
- /* make tables up to required level */
- while (k > w + l)
- {
- h++;
- w += l; /* previous table always l bits */
-
- /* compute minimum size table less than or equal to l bits */
- z = g - w;
- z = z > (uInt)l ? l : z; /* table size upper limit */
- if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
- { /* too few codes for k-w bit table */
- f -= a + 1; /* deduct codes from patterns left */
- xp = c + k;
- if (j < z)
- while (++j < z) /* try smaller tables up to z bits */
- {
- if ((f <<= 1) <= *++xp)
- break; /* enough codes to use up j bits */
- f -= *xp; /* else deduct codes from patterns */
- }
- }
- z = 1 << j; /* table entries for j-bit table */
-
- /* allocate new table */
- if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
- return Z_DATA_ERROR; /* overflow of MANY */
- u[h] = q = hp + *hn;
- *hn += z;
-
- /* connect to last table, if there is one */
- if (h)
- {
- x[h] = i; /* save pattern for backing up */
- r.bits = (Byte)l; /* bits to dump before this table */
- r.exop = (Byte)j; /* bits in this table */
- j = i >> (w - l);
- r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
- u[h-1][j] = r; /* connect to last table */
- }
- else
- *t = q; /* first table is returned result */
- }
-
- /* set up table entry in r */
- r.bits = (Byte)(k - w);
- if (p >= v + n)
- r.exop = 128 + 64; /* out of values--invalid code */
- else if (*p < s)
- {
- r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
- r.base = *p++; /* simple code is just the value */
- }
- else
- {
- r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
- r.base = d[*p++ - s];
- }
-
- /* fill code-like entries with r */
- f = 1 << (k - w);
- for (j = i >> w; j < z; j += f)
- q[j] = r;
-
- /* backwards increment the k-bit code i */
- for (j = 1 << (k - 1); i & j; j >>= 1)
- i ^= j;
- i ^= j;
-
- /* backup over finished tables */
- mask = (1 << w) - 1; /* needed on HP, cc -O bug */
- while ((i & mask) != x[h])
- {
- h--; /* don't need to update q */
- w -= l;
- mask = (1 << w) - 1;
- }
- }
- }
-
-
- /* Return Z_BUF_ERROR if we were given an incomplete table */
- return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-}
-
-
-int inflate_trees_bits(c, bb, tb, hp, z)
-uIntf *c; /* 19 code lengths */
-uIntf *bb; /* bits tree desired/actual depth */
-inflate_huft * FAR *tb; /* bits tree result */
-inflate_huft *hp; /* space for trees */
-z_streamp z; /* for messages */
-{
- int r;
- uInt hn = 0; /* hufts used in space */
- uIntf *v; /* work area for huft_build */
-
- if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
- return Z_MEM_ERROR;
- r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
- tb, bb, hp, &hn, v);
- if (r == Z_DATA_ERROR)
- z->msg = (char*)"oversubscribed dynamic bit lengths tree";
- else if (r == Z_BUF_ERROR || *bb == 0)
- {
- z->msg = (char*)"incomplete dynamic bit lengths tree";
- r = Z_DATA_ERROR;
- }
- ZFREE(z, v);
- return r;
-}
-
-
-int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
-uInt nl; /* number of literal/length codes */
-uInt nd; /* number of distance codes */
-uIntf *c; /* that many (total) code lengths */
-uIntf *bl; /* literal desired/actual bit depth */
-uIntf *bd; /* distance desired/actual bit depth */
-inflate_huft * FAR *tl; /* literal/length tree result */
-inflate_huft * FAR *td; /* distance tree result */
-inflate_huft *hp; /* space for trees */
-z_streamp z; /* for messages */
-{
- int r;
- uInt hn = 0; /* hufts used in space */
- uIntf *v; /* work area for huft_build */
-
- /* allocate work area */
- if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
- return Z_MEM_ERROR;
-
- /* build literal/length tree */
- r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
- if (r != Z_OK || *bl == 0)
- {
- if (r == Z_DATA_ERROR)
- z->msg = (char*)"oversubscribed literal/length tree";
- else if (r != Z_MEM_ERROR)
- {
- z->msg = (char*)"incomplete literal/length tree";
- r = Z_DATA_ERROR;
- }
- ZFREE(z, v);
- return r;
- }
-
- /* build distance tree */
- r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
- if (r != Z_OK || (*bd == 0 && nl > 257))
- {
- if (r == Z_DATA_ERROR)
- z->msg = (char*)"oversubscribed distance tree";
- else if (r == Z_BUF_ERROR) {
-#ifdef PKZIP_BUG_WORKAROUND
- r = Z_OK;
- }
-#else
- z->msg = (char*)"incomplete distance tree";
- r = Z_DATA_ERROR;
- }
- else if (r != Z_MEM_ERROR)
- {
- z->msg = (char*)"empty distance tree with lengths";
- r = Z_DATA_ERROR;
- }
- ZFREE(z, v);
- return r;
-#endif
- }
-
- /* done */
- ZFREE(z, v);
- return Z_OK;
-}
-
-
-/* build fixed tables only once--keep them here */
-#ifdef BUILDFIXED
-local int fixed_built = 0;
-#define FIXEDH 544 /* number of hufts used by fixed tables */
-local inflate_huft fixed_mem[FIXEDH];
-local uInt fixed_bl;
-local uInt fixed_bd;
-local inflate_huft *fixed_tl;
-local inflate_huft *fixed_td;
-#else
-#include "inffixed.h"
-#endif
-
-
-int inflate_trees_fixed(bl, bd, tl, td, z)
-uIntf *bl; /* literal desired/actual bit depth */
-uIntf *bd; /* distance desired/actual bit depth */
-inflate_huft * FAR *tl; /* literal/length tree result */
-inflate_huft * FAR *td; /* distance tree result */
-z_streamp z; /* for memory allocation */
-{
-#ifdef BUILDFIXED
- /* build fixed tables if not already */
- if (!fixed_built)
- {
- int k; /* temporary variable */
- uInt f = 0; /* number of hufts used in fixed_mem */
- uIntf *c; /* length list for huft_build */
- uIntf *v; /* work area for huft_build */
-
- /* allocate memory */
- if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
- return Z_MEM_ERROR;
- if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
- {
- ZFREE(z, c);
- return Z_MEM_ERROR;
- }
-
- /* literal table */
- for (k = 0; k < 144; k++)
- c[k] = 8;
- for (; k < 256; k++)
- c[k] = 9;
- for (; k < 280; k++)
- c[k] = 7;
- for (; k < 288; k++)
- c[k] = 8;
- fixed_bl = 9;
- huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
- fixed_mem, &f, v);
-
- /* distance table */
- for (k = 0; k < 30; k++)
- c[k] = 5;
- fixed_bd = 5;
- huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
- fixed_mem, &f, v);
-
- /* done */
- ZFREE(z, v);
- ZFREE(z, c);
- fixed_built = 1;
- }
-#endif
- *bl = fixed_bl;
- *bd = fixed_bd;
- *tl = fixed_tl;
- *td = fixed_td;
- return Z_OK;
-}
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#if !defined(BUILDFIXED) && !defined(STDC)
+# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
+#endif
+
+const char inflate_copyright[] =
+ " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+struct internal_state {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+
+local int huft_build OF((
+ uIntf *, /* code lengths in bits */
+ uInt, /* number of codes */
+ uInt, /* number of "simple" codes */
+ const uIntf *, /* list of base values for non-simple codes */
+ const uIntf *, /* list of extra bits for non-simple codes */
+ inflate_huft * FAR*,/* result: starting table */
+ uIntf *, /* maximum lookup bits (returns actual) */
+ inflate_huft *, /* space for trees */
+ uInt *, /* hufts used in space */
+ uIntf * )); /* space for values */
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ /* see note #13 above about 258 */
+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577};
+local const uInt cpdext[30] = { /* Extra bits for distance codes */
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+ 12, 12, 13, 13};
+
+/*
+ Huffman code decoding is performed using a multi-level table lookup.
+ The fastest way to decode is to simply build a lookup table whose
+ size is determined by the longest code. However, the time it takes
+ to build this table can also be a factor if the data being decoded
+ is not very long. The most common codes are necessarily the
+ shortest codes, so those codes dominate the decoding time, and hence
+ the speed. The idea is you can have a shorter table that decodes the
+ shorter, more probable codes, and then point to subsidiary tables for
+ the longer codes. The time it costs to decode the longer codes is
+ then traded against the time it takes to make longer tables.
+
+ This results of this trade are in the variables lbits and dbits
+ below. lbits is the number of bits the first level table for literal/
+ length codes can decode in one step, and dbits is the same thing for
+ the distance codes. Subsequent tables are also less than or equal to
+ those sizes. These values may be adjusted either when all of the
+ codes are shorter than that, in which case the longest code length in
+ bits is used, or when the shortest code is *longer* than the requested
+ table size, in which case the length of the shortest code in bits is
+ used.
+
+ There are two different values for the two tables, since they code a
+ different number of possibilities each. The literal/length table
+ codes 286 possible values, or in a flat code, a little over eight
+ bits. The distance table codes 30 possible values, or a little less
+ than five bits, flat. The optimum values for speed end up being
+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+ The optimum values may differ though from machine to machine, and
+ possibly even between compilers. Your mileage may vary.
+ */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
+#define BMAX 15 /* maximum bit length of any code */
+
+local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
+uInt n; /* number of codes (assumed <= 288) */
+uInt s; /* number of simple-valued codes (0..s-1) */
+const uIntf *d; /* list of base values for non-simple codes */
+const uIntf *e; /* list of extra bits for non-simple codes */
+inflate_huft * FAR *t; /* result: starting table */
+uIntf *m; /* maximum lookup bits, returns actual */
+inflate_huft *hp; /* space for trees */
+uInt *hn; /* hufts used in space */
+uIntf *v; /* working area: values in order of bit length */
+/* Given a list of code lengths and a maximum table size, make a set of
+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
+ if the given code set is incomplete (the tables are still built in this
+ case), or Z_DATA_ERROR if the input is invalid. */
+{
+
+ uInt a; /* counter for codes of length k */
+ uInt c[BMAX+1]; /* bit length count table */
+ uInt f; /* i repeats in table every f entries */
+ int g; /* maximum code length */
+ int h; /* table level */
+ register uInt i; /* counter, current code */
+ register uInt j; /* counter */
+ register int k; /* number of bits in current code */
+ int l; /* bits per table (returned in m) */
+ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
+ register uIntf *p; /* pointer into c[], b[], or v[] */
+ inflate_huft *q; /* points to current table */
+ struct inflate_huft_s r; /* table entry for structure assignment */
+ inflate_huft *u[BMAX]; /* table stack */
+ register int w; /* bits before this table == (l * h) */
+ uInt x[BMAX+1]; /* bit offsets, then code stack */
+ uIntf *xp; /* pointer into x */
+ int y; /* number of dummy codes added */
+ uInt z; /* number of entries in current table */
+
+
+ /* Generate counts for each bit length */
+ p = c;
+#define C0 *p++ = 0;
+#define C2 C0 C0 C0 C0
+#define C4 C2 C2 C2 C2
+ C4 /* clear c[]--assume BMAX+1 is 16 */
+ p = b; i = n;
+ do {
+ c[*p++]++; /* assume all entries <= BMAX */
+ } while (--i);
+ if (c[0] == n) /* null input--all zero length codes */
+ {
+ *t = (inflate_huft *)Z_NULL;
+ *m = 0;
+ return Z_OK;
+ }
+
+
+ /* Find minimum and maximum length, bound *m by those */
+ l = *m;
+ for (j = 1; j <= BMAX; j++)
+ if (c[j])
+ break;
+ k = j; /* minimum code length */
+ if ((uInt)l < j)
+ l = j;
+ for (i = BMAX; i; i--)
+ if (c[i])
+ break;
+ g = i; /* maximum code length */
+ if ((uInt)l > i)
+ l = i;
+ *m = l;
+
+
+ /* Adjust last length count to fill out codes, if needed */
+ for (y = 1 << j; j < i; j++, y <<= 1)
+ if ((y -= c[j]) < 0)
+ return Z_DATA_ERROR;
+ if ((y -= c[i]) < 0)
+ return Z_DATA_ERROR;
+ c[i] += y;
+
+
+ /* Generate starting offsets into the value table for each length */
+ x[1] = j = 0;
+ p = c + 1; xp = x + 2;
+ while (--i) { /* note that i == g from above */
+ *xp++ = (j += *p++);
+ }
+
+
+ /* Make a table of values in order of bit lengths */
+ p = b; i = 0;
+ do {
+ if ((j = *p++) != 0)
+ v[x[j]++] = i;
+ } while (++i < n);
+ n = x[g]; /* set n to length of v */
+
+
+ /* Generate the Huffman codes and for each, make the table entries */
+ x[0] = i = 0; /* first Huffman code is zero */
+ p = v; /* grab values in bit order */
+ h = -1; /* no tables yet--level -1 */
+ w = -l; /* bits decoded == (l * h) */
+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
+ q = (inflate_huft *)Z_NULL; /* ditto */
+ z = 0; /* ditto */
+
+ /* go through the bit lengths (k already is bits in shortest code) */
+ for (; k <= g; k++)
+ {
+ a = c[k];
+ while (a--)
+ {
+ /* here i is the Huffman code of length k bits for value *p */
+ /* make tables up to required level */
+ while (k > w + l)
+ {
+ h++;
+ w += l; /* previous table always l bits */
+
+ /* compute minimum size table less than or equal to l bits */
+ z = g - w;
+ z = z > (uInt)l ? l : z; /* table size upper limit */
+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
+ { /* too few codes for k-w bit table */
+ f -= a + 1; /* deduct codes from patterns left */
+ xp = c + k;
+ if (j < z)
+ while (++j < z) /* try smaller tables up to z bits */
+ {
+ if ((f <<= 1) <= *++xp)
+ break; /* enough codes to use up j bits */
+ f -= *xp; /* else deduct codes from patterns */
+ }
+ }
+ z = 1 << j; /* table entries for j-bit table */
+
+ /* allocate new table */
+ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
+ return Z_DATA_ERROR; /* overflow of MANY */
+ u[h] = q = hp + *hn;
+ *hn += z;
+
+ /* connect to last table, if there is one */
+ if (h)
+ {
+ x[h] = i; /* save pattern for backing up */
+ r.bits = (Byte)l; /* bits to dump before this table */
+ r.exop = (Byte)j; /* bits in this table */
+ j = i >> (w - l);
+ r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
+ u[h-1][j] = r; /* connect to last table */
+ }
+ else
+ *t = q; /* first table is returned result */
+ }
+
+ /* set up table entry in r */
+ r.bits = (Byte)(k - w);
+ if (p >= v + n)
+ r.exop = 128 + 64; /* out of values--invalid code */
+ else if (*p < s)
+ {
+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
+ r.base = *p++; /* simple code is just the value */
+ }
+ else
+ {
+ r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
+ r.base = d[*p++ - s];
+ }
+
+ /* fill code-like entries with r */
+ f = 1 << (k - w);
+ for (j = i >> w; j < z; j += f)
+ q[j] = r;
+
+ /* backwards increment the k-bit code i */
+ for (j = 1 << (k - 1); i & j; j >>= 1)
+ i ^= j;
+ i ^= j;
+
+ /* backup over finished tables */
+ mask = (1 << w) - 1; /* needed on HP, cc -O bug */
+ while ((i & mask) != x[h])
+ {
+ h--; /* don't need to update q */
+ w -= l;
+ mask = (1 << w) - 1;
+ }
+ }
+ }
+
+
+ /* Return Z_BUF_ERROR if we were given an incomplete table */
+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+}
+
+
+int inflate_trees_bits(c, bb, tb, hp, z)
+uIntf *c; /* 19 code lengths */
+uIntf *bb; /* bits tree desired/actual depth */
+inflate_huft * FAR *tb; /* bits tree result */
+inflate_huft *hp; /* space for trees */
+z_streamp z; /* for messages */
+{
+ int r;
+ uInt hn = 0; /* hufts used in space */
+ uIntf *v; /* work area for huft_build */
+
+ if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
+ return Z_MEM_ERROR;
+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
+ tb, bb, hp, &hn, v);
+ if (r == Z_DATA_ERROR)
+ z->msg = (char*)"oversubscribed dynamic bit lengths tree";
+ else if (r == Z_BUF_ERROR || *bb == 0)
+ {
+ z->msg = (char*)"incomplete dynamic bit lengths tree";
+ r = Z_DATA_ERROR;
+ }
+ ZFREE(z, v);
+ return r;
+}
+
+
+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
+uInt nl; /* number of literal/length codes */
+uInt nd; /* number of distance codes */
+uIntf *c; /* that many (total) code lengths */
+uIntf *bl; /* literal desired/actual bit depth */
+uIntf *bd; /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+inflate_huft *hp; /* space for trees */
+z_streamp z; /* for messages */
+{
+ int r;
+ uInt hn = 0; /* hufts used in space */
+ uIntf *v; /* work area for huft_build */
+
+ /* allocate work area */
+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+ return Z_MEM_ERROR;
+
+ /* build literal/length tree */
+ r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
+ if (r != Z_OK || *bl == 0)
+ {
+ if (r == Z_DATA_ERROR)
+ z->msg = (char*)"oversubscribed literal/length tree";
+ else if (r != Z_MEM_ERROR)
+ {
+ z->msg = (char*)"incomplete literal/length tree";
+ r = Z_DATA_ERROR;
+ }
+ ZFREE(z, v);
+ return r;
+ }
+
+ /* build distance tree */
+ r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
+ if (r != Z_OK || (*bd == 0 && nl > 257))
+ {
+ if (r == Z_DATA_ERROR)
+ z->msg = (char*)"oversubscribed distance tree";
+ else if (r == Z_BUF_ERROR) {
+#ifdef PKZIP_BUG_WORKAROUND
+ r = Z_OK;
+ }
+#else
+ z->msg = (char*)"incomplete distance tree";
+ r = Z_DATA_ERROR;
+ }
+ else if (r != Z_MEM_ERROR)
+ {
+ z->msg = (char*)"empty distance tree with lengths";
+ r = Z_DATA_ERROR;
+ }
+ ZFREE(z, v);
+ return r;
+#endif
+ }
+
+ /* done */
+ ZFREE(z, v);
+ return Z_OK;
+}
+
+
+/* build fixed tables only once--keep them here */
+#ifdef BUILDFIXED
+local int fixed_built = 0;
+#define FIXEDH 544 /* number of hufts used by fixed tables */
+local inflate_huft fixed_mem[FIXEDH];
+local uInt fixed_bl;
+local uInt fixed_bd;
+local inflate_huft *fixed_tl;
+local inflate_huft *fixed_td;
+#else
+#include "inffixed.h"
+#endif
+
+
+int inflate_trees_fixed(bl, bd, tl, td, z)
+uIntf *bl; /* literal desired/actual bit depth */
+uIntf *bd; /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+z_streamp z; /* for memory allocation */
+{
+#ifdef BUILDFIXED
+ /* build fixed tables if not already */
+ if (!fixed_built)
+ {
+ int k; /* temporary variable */
+ uInt f = 0; /* number of hufts used in fixed_mem */
+ uIntf *c; /* length list for huft_build */
+ uIntf *v; /* work area for huft_build */
+
+ /* allocate memory */
+ if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+ return Z_MEM_ERROR;
+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+ {
+ ZFREE(z, c);
+ return Z_MEM_ERROR;
+ }
+
+ /* literal table */
+ for (k = 0; k < 144; k++)
+ c[k] = 8;
+ for (; k < 256; k++)
+ c[k] = 9;
+ for (; k < 280; k++)
+ c[k] = 7;
+ for (; k < 288; k++)
+ c[k] = 8;
+ fixed_bl = 9;
+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
+ fixed_mem, &f, v);
+
+ /* distance table */
+ for (k = 0; k < 30; k++)
+ c[k] = 5;
+ fixed_bd = 5;
+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
+ fixed_mem, &f, v);
+
+ /* done */
+ ZFREE(z, v);
+ ZFREE(z, c);
+ fixed_built = 1;
+ }
+#endif
+ *bl = fixed_bl;
+ *bd = fixed_bd;
+ *tl = fixed_tl;
+ *td = fixed_td;
+ return Z_OK;
+}
diff --git a/lib/zlib/src/infutil.c b/lib/zlib/src/infutil.c
index 976d5e5..9a07622 100644
--- a/lib/zlib/src/infutil.c
+++ b/lib/zlib/src/infutil.c
@@ -1,87 +1,87 @@
-/* inflate_util.c -- data and routines common to blocks and codes
- * Copyright (C) 1995-2002 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "infblock.h"
-#include "inftrees.h"
-#include "infcodes.h"
-#include "infutil.h"
-
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-
-/* And'ing with mask[n] masks the lower n bits */
-uInt inflate_mask[17] = {
- 0x0000,
- 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
- 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-};
-
-
-/* copy as much as possible from the sliding window to the output area */
-int inflate_flush(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
- uInt n;
- Bytef *p;
- Bytef *q;
-
- /* local copies of source and destination pointers */
- p = z->next_out;
- q = s->read;
-
- /* compute number of bytes to copy as far as end of window */
- n = (uInt)((q <= s->write ? s->write : s->end) - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy as far as end of window */
- zmemcpy(p, q, n);
- p += n;
- q += n;
-
- /* see if more to copy at beginning of window */
- if (q == s->end)
- {
- /* wrap pointers */
- q = s->window;
- if (s->write == s->end)
- s->write = s->window;
-
- /* compute bytes to copy */
- n = (uInt)(s->write - q);
- if (n > z->avail_out) n = z->avail_out;
- if (n && r == Z_BUF_ERROR) r = Z_OK;
-
- /* update counters */
- z->avail_out -= n;
- z->total_out += n;
-
- /* update check information */
- if (s->checkfn != Z_NULL)
- z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
- /* copy */
- zmemcpy(p, q, n);
- p += n;
- q += n;
- }
-
- /* update pointers */
- z->next_out = p;
- s->read = q;
-
- /* done */
- return r;
-}
+/* inflate_util.c -- data and routines common to blocks and codes
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+#include "inftrees.h"
+#include "infcodes.h"
+#include "infutil.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* And'ing with mask[n] masks the lower n bits */
+uInt inflate_mask[17] = {
+ 0x0000,
+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+
+/* copy as much as possible from the sliding window to the output area */
+int inflate_flush(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+ uInt n;
+ Bytef *p;
+ Bytef *q;
+
+ /* local copies of source and destination pointers */
+ p = z->next_out;
+ q = s->read;
+
+ /* compute number of bytes to copy as far as end of window */
+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
+ if (n > z->avail_out) n = z->avail_out;
+ if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+ /* update counters */
+ z->avail_out -= n;
+ z->total_out += n;
+
+ /* update check information */
+ if (s->checkfn != Z_NULL)
+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+ /* copy as far as end of window */
+ zmemcpy(p, q, n);
+ p += n;
+ q += n;
+
+ /* see if more to copy at beginning of window */
+ if (q == s->end)
+ {
+ /* wrap pointers */
+ q = s->window;
+ if (s->write == s->end)
+ s->write = s->window;
+
+ /* compute bytes to copy */
+ n = (uInt)(s->write - q);
+ if (n > z->avail_out) n = z->avail_out;
+ if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+ /* update counters */
+ z->avail_out -= n;
+ z->total_out += n;
+
+ /* update check information */
+ if (s->checkfn != Z_NULL)
+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+ /* copy */
+ zmemcpy(p, q, n);
+ p += n;
+ q += n;
+ }
+
+ /* update pointers */
+ z->next_out = p;
+ s->read = q;
+
+ /* done */
+ return r;
+}
diff --git a/lib/zlib/src/trees.c b/lib/zlib/src/trees.c
index df3c065..aeecb5e 100644
--- a/lib/zlib/src/trees.c
+++ b/lib/zlib/src/trees.c
@@ -1,1214 +1,1214 @@
-/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2002 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process uses several Huffman trees. The more
- * common source values are represented by shorter bit sequences.
- *
- * Each code tree is stored in a compressed form which is itself
- * a Huffman encoding of the lengths of all the code strings (in
- * ascending order by source values). The actual code strings are
- * reconstructed from the lengths in the inflate process, as described
- * in the deflate specification.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
- * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
- *
- * Storer, James A.
- * Data Compression: Methods and Theory, pp. 49-50.
- * Computer Science Press, 1988. ISBN 0-7167-8156-5.
- *
- * Sedgewick, R.
- * Algorithms, p290.
- * Addison-Wesley, 1983. ISBN 0-201-06672-6.
- */
-
-/* @(#) $Id: trees.c,v 1.2 2004-11-27 21:35:22 pixel Exp $ */
-
-/* #define GEN_TREES_H */
-
-#include "deflate.h"
-
-#ifdef DEBUG
-# include <ctype.h>
-#endif
-
-/* ===========================================================================
- * Constants
- */
-
-#define MAX_BL_BITS 7
-/* Bit length codes must not exceed MAX_BL_BITS bits */
-
-#define END_BLOCK 256
-/* end of block literal code */
-
-#define REP_3_6 16
-/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
-#define REPZ_3_10 17
-/* repeat a zero length 3-10 times (3 bits of repeat count) */
-
-#define REPZ_11_138 18
-/* repeat a zero length 11-138 times (7 bits of repeat count) */
-
-local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
- = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-
-local const int extra_dbits[D_CODES] /* extra bits for each distance code */
- = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
-local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
- = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-
-local const uch bl_order[BL_CODES]
- = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-/* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
-#define Buf_size (8 * 2*sizeof(char))
-/* Number of bits used within bi_buf. (bi_buf might be implemented on
- * more than 16 bits on some systems.)
- */
-
-/* ===========================================================================
- * Local data. These are initialized only once.
- */
-
-#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
-/* non ANSI compilers may not accept trees.h */
-
-local ct_data static_ltree[L_CODES+2];
-/* The static literal tree. Since the bit lengths are imposed, there is no
- * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
- * below).
- */
-
-local ct_data static_dtree[D_CODES];
-/* The static distance tree. (Actually a trivial tree since all codes use
- * 5 bits.)
- */
-
-uch _dist_code[DIST_CODE_LEN];
-/* Distance codes. The first 256 values correspond to the distances
- * 3 .. 258, the last 256 values correspond to the top 8 bits of
- * the 15 bit distances.
- */
-
-uch _length_code[MAX_MATCH-MIN_MATCH+1];
-/* length code for each normalized match length (0 == MIN_MATCH) */
-
-local int base_length[LENGTH_CODES];
-/* First normalized length for each code (0 = MIN_MATCH) */
-
-local int base_dist[D_CODES];
-/* First normalized distance for each code (0 = distance of 1) */
-
-#else
-# include "trees.h"
-#endif /* GEN_TREES_H */
-
-struct static_tree_desc_s {
- const ct_data *static_tree; /* static tree or NULL */
- const intf *extra_bits; /* extra bits for each code or NULL */
- int extra_base; /* base index for extra_bits */
- int elems; /* max number of elements in the tree */
- int max_length; /* max bit length for the codes */
-};
-
-local static_tree_desc static_l_desc =
-{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-
-local static_tree_desc static_d_desc =
-{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
-
-local static_tree_desc static_bl_desc =
-{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
-
-/* ===========================================================================
- * Local (static) routines in this file.
- */
-
-local void tr_static_init OF((void));
-local void init_block OF((deflate_state *s));
-local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
-local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree OF((deflate_state *s, tree_desc *desc));
-local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local int build_bl_tree OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
- int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
- ct_data *dtree));
-local void set_data_type OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned value, int length));
-local void bi_windup OF((deflate_state *s));
-local void bi_flush OF((deflate_state *s));
-local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
- int header));
-
-#ifdef GEN_TREES_H
-local void gen_trees_header OF((void));
-#endif
-
-#ifndef DEBUG
-# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
- /* Send a code of the given tree. c and tree must not have side effects */
-
-#else /* DEBUG */
-# define send_code(s, c, tree) \
- { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
- send_bits(s, tree[c].Code, tree[c].Len); }
-#endif
-
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-#define put_short(s, w) { \
- put_byte(s, (uch)((w) & 0xff)); \
- put_byte(s, (uch)((ush)(w) >> 8)); \
-}
-
-/* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
-#ifdef DEBUG
-local void send_bits OF((deflate_state *s, int value, int length));
-
-local void send_bits(s, value, length)
- deflate_state *s;
- int value; /* value to send */
- int length; /* number of bits */
-{
- Tracevv((stderr," l %2d v %4x ", length, value));
- Assert(length > 0 && length <= 15, "invalid length");
- s->bits_sent += (ulg)length;
-
- /* If not enough room in bi_buf, use (valid) bits from bi_buf and
- * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
- * unused bits in value.
- */
- if (s->bi_valid > (int)Buf_size - length) {
- s->bi_buf |= (value << s->bi_valid);
- put_short(s, s->bi_buf);
- s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
- s->bi_valid += length - Buf_size;
- } else {
- s->bi_buf |= value << s->bi_valid;
- s->bi_valid += length;
- }
-}
-#else /* !DEBUG */
-
-#define send_bits(s, value, length) \
-{ int len = length;\
- if (s->bi_valid > (int)Buf_size - len) {\
- int val = value;\
- s->bi_buf |= (val << s->bi_valid);\
- put_short(s, s->bi_buf);\
- s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
- s->bi_valid += len - Buf_size;\
- } else {\
- s->bi_buf |= (value) << s->bi_valid;\
- s->bi_valid += len;\
- }\
-}
-#endif /* DEBUG */
-
-
-#define MAX(a,b) (a >= b ? a : b)
-/* the arguments must not have side effects */
-
-/* ===========================================================================
- * Initialize the various 'constant' tables.
- */
-local void tr_static_init()
-{
-#if defined(GEN_TREES_H) || !defined(STDC)
- static int static_init_done = 0;
- int n; /* iterates over tree elements */
- int bits; /* bit counter */
- int length; /* length value */
- int code; /* code value */
- int dist; /* distance index */
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- if (static_init_done) return;
-
- /* For some embedded targets, global variables are not initialized: */
- static_l_desc.static_tree = static_ltree;
- static_l_desc.extra_bits = extra_lbits;
- static_d_desc.static_tree = static_dtree;
- static_d_desc.extra_bits = extra_dbits;
- static_bl_desc.extra_bits = extra_blbits;
-
- /* Initialize the mapping length (0..255) -> length code (0..28) */
- length = 0;
- for (code = 0; code < LENGTH_CODES-1; code++) {
- base_length[code] = length;
- for (n = 0; n < (1<<extra_lbits[code]); n++) {
- _length_code[length++] = (uch)code;
- }
- }
- Assert (length == 256, "tr_static_init: length != 256");
- /* Note that the length 255 (match length 258) can be represented
- * in two different ways: code 284 + 5 bits or code 285, so we
- * overwrite length_code[255] to use the best encoding:
- */
- _length_code[length-1] = (uch)code;
-
- /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
- dist = 0;
- for (code = 0 ; code < 16; code++) {
- base_dist[code] = dist;
- for (n = 0; n < (1<<extra_dbits[code]); n++) {
- _dist_code[dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: dist != 256");
- dist >>= 7; /* from now on, all distances are divided by 128 */
- for ( ; code < D_CODES; code++) {
- base_dist[code] = dist << 7;
- for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
- _dist_code[256 + dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
- /* Construct the codes of the static literal tree */
- for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
- n = 0;
- while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
- while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
- while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
- while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
- /* Codes 286 and 287 do not exist, but we must include them in the
- * tree construction to get a canonical Huffman tree (longest code
- * all ones)
- */
- gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-
- /* The static distance tree is trivial: */
- for (n = 0; n < D_CODES; n++) {
- static_dtree[n].Len = 5;
- static_dtree[n].Code = bi_reverse((unsigned)n, 5);
- }
- static_init_done = 1;
-
-# ifdef GEN_TREES_H
- gen_trees_header();
-# endif
-#endif /* defined(GEN_TREES_H) || !defined(STDC) */
-}
-
-/* ===========================================================================
- * Genererate the file trees.h describing the static trees.
- */
-#ifdef GEN_TREES_H
-# ifndef DEBUG
-# include <stdio.h>
-# endif
-
-# define SEPARATOR(i, last, width) \
- ((i) == (last)? "\n};\n\n" : \
- ((i) % (width) == (width)-1 ? ",\n" : ", "))
-
-void gen_trees_header()
-{
- FILE *header = fopen("trees.h", "w");
- int i;
-
- Assert (header != NULL, "Can't open trees.h");
- fprintf(header,
- "/* header created automatically with -DGEN_TREES_H */\n\n");
-
- fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
- for (i = 0; i < L_CODES+2; i++) {
- fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
- static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
- }
-
- fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
- static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
- }
-
- fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
- for (i = 0; i < DIST_CODE_LEN; i++) {
- fprintf(header, "%2u%s", _dist_code[i],
- SEPARATOR(i, DIST_CODE_LEN-1, 20));
- }
-
- fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
- for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
- fprintf(header, "%2u%s", _length_code[i],
- SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
- }
-
- fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
- for (i = 0; i < LENGTH_CODES; i++) {
- fprintf(header, "%1u%s", base_length[i],
- SEPARATOR(i, LENGTH_CODES-1, 20));
- }
-
- fprintf(header, "local const int base_dist[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "%5u%s", base_dist[i],
- SEPARATOR(i, D_CODES-1, 10));
- }
-
- fclose(header);
-}
-#endif /* GEN_TREES_H */
-
-/* ===========================================================================
- * Initialize the tree data structures for a new zlib stream.
- */
-void _tr_init(s)
- deflate_state *s;
-{
- tr_static_init();
-
- s->l_desc.dyn_tree = s->dyn_ltree;
- s->l_desc.stat_desc = &static_l_desc;
-
- s->d_desc.dyn_tree = s->dyn_dtree;
- s->d_desc.stat_desc = &static_d_desc;
-
- s->bl_desc.dyn_tree = s->bl_tree;
- s->bl_desc.stat_desc = &static_bl_desc;
-
- s->bi_buf = 0;
- s->bi_valid = 0;
- s->last_eob_len = 8; /* enough lookahead for inflate */
-#ifdef DEBUG
- s->compressed_len = 0L;
- s->bits_sent = 0L;
-#endif
-
- /* Initialize the first block of the first file: */
- init_block(s);
-}
-
-/* ===========================================================================
- * Initialize a new block.
- */
-local void init_block(s)
- deflate_state *s;
-{
- int n; /* iterates over tree elements */
-
- /* Initialize the trees. */
- for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
- for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
- for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
- s->dyn_ltree[END_BLOCK].Freq = 1;
- s->opt_len = s->static_len = 0L;
- s->last_lit = s->matches = 0;
-}
-
-#define SMALLEST 1
-/* Index within the heap array of least frequent node in the Huffman tree */
-
-
-/* ===========================================================================
- * Remove the smallest element from the heap and recreate the heap with
- * one less element. Updates heap and heap_len.
- */
-#define pqremove(s, tree, top) \
-{\
- top = s->heap[SMALLEST]; \
- s->heap[SMALLEST] = s->heap[s->heap_len--]; \
- pqdownheap(s, tree, SMALLEST); \
-}
-
-/* ===========================================================================
- * Compares to subtrees, using the tree depth as tie breaker when
- * the subtrees have equal frequency. This minimizes the worst case length.
- */
-#define smaller(tree, n, m, depth) \
- (tree[n].Freq < tree[m].Freq || \
- (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-
-/* ===========================================================================
- * Restore the heap property by moving down the tree starting at node k,
- * exchanging a node with the smallest of its two sons if necessary, stopping
- * when the heap property is re-established (each father smaller than its
- * two sons).
- */
-local void pqdownheap(s, tree, k)
- deflate_state *s;
- ct_data *tree; /* the tree to restore */
- int k; /* node to move down */
-{
- int v = s->heap[k];
- int j = k << 1; /* left son of k */
- while (j <= s->heap_len) {
- /* Set j to the smallest of the two sons: */
- if (j < s->heap_len &&
- smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
- j++;
- }
- /* Exit if v is smaller than both sons */
- if (smaller(tree, v, s->heap[j], s->depth)) break;
-
- /* Exchange v with the smallest son */
- s->heap[k] = s->heap[j]; k = j;
-
- /* And continue down the tree, setting j to the left son of k */
- j <<= 1;
- }
- s->heap[k] = v;
-}
-
-/* ===========================================================================
- * Compute the optimal bit lengths for a tree and update the total bit length
- * for the current block.
- * IN assertion: the fields freq and dad are set, heap[heap_max] and
- * above are the tree nodes sorted by increasing frequency.
- * OUT assertions: the field len is set to the optimal bit length, the
- * array bl_count contains the frequencies for each bit length.
- * The length opt_len is updated; static_len is also updated if stree is
- * not null.
- */
-local void gen_bitlen(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- int max_code = desc->max_code;
- const ct_data *stree = desc->stat_desc->static_tree;
- const intf *extra = desc->stat_desc->extra_bits;
- int base = desc->stat_desc->extra_base;
- int max_length = desc->stat_desc->max_length;
- int h; /* heap index */
- int n, m; /* iterate over the tree elements */
- int bits; /* bit length */
- int xbits; /* extra bits */
- ush f; /* frequency */
- int overflow = 0; /* number of elements with bit length too large */
-
- for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-
- /* In a first pass, compute the optimal bit lengths (which may
- * overflow in the case of the bit length tree).
- */
- tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-
- for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
- n = s->heap[h];
- bits = tree[tree[n].Dad].Len + 1;
- if (bits > max_length) bits = max_length, overflow++;
- tree[n].Len = (ush)bits;
- /* We overwrite tree[n].Dad which is no longer needed */
-
- if (n > max_code) continue; /* not a leaf node */
-
- s->bl_count[bits]++;
- xbits = 0;
- if (n >= base) xbits = extra[n-base];
- f = tree[n].Freq;
- s->opt_len += (ulg)f * (bits + xbits);
- if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
- }
- if (overflow == 0) return;
-
- Trace((stderr,"\nbit length overflow\n"));
- /* This happens for example on obj2 and pic of the Calgary corpus */
-
- /* Find the first bit length which could increase: */
- do {
- bits = max_length-1;
- while (s->bl_count[bits] == 0) bits--;
- s->bl_count[bits]--; /* move one leaf down the tree */
- s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
- s->bl_count[max_length]--;
- /* The brother of the overflow item also moves one step up,
- * but this does not affect bl_count[max_length]
- */
- overflow -= 2;
- } while (overflow > 0);
-
- /* Now recompute all bit lengths, scanning in increasing frequency.
- * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
- * lengths instead of fixing only the wrong ones. This idea is taken
- * from 'ar' written by Haruhiko Okumura.)
- */
- for (bits = max_length; bits != 0; bits--) {
- n = s->bl_count[bits];
- while (n != 0) {
- m = s->heap[--h];
- if (m > max_code) continue;
- if (tree[m].Len != (unsigned) bits) {
- Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
- s->opt_len += ((long)bits - (long)tree[m].Len)
- *(long)tree[m].Freq;
- tree[m].Len = (ush)bits;
- }
- n--;
- }
- }
-}
-
-/* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- * zero code length.
- */
-local void gen_codes (tree, max_code, bl_count)
- ct_data *tree; /* the tree to decorate */
- int max_code; /* largest code with non zero frequency */
- ushf *bl_count; /* number of codes at each bit length */
-{
- ush next_code[MAX_BITS+1]; /* next code value for each bit length */
- ush code = 0; /* running code value */
- int bits; /* bit index */
- int n; /* code index */
-
- /* The distribution counts are first used to generate the code values
- * without bit reversal.
- */
- for (bits = 1; bits <= MAX_BITS; bits++) {
- next_code[bits] = code = (code + bl_count[bits-1]) << 1;
- }
- /* Check that the bit counts in bl_count are consistent. The last code
- * must be all ones.
- */
- Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
- "inconsistent bit counts");
- Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
- for (n = 0; n <= max_code; n++) {
- int len = tree[n].Len;
- if (len == 0) continue;
- /* Now reverse the bits */
- tree[n].Code = bi_reverse(next_code[len]++, len);
-
- Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
- n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
- }
-}
-
-/* ===========================================================================
- * Construct one Huffman tree and assigns the code bit strings and lengths.
- * Update the total bit length for the current block.
- * IN assertion: the field freq is set for all tree elements.
- * OUT assertions: the fields len and code are set to the optimal bit length
- * and corresponding code. The length opt_len is updated; static_len is
- * also updated if stree is not null. The field max_code is set.
- */
-local void build_tree(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- const ct_data *stree = desc->stat_desc->static_tree;
- int elems = desc->stat_desc->elems;
- int n, m; /* iterate over heap elements */
- int max_code = -1; /* largest code with non zero frequency */
- int node; /* new node being created */
-
- /* Construct the initial heap, with least frequent element in
- * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
- * heap[0] is not used.
- */
- s->heap_len = 0, s->heap_max = HEAP_SIZE;
-
- for (n = 0; n < elems; n++) {
- if (tree[n].Freq != 0) {
- s->heap[++(s->heap_len)] = max_code = n;
- s->depth[n] = 0;
- } else {
- tree[n].Len = 0;
- }
- }
-
- /* The pkzip format requires that at least one distance code exists,
- * and that at least one bit should be sent even if there is only one
- * possible code. So to avoid special checks later on we force at least
- * two codes of non zero frequency.
- */
- while (s->heap_len < 2) {
- node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
- tree[node].Freq = 1;
- s->depth[node] = 0;
- s->opt_len--; if (stree) s->static_len -= stree[node].Len;
- /* node is 0 or 1 so it does not have extra bits */
- }
- desc->max_code = max_code;
-
- /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
- * establish sub-heaps of increasing lengths:
- */
- for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-
- /* Construct the Huffman tree by repeatedly combining the least two
- * frequent nodes.
- */
- node = elems; /* next internal node of the tree */
- do {
- pqremove(s, tree, n); /* n = node of least frequency */
- m = s->heap[SMALLEST]; /* m = node of next least frequency */
-
- s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
- s->heap[--(s->heap_max)] = m;
-
- /* Create a new node father of n and m */
- tree[node].Freq = tree[n].Freq + tree[m].Freq;
- s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
- tree[n].Dad = tree[m].Dad = (ush)node;
-#ifdef DUMP_BL_TREE
- if (tree == s->bl_tree) {
- fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
- node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
- }
-#endif
- /* and insert the new node in the heap */
- s->heap[SMALLEST] = node++;
- pqdownheap(s, tree, SMALLEST);
-
- } while (s->heap_len >= 2);
-
- s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-
- /* At this point, the fields freq and dad are set. We can now
- * generate the bit lengths.
- */
- gen_bitlen(s, (tree_desc *)desc);
-
- /* The field len is now set, we can generate the bit codes */
- gen_codes ((ct_data *)tree, max_code, s->bl_count);
-}
-
-/* ===========================================================================
- * Scan a literal or distance tree to determine the frequencies of the codes
- * in the bit length tree.
- */
-local void scan_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- if (nextlen == 0) max_count = 138, min_count = 3;
- tree[max_code+1].Len = (ush)0xffff; /* guard */
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- s->bl_tree[curlen].Freq += count;
- } else if (curlen != 0) {
- if (curlen != prevlen) s->bl_tree[curlen].Freq++;
- s->bl_tree[REP_3_6].Freq++;
- } else if (count <= 10) {
- s->bl_tree[REPZ_3_10].Freq++;
- } else {
- s->bl_tree[REPZ_11_138].Freq++;
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Send a literal or distance tree in compressed form, using the codes in
- * bl_tree.
- */
-local void send_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- /* tree[max_code+1].Len = -1; */ /* guard already set */
- if (nextlen == 0) max_count = 138, min_count = 3;
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-
- } else if (curlen != 0) {
- if (curlen != prevlen) {
- send_code(s, curlen, s->bl_tree); count--;
- }
- Assert(count >= 3 && count <= 6, " 3_6?");
- send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-
- } else if (count <= 10) {
- send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-
- } else {
- send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Construct the Huffman tree for the bit lengths and return the index in
- * bl_order of the last bit length code to send.
- */
-local int build_bl_tree(s)
- deflate_state *s;
-{
- int max_blindex; /* index of last bit length code of non zero freq */
-
- /* Determine the bit length frequencies for literal and distance trees */
- scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
- scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-
- /* Build the bit length tree: */
- build_tree(s, (tree_desc *)(&(s->bl_desc)));
- /* opt_len now includes the length of the tree representations, except
- * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
- */
-
- /* Determine the number of bit length codes to send. The pkzip format
- * requires that at least 4 bit length codes be sent. (appnote.txt says
- * 3 but the actual value used is 4.)
- */
- for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
- if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
- }
- /* Update opt_len to include the bit length tree and counts */
- s->opt_len += 3*(max_blindex+1) + 5+5+4;
- Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
- s->opt_len, s->static_len));
-
- return max_blindex;
-}
-
-/* ===========================================================================
- * Send the header for a block using dynamic Huffman trees: the counts, the
- * lengths of the bit length codes, the literal tree and the distance tree.
- * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- */
-local void send_all_trees(s, lcodes, dcodes, blcodes)
- deflate_state *s;
- int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
- int rank; /* index in bl_order */
-
- Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
- Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
- "too many codes");
- Tracev((stderr, "\nbl counts: "));
- send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
- send_bits(s, dcodes-1, 5);
- send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
- for (rank = 0; rank < blcodes; rank++) {
- Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
- send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
- }
- Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
- Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
- Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-}
-
-/* ===========================================================================
- * Send a stored block
- */
-void _tr_stored_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
-#ifdef DEBUG
- s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
- s->compressed_len += (stored_len + 4) << 3;
-#endif
- copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-}
-
-/* ===========================================================================
- * Send one empty static block to give enough lookahead for inflate.
- * This takes 10 bits, of which 7 may remain in the bit buffer.
- * The current inflate code requires 9 bits of lookahead. If the
- * last two codes for the previous block (real code plus EOB) were coded
- * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- * the last real code. In this case we send two empty static blocks instead
- * of one. (There are no problems if the previous block is stored or fixed.)
- * To simplify the code, we assume the worst case of last real code encoded
- * on one bit only.
- */
-void _tr_align(s)
- deflate_state *s;
-{
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-#endif
- bi_flush(s);
- /* Of the 10 bits for the empty block, we have already sent
- * (10 - bi_valid) bits. The lookahead for the last real code (before
- * the EOB of the previous block) was thus at least one plus the length
- * of the EOB plus what we have just sent of the empty static block.
- */
- if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L;
-#endif
- bi_flush(s);
- }
- s->last_eob_len = 7;
-}
-
-/* ===========================================================================
- * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
- */
-void _tr_flush_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block, or NULL if too old */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
- int max_blindex = 0; /* index of last bit length code of non zero freq */
-
- /* Build the Huffman trees unless a stored block is forced */
- if (s->level > 0) {
-
- /* Check if the file is ascii or binary */
- if (s->data_type == Z_UNKNOWN) set_data_type(s);
-
- /* Construct the literal and distance trees */
- build_tree(s, (tree_desc *)(&(s->l_desc)));
- Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
-
- build_tree(s, (tree_desc *)(&(s->d_desc)));
- Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
- /* At this point, opt_len and static_len are the total bit lengths of
- * the compressed block data, excluding the tree representations.
- */
-
- /* Build the bit length tree for the above two trees, and get the index
- * in bl_order of the last bit length code to send.
- */
- max_blindex = build_bl_tree(s);
-
- /* Determine the best encoding. Compute first the block length in bytes*/
- opt_lenb = (s->opt_len+3+7)>>3;
- static_lenb = (s->static_len+3+7)>>3;
-
- Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
- opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
- s->last_lit));
-
- if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-
- } else {
- Assert(buf != (char*)0, "lost buf");
- opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
- }
-
-#ifdef FORCE_STORED
- if (buf != (char*)0) { /* force stored block */
-#else
- if (stored_len+4 <= opt_lenb && buf != (char*)0) {
- /* 4: two words for the lengths */
-#endif
- /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
- * Otherwise we can't have processed more than WSIZE input bytes since
- * the last block flush, because compression would have been
- * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
- * transform a block into a stored block.
- */
- _tr_stored_block(s, buf, stored_len, eof);
-
-#ifdef FORCE_STATIC
- } else if (static_lenb >= 0) { /* force static trees */
-#else
- } else if (static_lenb == opt_lenb) {
-#endif
- send_bits(s, (STATIC_TREES<<1)+eof, 3);
- compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->static_len;
-#endif
- } else {
- send_bits(s, (DYN_TREES<<1)+eof, 3);
- send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
- max_blindex+1);
- compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->opt_len;
-#endif
- }
- Assert (s->compressed_len == s->bits_sent, "bad compressed size");
- /* The above check is made mod 2^32, for files larger than 512 MB
- * and uLong implemented on 32 bits.
- */
- init_block(s);
-
- if (eof) {
- bi_windup(s);
-#ifdef DEBUG
- s->compressed_len += 7; /* align on byte boundary */
-#endif
- }
- Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
- s->compressed_len-7*eof));
-}
-
-/* ===========================================================================
- * Save the match info and tally the frequency counts. Return true if
- * the current block must be flushed.
- */
-int _tr_tally (s, dist, lc)
- deflate_state *s;
- unsigned dist; /* distance of matched string */
- unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
-{
- s->d_buf[s->last_lit] = (ush)dist;
- s->l_buf[s->last_lit++] = (uch)lc;
- if (dist == 0) {
- /* lc is the unmatched char */
- s->dyn_ltree[lc].Freq++;
- } else {
- s->matches++;
- /* Here, lc is the match length - MIN_MATCH */
- dist--; /* dist = match distance - 1 */
- Assert((ush)dist < (ush)MAX_DIST(s) &&
- (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
- (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
-
- s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
- s->dyn_dtree[d_code(dist)].Freq++;
- }
-
-#ifdef TRUNCATE_BLOCK
- /* Try to guess if it is profitable to stop the current block here */
- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
- /* Compute an upper bound for the compressed length */
- ulg out_length = (ulg)s->last_lit*8L;
- ulg in_length = (ulg)((long)s->strstart - s->block_start);
- int dcode;
- for (dcode = 0; dcode < D_CODES; dcode++) {
- out_length += (ulg)s->dyn_dtree[dcode].Freq *
- (5L+extra_dbits[dcode]);
- }
- out_length >>= 3;
- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
- s->last_lit, in_length, out_length,
- 100L - out_length*100L/in_length));
- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
- }
-#endif
- return (s->last_lit == s->lit_bufsize-1);
- /* We avoid equality with lit_bufsize because of wraparound at 64K
- * on 16 bit machines and because stored blocks are restricted to
- * 64K-1 bytes.
- */
-}
-
-/* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
-local void compress_block(s, ltree, dtree)
- deflate_state *s;
- ct_data *ltree; /* literal tree */
- ct_data *dtree; /* distance tree */
-{
- unsigned dist; /* distance of matched string */
- int lc; /* match length or unmatched char (if dist == 0) */
- unsigned lx = 0; /* running index in l_buf */
- unsigned code; /* the code to send */
- int extra; /* number of extra bits to send */
-
- if (s->last_lit != 0) do {
- dist = s->d_buf[lx];
- lc = s->l_buf[lx++];
- if (dist == 0) {
- send_code(s, lc, ltree); /* send a literal byte */
- Tracecv(isgraph(lc), (stderr," '%c' ", lc));
- } else {
- /* Here, lc is the match length - MIN_MATCH */
- code = _length_code[lc];
- send_code(s, code+LITERALS+1, ltree); /* send the length code */
- extra = extra_lbits[code];
- if (extra != 0) {
- lc -= base_length[code];
- send_bits(s, lc, extra); /* send the extra length bits */
- }
- dist--; /* dist is now the match distance - 1 */
- code = d_code(dist);
- Assert (code < D_CODES, "bad d_code");
-
- send_code(s, code, dtree); /* send the distance code */
- extra = extra_dbits[code];
- if (extra != 0) {
- dist -= base_dist[code];
- send_bits(s, dist, extra); /* send the extra distance bits */
- }
- } /* literal or match pair ? */
-
- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
- Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
-
- } while (lx < s->last_lit);
-
- send_code(s, END_BLOCK, ltree);
- s->last_eob_len = ltree[END_BLOCK].Len;
-}
-
-/* ===========================================================================
- * Set the data type to ASCII or BINARY, using a crude approximation:
- * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
- * IN assertion: the fields freq of dyn_ltree are set and the total of all
- * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
- */
-local void set_data_type(s)
- deflate_state *s;
-{
- int n = 0;
- unsigned ascii_freq = 0;
- unsigned bin_freq = 0;
- while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
- while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
- while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
- s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
-}
-
-/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
-local unsigned bi_reverse(code, len)
- unsigned code; /* the value to invert */
- int len; /* its bit length */
-{
- register unsigned res = 0;
- do {
- res |= code & 1;
- code >>= 1, res <<= 1;
- } while (--len > 0);
- return res >> 1;
-}
-
-/* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
-local void bi_flush(s)
- deflate_state *s;
-{
- if (s->bi_valid == 16) {
- put_short(s, s->bi_buf);
- s->bi_buf = 0;
- s->bi_valid = 0;
- } else if (s->bi_valid >= 8) {
- put_byte(s, (Byte)s->bi_buf);
- s->bi_buf >>= 8;
- s->bi_valid -= 8;
- }
-}
-
-/* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
-local void bi_windup(s)
- deflate_state *s;
-{
- if (s->bi_valid > 8) {
- put_short(s, s->bi_buf);
- } else if (s->bi_valid > 0) {
- put_byte(s, (Byte)s->bi_buf);
- }
- s->bi_buf = 0;
- s->bi_valid = 0;
-#ifdef DEBUG
- s->bits_sent = (s->bits_sent+7) & ~7;
-#endif
-}
-
-/* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
-local void copy_block(s, buf, len, header)
- deflate_state *s;
- charf *buf; /* the input data */
- unsigned len; /* its length */
- int header; /* true if block header must be written */
-{
- bi_windup(s); /* align on byte boundary */
- s->last_eob_len = 8; /* enough lookahead for inflate */
-
- if (header) {
- put_short(s, (ush)len);
- put_short(s, (ush)~len);
-#ifdef DEBUG
- s->bits_sent += 2*16;
-#endif
- }
-#ifdef DEBUG
- s->bits_sent += (ulg)len<<3;
-#endif
- while (len--) {
- put_byte(s, *buf++);
- }
-}
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2002 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process uses several Huffman trees. The more
+ * common source values are represented by shorter bit sequences.
+ *
+ * Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values). The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ * Storer, James A.
+ * Data Compression: Methods and Theory, pp. 49-50.
+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
+ *
+ * Sedgewick, R.
+ * Algorithms, p290.
+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id: trees.c,v 1.3 2004-11-27 21:46:13 pixel Exp $ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+# include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6 16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10 17
+/* repeat a zero length 3-10 times (3 bits of repeat count) */
+
+#define REPZ_11_138 18
+/* repeat a zero length 11-138 times (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+# include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+ const ct_data *static_tree; /* static tree or NULL */
+ const intf *extra_bits; /* extra bits for each code or NULL */
+ int extra_base; /* base index for extra_bits */
+ int elems; /* max number of elements in the tree */
+ int max_length; /* max bit length for the codes */
+};
+
+local static_tree_desc static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc static_d_desc =
+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
+
+local static_tree_desc static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block OF((deflate_state *s));
+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree OF((deflate_state *s, tree_desc *desc));
+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local int build_bl_tree OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+ int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+ ct_data *dtree));
+local void set_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup OF((deflate_state *s));
+local void bi_flush OF((deflate_state *s));
+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
+ int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+ /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+# define send_code(s, c, tree) \
+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+ send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+ put_byte(s, (uch)((w) & 0xff)); \
+ put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+ deflate_state *s;
+ int value; /* value to send */
+ int length; /* number of bits */
+{
+ Tracevv((stderr," l %2d v %4x ", length, value));
+ Assert(length > 0 && length <= 15, "invalid length");
+ s->bits_sent += (ulg)length;
+
+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+ * unused bits in value.
+ */
+ if (s->bi_valid > (int)Buf_size - length) {
+ s->bi_buf |= (value << s->bi_valid);
+ put_short(s, s->bi_buf);
+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+ s->bi_valid += length - Buf_size;
+ } else {
+ s->bi_buf |= value << s->bi_valid;
+ s->bi_valid += length;
+ }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+ if (s->bi_valid > (int)Buf_size - len) {\
+ int val = value;\
+ s->bi_buf |= (val << s->bi_valid);\
+ put_short(s, s->bi_buf);\
+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+ s->bi_valid += len - Buf_size;\
+ } else {\
+ s->bi_buf |= (value) << s->bi_valid;\
+ s->bi_valid += len;\
+ }\
+}
+#endif /* DEBUG */
+
+
+#define MAX(a,b) (a >= b ? a : b)
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+ static int static_init_done = 0;
+ int n; /* iterates over tree elements */
+ int bits; /* bit counter */
+ int length; /* length value */
+ int code; /* code value */
+ int dist; /* distance index */
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ if (static_init_done) return;
+
+ /* For some embedded targets, global variables are not initialized: */
+ static_l_desc.static_tree = static_ltree;
+ static_l_desc.extra_bits = extra_lbits;
+ static_d_desc.static_tree = static_dtree;
+ static_d_desc.extra_bits = extra_dbits;
+ static_bl_desc.extra_bits = extra_blbits;
+
+ /* Initialize the mapping length (0..255) -> length code (0..28) */
+ length = 0;
+ for (code = 0; code < LENGTH_CODES-1; code++) {
+ base_length[code] = length;
+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
+ _length_code[length++] = (uch)code;
+ }
+ }
+ Assert (length == 256, "tr_static_init: length != 256");
+ /* Note that the length 255 (match length 258) can be represented
+ * in two different ways: code 284 + 5 bits or code 285, so we
+ * overwrite length_code[255] to use the best encoding:
+ */
+ _length_code[length-1] = (uch)code;
+
+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+ dist = 0;
+ for (code = 0 ; code < 16; code++) {
+ base_dist[code] = dist;
+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
+ _dist_code[dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: dist != 256");
+ dist >>= 7; /* from now on, all distances are divided by 128 */
+ for ( ; code < D_CODES; code++) {
+ base_dist[code] = dist << 7;
+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+ _dist_code[256 + dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+ /* Construct the codes of the static literal tree */
+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+ n = 0;
+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+ /* Codes 286 and 287 do not exist, but we must include them in the
+ * tree construction to get a canonical Huffman tree (longest code
+ * all ones)
+ */
+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+ /* The static distance tree is trivial: */
+ for (n = 0; n < D_CODES; n++) {
+ static_dtree[n].Len = 5;
+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+ }
+ static_init_done = 1;
+
+# ifdef GEN_TREES_H
+ gen_trees_header();
+# endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+# ifndef DEBUG
+# include <stdio.h>
+# endif
+
+# define SEPARATOR(i, last, width) \
+ ((i) == (last)? "\n};\n\n" : \
+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+ FILE *header = fopen("trees.h", "w");
+ int i;
+
+ Assert (header != NULL, "Can't open trees.h");
+ fprintf(header,
+ "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+ for (i = 0; i < L_CODES+2; i++) {
+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+ }
+
+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+ }
+
+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+ for (i = 0; i < DIST_CODE_LEN; i++) {
+ fprintf(header, "%2u%s", _dist_code[i],
+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
+ }
+
+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+ fprintf(header, "%2u%s", _length_code[i],
+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+ }
+
+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+ for (i = 0; i < LENGTH_CODES; i++) {
+ fprintf(header, "%1u%s", base_length[i],
+ SEPARATOR(i, LENGTH_CODES-1, 20));
+ }
+
+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "%5u%s", base_dist[i],
+ SEPARATOR(i, D_CODES-1, 10));
+ }
+
+ fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void _tr_init(s)
+ deflate_state *s;
+{
+ tr_static_init();
+
+ s->l_desc.dyn_tree = s->dyn_ltree;
+ s->l_desc.stat_desc = &static_l_desc;
+
+ s->d_desc.dyn_tree = s->dyn_dtree;
+ s->d_desc.stat_desc = &static_d_desc;
+
+ s->bl_desc.dyn_tree = s->bl_tree;
+ s->bl_desc.stat_desc = &static_bl_desc;
+
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+ s->compressed_len = 0L;
+ s->bits_sent = 0L;
+#endif
+
+ /* Initialize the first block of the first file: */
+ init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+ deflate_state *s;
+{
+ int n; /* iterates over tree elements */
+
+ /* Initialize the trees. */
+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+ s->dyn_ltree[END_BLOCK].Freq = 1;
+ s->opt_len = s->static_len = 0L;
+ s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+ top = s->heap[SMALLEST]; \
+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+ pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+ (tree[n].Freq < tree[m].Freq || \
+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+ deflate_state *s;
+ ct_data *tree; /* the tree to restore */
+ int k; /* node to move down */
+{
+ int v = s->heap[k];
+ int j = k << 1; /* left son of k */
+ while (j <= s->heap_len) {
+ /* Set j to the smallest of the two sons: */
+ if (j < s->heap_len &&
+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+ j++;
+ }
+ /* Exit if v is smaller than both sons */
+ if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+ /* Exchange v with the smallest son */
+ s->heap[k] = s->heap[j]; k = j;
+
+ /* And continue down the tree, setting j to the left son of k */
+ j <<= 1;
+ }
+ s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ * above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ * array bl_count contains the frequencies for each bit length.
+ * The length opt_len is updated; static_len is also updated if stree is
+ * not null.
+ */
+local void gen_bitlen(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ int max_code = desc->max_code;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ const intf *extra = desc->stat_desc->extra_bits;
+ int base = desc->stat_desc->extra_base;
+ int max_length = desc->stat_desc->max_length;
+ int h; /* heap index */
+ int n, m; /* iterate over the tree elements */
+ int bits; /* bit length */
+ int xbits; /* extra bits */
+ ush f; /* frequency */
+ int overflow = 0; /* number of elements with bit length too large */
+
+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+ /* In a first pass, compute the optimal bit lengths (which may
+ * overflow in the case of the bit length tree).
+ */
+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+ n = s->heap[h];
+ bits = tree[tree[n].Dad].Len + 1;
+ if (bits > max_length) bits = max_length, overflow++;
+ tree[n].Len = (ush)bits;
+ /* We overwrite tree[n].Dad which is no longer needed */
+
+ if (n > max_code) continue; /* not a leaf node */
+
+ s->bl_count[bits]++;
+ xbits = 0;
+ if (n >= base) xbits = extra[n-base];
+ f = tree[n].Freq;
+ s->opt_len += (ulg)f * (bits + xbits);
+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+ }
+ if (overflow == 0) return;
+
+ Trace((stderr,"\nbit length overflow\n"));
+ /* This happens for example on obj2 and pic of the Calgary corpus */
+
+ /* Find the first bit length which could increase: */
+ do {
+ bits = max_length-1;
+ while (s->bl_count[bits] == 0) bits--;
+ s->bl_count[bits]--; /* move one leaf down the tree */
+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+ s->bl_count[max_length]--;
+ /* The brother of the overflow item also moves one step up,
+ * but this does not affect bl_count[max_length]
+ */
+ overflow -= 2;
+ } while (overflow > 0);
+
+ /* Now recompute all bit lengths, scanning in increasing frequency.
+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+ * lengths instead of fixing only the wrong ones. This idea is taken
+ * from 'ar' written by Haruhiko Okumura.)
+ */
+ for (bits = max_length; bits != 0; bits--) {
+ n = s->bl_count[bits];
+ while (n != 0) {
+ m = s->heap[--h];
+ if (m > max_code) continue;
+ if (tree[m].Len != (unsigned) bits) {
+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+ s->opt_len += ((long)bits - (long)tree[m].Len)
+ *(long)tree[m].Freq;
+ tree[m].Len = (ush)bits;
+ }
+ n--;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ * zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+ ct_data *tree; /* the tree to decorate */
+ int max_code; /* largest code with non zero frequency */
+ ushf *bl_count; /* number of codes at each bit length */
+{
+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+ ush code = 0; /* running code value */
+ int bits; /* bit index */
+ int n; /* code index */
+
+ /* The distribution counts are first used to generate the code values
+ * without bit reversal.
+ */
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+ }
+ /* Check that the bit counts in bl_count are consistent. The last code
+ * must be all ones.
+ */
+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+ "inconsistent bit counts");
+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+ for (n = 0; n <= max_code; n++) {
+ int len = tree[n].Len;
+ if (len == 0) continue;
+ /* Now reverse the bits */
+ tree[n].Code = bi_reverse(next_code[len]++, len);
+
+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+ }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ * and corresponding code. The length opt_len is updated; static_len is
+ * also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ int elems = desc->stat_desc->elems;
+ int n, m; /* iterate over heap elements */
+ int max_code = -1; /* largest code with non zero frequency */
+ int node; /* new node being created */
+
+ /* Construct the initial heap, with least frequent element in
+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+ * heap[0] is not used.
+ */
+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+ for (n = 0; n < elems; n++) {
+ if (tree[n].Freq != 0) {
+ s->heap[++(s->heap_len)] = max_code = n;
+ s->depth[n] = 0;
+ } else {
+ tree[n].Len = 0;
+ }
+ }
+
+ /* The pkzip format requires that at least one distance code exists,
+ * and that at least one bit should be sent even if there is only one
+ * possible code. So to avoid special checks later on we force at least
+ * two codes of non zero frequency.
+ */
+ while (s->heap_len < 2) {
+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+ tree[node].Freq = 1;
+ s->depth[node] = 0;
+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+ /* node is 0 or 1 so it does not have extra bits */
+ }
+ desc->max_code = max_code;
+
+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+ * establish sub-heaps of increasing lengths:
+ */
+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+ /* Construct the Huffman tree by repeatedly combining the least two
+ * frequent nodes.
+ */
+ node = elems; /* next internal node of the tree */
+ do {
+ pqremove(s, tree, n); /* n = node of least frequency */
+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+ s->heap[--(s->heap_max)] = m;
+
+ /* Create a new node father of n and m */
+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
+ s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
+ tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+ if (tree == s->bl_tree) {
+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+ }
+#endif
+ /* and insert the new node in the heap */
+ s->heap[SMALLEST] = node++;
+ pqdownheap(s, tree, SMALLEST);
+
+ } while (s->heap_len >= 2);
+
+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+ /* At this point, the fields freq and dad are set. We can now
+ * generate the bit lengths.
+ */
+ gen_bitlen(s, (tree_desc *)desc);
+
+ /* The field len is now set, we can generate the bit codes */
+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ if (nextlen == 0) max_count = 138, min_count = 3;
+ tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ s->bl_tree[curlen].Freq += count;
+ } else if (curlen != 0) {
+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+ s->bl_tree[REP_3_6].Freq++;
+ } else if (count <= 10) {
+ s->bl_tree[REPZ_3_10].Freq++;
+ } else {
+ s->bl_tree[REPZ_11_138].Freq++;
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ /* tree[max_code+1].Len = -1; */ /* guard already set */
+ if (nextlen == 0) max_count = 138, min_count = 3;
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+ } else if (curlen != 0) {
+ if (curlen != prevlen) {
+ send_code(s, curlen, s->bl_tree); count--;
+ }
+ Assert(count >= 3 && count <= 6, " 3_6?");
+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+ } else if (count <= 10) {
+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+ } else {
+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+ deflate_state *s;
+{
+ int max_blindex; /* index of last bit length code of non zero freq */
+
+ /* Determine the bit length frequencies for literal and distance trees */
+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+ /* Build the bit length tree: */
+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
+ /* opt_len now includes the length of the tree representations, except
+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+ */
+
+ /* Determine the number of bit length codes to send. The pkzip format
+ * requires that at least 4 bit length codes be sent. (appnote.txt says
+ * 3 but the actual value used is 4.)
+ */
+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+ }
+ /* Update opt_len to include the bit length tree and counts */
+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+ s->opt_len, s->static_len));
+
+ return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+ deflate_state *s;
+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+ int rank; /* index in bl_order */
+
+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+ "too many codes");
+ Tracev((stderr, "\nbl counts: "));
+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+ send_bits(s, dcodes-1, 5);
+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
+ for (rank = 0; rank < blcodes; rank++) {
+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+ }
+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void _tr_stored_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
+#ifdef DEBUG
+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+ s->compressed_len += (stored_len + 4) << 3;
+#endif
+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void _tr_align(s)
+ deflate_state *s;
+{
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+ bi_flush(s);
+ /* Of the 10 bits for the empty block, we have already sent
+ * (10 - bi_valid) bits. The lookahead for the last real code (before
+ * the EOB of the previous block) was thus at least one plus the length
+ * of the EOB plus what we have just sent of the empty static block.
+ */
+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L;
+#endif
+ bi_flush(s);
+ }
+ s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void _tr_flush_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block, or NULL if too old */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+ int max_blindex = 0; /* index of last bit length code of non zero freq */
+
+ /* Build the Huffman trees unless a stored block is forced */
+ if (s->level > 0) {
+
+ /* Check if the file is ascii or binary */
+ if (s->data_type == Z_UNKNOWN) set_data_type(s);
+
+ /* Construct the literal and distance trees */
+ build_tree(s, (tree_desc *)(&(s->l_desc)));
+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+
+ build_tree(s, (tree_desc *)(&(s->d_desc)));
+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+ /* At this point, opt_len and static_len are the total bit lengths of
+ * the compressed block data, excluding the tree representations.
+ */
+
+ /* Build the bit length tree for the above two trees, and get the index
+ * in bl_order of the last bit length code to send.
+ */
+ max_blindex = build_bl_tree(s);
+
+ /* Determine the best encoding. Compute first the block length in bytes*/
+ opt_lenb = (s->opt_len+3+7)>>3;
+ static_lenb = (s->static_len+3+7)>>3;
+
+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+ s->last_lit));
+
+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+ } else {
+ Assert(buf != (char*)0, "lost buf");
+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+ }
+
+#ifdef FORCE_STORED
+ if (buf != (char*)0) { /* force stored block */
+#else
+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+ /* 4: two words for the lengths */
+#endif
+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+ * Otherwise we can't have processed more than WSIZE input bytes since
+ * the last block flush, because compression would have been
+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+ * transform a block into a stored block.
+ */
+ _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+ } else if (static_lenb >= 0) { /* force static trees */
+#else
+ } else if (static_lenb == opt_lenb) {
+#endif
+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
+ compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->static_len;
+#endif
+ } else {
+ send_bits(s, (DYN_TREES<<1)+eof, 3);
+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+ max_blindex+1);
+ compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->opt_len;
+#endif
+ }
+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+ /* The above check is made mod 2^32, for files larger than 512 MB
+ * and uLong implemented on 32 bits.
+ */
+ init_block(s);
+
+ if (eof) {
+ bi_windup(s);
+#ifdef DEBUG
+ s->compressed_len += 7; /* align on byte boundary */
+#endif
+ }
+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+ s->compressed_len-7*eof));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _tr_tally (s, dist, lc)
+ deflate_state *s;
+ unsigned dist; /* distance of matched string */
+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+ s->d_buf[s->last_lit] = (ush)dist;
+ s->l_buf[s->last_lit++] = (uch)lc;
+ if (dist == 0) {
+ /* lc is the unmatched char */
+ s->dyn_ltree[lc].Freq++;
+ } else {
+ s->matches++;
+ /* Here, lc is the match length - MIN_MATCH */
+ dist--; /* dist = match distance - 1 */
+ Assert((ush)dist < (ush)MAX_DIST(s) &&
+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
+
+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+ s->dyn_dtree[d_code(dist)].Freq++;
+ }
+
+#ifdef TRUNCATE_BLOCK
+ /* Try to guess if it is profitable to stop the current block here */
+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+ /* Compute an upper bound for the compressed length */
+ ulg out_length = (ulg)s->last_lit*8L;
+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
+ int dcode;
+ for (dcode = 0; dcode < D_CODES; dcode++) {
+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
+ (5L+extra_dbits[dcode]);
+ }
+ out_length >>= 3;
+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+ s->last_lit, in_length, out_length,
+ 100L - out_length*100L/in_length));
+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+ }
+#endif
+ return (s->last_lit == s->lit_bufsize-1);
+ /* We avoid equality with lit_bufsize because of wraparound at 64K
+ * on 16 bit machines and because stored blocks are restricted to
+ * 64K-1 bytes.
+ */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+ deflate_state *s;
+ ct_data *ltree; /* literal tree */
+ ct_data *dtree; /* distance tree */
+{
+ unsigned dist; /* distance of matched string */
+ int lc; /* match length or unmatched char (if dist == 0) */
+ unsigned lx = 0; /* running index in l_buf */
+ unsigned code; /* the code to send */
+ int extra; /* number of extra bits to send */
+
+ if (s->last_lit != 0) do {
+ dist = s->d_buf[lx];
+ lc = s->l_buf[lx++];
+ if (dist == 0) {
+ send_code(s, lc, ltree); /* send a literal byte */
+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+ } else {
+ /* Here, lc is the match length - MIN_MATCH */
+ code = _length_code[lc];
+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
+ extra = extra_lbits[code];
+ if (extra != 0) {
+ lc -= base_length[code];
+ send_bits(s, lc, extra); /* send the extra length bits */
+ }
+ dist--; /* dist is now the match distance - 1 */
+ code = d_code(dist);
+ Assert (code < D_CODES, "bad d_code");
+
+ send_code(s, code, dtree); /* send the distance code */
+ extra = extra_dbits[code];
+ if (extra != 0) {
+ dist -= base_dist[code];
+ send_bits(s, dist, extra); /* send the extra distance bits */
+ }
+ } /* literal or match pair ? */
+
+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
+
+ } while (lx < s->last_lit);
+
+ send_code(s, END_BLOCK, ltree);
+ s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to ASCII or BINARY, using a crude approximation:
+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ */
+local void set_data_type(s)
+ deflate_state *s;
+{
+ int n = 0;
+ unsigned ascii_freq = 0;
+ unsigned bin_freq = 0;
+ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
+ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
+ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
+ s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+ unsigned code; /* the value to invert */
+ int len; /* its bit length */
+{
+ register unsigned res = 0;
+ do {
+ res |= code & 1;
+ code >>= 1, res <<= 1;
+ } while (--len > 0);
+ return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+ deflate_state *s;
+{
+ if (s->bi_valid == 16) {
+ put_short(s, s->bi_buf);
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ } else if (s->bi_valid >= 8) {
+ put_byte(s, (Byte)s->bi_buf);
+ s->bi_buf >>= 8;
+ s->bi_valid -= 8;
+ }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+ deflate_state *s;
+{
+ if (s->bi_valid > 8) {
+ put_short(s, s->bi_buf);
+ } else if (s->bi_valid > 0) {
+ put_byte(s, (Byte)s->bi_buf);
+ }
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef DEBUG
+ s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+ deflate_state *s;
+ charf *buf; /* the input data */
+ unsigned len; /* its length */
+ int header; /* true if block header must be written */
+{
+ bi_windup(s); /* align on byte boundary */
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+
+ if (header) {
+ put_short(s, (ush)len);
+ put_short(s, (ush)~len);
+#ifdef DEBUG
+ s->bits_sent += 2*16;
+#endif
+ }
+#ifdef DEBUG
+ s->bits_sent += (ulg)len<<3;
+#endif
+ while (len--) {
+ put_byte(s, *buf++);
+ }
+}
diff --git a/lib/zlib/src/uncompr.c b/lib/zlib/src/uncompr.c
index c7f3ac4..9baedde 100644
--- a/lib/zlib/src/uncompr.c
+++ b/lib/zlib/src/uncompr.c
@@ -1,58 +1,58 @@
-/* uncompr.c -- decompress a memory buffer
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: uncompr.c,v 1.2 2004-11-27 21:35:22 pixel Exp $ */
-
-#include "zlib.h"
-
-/* ===========================================================================
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted.
-*/
-int ZEXPORT uncompress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
-
- err = inflateInit(&stream);
- if (err != Z_OK) return err;
-
- err = inflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- inflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = inflateEnd(&stream);
- return err;
-}
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id: uncompr.c,v 1.3 2004-11-27 21:46:13 pixel Exp $ */
+
+#include "zlib.h"
+
+/* ===========================================================================
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+
+ err = inflateInit(&stream);
+ if (err != Z_OK) return err;
+
+ err = inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ inflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out;
+
+ err = inflateEnd(&stream);
+ return err;
+}
diff --git a/lib/zlib/src/zutil.c b/lib/zlib/src/zutil.c
index 1e4753e..c51c709 100644
--- a/lib/zlib/src/zutil.c
+++ b/lib/zlib/src/zutil.c
@@ -1,225 +1,225 @@
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2002 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: zutil.c,v 1.2 2004-11-27 21:35:22 pixel Exp $ */
-
-#include "zutil.h"
-
-struct internal_state {int dummy;}; /* for buggy compilers */
-
-#ifndef STDC
-extern void exit OF((int));
-#endif
-
-const char *z_errmsg[10] = {
-"need dictionary", /* Z_NEED_DICT 2 */
-"stream end", /* Z_STREAM_END 1 */
-"", /* Z_OK 0 */
-"file error", /* Z_ERRNO (-1) */
-"stream error", /* Z_STREAM_ERROR (-2) */
-"data error", /* Z_DATA_ERROR (-3) */
-"insufficient memory", /* Z_MEM_ERROR (-4) */
-"buffer error", /* Z_BUF_ERROR (-5) */
-"incompatible version",/* Z_VERSION_ERROR (-6) */
-""};
-
-
-const char * ZEXPORT zlibVersion()
-{
- return ZLIB_VERSION;
-}
-
-#ifdef DEBUG
-
-# ifndef verbose
-# define verbose 0
-# endif
-int z_verbose = verbose;
-
-void z_error (m)
- char *m;
-{
- fprintf(stderr, "%s\n", m);
- exit(1);
-}
-#endif
-
-/* exported to allow conversion of error code to string for compress() and
- * uncompress()
- */
-const char * ZEXPORT zError(err)
- int err;
-{
- return ERR_MSG(err);
-}
-
-
-#ifndef HAVE_MEMCPY
-
-void zmemcpy(dest, source, len)
- Bytef* dest;
- const Bytef* source;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = *source++; /* ??? to be unrolled */
- } while (--len != 0);
-}
-
-int zmemcmp(s1, s2, len)
- const Bytef* s1;
- const Bytef* s2;
- uInt len;
-{
- uInt j;
-
- for (j = 0; j < len; j++) {
- if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
- }
- return 0;
-}
-
-void zmemzero(dest, len)
- Bytef* dest;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = 0; /* ??? to be unrolled */
- } while (--len != 0);
-}
-#endif
-
-#ifdef __TURBOC__
-#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
-/* Small and medium model in Turbo C are for now limited to near allocation
- * with reduced MAX_WBITS and MAX_MEM_LEVEL
- */
-# define MY_ZCALLOC
-
-/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
- * and farmalloc(64K) returns a pointer with an offset of 8, so we
- * must fix the pointer. Warning: the pointer must be put back to its
- * original form in order to free it, use zcfree().
- */
-
-#define MAX_PTR 10
-/* 10*64K = 640K */
-
-local int next_ptr = 0;
-
-typedef struct ptr_table_s {
- voidpf org_ptr;
- voidpf new_ptr;
-} ptr_table;
-
-local ptr_table table[MAX_PTR];
-/* This table is used to remember the original form of pointers
- * to large buffers (64K). Such pointers are normalized with a zero offset.
- * Since MSDOS is not a preemptive multitasking OS, this table is not
- * protected from concurrent access. This hack doesn't work anyway on
- * a protected system like OS/2. Use Microsoft C instead.
- */
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
- voidpf buf = opaque; /* just to make some compilers happy */
- ulg bsize = (ulg)items*size;
-
- /* If we allocate less than 65520 bytes, we assume that farmalloc
- * will return a usable pointer which doesn't have to be normalized.
- */
- if (bsize < 65520L) {
- buf = farmalloc(bsize);
- if (*(ush*)&buf != 0) return buf;
- } else {
- buf = farmalloc(bsize + 16L);
- }
- if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
- table[next_ptr].org_ptr = buf;
-
- /* Normalize the pointer to seg:0 */
- *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
- *(ush*)&buf = 0;
- table[next_ptr++].new_ptr = buf;
- return buf;
-}
-
-void zcfree (voidpf opaque, voidpf ptr)
-{
- int n;
- if (*(ush*)&ptr != 0) { /* object < 64K */
- farfree(ptr);
- return;
- }
- /* Find the original pointer */
- for (n = 0; n < next_ptr; n++) {
- if (ptr != table[n].new_ptr) continue;
-
- farfree(table[n].org_ptr);
- while (++n < next_ptr) {
- table[n-1] = table[n];
- }
- next_ptr--;
- return;
- }
- ptr = opaque; /* just to make some compilers happy */
- Assert(0, "zcfree: ptr not found");
-}
-#endif
-#endif /* __TURBOC__ */
-
-
-#if defined(M_I86) && !defined(__32BIT__)
-/* Microsoft C in 16-bit mode */
-
-# define MY_ZCALLOC
-
-#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
-# define _halloc halloc
-# define _hfree hfree
-#endif
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- return _halloc((long)items, size);
-}
-
-void zcfree (voidpf opaque, voidpf ptr)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- _hfree(ptr);
-}
-
-#endif /* MSC */
-
-
-#ifndef MY_ZCALLOC /* Any system without a special alloc function */
-
-#ifndef STDC
-extern voidp calloc OF((uInt items, uInt size));
-extern void free OF((voidpf ptr));
-#endif
-
-voidpf zcalloc (opaque, items, size)
- voidpf opaque;
- unsigned items;
- unsigned size;
-{
- if (opaque) items += size - size; /* make compiler happy */
- return (voidpf)calloc(items, size);
-}
-
-void zcfree (opaque, ptr)
- voidpf opaque;
- voidpf ptr;
-{
- free(ptr);
- if (opaque) return; /* make compiler happy */
-}
-
-#endif /* MY_ZCALLOC */
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id: zutil.c,v 1.3 2004-11-27 21:46:13 pixel Exp $ */
+
+#include "zutil.h"
+
+struct internal_state {int dummy;}; /* for buggy compilers */
+
+#ifndef STDC
+extern void exit OF((int));
+#endif
+
+const char *z_errmsg[10] = {
+"need dictionary", /* Z_NEED_DICT 2 */
+"stream end", /* Z_STREAM_END 1 */
+"", /* Z_OK 0 */
+"file error", /* Z_ERRNO (-1) */
+"stream error", /* Z_STREAM_ERROR (-2) */
+"data error", /* Z_DATA_ERROR (-3) */
+"insufficient memory", /* Z_MEM_ERROR (-4) */
+"buffer error", /* Z_BUF_ERROR (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+ return ZLIB_VERSION;
+}
+
+#ifdef DEBUG
+
+# ifndef verbose
+# define verbose 0
+# endif
+int z_verbose = verbose;
+
+void z_error (m)
+ char *m;
+{
+ fprintf(stderr, "%s\n", m);
+ exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+ int err;
+{
+ return ERR_MSG(err);
+}
+
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+ Bytef* dest;
+ const Bytef* source;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = *source++; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+
+int zmemcmp(s1, s2, len)
+ const Bytef* s1;
+ const Bytef* s2;
+ uInt len;
+{
+ uInt j;
+
+ for (j = 0; j < len; j++) {
+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+ }
+ return 0;
+}
+
+void zmemzero(dest, len)
+ Bytef* dest;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = 0; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+#endif
+
+#ifdef __TURBOC__
+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
+/* Small and medium model in Turbo C are for now limited to near allocation
+ * with reduced MAX_WBITS and MAX_MEM_LEVEL
+ */
+# define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+ voidpf org_ptr;
+ voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ voidpf buf = opaque; /* just to make some compilers happy */
+ ulg bsize = (ulg)items*size;
+
+ /* If we allocate less than 65520 bytes, we assume that farmalloc
+ * will return a usable pointer which doesn't have to be normalized.
+ */
+ if (bsize < 65520L) {
+ buf = farmalloc(bsize);
+ if (*(ush*)&buf != 0) return buf;
+ } else {
+ buf = farmalloc(bsize + 16L);
+ }
+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+ table[next_ptr].org_ptr = buf;
+
+ /* Normalize the pointer to seg:0 */
+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+ *(ush*)&buf = 0;
+ table[next_ptr++].new_ptr = buf;
+ return buf;
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ int n;
+ if (*(ush*)&ptr != 0) { /* object < 64K */
+ farfree(ptr);
+ return;
+ }
+ /* Find the original pointer */
+ for (n = 0; n < next_ptr; n++) {
+ if (ptr != table[n].new_ptr) continue;
+
+ farfree(table[n].org_ptr);
+ while (++n < next_ptr) {
+ table[n-1] = table[n];
+ }
+ next_ptr--;
+ return;
+ }
+ ptr = opaque; /* just to make some compilers happy */
+ Assert(0, "zcfree: ptr not found");
+}
+#endif
+#endif /* __TURBOC__ */
+
+
+#if defined(M_I86) && !defined(__32BIT__)
+/* Microsoft C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+# define _halloc halloc
+# define _hfree hfree
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ return _halloc((long)items, size);
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ _hfree(ptr);
+}
+
+#endif /* MSC */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp calloc OF((uInt items, uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (opaque, items, size)
+ voidpf opaque;
+ unsigned items;
+ unsigned size;
+{
+ if (opaque) items += size - size; /* make compiler happy */
+ return (voidpf)calloc(items, size);
+}
+
+void zcfree (opaque, ptr)
+ voidpf opaque;
+ voidpf ptr;
+{
+ free(ptr);
+ if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/src/Main.cc b/src/Main.cc
index 7cc062e..ecec54e 100644
--- a/src/Main.cc
+++ b/src/Main.cc
@@ -1,215 +1,215 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <unistd.h>
-#include <list>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include "Handle.h"
-#include "Task.h"
-#include "TaskMan.h"
-#include "HttpServ.h"
-#include "Socket.h"
-#include "config.h"
-#include "Message.h"
-#include "Menu.h"
-#include "Exceptions.h"
-#include "Form.h"
-#include "Confirm.h"
-#include "Table.h"
-#include "InPipe.h"
-#include "Image.h"
-#include "CopyJob.h"
-#include "IRC.h"
-#include "Main.h"
-#include "gettext.h"
-
-InPipe * in;
-
-class ad_run : public Task {
- public:
- ad_run(Variables * av, Variables * ahds, Handle * ah) : v(*av), hds(*ahds), h(ah) {
- SetBurst();
- }
- virtual ~ad_run() {}
- virtual String GetName() { return "Action dynamique"; }
- protected:
- virtual int Do() throw (GeneralException) {
- pid_t p;
-
- switch (current) {
- case 0:
- if (!(p = fork())) {
- execlp("uptime", "uptime", NULL);
- }
- current = 1;
- WaitFor(p);
- Suspend(TASK_ON_HOLD);
-
- case 1:
- (*in) >> ut;
- if (!(p = fork())) {
- execlp("uname", "uname", "-a", NULL);
- }
- current = 2;
- WaitFor(p);
- Suspend(TASK_ON_HOLD);
-
- case 2:
- (*in) >> un;
- for (int i = 0; i < hds.GetNb(); i++) {
- shds += hds[i] + "<BR>\n";
- }
-
- m = new Message("Action dynamique",
- String("Vous avez choisi l'action dynamique. L'uptime de la machine est '") +
- ut + "' et sa définition complète est '" + un + "'<BR><BR><BR>Voici la liste des entêtes:<BR><BR>" + shds, "");
-
- current = 3;
- WaitFor(m->Do(&v, &hds, h));
- Suspend(TASK_ON_HOLD);
-
- case 3:
- delete m;
- testimg = new Image(100, 100);
- testimg->Prepare();
-
- testoutput = new Output("TestImg.tga");
-
- current = 4;
- WaitFor(new CopyJob(testimg, testoutput, -1, true, true));
- Suspend(TASK_ON_HOLD);
-
- case 4:
- return TASK_DONE;
- }
- return TASK_DONE;
- }
- private:
- Variables v, hds;
- Handle * h;
- String ut, un, shds;
- Action * m;
- Image * testimg;
- Output * testoutput;
-};
-
-class ad_t : public Action {
- public:
- ad_t() : Action("menu6") { }
- virtual ~ad_t() { }
- virtual String GetTitle() { return "Action dynamique"; }
- virtual Task * Do(Variables * v, Variables * hds, Handle * h) {
- return new ad_run(v, hds, h);
- }
-};
-Action * ad = new ad_t();
-
-class dostop_t : public Action {
- public:
- dostop_t() : Action("dostop") { }
- virtual ~dostop_t() { }
- virtual String GetTitle() { return "Arret du serveur"; }
- virtual Task * Do(Variables * v, Variables * hds, Handle * h) {
- TaskMan::Stop();
- return 0;
- }
-};
-Action * dostop = new dostop_t();
-
-String Noms[] = {"Champ1", "Champ2", "Champ3"};
-String Defaults[] = {"Default1", "Default2", 0};
-String Invites[] = {"Champ 1:", "Champ 2:", "Champ 3:"};
-String Options[] = {"Option1", "Option2", ""};
-String ODescs[] = {"Description 1", "Description 2", ""};
-String * Lists[] = {0, 0, Options};
-String * Descs[] = {0, 0, ODescs};
-String Titres[] = {"Titre 1", "Titre 2", "Titre 3"};
-String Cells[] = {"L1C1", "L1C2", "L1C3", "L2C1", "L2C2", "L2C3", "L3C1", "L3C2", "L3C3", "L4C1", "L4C2", "L4C3"};
-Action * a1 = new Message("Action 1", "Vous avez cliqué sur l'option 1 du menu", "menu1");
-Action * a2 = new Table("Petite table", "menu2", Titres, Cells, 3, 4);
-Action * a3 = new Message("Test d'image",
-"Voici un test d'affichage d'image:"
-"<center><table border=0><td><tr><img src=\"/image/nobis-logo-small.jpg\"></tr></td></table></center>",
-"menu3");
-Action * a4 = new Form("Test de formulaire...", "menu4", "Rentrez des trucs...", Noms, Invites, Defaults, Lists, Descs, 3);
-Action * a5 = new Confirm("Confirmation", "Oui ou non?", "menu5", 0, 0);
-Action * java = new Message("Applet JAVA",
-"\n"
-"<center>\n"
-"<APPLET CODE = \"TestApplet.class\" CODEBASE =\"/image\" WIDTH = 400 HEIGHT = 50>\n"
-"</APPLET>\n"
-"</center>\n", "java");
-
-Action * up = new Message("Test d'upload",
-"\n"
-"<FORM ENCTYPE=\"multipart/form-data\" ACTION=\"/bin/start\" METHOD=POST>\n"
-"<INPUT TYPE=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"1000\">\n"
-"Send this file: <INPUT NAME=\"userfile\" TYPE=\"file\">\n"
-"<INPUT TYPE=\"submit\" VALUE=\"Send File\">\n"
-"</FORM>\n", "upload");
-
-Action * stop = new Confirm("Stopper", "Stopper le serveur?", "stop", dostop, 0);
-
-Action * Liste[] = {a1, a2, a3, a4, a5, ad, java, up, stop};
-String Labels[] = {"Action 1", "Action 2", "Action 3", "Action 4", "Action 5", "Action dynamique", "Essai de java", "Test d'upload", "Stop"};
-
-CODE_BEGINS
-
-Action * buildmenu(void) {
- Action * m = new Menu("Menu Principal", "start", Labels, Liste, 9);
- return m;
-}
-
-int startup() throw (GeneralException) {
- int c;
- String port = "1500";
-
- std::list<String> testlist;
- testlist.push_front("poide");
-
- in = new InPipe();
-
- in->Hook();
-
- String test = "poide\n", r;
- std::cout << test;
- std::cout.flush();
- (*in) >> r;
- if (r != "poide") {
- printm(M_ERROR, "The stdout redirect has failed.\n");
- exit(-1);
- }
-
- while ((c = getopt(argc, argv, "p:")) != EOF) {
- switch (c) {
- case 'p':
- port = optarg;
- break;
- default:
- printm(M_BARE, String(_("Usage: ")) + argv[0] + " [-p port]\n");
- exit(-1);
- }
- }
-
- try {
- HttpServ h(buildmenu(), port.to_int(), "testing");
-// IRC i("botalacon");
-// i.Connect();
-// i.MainLoop();
- TaskMan::MainLoop();
- }
- catch (GeneralException e) {
- std::cerr << "Main function got an exception: '" << e.GetMsg() << "'.\n";
- exit(-1);
- }
-
- catch (...) {
- std::cerr << "Unknow exception.\n" << std::endl;
- exit(-1);
- }
-
- delete in;
- return 0;
-}
-CODE_ENDS
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <unistd.h>
+#include <list>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "Handle.h"
+#include "Task.h"
+#include "TaskMan.h"
+#include "HttpServ.h"
+#include "Socket.h"
+#include "config.h"
+#include "Message.h"
+#include "Menu.h"
+#include "Exceptions.h"
+#include "Form.h"
+#include "Confirm.h"
+#include "Table.h"
+#include "InPipe.h"
+#include "Image.h"
+#include "CopyJob.h"
+#include "IRC.h"
+#include "Main.h"
+#include "gettext.h"
+
+InPipe * in;
+
+class ad_run : public Task {
+ public:
+ ad_run(Variables * av, Variables * ahds, Handle * ah) : v(*av), hds(*ahds), h(ah) {
+ SetBurst();
+ }
+ virtual ~ad_run() {}
+ virtual String GetName() { return "Action dynamique"; }
+ protected:
+ virtual int Do() throw (GeneralException) {
+ pid_t p;
+
+ switch (current) {
+ case 0:
+ if (!(p = fork())) {
+ execlp("uptime", "uptime", NULL);
+ }
+ current = 1;
+ WaitFor(p);
+ Suspend(TASK_ON_HOLD);
+
+ case 1:
+ (*in) >> ut;
+ if (!(p = fork())) {
+ execlp("uname", "uname", "-a", NULL);
+ }
+ current = 2;
+ WaitFor(p);
+ Suspend(TASK_ON_HOLD);
+
+ case 2:
+ (*in) >> un;
+ for (int i = 0; i < hds.GetNb(); i++) {
+ shds += hds[i] + "<BR>\n";
+ }
+
+ m = new Message("Action dynamique",
+ String("Vous avez choisi l'action dynamique. L'uptime de la machine est '") +
+ ut + "' et sa définition complète est '" + un + "'<BR><BR><BR>Voici la liste des entêtes:<BR><BR>" + shds, "");
+
+ current = 3;
+ WaitFor(m->Do(&v, &hds, h));
+ Suspend(TASK_ON_HOLD);
+
+ case 3:
+ delete m;
+ testimg = new Image(100, 100);
+ testimg->Prepare();
+
+ testoutput = new Output("TestImg.tga");
+
+ current = 4;
+ WaitFor(new CopyJob(testimg, testoutput, -1, true, true));
+ Suspend(TASK_ON_HOLD);
+
+ case 4:
+ return TASK_DONE;
+ }
+ return TASK_DONE;
+ }
+ private:
+ Variables v, hds;
+ Handle * h;
+ String ut, un, shds;
+ Action * m;
+ Image * testimg;
+ Output * testoutput;
+};
+
+class ad_t : public Action {
+ public:
+ ad_t() : Action("menu6") { }
+ virtual ~ad_t() { }
+ virtual String GetTitle() { return "Action dynamique"; }
+ virtual Task * Do(Variables * v, Variables * hds, Handle * h) {
+ return new ad_run(v, hds, h);
+ }
+};
+Action * ad = new ad_t();
+
+class dostop_t : public Action {
+ public:
+ dostop_t() : Action("dostop") { }
+ virtual ~dostop_t() { }
+ virtual String GetTitle() { return "Arret du serveur"; }
+ virtual Task * Do(Variables * v, Variables * hds, Handle * h) {
+ TaskMan::Stop();
+ return 0;
+ }
+};
+Action * dostop = new dostop_t();
+
+String Noms[] = {"Champ1", "Champ2", "Champ3"};
+String Defaults[] = {"Default1", "Default2", 0};
+String Invites[] = {"Champ 1:", "Champ 2:", "Champ 3:"};
+String Options[] = {"Option1", "Option2", ""};
+String ODescs[] = {"Description 1", "Description 2", ""};
+String * Lists[] = {0, 0, Options};
+String * Descs[] = {0, 0, ODescs};
+String Titres[] = {"Titre 1", "Titre 2", "Titre 3"};
+String Cells[] = {"L1C1", "L1C2", "L1C3", "L2C1", "L2C2", "L2C3", "L3C1", "L3C2", "L3C3", "L4C1", "L4C2", "L4C3"};
+Action * a1 = new Message("Action 1", "Vous avez cliqué sur l'option 1 du menu", "menu1");
+Action * a2 = new Table("Petite table", "menu2", Titres, Cells, 3, 4);
+Action * a3 = new Message("Test d'image",
+"Voici un test d'affichage d'image:"
+"<center><table border=0><td><tr><img src=\"/image/nobis-logo-small.jpg\"></tr></td></table></center>",
+"menu3");
+Action * a4 = new Form("Test de formulaire...", "menu4", "Rentrez des trucs...", Noms, Invites, Defaults, Lists, Descs, 3);
+Action * a5 = new Confirm("Confirmation", "Oui ou non?", "menu5", 0, 0);
+Action * java = new Message("Applet JAVA",
+"\n"
+"<center>\n"
+"<APPLET CODE = \"TestApplet.class\" CODEBASE =\"/image\" WIDTH = 400 HEIGHT = 50>\n"
+"</APPLET>\n"
+"</center>\n", "java");
+
+Action * up = new Message("Test d'upload",
+"\n"
+"<FORM ENCTYPE=\"multipart/form-data\" ACTION=\"/bin/start\" METHOD=POST>\n"
+"<INPUT TYPE=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"1000\">\n"
+"Send this file: <INPUT NAME=\"userfile\" TYPE=\"file\">\n"
+"<INPUT TYPE=\"submit\" VALUE=\"Send File\">\n"
+"</FORM>\n", "upload");
+
+Action * stop = new Confirm("Stopper", "Stopper le serveur?", "stop", dostop, 0);
+
+Action * Liste[] = {a1, a2, a3, a4, a5, ad, java, up, stop};
+String Labels[] = {"Action 1", "Action 2", "Action 3", "Action 4", "Action 5", "Action dynamique", "Essai de java", "Test d'upload", "Stop"};
+
+CODE_BEGINS
+
+Action * buildmenu(void) {
+ Action * m = new Menu("Menu Principal", "start", Labels, Liste, 9);
+ return m;
+}
+
+int startup() throw (GeneralException) {
+ int c;
+ String port = "1500";
+
+ std::list<String> testlist;
+ testlist.push_front("poide");
+
+ in = new InPipe();
+
+ in->Hook();
+
+ String test = "poide\n", r;
+ std::cout << test;
+ std::cout.flush();
+ (*in) >> r;
+ if (r != "poide") {
+ printm(M_ERROR, "The stdout redirect has failed.\n");
+ exit(-1);
+ }
+
+ while ((c = getopt(argc, argv, "p:")) != EOF) {
+ switch (c) {
+ case 'p':
+ port = optarg;
+ break;
+ default:
+ printm(M_BARE, String(_("Usage: ")) + argv[0] + " [-p port]\n");
+ exit(-1);
+ }
+ }
+
+ try {
+ HttpServ h(buildmenu(), port.to_int(), "testing");
+// IRC i("botalacon");
+// i.Connect();
+// i.MainLoop();
+ TaskMan::MainLoop();
+ }
+ catch (GeneralException e) {
+ std::cerr << "Main function got an exception: '" << e.GetMsg() << "'.\n";
+ exit(-1);
+ }
+
+ catch (...) {
+ std::cerr << "Unknow exception.\n" << std::endl;
+ exit(-1);
+ }
+
+ delete in;
+ return 0;
+}
+CODE_ENDS
diff --git a/src/misc.cc b/src/misc.cc
index d79204d..ea72572 100644
--- a/src/misc.cc
+++ b/src/misc.cc
@@ -1,66 +1,66 @@
-#include <list>
-#include "Handle.h"
-#include "String.h"
-
-void GeneDeroul(Handle * h, String * & l1, String * & l2) {
- int count;
- list<String> result;
- String r1, r2;
-
- count = 0;
-
- while (1) {
- (*h) >> r1;
- (*h) >> r2;
- if ((r1 == "") && (r2 == "")) break;
- result.push_back(r1);
- result.push_back(r2);
- count++;
- }
-
- l1 = new String[count + 1];
- l2 = new String[count + 1];
-
- for (int i = 0; i < count; i++) {
- r1 = result.front();
- result.pop_front();
- r2 = result.front();
- result.pop_front();
- l1[i] = r1;
- l2[i] = r2;
- }
-
- l1[count] = "";
- l2[count] = "";
-}
-
-int GeneList(Handle * h, int nbcol, String * & l) {
- int nblig;
- list<String> result;
- String r;
- bool is_null;
-
- nblig = 0;
- while (1) {
- is_null = true;
- for (int i = 0; i < nbcol; i++) {
- (*h) >> r;
- result.push_back(r);
- if (r != "") is_null = false;
- }
- if (is_null) break;
- nblig++;
- }
-
- l = new String[nbcol * nblig + 1];
-
- for (int i = 0; i < (nbcol * nblig); i++) {
- r = result.front();
- result.pop_front();
- l[i] = r;
- }
-
- l[nbcol * nblig] = "";
-
- return nblig;
-}
+#include <list>
+#include "Handle.h"
+#include "String.h"
+
+void GeneDeroul(Handle * h, String * & l1, String * & l2) {
+ int count;
+ list<String> result;
+ String r1, r2;
+
+ count = 0;
+
+ while (1) {
+ (*h) >> r1;
+ (*h) >> r2;
+ if ((r1 == "") && (r2 == "")) break;
+ result.push_back(r1);
+ result.push_back(r2);
+ count++;
+ }
+
+ l1 = new String[count + 1];
+ l2 = new String[count + 1];
+
+ for (int i = 0; i < count; i++) {
+ r1 = result.front();
+ result.pop_front();
+ r2 = result.front();
+ result.pop_front();
+ l1[i] = r1;
+ l2[i] = r2;
+ }
+
+ l1[count] = "";
+ l2[count] = "";
+}
+
+int GeneList(Handle * h, int nbcol, String * & l) {
+ int nblig;
+ list<String> result;
+ String r;
+ bool is_null;
+
+ nblig = 0;
+ while (1) {
+ is_null = true;
+ for (int i = 0; i < nbcol; i++) {
+ (*h) >> r;
+ result.push_back(r);
+ if (r != "") is_null = false;
+ }
+ if (is_null) break;
+ nblig++;
+ }
+
+ l = new String[nbcol * nblig + 1];
+
+ for (int i = 0; i < (nbcol * nblig); i++) {
+ r = result.front();
+ result.pop_front();
+ l[i] = r;
+ }
+
+ l[nbcol * nblig] = "";
+
+ return nblig;
+}
diff --git a/src/paq.cc b/src/paq.cc
index 7a56989..2cbddd4 100644
--- a/src/paq.cc
+++ b/src/paq.cc
@@ -1,165 +1,165 @@
-#include <dirent.h>
-#include <unistd.h>
-#include <iostream.h>
-#include <list>
-#include <Main.h>
-#include <Input.h>
-#include <Output.h>
-#include <Regex.h>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef WORDS_BIGENDIAN
-#define SIGNATURE 0x4e504151
-#else
-#define SIGNATURE 0x5141504e
-#endif
-
-String current_dir;
-
-extern "C" int sortdir(const void * d1, const void * d2) {
- struct stat fstats1, fstats2;
- String n;
-
- n = current_dir + "/" + (**((const dirent **)d1)).d_name;
- stat(n.to_charp(), &fstats1);
-
- n = current_dir + "/" + (**((const dirent **)d2)).d_name;
- stat(n.to_charp(), &fstats2);
-
- if (!((S_ISDIR(fstats1.st_mode) ? 1 : 0) ^ (S_ISDIR(fstats2.st_mode) ? 1 : 0))) {
- return alphasort(d1, d2);
- } else {
- if (S_ISDIR(fstats1.st_mode))
- return -1;
- else
- return 1;
- }
-}
-
-CODE_BEGINS
-
-private:
-
-struct couple {
- String p, v;
-};
-
-Output * Archive;
-
-std::list<String> filelist;
-
-void finalize(void) {
- int size;
- Input * file;
- for (std::list<String>::iterator i = filelist.begin(); i != filelist.end(); i++) {
- cerr << "Finalize file " << *i << endl;
- file = new Input(*i);
- size = file->GetSize();
- Archive->writeU32(size);
- delete file;
- file = new Input(*i + ".gz");
- copy(file, Archive);
- delete file;
- unlink((*i + ".gz").to_charp());
- }
-}
-
-void process_file(const String & filename) {
- char t;
- int size, old_size;
- cerr << "Processing file " << filename << "... ";
-
- Input * from = new Input(filename);
- Output * to = new Output(filename + ".gz");
-
- to->SetZ();
-
- old_size = from->GetSize();
-
- copy(from, to);
-
- delete to;
- delete from;
-
- filelist.push_back(filename);
-
- from = new Input(filename + ".gz");
- size = from->GetSize() + 4;
- cerr << old_size << " --> " << from->GetSize() << " (" << 100 * from->GetSize() / old_size << "%)\n";
-
- Archive->writeU32(size);
-
- delete from;
-
- t = 0;
- Archive->writeU8(t);
-}
-
-void process_directory(const String & dirname) throw (GeneralException) {
- struct dirent ** namelist;
- int n, i;
- Uint32 t;
- struct stat fstats;
- String fname;
-
- current_dir = dirname;
- n = scandir(dirname.to_charp(), &namelist, NULL, sortdir);
- cerr << "Processing directory " << dirname << endl;
-
- if (n < 0) {
- throw GeneralException("Unable to open directory " + dirname);
- }
-
- for (i = 0; i < n; i++) {
- fname = dirname + "/" + namelist[i]->d_name;
- stat(fname.to_charp(), &fstats);
- if (S_ISDIR(fstats.st_mode)) {
- if (!Regex("^\\.{1,2}$").Match(namelist[i]->d_name)) {
- t = strlen(namelist[i]->d_name);
- Archive->writeU8(t);
- Archive->write(namelist[i]->d_name, t);
- t = 0;
- Archive->writeU32(t);
- t = 1;
- Archive->writeU8(t);
- process_directory(dirname + "/" + namelist[i]->d_name);
- }
- } else {
- if (!Regex("\\.gz$").Match(namelist[i]->d_name)) {
- t = strlen(namelist[i]->d_name);
- Archive->writeU8(t);
- Archive->write(namelist[i]->d_name, t);
- process_file(dirname + "/" + namelist[i]->d_name);
- }
- }
- free((void *)namelist[i]);
- }
-
- free((void *)namelist);
-
- t = 0;
- Archive->writeU8(t);
-}
-
-void build_archive(const String & dirname) {
- char buff[4];
-
- *((int *) buff) = SIGNATURE;
-
- Archive->write(buff, 4);
-
- process_directory(dirname);
-
- finalize();
-}
-
-public:
-
-virtual int startup(void) throw (GeneralException) {
- Archive = new Output("/tmp/bleh.paq");
- build_archive(".");
- return 0;
-}
-CODE_ENDS
+#include <dirent.h>
+#include <unistd.h>
+#include <iostream.h>
+#include <list>
+#include <Main.h>
+#include <Input.h>
+#include <Output.h>
+#include <Regex.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define SIGNATURE 0x4e504151
+#else
+#define SIGNATURE 0x5141504e
+#endif
+
+String current_dir;
+
+extern "C" int sortdir(const void * d1, const void * d2) {
+ struct stat fstats1, fstats2;
+ String n;
+
+ n = current_dir + "/" + (**((const dirent **)d1)).d_name;
+ stat(n.to_charp(), &fstats1);
+
+ n = current_dir + "/" + (**((const dirent **)d2)).d_name;
+ stat(n.to_charp(), &fstats2);
+
+ if (!((S_ISDIR(fstats1.st_mode) ? 1 : 0) ^ (S_ISDIR(fstats2.st_mode) ? 1 : 0))) {
+ return alphasort(d1, d2);
+ } else {
+ if (S_ISDIR(fstats1.st_mode))
+ return -1;
+ else
+ return 1;
+ }
+}
+
+CODE_BEGINS
+
+private:
+
+struct couple {
+ String p, v;
+};
+
+Output * Archive;
+
+std::list<String> filelist;
+
+void finalize(void) {
+ int size;
+ Input * file;
+ for (std::list<String>::iterator i = filelist.begin(); i != filelist.end(); i++) {
+ cerr << "Finalize file " << *i << endl;
+ file = new Input(*i);
+ size = file->GetSize();
+ Archive->writeU32(size);
+ delete file;
+ file = new Input(*i + ".gz");
+ copy(file, Archive);
+ delete file;
+ unlink((*i + ".gz").to_charp());
+ }
+}
+
+void process_file(const String & filename) {
+ char t;
+ int size, old_size;
+ cerr << "Processing file " << filename << "... ";
+
+ Input * from = new Input(filename);
+ Output * to = new Output(filename + ".gz");
+
+ to->SetZ();
+
+ old_size = from->GetSize();
+
+ copy(from, to);
+
+ delete to;
+ delete from;
+
+ filelist.push_back(filename);
+
+ from = new Input(filename + ".gz");
+ size = from->GetSize() + 4;
+ cerr << old_size << " --> " << from->GetSize() << " (" << 100 * from->GetSize() / old_size << "%)\n";
+
+ Archive->writeU32(size);
+
+ delete from;
+
+ t = 0;
+ Archive->writeU8(t);
+}
+
+void process_directory(const String & dirname) throw (GeneralException) {
+ struct dirent ** namelist;
+ int n, i;
+ Uint32 t;
+ struct stat fstats;
+ String fname;
+
+ current_dir = dirname;
+ n = scandir(dirname.to_charp(), &namelist, NULL, sortdir);
+ cerr << "Processing directory " << dirname << endl;
+
+ if (n < 0) {
+ throw GeneralException("Unable to open directory " + dirname);
+ }
+
+ for (i = 0; i < n; i++) {
+ fname = dirname + "/" + namelist[i]->d_name;
+ stat(fname.to_charp(), &fstats);
+ if (S_ISDIR(fstats.st_mode)) {
+ if (!Regex("^\\.{1,2}$").Match(namelist[i]->d_name)) {
+ t = strlen(namelist[i]->d_name);
+ Archive->writeU8(t);
+ Archive->write(namelist[i]->d_name, t);
+ t = 0;
+ Archive->writeU32(t);
+ t = 1;
+ Archive->writeU8(t);
+ process_directory(dirname + "/" + namelist[i]->d_name);
+ }
+ } else {
+ if (!Regex("\\.gz$").Match(namelist[i]->d_name)) {
+ t = strlen(namelist[i]->d_name);
+ Archive->writeU8(t);
+ Archive->write(namelist[i]->d_name, t);
+ process_file(dirname + "/" + namelist[i]->d_name);
+ }
+ }
+ free((void *)namelist[i]);
+ }
+
+ free((void *)namelist);
+
+ t = 0;
+ Archive->writeU8(t);
+}
+
+void build_archive(const String & dirname) {
+ char buff[4];
+
+ *((int *) buff) = SIGNATURE;
+
+ Archive->write(buff, 4);
+
+ process_directory(dirname);
+
+ finalize();
+}
+
+public:
+
+virtual int startup(void) throw (GeneralException) {
+ Archive = new Output("/tmp/bleh.paq");
+ build_archive(".");
+ return 0;
+}
+CODE_ENDS