aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--bootstrap.am1
-rwxr-xr-xdoc/grosciteco.tes2
-rwxr-xr-xdoc/htbl.tes2
-rw-r--r--doc/sciteco.1.in42
-rw-r--r--src/Makefile.am21
-rw-r--r--src/interface-curses/interface-curses.cpp10
-rw-r--r--src/interface-curses/interface-curses.h4
-rw-r--r--src/interface-gtk/interface-gtk.cpp10
-rw-r--r--src/interface-gtk/interface-gtk.h4
-rw-r--r--src/interface.h7
-rw-r--r--src/main.cpp92
-rwxr-xr-xsrc/symbols-extract.tes2
13 files changed, 149 insertions, 49 deletions
diff --git a/.gitignore b/.gitignore
index 39983d8..2028f73 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,7 @@ testsuite.dir
# Binaries
/src/sciteco
/src/sciteco-minimal
+/src/sciteco-wrapper
# Generated source files
/src/interface-gtk/gtk-info-popup.[ch]
diff --git a/bootstrap.am b/bootstrap.am
index 7ff35d3..bc6f721 100644
--- a/bootstrap.am
+++ b/bootstrap.am
@@ -25,6 +25,7 @@ SUBST_MACRO = eb$<\e \
<fs@PACKAGE_URL^Q@\e@PACKAGE_URL@\e;>j \
<fs@PACKAGE_URL_DEV^Q@\e@PACKAGE_URL_DEV@\e;>j \
<fs@bindir^Q@\e$(bindir)\e;>j \
+ <fs@libexecdir^Q@\e$(libexecdir)\e;>j \
<fs@pkgdatadir^Q@\e$(pkgdatadir)\e;>j \
<fs@scitecolibdir^Q@\e$(scitecolibdir)\e;>j \
<fs@TECO_INTEGER^Q@\e@TECO_INTEGER@\e;>j \
diff --git a/doc/grosciteco.tes b/doc/grosciteco.tes
index d84c6ab..7be01fb 100755
--- a/doc/grosciteco.tes
+++ b/doc/grosciteco.tes
@@ -1,4 +1,4 @@
-#!/usr/bin/env sciteco -m
+#!/usr/local/bin/sciteco -m
!* grosciteco.tes <output-woman> <output-tec> <input> *!
!* Process command-line options *!
diff --git a/doc/htbl.tes b/doc/htbl.tes
index 4118e55..fced7e7 100755
--- a/doc/htbl.tes
+++ b/doc/htbl.tes
@@ -1,4 +1,4 @@
-#!/usr/bin/env sciteco -m
+#!/usr/local/bin/sciteco -m
!* htbl.tes <input> <output> *!
!* Troff tbl "drop-in" replacement *!
diff --git a/doc/sciteco.1.in b/doc/sciteco.1.in
index e6c4d8a..ed3892f 100644
--- a/doc/sciteco.1.in
+++ b/doc/sciteco.1.in
@@ -17,10 +17,11 @@ Scintilla-based \fBT\fPext \fBE\fPditor and \fBCO\fPrrector
.SY @PACKAGE@
.OP "-h|--help"
.OP "-e|--eval" macro
-.OP "-m|--mung" file
+.OP "-m|--mung"
.OP "--no-profile"
.RI [ "UI option .\|.\|." ]
.OP "--"
+.RI [ script ]
.RI [ "argument .\|.\|." ]
.YS
.
@@ -40,26 +41,46 @@ natively supports Microsoft Windows NT\*(Tm.
.LP
.SCITECO_TOPIC mung
When executed, \*(ST mungs (executes) the TECO macro stored in the file
-specified by the
+specified in the \fIscript\fP argument if
.B "--mung"
-option or the macro specified via
+is given or the macro specified via
.B "--eval"
respectively.
Munged files and macros are executed in non-interactive (\fIbatch\fP)
mode, allowing the user to write stand-alone TECO scripts.
Only when munging files as opposed to other means of executing macros,
-the first line is ignored if it begins with \(lq#!\(rq.
+the first line is ignored if it begins with a \(lq#\(rq (hash sign).
Therefore under UNIX-like operating systems, TECO macro files may be
invoked as scripts by using a Hash-Bang line like
.\" FIXME: We'd like to include #! as a topic, but ! character are currently
.\" not allowed since they are not escaped correctly.
.SCITECO_TOPIC scripting
.RS
-.SCITECO_TT
.EX
+.SCITECO_TT
#!@bindir@/sciteco -m
+.SCITECO_TT_END
.EE
+.RE
+.
+.LP
+Note that UNIX Hash-Bang lines will only pass a \fBsingle\fP argument to the
+interpreter before the script's file name, so all required \*(ST options must
+be mangled into a single argument with their single-letter names.
+Passing option-like arguments (beginning with a dash) to scripts may cause
+problems because \*(ST might try to interpret these options.
+Beginning with Glib 2.44, \*(ST thus stops parsing at the first non-option
+argument (which will always be the munged file name in a script invocation).
+For binaries linked against older versions of Glib, \*(ST works around this
+issue by providing a wrapper script that can be used in place of the main
+executable.
+A portable Hash-Bang line should thus look like:
+.RS
+.EX
+.SCITECO_TT
+#!@libexecdir@/sciteco-wrapper -m
.SCITECO_TT_END
+.EE
.RE
.
.LP
@@ -69,6 +90,8 @@ All command line arguments after the \*(ST options are passed as
.I arguments
to the munged macro by placing each argument on its own line in
the buffer.
+The \fIscript\fP file name expected when \(lq--mung\(rq is given
+is currently \fBnot\fP considered a macro argument.
In any case the current buffer position (called
.IR dot )
is left at the beginning of the buffer.
@@ -137,6 +160,8 @@ option is absent, \*(ST will mung
On UNIX/Linux, the default profile is at
.I ~/.teco_ini
(see \fBENVIRONMENT\fP).
+It will consequently not expect a \fIscript\fP file name as
+the first non-option argument.
The profile will usually set up various Scintilla and \*(ST options,
configure syntax highlighting,
define commonly used macros and open files specified as arguments to \*(ST.
@@ -160,9 +185,12 @@ Similar to munging but always exits afterwards.
If the option is specified, the
.B \-\-mung
option has no effect.
-.IP "\fB-m\fR, \fB--mung\fR \fIfile"
+.IP "\fB-m\fR, \fB--mung\fR"
.SCITECO_TOPIC "-m" "--mung"
-Mung \fIfile\fP.
+Mung \fIscript\fP.
+The script file name is expected as the first non-option
+argument, so it does not necessarily have to follow the
+\fB--mung\fP option.
Default is
.IR $SCITECOCONFIG/.teco_ini .
.IP "\fB--no-profile\fP"
diff --git a/src/Makefile.am b/src/Makefile.am
index 314faa4..72e9157 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -76,10 +76,27 @@ CLEANFILES = $(BUILT_SOURCES) \
symbols-scintilla.cpp : @SCINTILLA_PATH@/include/Scintilla.h \
symbols-extract.tes
- $(SCITECO_MINIMAL) -m @srcdir@/symbols-extract.tes \
+ $(SCITECO_MINIMAL) -m -- @srcdir@/symbols-extract.tes \
$< $@ "SCI_" scintilla
symbols-scilexer.cpp : @SCINTILLA_PATH@/include/SciLexer.h \
symbols-extract.tes
- $(SCITECO_MINIMAL) -m @srcdir@/symbols-extract.tes \
+ $(SCITECO_MINIMAL) -m -- @srcdir@/symbols-extract.tes \
$< $@ "SCLEX_,SCE_" scilexer
+
+# This installs a wrapper script to libexecdir to be used as
+# the SciTECO interpreter in Hash-Bang lines.
+# It makes sure that option parsing is disabled for all
+# script arguments which is necessary for builds against Glib < 2.44.
+# NOTE: When we raise the Glib requirement to 2.44, the sciteco-wrapper
+# workaround can be removed completely.
+libexec_SCRIPTS = sciteco-wrapper
+CLEANFILES += $(libexec_SCRIPTS)
+
+.PHONY: sciteco-wrapper
+sciteco-wrapper:
+ echo '#!/bin/sh' >$@
+ echo 'OPT=$$1;' \
+ 'shift;' \
+ "exec $(bindir)/`echo sciteco | @SED@ '$(transform)'`$(EXEEXT)" \
+ '"$$OPT" -- $$@' >>$@
diff --git a/src/interface-curses/interface-curses.cpp b/src/interface-curses/interface-curses.cpp
index d592b89..5e5b8d8 100644
--- a/src/interface-curses/interface-curses.cpp
+++ b/src/interface-curses/interface-curses.cpp
@@ -312,7 +312,7 @@ InterfaceCurses::InterfaceCurses() : stdout_orig(-1), stderr_orig(-1),
}
void
-InterfaceCurses::main_impl(int &argc, char **&argv)
+InterfaceCurses::init(void)
{
/*
* We must register this handler to handle
@@ -518,12 +518,16 @@ InterfaceCurses::init_screen(void)
* This sets the program name to "SciTECO"
* which may then also be used as the X11 class name
* for overwriting X11 resources in .Xdefaults
+ *
* FIXME: We could support passing in resource
* overrides via the SciTECO command line.
* But unfortunately, Xinitscr() is called too
- * late to modify argc/argv for command-line parsing.
+ * late to modify argc/argv for command-line parsing
+ * (and GOption needs to know about the additional
+ * possible arguments since they are not passed through
+ * transparently).
* Therefore this could only be supported by
- * adding a special option like --resource.
+ * adding a special option like --resource KEY=VAL.
*/
Xinitscr(1, (char **)argv);
}
diff --git a/src/interface-curses/interface-curses.h b/src/interface-curses/interface-curses.h
index d036d37..a0198cc 100644
--- a/src/interface-curses/interface-curses.h
+++ b/src/interface-curses/interface-curses.h
@@ -121,8 +121,8 @@ public:
InterfaceCurses();
~InterfaceCurses();
- /* implementation of Interface::main() */
- void main_impl(int &argc, char **&argv);
+ /* override of Interface::init() */
+ void init(void);
/* override of Interface::init_color() */
void init_color(guint color, guint32 rgb);
diff --git a/src/interface-gtk/interface-gtk.cpp b/src/interface-gtk/interface-gtk.cpp
index 4ef0b38..920f01b 100644
--- a/src/interface-gtk/interface-gtk.cpp
+++ b/src/interface-gtk/interface-gtk.cpp
@@ -183,7 +183,12 @@ InterfaceGtk::get_options(void)
{NULL}
};
- GOptionGroup *group = gtk_get_option_group(TRUE);
+ /*
+ * Parsing the option context with the Gtk option group
+ * will automatically initialize Gtk, so gtk_init()
+ * does not have to be called.
+ */
+ GOptionGroup *group = gtk_get_option_group(FALSE);
g_option_group_add_entries(group, entries);
@@ -191,7 +196,7 @@ InterfaceGtk::get_options(void)
}
void
-InterfaceGtk::main_impl(int &argc, char **&argv)
+InterfaceGtk::init(void)
{
static const Cmdline empty_cmdline;
@@ -208,7 +213,6 @@ InterfaceGtk::main_impl(int &argc, char **&argv)
g_thread_init(NULL);
#endif
gdk_threads_init();
- gtk_init(&argc, &argv);
/*
* Register clipboard registers.
diff --git a/src/interface-gtk/interface-gtk.h b/src/interface-gtk/interface-gtk.h
index 0145ff4..a19d253 100644
--- a/src/interface-gtk/interface-gtk.h
+++ b/src/interface-gtk/interface-gtk.h
@@ -113,8 +113,8 @@ public:
/* overrides Interface::get_options() */
GOptionGroup *get_options(void);
- /* implementation of Interface::main() */
- void main_impl(int &argc, char **&argv);
+ /* override of Interface::init() */
+ void init(void);
/* implementation of Interface::vmsg() */
void vmsg_impl(MessageType type, const gchar *fmt, va_list ap);
diff --git a/src/interface.h b/src/interface.h
index 98254ac..e841680 100644
--- a/src/interface.h
+++ b/src/interface.h
@@ -194,11 +194,8 @@ public:
return NULL;
}
- inline void
- main(int &argc, char **&argv)
- {
- impl().main_impl(argc, argv);
- }
+ /* default implementation */
+ inline void init(void) {}
/* makes sense only on Curses */
inline void init_color(guint color, guint32 rgb) {}
diff --git a/src/main.cpp b/src/main.cpp
index d14e2e5..e9be929 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -75,7 +75,7 @@ namespace Flags {
}
static gchar *eval_macro = NULL;
-static gchar *mung_file = NULL;
+static gboolean mung_file = FALSE;
static gboolean mung_profile = TRUE;
sig_atomic_t sigint_occurred = FALSE;
@@ -165,29 +165,31 @@ get_default_config_path(const gchar *program)
#endif
-static inline void
+static inline gchar *
process_options(int &argc, char **&argv)
{
static const GOptionEntry option_entries[] = {
{"eval", 'e', 0, G_OPTION_ARG_STRING, &eval_macro,
"Evaluate macro", "macro"},
- {"mung", 'm', 0, G_OPTION_ARG_FILENAME, &mung_file,
- "Mung file instead of "
- "$SCITECOCONFIG" G_DIR_SEPARATOR_S INI_FILE, "file"},
+ {"mung", 'm', 0, G_OPTION_ARG_NONE, &mung_file,
+ "Mung script file (first non-option argument) instead of "
+ "$SCITECOCONFIG" G_DIR_SEPARATOR_S INI_FILE},
{"no-profile", 0, G_OPTION_FLAG_REVERSE,
G_OPTION_ARG_NONE, &mung_profile,
"Do not mung "
- "$SCITECOCONFIG" G_DIR_SEPARATOR_S INI_FILE
- " even if it exists"},
+ "$SCITECOCONFIG" G_DIR_SEPARATOR_S INI_FILE " "
+ "even if it exists"},
{NULL}
};
+ gchar *mung_filename = NULL;
+
GError *gerror = NULL;
GOptionContext *options;
GOptionGroup *interface_group = interface.get_options();
- options = g_option_context_new("[--] [ARGUMENT...]");
+ options = g_option_context_new("[--] [SCRIPT] [ARGUMENT...]");
g_option_context_set_summary(
options,
@@ -203,6 +205,21 @@ process_options(int &argc, char **&argv)
if (interface_group)
g_option_context_add_group(options, interface_group);
+#if GLIB_CHECK_VERSION(2,44,0)
+ /*
+ * If possible we parse in POSIX mode, which means that
+ * the first non-option argument terminates option parsing.
+ * SciTECO considers all non-option arguments to be script
+ * arguments and it makes little sense to mix script arguments
+ * with SciTECO options, so this lets the user avoid "--"
+ * in many situations.
+ * It is also strictly required to make hash-bang lines like
+ * #!/usr/bin/sciteco -m
+ * work (see sciteco(1)).
+ */
+ g_option_context_set_strict_posix(options, TRUE);
+#endif
+
if (!g_option_context_parse(options, &argc, &argv, &gerror)) {
g_fprintf(stderr, "Option parsing failed: %s\n",
gerror->message);
@@ -212,15 +229,41 @@ process_options(int &argc, char **&argv)
g_option_context_free(options);
+ /*
+ * GOption will NOT remove "--" if followed by an
+ * option-argument, which may interfer with scripts
+ * doing their own option handling and interpreting "--".
+ *
+ * NOTE: This is still true if we're parsing in GNU-mode
+ * and "--" is not the first non-option argument as in
+ * sciteco foo -- -C bar.
+ */
+ if (argc >= 2 && !strcmp(argv[1], "--")) {
+ argv[1] = argv[0];
+ argv++;
+ argc--;
+ }
+
if (mung_file) {
- if (!g_file_test(mung_file, G_FILE_TEST_IS_REGULAR)) {
+ if (argc < 2) {
+ g_fprintf(stderr, "Script to mung expected!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (!g_file_test(argv[1], G_FILE_TEST_IS_REGULAR)) {
g_fprintf(stderr, "Cannot mung \"%s\". File does not exist!\n",
- mung_file);
+ argv[1]);
exit(EXIT_FAILURE);
}
+
+ mung_filename = g_strdup(argv[1]);
+
+ argv[1] = argv[0];
+ argv++;
+ argc--;
}
- /* remaining arguments, are arguments to the interface */
+ return mung_filename;
}
static inline void
@@ -369,6 +412,8 @@ main(int argc, char **argv)
realloc /* try_realloc */
};
+ gchar *mung_filename;
+
#ifdef DEBUG_PAUSE
/* Windows debugging hack (see above) */
system("pause");
@@ -379,9 +424,12 @@ main(int argc, char **argv)
g_mem_set_vtable(&vtable);
- process_options(argc, argv);
- interface.main(argc, argv);
- /* remaining arguments are arguments to the munged file */
+ mung_filename = process_options(argc, argv);
+ /*
+ * All remaining arguments in argv are arguments
+ * to the macro or munged file.
+ */
+ interface.init();
/*
* QRegister view must be initialized only now
@@ -405,7 +453,7 @@ main(int argc, char **argv)
ring.edit((const gchar *)NULL);
/* add remaining arguments to unnamed buffer */
- for (int i = 1; i < argc; i++) {
+ for (gint i = 1; i < argc; i++) {
/*
* FIXME: arguments may contain line-feeds.
* Once SciTECO is 8-byte clear, we can add the
@@ -435,15 +483,15 @@ main(int argc, char **argv)
exit(EXIT_SUCCESS);
}
- if (!mung_file && mung_profile)
+ if (!mung_filename && mung_profile)
/* NOTE: Still safe to use g_getenv() */
- mung_file = g_build_filename(g_getenv("SCITECOCONFIG"),
- INI_FILE, NIL);
+ mung_filename = g_build_filename(g_getenv("SCITECOCONFIG"),
+ INI_FILE, NIL);
- if (mung_file &&
- g_file_test(mung_file, G_FILE_TEST_IS_REGULAR)) {
+ if (mung_filename &&
+ g_file_test(mung_filename, G_FILE_TEST_IS_REGULAR)) {
try {
- Execute::file(mung_file, false);
+ Execute::file(mung_filename, false);
} catch (Quit) {
/*
* ^C invoked, quit hook should still
@@ -456,7 +504,6 @@ main(int argc, char **argv)
exit(EXIT_SUCCESS);
}
}
- g_free(mung_file);
} catch (Error &error) {
error.display_full();
exit(EXIT_FAILURE);
@@ -495,5 +542,6 @@ main(int argc, char **argv)
exit(EXIT_FAILURE);
}
+ g_free(mung_filename);
return 0;
}
diff --git a/src/symbols-extract.tes b/src/symbols-extract.tes
index 2a6664c..e81331a 100755
--- a/src/symbols-extract.tes
+++ b/src/symbols-extract.tes
@@ -1,4 +1,4 @@
-#!./sciteco-minimal -m
+#!/usr/local/bin/sciteco -m
! ./symbols-extract.tes <input file> <output file> <prefix pattern list> <array name> !
EMQ[$SCITECOPATH]/string.tes