[comp.sys.apollo] Editing a file through DM edit pad from the shell: dmvi

janick@bnr.ca (Janick Bergeron 1617964) (03/27/90)

Here is a new version of the DM editor I posted a few months ago...

For those who didn't get the first version:

 o dmvi(1) will open a DM edit window on the specified file
   from a shell command line or from within a shell script,
   then (optionaly) wait for the window to be closed before
   continuing.

 o Can be used as default visual editor through EDITOR and VISUAL
   environment variables for programs who support them.


Changes from the previous version:

 o dmvi(1) checks the type of the standard output stream and
   invoke the editor most appropriate for that stream:

   - DM edit pad if it is a pad on the local DM
   - TTYEDITOR/vi(1) if not

   You won't need to fiddle with the EDITOR variable every time
   you get into VT100 mode or crp on another node...

 o "-l <line>" option is gone. Uses "+line" like emacs or vi(1).

jb


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  dmvi.man dmvi.c Makefile
# Wrapped by janick@crk56 on Mon Mar 26 11:07:23 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'dmvi.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dmvi.man'\"
else
echo shar: Extracting \"'dmvi.man'\" \(668 characters\)
sed "s/^X//" >'dmvi.man' <<'END_OF_FILE'
X.TH dmvi 1 "" "" "Apollo User's Manual"
X.SH NAME
dmvi \- Edit a file via a DM edit pad
X.SH USAGE
dmvi [+lineno] [-w] file
X.SH OPTIONS
X.IP "+lineno"
Position cursor at the beginning of line \fIlineno\fP.
X.IP -w
Do not suspend execution until the edit pad is closed.
X.SH DESCRIPTION
X\fIdmvi\fP check the type of the standard output stream
and opens an Display Manager edit pad if it is connected to
a pad on the local DM.
If not, if the environment variable TTYEDITOR is set,
the specified editor will be invoked;
otherwise a default editor (normally vi(1)) is
invoked on the specified file.
The file is created if it does not already exist.
X.SH AUTHOR
X<janick@bnr.ca>
X
END_OF_FILE
if test 668 -ne `wc -c <'dmvi.man'`; then
    echo shar: \"'dmvi.man'\" unpacked with wrong size!
fi
chmod +x 'dmvi.man'
# end of 'dmvi.man'
fi
if test -f 'dmvi.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dmvi.c'\"
else
echo shar: Extracting \"'dmvi.c'\" \(7137 characters\)
sed "s/^X//" >'dmvi.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <strings.h>
X#include <ctype.h>
X#include <apollo/base.h>
X#include <apollo/pad.h>
X#include <apollo/ios.h>
X
X/***************************************************************************\
X**                                                                         **
X**   Function name: getopt()                                               **
X**   Author:        Henry Spencer, UofT                                    **
X**   Coding date:   84/04/28                                               **
X**                                                                         **
X**   Description:                                                          **
X**                                                                         **
X**   Parses argv[] for arguments.                                          **
X**   Works with Whitesmith's C compiler.                                   **
X**                                                                         **
X**   Inputs   - The number of arguments                                    **
X**            - The base address of the array of arguments                 **
X**            - A string listing the valid options (':' indicates an       **
X**              argument to the preceding option is required, a ';'        **
X**              indicates an argument to the preceding option is optional) **
X**                                                                         **
X**   Outputs  - Returns the next option character,                         **
X**              '?' for non '-' arguments                                  **
X**              or ':' when there is no more arguments.                    **
X**                                                                         **
X**   Side Effects + The argument to an option is pointed to by 'optarg'    **
X**                                                                         **
X*****************************************************************************
X**                                                                         **
X**   REVISION HISTORY:                                                     **
X**                                                                         **
X**     DATE           NAME                        DESCRIPTION              **
X**   YY/MM/DD  ------------------   ------------------------------------   **
X**   88/10/20  Janick Bergeron      Returns '?' on unamed arguments        **
X**                                  returns '!' on unknown options         **
X**                                  and 'EOF' only when exhausted.         **
X**   88/11/18  Janick Bergeron      Return ':' when no more arguments      **
X**   89/08/11  Janick Bergeron      Optional optarg when ';' in optstring  **
X**                                                                         **
X\***************************************************************************/
X
char * optarg;          /* Global argument pointer. */
X
char  getopt( argc, argv, optstring)
int     argc;
char ** argv;
char  * optstring;
X{
X  register int    c;
X  register char * place;
X  extern   char * index();
X  static   int    optind = 0;
X  static   char * scan   = NULL;
X
X  optarg = NULL;
X
X  if ( scan == NULL || *scan == '\0') {
X
X    if ( optind == 0 ) optind++;
X    if ( optind >= argc ) return ':';
X
X    optarg = place = argv[ optind++ ];
X    if ( place[ 0 ] != '-' || place[ 1 ] == '\0' ) return '?';
X    if ( place[ 1 ] == '-' && place[ 2 ] == '\0' ) return '?';
X    scan = place + 1;
X  }
X
X  c = *scan++;
X  place = index( optstring, c );
X  if ( place == NULL || c == ':' || c == ';' ) {
X
X    (void) fprintf( stderr, "%s: unknown option %c\n", argv[ 0 ], c );
X    scan = NULL;
X    return '!';
X  }
X  if ( *++place == ':' ) {
X
X    if ( *scan != '\0') {
X
X      optarg = scan;
X      scan = NULL;
X
X    } else {
X
X      if ( optind >= argc ) {
X
X        (void) fprintf( stderr, "%s: %c requires an argument\n",
X                        argv[ 0 ], c );
X        return '!';
X      }
X      optarg = argv[ optind ];
X      optind++;
X    }
X  } else if ( *place == ';' ) {
X
X    if ( *scan != '\0' ) {
X
X      optarg = scan;
X      scan = NULL;
X
X    } else {
X
X      if ( optind >= argc || *argv[ optind ] == '-' ) optarg = NULL;
X      else {
X        optarg = argv[ optind ];
X        optind++;
X      }
X    }
X  }
X  return c;
X}
X
int  main(
X           int     argc,
X           char ** argv
X         )
X{
X  char                 opt;
X  char               * fname = NULL;
X  char               * lineno = NULL;
X  char               * p;
X  char               * bfr;
X  int                  wait = 1;
X  int                  usage = 0;
X  int                  rc = 0;
X  pad_$window_desc_t   window;
X  ios_$id_t            stream;
X  status_$t            status;
X  
X  while( ( opt = getopt( argc, argv, "w" ) ) != ':' ) {
X
X    switch ( opt ) {
X  
X    case 'w':
X      wait = 0;
X      break;
X
X    case '?':
X      if ( *optarg == '+' ) {
X        for( p = optarg+1; *p != '\0'; p++ ) {
X          if ( !isdigit( *p ) ) {
X            fprintf( stderr, "%s: Invalid line number %s.\n", argv[ 0 ], optarg+1 );
X            usage = 1;
X            break;
X          }
X        }
X        if ( *p == '\0' ) lineno = optarg+1;
X      } else if ( fname != NULL ) {
X        fprintf( stderr, "%s: Only one file to edit can be specified.\n", argv[ 0 ] );
X        usage = 1;
X      } else fname = optarg;
X      break;
X
X    default:
X      usage = 1;
X      break;
X    }
X
X  }
X  if ( fname == NULL ) {
X    fprintf( stderr, "%s: No file to edit were specified.\n", argv[ 0 ] );
X    usage = 1;
X  }
X  if ( lineno == NULL ) lineno = "1";
X  if ( usage ) {
X    fprintf( stderr, "Usage: %s [+lineno] [-w] fname\n", argv[ 0 ] );
X    exit( -1 );
X  }
X  
X  /*
X   * Check if the standard output is a pad where we can use the DM editor
X   * Otherwise, use TTYEDITOR or else vi
X   */
X
X  stream = 1;
X  pad_$isa( stream, &status );
X  if (status_$ok != status.all ||
X    (pad_$isa_dm_pad( stream, &status ), status_$ok != status.all)) {
X    if ( !(p=(char*)getenv("TTYEDITOR")) ) p = "/usr/ucb/vi";
X    bfr = (char *) malloc( (strlen(p)+strlen(fname)+2) * sizeof(char) );
X    sprintf( bfr, "%s +%s %s", p, lineno, fname );
X    exit( system(bfr) );
X  }
X
X  /* Create the window in the next DM default region */
X  window.width = window.height = 0;
X  
X  pad_$create_window( fname, strlen( fname ), pad_$edit, 1, window, &stream, &status );
X  if (status_$ok != status.all) {                                                             
X    fprintf( stderr, "could not open:  %s\n" , fname ) ;        
X    exit( 1 );                                                     
X  }                                                             
X  pad_$dm_cmd( stream, lineno, strlen( lineno ), &status );
X  if ( wait ) {
X    pad_$edit_wait( stream, &status );
X    if ( status_$ok != status.all ) {
X      fprintf( stderr, "editing aborted on %s\n", fname );
X      rc = 2;
X    }
X    ios_$close( stream, &status );
X    /* This is necessary because pad_$edit_wait may exit before the file
X     * is actually unlocked (troy@mr_plod.cbme.unsw.oz.au) */
X    sleep(2);
X  }
X  exit( rc );
X}
END_OF_FILE
if test 7137 -ne `wc -c <'dmvi.c'`; then
    echo shar: \"'dmvi.c'\" unpacked with wrong size!
fi
# end of 'dmvi.c'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(202 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
CC         = /bin/cc
CFLAGS     = -O
X
X.c.o:
X	$(CC) -c $(CFLAGS) $*.c
X
install: dmvi dmvi.1
X
dmvi: dmvi.c
X	/bin/cc $(CFLAGS) -o dmvi dmvi.c
X
dmvi.1: dmvi.man
X	nroff -man dmvi.man | swapul | col > dmvi.1
END_OF_FILE
if test 202 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
chmod +x 'Makefile'
# end of 'Makefile'
fi
echo shar: End of shell archive.
exit 0

-- 
Janick Bergeron     Bell-Northern Research, Ltd       Ph.: (613) 763-5457
VHDL Tools            P.O. Box 3511, Station C        Fax: (613) 763-2661
                  Ottawa, Ontario, Canada, K1Y 4H7  Flame: 1-800-DEV-NULL
janick@bnr.ca                     library disclaimer; use disclaimer.all;