summaryrefslogtreecommitdiffstats
path: root/src/sed/sed/sed.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sed/sed/sed.c')
-rw-r--r--src/sed/sed/sed.c455
1 files changed, 455 insertions, 0 deletions
diff --git a/src/sed/sed/sed.c b/src/sed/sed/sed.c
new file mode 100644
index 0000000..b3bc2ea
--- /dev/null
+++ b/src/sed/sed/sed.c
@@ -0,0 +1,455 @@
+#define COPYRIGHT_NOTICE "Copyright (C) 2003 Free Software Foundation, Inc."
+#define BUG_ADDRESS "bonzini@gnu.org"
+
+/* GNU SED, a batch stream editor.
+ Copyright (C) 1989,90,91,92,93,94,95,98,99,2002,2003
+ 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+#include "sed.h"
+
+
+#include <stdio.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#else
+# include <string.h>
+#endif /*HAVE_STRINGS_H*/
+#ifdef HAVE_MEMORY_H
+# include <memory.h>
+#endif
+
+#ifndef HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+#endif
+
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#include "getopt.h"
+
+#ifndef BOOTSTRAP
+#ifndef HAVE_STDLIB_H
+ extern char *getenv P_((const char *));
+#endif
+#endif
+
+#ifndef HAVE_STRTOUL
+# define ATOI(x) atoi(x)
+#else
+# define ATOI(x) strtoul(x, NULL, 0)
+#endif
+
+int extended_regexp_flags = 0;
+
+#ifndef CONFIG_WITHOUT_O_OPT
+/* The output file, defaults to stdout but can be overridden
+ by the -o or --output option. main sets this to avoid problems. */
+FILE *sed_stdout = NULL;
+#endif
+
+/* If set, fflush(stdout) on every line output. */
+bool unbuffered_output = false;
+
+/* If set, don't write out the line unless explicitly told to */
+bool no_default_output = false;
+
+/* If set, reset line counts on every new file. */
+bool separate_files = false;
+
+/* How do we edit files in-place? (we don't if NULL) */
+char *in_place_extension = NULL;
+
+/* Do we need to be pedantically POSIX compliant? */
+enum posixicity_types posixicity;
+
+/* How long should the `l' command's output line be? */
+countT lcmd_out_line_len = 70;
+
+/* The complete compiled SED program that we are going to run: */
+static struct vector *the_program = NULL;
+
+static void usage P_((int));
+static void
+usage(status)
+ int status;
+{
+ FILE *out = status ? stderr : stdout;
+
+#ifdef REG_PERL
+#define PERL_HELP _(" -R, --regexp-perl\n use Perl 5's regular expressions syntax in the script.\n")
+#else
+#define PERL_HELP ""
+#endif
+
+ fprintf(out, _("\
+Usage: %s [OPTION]... {script-only-if-no-other-script} [input-file]...\n\
+\n"), myname);
+
+ fprintf(out, _(" -n, --quiet, --silent\n\
+ suppress automatic printing of pattern space\n"));
+ fprintf(out, _(" -e script, --expression=script\n\
+ add the script to the commands to be executed\n"));
+ fprintf(out, _(" -f script-file, --file=script-file\n\
+ add the contents of script-file to the commands to be executed\n"));
+ fprintf(out, _(" -i[SUFFIX], --in-place[=SUFFIX]\n\
+ edit files in place (makes backup if extension supplied)\n"));
+ fprintf(out, _(" -l N, --line-length=N\n\
+ specify the desired line-wrap length for the `l' command\n"));
+#ifndef CONFIG_WITHOUT_O_LANG_C
+ fprintf(out, _(" --codepage=N\n\
+ switches the locale to the given codepage, affecting how\n\
+ input files are treated and outputted\n\
+ windows only, ignored elsewhere\n"));
+# if _MSC_VER >= 1900
+ fprintf(out, _(" --utf8\n\
+ alias for --codepage=.UTF-8\n"));
+# endif
+ fprintf(out, _(" --lang_c\n\
+ specify C locale\n"));
+#endif
+ fprintf(out, _(" --posix\n\
+ disable all GNU extensions.\n"));
+#ifndef CONFIG_WITHOUT_O_OPT
+ fprintf(out, _(" -o, --output=file, --append=file, --output-text=file,\n"));
+ fprintf(out, _(" --output-binary=file, --append-text=file, append-binary=file\n\
+ use the specified file instead of stdout; the first\n\
+ three uses the default text/binary mode.\n"));
+#endif
+ fprintf(out, _(" -r, --regexp-extended\n\
+ use extended regular expressions in the script.\n"));
+ fprintf(out, "%s", PERL_HELP);
+ fprintf(out, _(" -s, --separate\n\
+ consider files as separate rather than as a single continuous\n\
+ long stream.\n"));
+ fprintf(out, _(" -u, --unbuffered\n\
+ load minimal amounts of data from the input files and flush\n\
+ the output buffers more often\n"));
+ fprintf(out, _(" --help display this help and exit\n"));
+ fprintf(out, _(" --version output version information and exit\n"));
+ fprintf(out, _("\n\
+If no -e, --expression, -f, or --file option is given, then the first\n\
+non-option argument is taken as the sed script to interpret. All\n\
+remaining arguments are names of input files; if no input files are\n\
+specified, then the standard input is read.\n\
+\n"));
+ fprintf(out, _("E-mail bug reports to: %s .\n\
+Be sure to include the word ``%s'' somewhere in the ``Subject:'' field.\n"),
+ BUG_ADDRESS, PACKAGE);
+
+ ck_fclose (NULL);
+ exit (status);
+}
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+#ifdef REG_PERL
+# ifndef CONFIG_WITHOUT_O_OPT
+#define SHORTOPTS "snrRue:f:l:i::o:V:"
+# else
+#define SHORTOPTS "snrRue:f:l:i::V:"
+# endif
+#else
+# ifndef CONFIG_WITHOUT_O_OPT
+#define SHORTOPTS "snrue:f:l:i::o:V:"
+# else
+#define SHORTOPTS "snrue:f:l:i::V:"
+# endif
+#endif
+
+ static struct option longopts[] = {
+ {"regexp-extended", 0, NULL, 'r'},
+#ifdef REG_PERL
+ {"regexp-perl", 0, NULL, 'R'},
+#endif
+ {"expression", 1, NULL, 'e'},
+ {"file", 1, NULL, 'f'},
+ {"in-place", 2, NULL, 'i'},
+ {"line-length", 1, NULL, 'l'},
+#ifndef CONFIG_WITHOUT_O_LANG_C
+ {"lang_c", 0, NULL, 'L'},
+ {"codepage", 1, NULL, 305},
+ {"utf8", 0, NULL, 306},
+#endif
+ {"quiet", 0, NULL, 'n'},
+ {"posix", 0, NULL, 'p'},
+ {"silent", 0, NULL, 'n'},
+ {"separate", 0, NULL, 's'},
+ {"unbuffered", 0, NULL, 'u'},
+#ifndef CONFIG_WITHOUT_O_OPT
+ {"output", 1, NULL, 'o'},
+ {"output-binary", 1, NULL, 300},
+ {"output-text", 1, NULL, 301},
+ {"append", 1, NULL, 302},
+ {"append-binary", 1, NULL, 303},
+ {"append-text", 1, NULL, 304},
+#endif
+ {"version", 0, NULL, 'v'},
+ {"help", 0, NULL, 'h'},
+ {NULL, 0, NULL, 0}
+ };
+
+ int opt;
+ int return_code;
+ const char *cols = getenv("COLS");
+#ifdef KBUILD_OS_WINDOWS
+ const char *locale;
+#endif
+
+ initialize_main (&argc, &argv);
+#ifndef CONFIG_WITHOUT_O_OPT
+ sed_stdout = stdout;
+#endif
+#if HAVE_SETLOCALE
+# ifdef KBUILD_OS_WINDOWS
+ locale = setlocale (LC_ALL, "");
+ if (getenv("KMK_SED_CODEPAGE_DEBUG"))
+ fprintf (stderr, "kmk_sed: codepage=%u locale=%s ACP=%u\n",
+ get_crt_codepage(), locale, get_ansi_codepage());
+# else
+ setlocale (LC_ALL, "");
+# endif
+#endif
+ initialize_mbcs ();
+
+#if ENABLE_NLS
+
+ /* Tell program which translations to use and where to find. */
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+#endif
+
+ if (getenv("POSIXLY_CORRECT") != NULL)
+ posixicity = POSIXLY_CORRECT;
+ else
+ posixicity = POSIXLY_EXTENDED;
+
+ /* If environment variable `COLS' is set, use its value for
+ the baseline setting of `lcmd_out_line_len'. The "-1"
+ is to avoid gratuitous auto-line-wrap on ttys.
+ */
+ if (cols)
+ {
+ countT t = ATOI(cols);
+ if (t > 1)
+ lcmd_out_line_len = t-1;
+ }
+
+ myname = *argv;
+ while ((opt = getopt_long(argc, argv, SHORTOPTS, longopts, NULL)) != EOF)
+ {
+ switch (opt)
+ {
+ case 'n':
+ no_default_output = true;
+ break;
+ case 'e':
+ the_program = compile_string(the_program, optarg, strlen(optarg));
+ break;
+ case 'f':
+ the_program = compile_file(the_program, optarg);
+ break;
+
+ case 'i':
+ separate_files = true;
+ if (optarg == NULL)
+ /* use no backups */
+ in_place_extension = ck_strdup ("*");
+
+ else if (strchr(optarg, '*') != NULL)
+ in_place_extension = ck_strdup(optarg);
+
+ else
+ {
+ in_place_extension = MALLOC (strlen(optarg) + 2, char);
+ in_place_extension[0] = '*';
+ strcpy (in_place_extension + 1, optarg);
+ }
+
+ break;
+
+ case 'l':
+ lcmd_out_line_len = ATOI(optarg);
+ break;
+
+#ifndef CONFIG_WITHOUT_O_LANG_C
+ case 'L':
+# ifdef KBUILD_OS_WINDOWS
+ locale = setlocale (LC_ALL, "C");
+ if (getenv("KMK_SED_CODEPAGE_DEBUG"))
+ fprintf (stderr, "kmk_sed: codepage=%u locale=%s ACP=%u\n",
+ get_crt_codepage(), locale, get_ansi_codepage());
+# else
+ setlocale (LC_ALL, "C");
+# endif
+ initialize_mbcs ();
+# if ENABLE_NLS
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+# endif
+ break;
+
+ case 306: /* --codepage=N */
+# if _MSC_VER < 1900
+ break; /* does not work, so ignore */
+# else
+ optarg = ".UTF-8";
+# endif
+ /* fall through */
+ case 305: /* --codepage=N */
+ {
+# ifdef KBUILD_OS_WINDOWS
+ char szTmp[64];
+ if (optarg[0] != '.')
+ optarg = strncat (strcpy (szTmp, "."), optarg, sizeof (szTmp) - 1);
+ locale = setlocale (LC_ALL, optarg);
+ if (locale == NULL)
+ fprintf (stderr,
+ _("%s: warning: setlocale (LC_ALL, \"%s\") failed: %d\n"),
+ myname, optarg, errno);
+ else if (getenv("KMK_SED_CODEPAGE_DEBUG"))
+ fprintf (stderr, "kmk_sed: codepage=%u locale=%s ACP=%u\n",
+ get_crt_codepage(), locale, get_ansi_codepage());
+ initialize_mbcs();
+# if ENABLE_NLS
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+# endif
+# endif
+ break;
+ }
+#endif
+
+#ifndef CONFIG_WITHOUT_O_OPT
+ case 'o':
+ sed_stdout = ck_fopen (optarg, "w", true /* fail on error */);
+ break;
+
+ case 300:
+ sed_stdout = ck_fopen (optarg, "wb", true /* fail on error */);
+ break;
+
+ case 301:
+ sed_stdout = ck_fopen (optarg, "wt", true /* fail on error */);
+ break;
+
+ case 302:
+ sed_stdout = ck_fopen (optarg, "a", true /* fail on error */);
+ break;
+
+ case 303:
+ sed_stdout = ck_fopen (optarg, "ab", true /* fail on error */);
+ break;
+
+ case 304:
+ sed_stdout = ck_fopen (optarg, "at", true /* fail on error */);
+ break;
+#endif
+
+ case 'p':
+ posixicity = POSIXLY_BASIC;
+ break;
+
+ case 'r':
+ if (extended_regexp_flags)
+ usage(4);
+ extended_regexp_flags = REG_EXTENDED;
+ break;
+
+#ifdef REG_PERL
+ case 'R':
+ if (extended_regexp_flags)
+ usage(4);
+ extended_regexp_flags = REG_PERL;
+ break;
+#endif
+
+ case 's':
+ separate_files = true;
+ break;
+
+ case 'u':
+ unbuffered_output = true;
+ break;
+
+ case 'v':
+#ifdef KBUILD_VERSION_MAJOR
+ fprintf(stdout, _("kmk_sed - kBuild version %d.%d.%d\n"
+ "\n"
+ "Based on "),
+ KBUILD_VERSION_MAJOR, KBUILD_VERSION_MINOR, KBUILD_VERSION_PATCH);
+#endif
+#ifdef REG_PERL
+ fprintf(stdout, _("super-sed version %s\n"), VERSION);
+ fprintf(stdout, _("based on GNU sed version %s\n\n"), SED_FEATURE_VERSION);
+#else
+ fprintf(stdout, _("GNU sed version %s\n"), VERSION);
+#endif
+ fprintf(stdout, _("%s\n\
+This is free software; see the source for copying conditions. There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n\
+to the extent permitted by law.\n\
+"), COPYRIGHT_NOTICE);
+
+ ck_fclose (NULL);
+ exit (0);
+ case 'h':
+ usage(0);
+ break;
+ default:
+ usage(4);
+ }
+ }
+
+ if (!the_program)
+ {
+ if (optind < argc)
+ {
+ char *arg = argv[optind++];
+ the_program = compile_string(the_program, arg, strlen(arg));
+ }
+ else
+ usage(4);
+ }
+ check_final_program(the_program);
+
+ return_code = process_files(the_program, argv+optind);
+
+ finish_program(the_program);
+ ck_fclose(NULL);
+
+ return return_code;
+}
+
+#ifdef __HAIKU__ /* mbrtowc is busted, just stub it and pray the input won't ever acutally be multibyte... */
+size_t mbrtowc(wchar_t *pwc, const char *pch, size_t n, mbstate_t *ps)
+{
+ if (!n)
+ return 0;
+ if (pwc)
+ *pwc = *pch;
+ return 1;
+}
+#endif