lynx-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

lynx-dev -nozap, poor man's scripting - patch and example


From: Klaus Weide
Subject: lynx-dev -nozap, poor man's scripting - patch and example
Date: Sun, 31 Oct 1999 13:25:41 -0600 (CST)

Here is a fun little feature...

I can live with it not getting included in the mainstream, if people
feel this is too frivolous or improper.  I think it's useful though.
it answers to some recent questions; I assume the mystery in the
recently posted expect script

  send -- "/";        # not sure why, but need to send '/' twice here
  send -- "/"

(cf. "Scripting LYNX to follow links" thread) is resolved by it.

Don't get misled by the lenght of the message, the actual code change
isn't much longer (or is shorter) than the explanation...

* Added -nozap command line option.  In its basic form, it disables
  all checks for 'z' or ^G or other "immediate" keys that otherwise
  happen while processing a request (for name lookups, before or during
  loading of a document).  Note that it also disables paging through
  an incompletely loaded document during "partial display".  Normally,
  i.e. without this option, key input gets "swallowed" or "used up"
  by the quasi-asynchronous checks even if they are not 'z' etc. or
  keys that have meaning during partial display (meaningless keys just
  get ignored).  With this option, key input only gets read when lynx
  is ready to act on it.
  This can be used (a) by people who like to always have predictable
  type-ahead (and don't care for 'z'apping and partial display scrolling),
  (b) to achieve predictable reaction to keys if lynx is used under some
  scripting environment that feeds it input like expect, and (c) for
  scripting a lynx session by feeding it keyboard-like character input
  via input redirection from a file or pipe (a simpler alternative to b,
  without the need for expect or similar).
  Point (c) could be called "poor man's scripting".  Note that the input
  has to be provided in a raw form (as lynx would see it when it is
  actually sent by keys), including raw control characters and escape
  sequences if necessary.  This patch does not change anything in the
  way such input is read and parsed, other that what is explicitly
  described here.  (This paragraph is only here to explain the context,
  it does not describe new features.)  P.m.s. will only work as expected
  if lynx, on a given platform and with the display library chosen, uses
  standard input for reading keyboard input.  This is the case with
  ncurses and possibly other curses implementations, but not with slang,
  on Unix-like platforms, and cannot work on platforms where lynx gets
  keyboard input in the form of platform- or implementation-specific
  keycodes (DOS, Windows - except with cygwin?) instead of as an octet
  stream.
  The -nozap option takes an argument.  The basic functionality as already
  described gets invoked if the argument is not a specially recognized
  keyword (it is suggested that -nozap=full or -nozap=all be used).  The
  only recognized keyword is "initially".  With -nozap=initially, additional
  special behavior is invoked the first time (and *only* the first time)
  when lynx encounters an error or EOF when reading key input.  (Currently
  this will not get detected if slang with USE_KEYMAPS is used.)  In this,
  case, -nozap reverts to the default state ('z' will be ckecked for again).
  Under some conditions are true (key input was taken from stdin, and
  stdin was not connected to a terminal), lynx will then attempt to reopen
  stdin, connecting it to a terminal (stdout, stderr, and the process's
  controlling tty are tried, in that order - this is subject to change
  if something would be more reasonable).
  The -nozap=initially special behavior will get triggered if input comes
  from a file or pipe (p.m.s. above) when the provided characters are
  "used up".  Normally lynx should then just exit.  The special behavior
  hands control of the session to the interactive user instead at that point.
  All code for -nozap is only compiled in if preprocessor symbol MISC_EXP is
  explicitly defined.

I don't know how portable the "special behavior" (reopening stdin) is.  It
may not make sense on anything but Unix-like systems (but that may include
cygwin).  I tried to avoid Unix-specific conventions like "/dev/tty".  I
encourage folks to at least try to compile with -DMISC_EXP for those
platforms, and ifdef out stuff that doesn't work.  The "basic" 'z'
suppression may also be useful e.g. on Windows for mouse- pasting and replay
of macros (or whatever it's called; Windows 3.1 had something like it...)

A simple shell script to demonstrate poor man's scripting is appended
after the patch.  Note once more, this won't work with slang.

   Klaus

Index: 2.16/src/LYUtils.c
--- 2.16/src/LYUtils.c Tue, 26 Oct 1999 00:56:20 -0500
+++ 2.16(w)/src/LYUtils.c Thu, 28 Oct 1999 19:07:57 -0500
@@ -2111,7 +2111,7 @@
     return;
 }
 
-#ifdef NSL_FORK
+#if defined(NSL_FORK) || defined(MISC_EXP)
 /*
  *  Returns the file descriptor from which keyboard input is expected,
  *  or INVSOC (-1) if not available.
@@ -2146,7 +2146,7 @@
     }
     return fd;
 }
-#endif /* NSL_FORK */
+#endif /* NSL_FORK || MISC_EXP */
 
 PRIVATE int fake_zap = 0;
 
@@ -2177,6 +2177,10 @@
     if (dump_output_immediately)
        return(TRUE);
 
+#ifdef MISC_EXP
+    if (LYNoZapKey)
+       return(TRUE);
+#endif
     /*
      * Avoid checking interrupts more than one per second, since it is a slow
      * and expensive operation - TD
Index: 2.16/src/LYStrings.c
--- 2.16/src/LYStrings.c Tue, 26 Oct 1999 00:56:20 -0500
+++ 2.16(w)/src/LYStrings.c Fri, 29 Oct 1999 07:07:29 -0500
@@ -1471,6 +1471,50 @@
     }
 #endif /* !USE_SLANG || VMS */
 
+#ifdef MISC_EXP
+    if (LYNoZapKey > 1 && errno != EINTR &&
+       (c == EOF
+#ifdef USE_SLANG
+        || c = 0xFFFF
+#endif
+           )) {
+       int fd, kbd_fd;
+       CTRACE((tfp,
+               "nozap: Got EOF, curses %s, stdin is %p, LYNoZapKey reduced 
from %d to 0.\n",
+               LYCursesON ? "on" : "off", stdin, LYNoZapKey));
+       LYNoZapKey = 0;         /* 2 -> 0 */
+       if ((fd = fileno(stdin)) == 0 && !isatty(fd) &&
+           (kbd_fd = LYConsoleInputFD(FALSE)) == fd) {
+           char *term_name;
+           int new_fd = INVSOC;
+           if ((term_name = ttyname(fileno(stdout))) != NULL)
+               new_fd = open(term_name, O_RDONLY);
+           if (new_fd == INVSOC &&
+               (term_name = ttyname(fileno(stderr))) != NULL)
+               new_fd = open(term_name, O_RDONLY);
+           if (new_fd == INVSOC) {
+               term_name = ctermid(NULL);
+               new_fd = open(term_name, O_RDONLY);
+           }
+           CTRACE((tfp, "nozap: open(%s) returned %d.\n", term_name, new_fd));
+           if (new_fd >= 0) {
+               FILE *frp;
+               close(new_fd);
+               freopen(term_name, "r", stdin);
+               CTRACE((tfp,
+               "nozap: freopen(%s,\"r\",stdin) returned %p, stdin is now %p 
with fd %d.\n",
+                       term_name, frp, stdin, fileno(stdin)));
+               if (LYCursesON) {
+                   stop_curses();
+                   start_curses();
+                   refresh();
+               }
+               goto re_read;
+           }
+       }
+    }
+#endif /* MISC_EXP */
+
 #ifdef USE_GETCHAR
     if (c == EOF && errno == EINTR)    /* Ctrl-Z causes EINTR in getchar() */
        goto re_read;
Index: 2.16/src/LYGlobalDefs.h
--- 2.16/src/LYGlobalDefs.h Mon, 25 Oct 1999 09:01:18 -0500
+++ 2.16(w)/src/LYGlobalDefs.h Thu, 28 Oct 1999 19:07:58 -0500
@@ -388,6 +388,10 @@
 extern BOOLEAN LYUseBuiltinSuffixes;
 extern BOOLEAN dont_wrap_pre;
 
+#ifdef MISC_EXP
+extern int LYNoZapKey;  /* 0: off (do 'z' checking), 1: full, 2: initially */
+#endif
+
 #ifdef EXP_JUSTIFY_ELTS
 extern BOOL ok_justify;
 #endif
Index: 2.16/src/LYMain.c
--- 2.16/src/LYMain.c Mon, 25 Oct 1999 16:08:27 -0500
+++ 2.16(w)/src/LYMain.c Thu, 28 Oct 1999 19:07:55 -0500
@@ -464,6 +464,10 @@
 PUBLIC BOOLEAN LYReuseTempfiles = FALSE;
 PUBLIC BOOLEAN LYUseBuiltinSuffixes = TRUE;
 
+#ifdef MISC_EXP
+PUBLIC int LYNoZapKey = 0; /* 0: off (do z checking), 1: full, 2: initially */
+#endif
+
 /* These are declared in cutil.h for current freeWAIS libraries. - FM */
 #ifdef DECLARE_WAIS_LOGFILES
 PUBLIC char *log_file_name = NULL; /* for WAIS log file name   in libWWW */
@@ -2710,6 +2714,21 @@
    return 0;
 }
 
+#ifdef MISC_EXP
+/* -nozap */
+static int nozap_fun ARGS1(
+       char *,                 next_arg)
+{
+    LYNoZapKey = 1; /* everything but "initially" treated as "full" - kw */
+    if (next_arg != 0) {
+       if (strcasecomp(next_arg, "initially") == 0)
+           LYNoZapKey = 2;
+       
+    }
+   return 0;
+}
+#endif /* MISC_EXP */
+
 /* -pauth */
 static int pauth_fun ARGS1(
        char *,                 next_arg)
@@ -3314,6 +3333,12 @@
       "nounderline",   FUNCTION_ARG,           nounderline_fun,
       "disable underline video-attribute"
    ),
+#ifdef MISC_EXP
+   PARSE_FUN(
+      "nozap",         FUNCTION_ARG,           nozap_fun,
+      "=DURATION (\"initially\" or \"full\") disable checks for 'z' key"
+   ),
+#endif
    PARSE_SET(
       "number_fields", SET_ARG,                &number_fields,
       "force numbering of links as well as form input fields"
@@ -3590,9 +3615,13 @@
 
     fprintf (stdout, gettext("USAGE: %s [options] [file]\n"), pgm);
     fprintf (stdout, gettext("Options are:\n"));
+#ifdef VMS
     print_help_strings("",
 "receive the arguments from stdin (enclose\n\
 in double-quotes (\"-\") on VMS)", NULL);
+#else
+    print_help_strings("", "receive options and arguments from stdin", NULL);
+#endif /* VMS */
 
     for (p = Arg_Table; p->name != 0; p++) {
        char temp[LINESIZE], *value = temp;



========== Now the example script ============

Save as file "lynxgo" (or whatever),
CHANGE THE PATH TO lynx ON THE LAST LINE, (and take out the 3 lines before
                                        that, they're just for debugging)
make it executable.

------------------ snip --------------------
#! /bin/sh
# lynxgo - starts interactive lynx, pre-loads a bunch of files or URLs
#          passed on the command line, hands control to user
# Needs patched lynx compiled with ncurses and -DMISC_EXP
# Call it like (for example)
#   $ lynxgo *.html
# to load all HTML files in the current directory.
#
# address@hidden 1999-10-31
#
OPTS=""
FIRST=""
PUSH=""
while [ $# -ne 0 ]; do
        echo $1
        if [ "${1#-}" != "$1" ]; then
                if [ -z "$OPTS" ]; then
                        OPTS="$1"
                else
                        OPTS="$OPTS $1"
                fi
                if [ "$2" = "on" -o "$2" = "off" -o "$2" = 1 -o "$2" = 0 ]; then
                        OPTS="$OPTS $2"
                        shift
                fi
        else
                if [ -z "$FIRST" -a -z "$PUSH" ]; then
                        FIRST="$1"
                elif [ -z "$PUSH" ]; then
                        PUSH="g$1"'\r'
                else
                        PUSH="${PUSH}g$1"'\r'
                fi
        fi
        shift
done

echo OPTS="$OPTS" FIRST="$FIRST" PUSH="$PUSH"  # debug
sleep 2                                        # debug
set -vx                                        # debug
echo -ne "$PUSH" |/usr/local/src3/lynx2-8-3/src/lynx -nozap=initially $OPTS 
$FIRST


reply via email to

[Prev in Thread] Current Thread [Next in Thread]