VMS like HELP for the PC. Executable in comp.sys.ibm.pc.
Michael A. Shiels
broehl at watale.UUCP
Thu Dec 11 12:48:17 AEST 1986
This is a help program which was written to simulate the VMS help facility
using a directory structure which is traversed. This version also has
alot of customization features and pauses every 24 lines because it uses
the NANSI.SYS raw mode.
I hope I put in all the support routines. It's hard to tell when all I do
is link with my whole library. But it is too big too post!!
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by watale!broehl on Wed Dec 10 21:44:11 EST 1986
# Contents: cd.c cptodlow.c cptolow.x cpy.x denv.x findfile.c fptext.c
# fptext.x getargs.c getargs.h getargs.x help.c help.man help.rc
# helpdir.c helpdir.h intro.txt make.ini makefile masdos.h maserr.h
# mynewlin.x mynewline.def next.c next.x reargv.c reargv.x setraw2.c
# ssort.c ssort.x unargv.c unargv.x
echo x - cd.c
sed 's/^@//' > "cd.c" <<'@//E*O*F cd.c//'
#define LINT_ARGS
#include <stdio.h>
#include <dos.h>
cd( name )
register char *name;
{
union REGS regs;
int todrive,todrive2;
if( name[1] == ':')
{
todrive = toupper(*name) - 'A';
bdos( 0x0E, todrive, 0);
regs.h.ah = 0x19;
regs.h.al = 0x00;
intdos( ®s, ®s );
todrive2 = regs.h.al;
if( todrive != todrive2 )
return( -1 );
name += 2;
}
if( *name && chdir( name ) < 0 )
return( -1 );
return( 0 );
}
chdrv( name )
register char *name;
{
union REGS regs;
int todrive,todrive2;
todrive = toupper(*name) - 'A';
bdos( 0x0E, todrive, 0);
regs.h.ah = 0x19;
regs.h.al = 0x00;
intdos( ®s, ®s );
todrive2 = regs.h.al;
if( todrive != todrive2 )
return( -1 );
return( 0 );
}
@//E*O*F cd.c//
chmod u=rw,g=r,o=r cd.c
echo x - cptodlow.c
sed 's/^@//' > "cptodlow.c" <<'@//E*O*F cptodlow.c//'
char *cptodlower( dest, src )
register char *dest, *src;
{
/* Copy src to dest, mapping all upper case letters to lower
* case. src and dest may be the same.
*/
for(; *src ; src++ )
{
if( *src == '.' )
break;
*dest++ = ('A' <= *src && *src <= 'Z')
? *src + ('a'-'A') : *src ;
}
*dest = '\0' ;
return dest ;
@//E*O*F cptodlow.c//
chmod u=rw,g=r,o=r cptodlow.c
echo x - cptolow.x
sed 's/^@//' > "cptolow.x" <<'@//E*O*F cptolow.x//'
extern char *cptolower( char *, char * );
@//E*O*F cptolow.x//
chmod u=rw,g=r,o=r cptolow.x
echo x - cpy.x
sed 's/^@//' > "cpy.x" <<'@//E*O*F cpy.x//'
extern char *cpy( char *, char * );
@//E*O*F cpy.x//
chmod u=rw,g=r,o=r cpy.x
echo x - denv.x
sed 's/^@//' > "denv.x" <<'@//E*O*F denv.x//'
extern int Dfind_orig( void );
extern int Dfind_size( void );
extern int putdenv( char * );
extern char *getdenv( char * );
@//E*O*F denv.x//
chmod u=rw,g=r,o=r denv.x
echo x - findfile.c
sed 's/^@//' > "findfile.c" <<'@//E*O*F findfile.c//'
#define LINT_ARGS
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <dos.h>
#include "masdos.h"
static struct FILEINFO *Dta_save;
find_first( filespec, attributes, dta )
char *filespec;
unsigned int attributes;
char *dta;
{
union REGS regs;
int ercode;
D_IN("find_first");
regs.x.ax = B_GETDTA;
intdos( ®s, ®s );
Dta_save = (struct FILEINFO *) regs.x.bx;
regs.x.ax = B_SETDTA;
regs.x.dx = dta;
intdos( ®s, ®s );
regs.x.ax = B_FINDFIRST;
regs.x.dx = (int) filespec;
regs.x.cx = attributes;
ercode = intdos( ®s, ®s );
regs.x.ax = B_SETDTA;
regs.x.dx = (unsigned int) Dta_save;
intdos( ®s, ®s );
if( ercode == 0 )
{
D_PRT("find_first","no error");
}
D_OUT("find_first");
return( ercode );
}
int find_next( dta )
char *dta;
{
union REGS regs;
int ercode;
D_IN("find_next");
regs.x.ax = B_GETDTA;
intdos( ®s, ®s );
Dta_save = (struct FILEINFO *) regs.x.bx;
regs.x.ax = B_SETDTA;
regs.x.dx = dta;
intdos( ®s, ®s );
regs.x.ax = B_FINDNEXT;
ercode = intdos( ®s, ®s );
regs.x.ax = B_SETDTA;
regs.x.dx = (unsigned int) Dta_save;
intdos( ®s, ®s );
if( ercode == 0 )
{
D_PRT("find_next","no error");
}
D_OUT("find_next");
return( ercode );
}
ffind_first( filespec, attributes )
char *filespec;
unsigned int attributes;
{
union REGS regs;
int ercode;
D_IN("find_first");
regs.x.ax = B_FINDFIRST;
regs.x.dx = (int) filespec;
regs.x.cx = attributes;
ercode = intdos( ®s, ®s );
if( ercode == 0 )
{
D_PRT("find_first","no error");
}
D_OUT("find_first");
return( ercode );
}
int ffind_next()
{
union REGS regs;
int ercode;
D_IN("find_next");
regs.x.ax = B_FINDNEXT;
ercode = intdos( ®s, ®s );
if( ercode == 0 )
{
D_PRT("find_next","no error");
}
D_OUT("find_next");
return( ercode );
}
void frstdta()
{
union REGS regs;
regs.x.ax = B_SETDTA;
regs.x.dx = (unsigned int) Dta_save;
intdos( ®s, ®s );
}
void fchgdta( dta )
char *dta;
{
union REGS regs;
regs.x.ax = B_GETDTA;
intdos( ®s, ®s );
Dta_save = (struct FILEINFO *) regs.x.bx;
regs.x.ax = B_SETDTA;
regs.x.dx = dta;
intdos( ®s, ®s );
}
@//E*O*F findfile.c//
chmod u=rw,g=r,o=r findfile.c
echo x - fptext.c
sed 's/^@//' > "fptext.c" <<'@//E*O*F fptext.c//'
/*
*
*!AU: Michael A. Shiels
*!CD: 1-Jun-86
*!FR: Dr. Dobbs July 1985
*
*/
#define LINT_ARGS
#include <stdio.h>
#include <signal.h>
#include "masdos.h"
#include "waitfork.x"
#define PTEXT_IBM
static int ptextctrlchit = 0;
static int (*oldsignal)();
static ptextctrlc()
{
ptextctrlchit = 1;
signal( SIGINT, ptextctrlc );
}
/* ptext( dirc, dirv, Arg_Num_Cols, 79 / Arg_Num_Cols,
(dirc/Arg_Num_Cols) + (dirc % Arg_Num_Cols != 0) ); */
fptexth( linec, linev, numcols, colwidth, numrows, where )
int linec, numcols, colwidth;
char **linev;
int numrows;
FILE *where;
{
register int j,i;
register char **lineend, **line, **nextline;
register int linenum = 0;
ptextctrlchit = 0;
oldsignal = signal( SIGINT, ptextctrlc );
for( j = numrows ; --j >= 0 && !ptextctrlchit ; )
{
#ifdef PTEXT_IBM
putc( ' ', where );
#endif
lineend = &linev[numcols - 1];
for( i = numcols ; --i >= 0 && *linev ; linev++ )
{
pr_line( *linev, colwidth,
linev < lineend, where );
}
mynewline( where );
}
fflush( where );
signal( SIGINT, oldsignal );
D_OUT("ptexth");
}
fptextv( linec, linev, numcols, colwidth, numrows, where )
int linec, numcols, colwidth;
char **linev;
int numrows;
FILE *where;
{
register int j;
register char **lineend, **line, **nextline;
register int linenum = 0;
lineend = &linev[linec - 1];
for( j = numrows ; --j >= 0 ; )
{
#ifdef PTEXT_IBM
putc( ' ', where );
#endif
for( line = linev++ ; line <= lineend ; line = nextline )
{
nextline = line + numrows;
pr_line( *line, colwidth,
nextline <= lineend );
}
mynewline( where );
}
D_OUT("ptextv");
}
static pr_line( str, width, padded, where )
register char *str;
int width, padded;
FILE *where;
{
int col = 0;
while( col < width && *str )
{
if( *str == '\n' )
break;
else if( *str == '\r' )
{
while( col > 0 )
{
--col;
putc( '\b', where );
}
str++;
}
else if( *str == '\t' )
{
str++;
col++;
putc( ' ', where );
while( ( col % 8 ) && col < width )
{
putc( ' ', where );
col++;
}
}
else
{
if( *str == Q_ESC )
{
putc( *str++, where );
if( !*str )
break;
putc( *str++, where );
if( !*str )
break;
putc( *str++, where );
if( !*str )
break;
}
else if( *str == '\b' )
--col;
else if( *str >= ' ' )
++col;
putc( *str++, where );
}
}
if( padded )
while( col++ < width )
putc( ' ', where );
}
@//E*O*F fptext.c//
chmod u=rw,g=r,o=r fptext.c
echo x - fptext.x
sed 's/^@//' > "fptext.x" <<'@//E*O*F fptext.x//'
extern int fptexth( int, char **, int, int, int, FILE * );
extern int fptextv( int, char **, int, int, int, FILE * );
@//E*O*F fptext.x//
chmod u=rw,g=r,o=r fptext.x
echo x - getargs.c
sed 's/^@//' > "getargs.c" <<'@//E*O*F getargs.c//'
/*
*
* Getargs.c
*
*!AU: Michael A. Shiels
*!CD: 21-May-86
*!FR: Dr. Dobb's May 1985
*
*/
#define GETARGS_C
#define LINT_ARGS
#include <stdio.h>
#include <stdlib.h>
#include "masdos.h"
#include "maserr.h"
#include "getargs.h"
extern void usage( void );
extern int stoi( char ** );
typedef int (*PFI)();
char ARG_Switch = '/';
int ARG_ICase = 0;
static char getsoptb[100];
static char *setarg( argp, linep )
ARG *argp ;
char *linep ;
{
++linep ;
switch( argp->type )
{
case ARG_INTEGER :
*argp->variable = stoi( &linep ) ;
break ;
case ARG_FBOOLEAN :
*argp->variable = 1;
break ;
case ARG_TBOOLEAN :
*argp->variable = 0;
break ;
case ARG_SBOOLEAN :
*argp->variable = ( *argp->variable ? 0 : 1 );
break ;
case ARG_CHARACTER :
*argp->variable = *linep++ ;
break ;
case ARG_STRING :
*(char **)argp->variable = linep ;
linep = "" ;
break;
case ARG_PROCESS :
(* (PFI)(argp->variable) )( linep );
linep = "";
break;
default :
fprintf( stderr, "GetArgs: Internal Error: Bad Argument Type\n" );
break ;
}
return( linep ) ;
}
static ARG *findarg( c, tabp, tabsize )
int c, tabsize ;
ARG *tabp ;
{
for( ; --tabsize >= 0 ; tabp++ )
{
if( ARG_ICase && toupper(tabp->arg) == toupper(c) )
return( tabp );
if( tabp->arg == c )
return( tabp );
}
return( NULL );
}
static pr_usage( tabp, tabsize )
ARG *tabp;
int tabsize;
{
for( ; --tabsize >= 0 ; tabp++ )
{
switch( tabp->type )
{
case ARG_INTEGER :
fprintf(stderr, "%c%c<num> %-40s (value is ",
ARG_Switch, tabp->arg, tabp->errmsg) ;
fprintf(stderr, "%-5d)\n", *(tabp->variable) ) ;
break ;
case ARG_TBOOLEAN :
fprintf(stderr, "%c%c T %-40s (value is ",
ARG_Switch, tabp->arg, tabp->errmsg) ;
fprintf(stderr, "%-5s)\n", *(tabp->variable)
? "True" : "False") ;
break ;
case ARG_SBOOLEAN :
fprintf(stderr, "%c%c S %-40s (value is ",
ARG_Switch, tabp->arg, tabp->errmsg) ;
fprintf(stderr, "%-5s)\n", *(tabp->variable)
? "True" : "False") ;
break ;
case ARG_FBOOLEAN :
fprintf(stderr, "%c%c F %-40s (value is ",
ARG_Switch, tabp->arg, tabp->errmsg) ;
fprintf(stderr, "%-5s)\n", *(tabp->variable)
? "True" : "False") ;
break ;
case ARG_CHARACTER :
fprintf(stderr, "%c%c<c> %-40s (value is ",
ARG_Switch, tabp->arg, tabp->errmsg) ;
fprintf(stderr, "%-5c)\n", *(tabp->variable) ) ;
break ;
case ARG_STRING :
fprintf(stderr, "%c%c<str> %-40s (value is ",
ARG_Switch, tabp->arg, tabp->errmsg) ;
fprintf(stderr, "<%s>)\n",
*(char **)tabp->variable) ;
break ;
case ARG_PROCESS :
fprintf(stderr, "%c%c<str> %-40s\n",
ARG_Switch, tabp->arg, tabp->errmsg);
break;
}
}
}
#define ARG_ERRMSG "Illegal argument <%c>. Legal arguments are:\n\n"
int getargs( argc, argv, tabp, tabsize )
int argc, tabsize ;
char **argv ;
ARG *tabp ;
{
register int nargc ;
register char **nargv, *p ;
register ARG *argp ;
char buf[2], *bufp = buf;
if( (bufp = getenv("SWITCHAR")) )
ARG_Switch = *bufp;
nargc = 1 ;
for( nargv = ++argv ; --argc > 0 ; argv++ )
{
if( **argv != ARG_Switch || !strcmp( *argv, "-" ) )
{
*nargv++ = *argv ;
nargc++ ;
}
else
{
p = ( *argv ) + 1 ;
while( *p )
{
if( *p == ARG_Switch )
p++;
else if( argp = findarg( *p, tabp, tabsize ) )
{
p = setarg( argp, p ) ;
}
else
{
usage();
fprintf( stderr, ARG_ERRMSG, *p );
pr_usage( tabp, tabsize );
exit( E_USAGE );
}
}
}
}
return nargc ;
}
void getopts( tabp, tabsize, opts )
int tabsize ;
ARG *tabp ;
char *opts;
{
register char *p ;
register ARG *argp ;
char *buf, *bufp;
if( (buf = getmenv(opts)) )
{
while( bufp = next( &buf, ',', -1 ) )
{
p = ( bufp );
while( *p )
{
if( argp = findarg( *p, tabp, tabsize ) )
{
p = setarg( argp, p ) ;
}
else
{
usage();
fprintf( stderr, ARG_ERRMSG, *p );
pr_usage( tabp, tabsize );
exit( E_USAGE );
}
}
}
}
}
void getsopts( tabp, tabsize, file )
int tabsize ;
ARG *tabp ;
char *file;
{
register char *p ;
register ARG *argp ;
char *buf = getsoptb, *bufp = getsoptb;
FILE *fp = NULL;
strcat( getsoptb, getmenv("GETSOPTS") );
strcat( getsoptb, file );
if( (fp = fopen(getsoptb, "r")) )
{
if( !getl( getsoptb, 255, fp) )
{
fclose( fp );
return;
}
else
{
while( bufp = next( &buf, ',', -1 ) )
{
p = ( bufp );
while( *p )
{
if( argp = findarg( *p, tabp, tabsize ) )
p = setarg( argp, p );
else
{
usage();
fprintf( stderr, ARG_ERRMSG, *p );
pr_usage( tabp, tabsize );
exit( E_USAGE );
}
}
}
}
}
}
@//E*O*F getargs.c//
chmod u=rw,g=r,o=r getargs.c
echo x - getargs.h
sed 's/^@//' > "getargs.h" <<'@//E*O*F getargs.h//'
#ifndef GETARGS_INCLUDED
#define GETARGS_INCLUDED
/*
*
* Getargs.h
*
*!AU: Michael A. Shiels
*!CD: 22-May-86
*!FR: Dr. Dobb's May 1985
*
*/
#define ARG_INTEGER 0
#define ARG_TBOOLEAN 1
#define ARG_SBOOLEAN 2
#define ARG_FBOOLEAN 3
#define ARG_CHARACTER 4
#define ARG_STRING 5
#define ARG_PROCESS 6
typedef struct
{
int arg; /* Command Line Switch */
int type; /* Variable Type */
int *variable; /* Pointer to Variable */
char *errmsg; /* Pointer to Error Message */
}
ARG ;
#ifndef GETARGS_C
extern int ARG_ICase;
extern int ARG_Switch;
#endif
#endif /* GETARGS_INCLUDED */
@//E*O*F getargs.h//
chmod u=rw,g=r,o=r getargs.h
echo x - getargs.x
sed 's/^@//' > "getargs.x" <<'@//E*O*F getargs.x//'
extern int getargs( int, char **, ARG *, int );
extern void getopts( ARG *, int, char * );
extern void getsopts( ARG *, int, char * );
@//E*O*F getargs.x//
chmod u=rw,g=r,o=r getargs.x
echo x - help.c
sed 's/^@//' > "help.c" <<'@//E*O*F help.c//'
/* Help: (C) Copyright 1986 Michael A. Shiels
This program is Copyright by Michael Shiels and may be given away and
used in other programs as long as the Copyright notices are not removed
or altered. No profit can be made from the distribution of this product
except by the author.
*/
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <conio.h>
#include <direct.h>
#include <process.h>
#include <signal.h>
#include <string.h>
#include "getargs.h"
#include "masdos.h"
#include "maserr.h"
#include "helpdir.h"
#include "denv.x"
#include "unargv.x"
#include "getargs.x"
#include "reargv.x"
#include "mynewlin.x"
#include "fptext.x"
extern int Lusage( char * );
static int Arg_Copy = 1;
static int Arg_Max_Wild = 100;
static int Arg_Max_Help = 100;
static char *Arg_Help_Dir = "";
static int Arg_Num_Cols = 5;
static int Arg_Vert_Prt = 0;
ARG Argtab[] =
{
{ 'c', ARG_INTEGER, &Arg_Num_Cols, "Number of columns for Topics" },
{ 'd', ARG_STRING, (int *)&Arg_Help_Dir, "Help Directory" },
{ 'h', ARG_INTEGER, &Arg_Max_Help, "Maximum number of help Topics" },
{ 'v', ARG_SBOOLEAN, &Arg_Vert_Prt, "Print Topics Vertically" },
{ 'w', ARG_INTEGER, &Arg_Max_Wild, "Maximum number of wildcard searchs" },
{ '(', ARG_SBOOLEAN, &Arg_Copy, "Print Copyright Notice" },
{ '!', ARG_PROCESS, Lusage, "Long Usage" }
};
#define ARG_TABSIZE ( sizeof(Argtab) / sizeof(ARG) )
void usage()
{
E( "Usage: Help [Topic [Subtopic]...]\n" );
E( "\n" );
E( "Version 1.00 Copyright (c) 1986, Michael A. Shiels\n");
E( "\n" );
}
Lusage( dum )
char *dum;
{
E( "Usage: Help [Topic [Subtopic]...]\n" );
E( "\n");
E( "Set the environment variable SWITCHAR to the character\n");
E( "you wish to use for the Switch Character.\n");
E( "\n" );
E( "Set the environment variable HELPOPTS to the standard options\n");
E( "you wish to have Help use every time. These can be overidden\n");
E( "with the command line switches. (eg. HELPOPTS=( will cause it to\n");
E( "suppress the copyright notice)\n");
E( "\n" );
E( "Set the environment variable GETSOPTS to the directory where\n");
E( "you wish to store the .RC file for Help to use. These can be overidden\n");
E( "with the command line switches. (eg. HELP.RC contains ( will\n");
E( "cause it to supress the copyright notice)\n");
E( "\n" );
E2( "Case of the command line switches %s important\n", ARG_ICase ? "is not" : "is" );
E( "\n" );
E( "Version 1.00 Copyright (c) 1986, Michael A. Shiels. All rights reserved.\n" );
E( "\n" );
exit( E_USAGE );
}
#define HELPDIR "/usr/help"
char olddir[101];
static char helplev[101], *helplevp = helplev;
static FILE *stderrR;
static int oldraw;
static int helpctrlchit = 0;
static int helpwild = 0;
extern helpreset();
extern char *helpprompt();
extern void helplevel();
extern void helptopics();
extern void helpdisplay1( char * );
extern void helpdisplay2( char * );
extern void helpr( char * );
mynewline( where )
FILE *where;
{
static int linenum = 0;
int oldraw;
fputs( "\n", where );
if( !(++linenum % 24) )
{
fflush( where );
oldraw = getraw( fileno( where ) );
setraw( fileno( where ), 0 );
fputs( P_REVERSE, stderr );
fputs( P_BLINKING, stderr );
fputs("<Hit any character for next page>",stderr);
fputs( P_ALL_OFF, stderr );
getch();
setraw( fileno( where ), oldraw );
fputs("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b",where);
fputs("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", where );
fputs(" ",where);
fputs("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b",where);
fputs("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", where );
fflush( where );
}
return( 0 );
}
helpctrlc()
{
helpctrlchit = 1;
signal( SIGINT, helpctrlc );
}
helpreset()
{
cd( olddir );
setraw( fileno( stderrR ), 0 );
fclose( stderrR );
exit( 0 );
}
char *helpprompt()
{
static char tmpstr[103], *tmpstrp = tmpstr;
tmpstr[0] = 100;
redo:
mynewline( stderrR );
if( helplevp == NULL || *helplevp == NULL )
fprintf( stderrR, "Topic? " );
else
fprintf( stderrR, "%s %s", helplevp, "Subtopic? " );
fflush( stderrR );
oldraw = getraw( fileno( stderrR ) );
setraw( fileno( stderrR ), 0 );
tmpstrp = cgets( tmpstr );
setraw( fileno( stderrR ), 1 );
mynewline( stderrR );
if( tmpstr[2] == 26 )
helpreset();
if( tmpstr[2] == '?' && tmpstr[3] == '\0' )
{
helplevel( NULL );
if( access( "intro.txt", 0 ) >= 0 )
helpdisplay1( "intro.txt" );
helptopics();
goto redo;
}
else if( tmpstr[2] == '#' && tmpstr[3] == '\0' )
{
helplevel( NULL );
if( access( "intro.txt", 0 ) >= 0 )
helpdisplay1( "intro.txt" );
goto redo;
}
else if( tmpstr[2] == '$' && tmpstr[3] == '\0' )
{
helplevel( NULL );
helptopics();
goto redo;
}
else if( tmpstr[2] == '!' && tmpstr[3] == '\0' )
{
spawnl( P_WAIT, getenv("COMSPEC"), getenv("COMSPEC"), NULL );
goto redo;
}
else if( tmpstr[2] == '!' )
{
system( tmpstrp + 1 );
goto redo;
}
else if( tmpstr[1] > 0 )
return( tmpstrp );
else
return( NULL );
}
void helplevel( level )
char *level;
{
if( (level != NULL && *level != NULL) || (helplevp != NULL && *helplevp != NULL) )
{
mynewline( stderrR );
}
if( helplevp != NULL && *helplevp != NULL )
fprintf( stderrR, "%s%s%s", P_REVERSE, helplevp, P_ALL_OFF );
if( level != NULL && *level != NULL )
fprintf( stderrR, " %s%s%s", P_REVERSE, level, P_ALL_OFF );
if( (level != NULL && *level != NULL) || (helplevp != NULL && *helplevp != NULL) )
{
mynewline( stderrR );
mynewline( stderrR );
}
fflush( stderrR );
}
static void printdir(dirc, dirv, maxwidth)
int dirc ;
char **dirv ;
{
if( !Arg_Num_Cols )
Arg_Num_Cols = 79 / (maxwidth+1) ;
mynewline( stderrR );
if( Arg_Vert_Prt )
fptextv( dirc, dirv, Arg_Num_Cols, 79 / Arg_Num_Cols,
(dirc/Arg_Num_Cols) + (dirc % Arg_Num_Cols != 0), stderrR );
else
fptexth( dirc, dirv, Arg_Num_Cols, 79 / Arg_Num_Cols,
(dirc/Arg_Num_Cols) + (dirc % Arg_Num_Cols != 0), stderrR );
mynewline( stderrR );
}
void helptopics()
{
char tmpstr[101], *tmpstrp = tmpstr;
int i;
HDIRECTORY *hdp1 = 0;
char *nexthelp;
if( (hdp1 = mk_hdir( Arg_Max_Help )) )
{
hdp1->sort = 1;
hdp1->dirs = 1;
hdp1->files = 1;
hdir( "*.hl*" , hdp1 );
if( (hdp1->ndirs + hdp1->nfiles) )
{
mynewline( stderrR );
if( helplevp == NULL || *helplevp == NULL )
fprintf( stderrR, "Topics Available." );
else
fprintf( stderrR, "Subtopics Available." );
mynewline( stderrR );
fflush( stderrR );
printdir( hdp1->nfiles + hdp1->ndirs, hdp1->dirv, hdp1->width);
}
del_hdir( hdp1 );
}
else
{
E( "Help:helptopics: unable to create hdir structure for topic searching\n" );
}
}
void helpdisplay1( filename )
char *filename;
{
register FILE *fp;
char buf[1024];
int (*oldsignal)();
if( getenv("HELPDISPLAY1") )
{
putenv("CMDLINE");
spawnlp( P_WAIT, getenv("HELPDISPLAY1"), getenv("HELPDISPLAY1"), filename, NULL );
}
else
{
helpctrlchit = 0;
oldsignal = signal( SIGINT, helpctrlc );
if( (fp = fopen( filename, "r")) )
{
while( fgets(buf, 1024, fp) != NULL && !helpctrlchit )
{
buf[strlen(buf)-1] = '\0';
fputs( buf, stderrR );
mynewline( stderrR );
}
fflush( stderrR );
fclose( fp );
signal( SIGINT, oldsignal );
helpctrlchit = 0;
}
}
}
void helpdisplay2( filename )
char *filename;
{
register FILE *fp;
char buf[1024];
int (*oldsignal)();
if( getenv("HELPDISPLAY2") )
{
putenv("CMDLINE");
spawnlp( P_WAIT, getenv("HELPDISPLAY2"), getenv("HELPDISPLAY2"), filename, NULL );
}
else
{
helpctrlchit = 0;
oldsignal = signal( SIGINT, helpctrlc );
if( (fp = fopen( filename, "r")) )
{
while( fgets(buf, 1024, fp) != NULL && !helpctrlchit )
{
buf[strlen(buf)-1] = '\0';
fputs( buf, stderrR );
mynewline( stderrR );
}
fflush( stderrR );
fclose( fp );
signal( SIGINT, oldsignal );
helpctrlchit = 0;
}
}
}
dohelp( retstr )
char *retstr;
{
char tmpstr[101], *tmpstrp = tmpstr;
char tmpstr2[101], *tmpstr2p = tmpstr2;
int i;
HDIRECTORY *hdp = 0;
char *nexthelp;
char *tmpp;
int (*oldsignal)();
nexthelp = next( &retstr, ' ', 0 );
strcpy( tmpstr, nexthelp );
strcat( tmpstr, ".hlp" );
strcpy( tmpstr2, nexthelp );
strcat( tmpstr2, ".hld" );
if( chdir( tmpstr2 ) >= 0 )
{
strcat( helplevp, " " );
strcat( helplevp, nexthelp );
helpr( retstr );
chdir( ".." );
tmpp = strrchr( helplevp, ' ' );
*tmpp = '\0';
}
else if( access( tmpstr, 0 ) >= 0 )
{
helplevel( nexthelp );
if( retstr != NULL && *retstr != NULL )
{
fprintf( stderrR, "Help: reached end of help tree - ignoring '%s'", retstr );
mynewline( stderrR );
}
helpdisplay2( tmpstr );
}
else
{
if( (hdp = mk_hdir( Arg_Max_Wild ) ) )
{
strcpy( tmpstr, nexthelp );
strcat( tmpstr, "*.hl*" );
hdp->files = 1;
hdp->dirs = 1;
hdp->sort = 1;
hdir( tmpstr, hdp );
if( ( hdp->ndirs + hdp->nfiles ) == 1 )
{
strcpy( tmpstr, hdp->dirv[0] );
strcat( tmpstr, retstr );
dohelp( tmpstrp );
}
else if( ( hdp->ndirs + hdp->nfiles ) == 0 )
{
fprintf( stderrR, "Help: unable to find help for '%s'", nexthelp );
mynewline( stderrR );
}
else
{
i = 0;
helpwild = 1;
helpctrlchit = 0;
oldsignal = signal( SIGINT, helpctrlc );
while( i <= ( hdp->ndirs + hdp->nfiles - 1 ) && !helpctrlchit )
{
strcpy( tmpstr, hdp->dirv[i++] );
strcat( tmpstr, retstr );
dohelp( tmpstrp );
tmpstrp = tmpstr;
}
signal( SIGINT, oldsignal );
helpctrlchit = 0;
helpwild = 0;
}
del_hdir( hdp );
}
else
{
E( "Help:dohelp: Unable to create hdir structure for multiple help requests\n" );
}
}
}
void helpr( topic )
char *topic;
{
char *retstr = 1;
if( topic == NULL || *topic == NULL )
{
helplevel( NULL );
if( access( "intro.txt", 0 ) >= 0 )
helpdisplay1( "intro.txt" );
helptopics();
}
else
{
dohelp( topic );
}
while( retstr != NULL && !helpwild )
{
retstr = helpprompt();
if( retstr != NULL && *retstr != NULL )
{
dohelp( retstr );
}
}
}
main(argc, argv)
int argc;
char *argv[];
{
char helpstr[128], *helpstrp = helpstr;
reargv( &argc, &argv );
getsopts( Argtab, ARG_TABSIZE, "HELP.RC" );
Arg_Copy = 1;
getopts( Argtab, ARG_TABSIZE, "HELPOPTS" );
argc = getargs( argc, argv, Argtab, ARG_TABSIZE );
if( Arg_Copy )
E( "Help Version 1.00 Copyright (c) 1986, Michael A. Shiels. All rights reserved.\n" );
signal( SIGINT, helpreset );
stderrR = fopen( "con", "w" );
if (stderrR == NULL)
{
E( "Help: can't open 'con' for rawmode\n");
exit( 100 );
}
setraw( fileno( stderrR ), 1 );
getcwd( olddir, 101 );
if( Arg_Help_Dir == NULL || *Arg_Help_Dir == NULL )
Arg_Help_Dir = getdenv("HELPDIR");
if( Arg_Help_Dir == NULL || *Arg_Help_Dir == NULL )
Arg_Help_Dir = HELPDIR;
if( cd( Arg_Help_Dir ) < 0)
{
E2( "Help: Help root directory not found for %s.\n", Arg_Help_Dir );
exit(100);
}
*argv++;
unargv( argc-1, argv, helpstrp, 128 );
if (argc >= 1)
helpr( helpstr );
else
helpr( NULL );
helpreset();
}
@//E*O*F help.c//
chmod u=rw,g=r,o=r help.c
echo x - help.man
sed 's/^@//' > "help.man" <<'@//E*O*F help.man//'
HELP Michael Shiels' DOSIX Programmer's Manual HELP
NAME
help - user-friendly documentation reader
SYNOPSIS
help [ -c<#>d<str>h<#>vw<#> ] [ topic-path ]
DESCRIPTION
Help is a documentation reader based closely on the VMS(tm)
help facility. Documentation texts are arranged in a tree,
and the users reads them with the built in interface or with
another file viewer. Help allows documentation to be treated
as an n-tree, the structure of the help tree is the structure
of the directory tree in which the help files reside.
The help program is invoked from the shell like
help [ options ] topic sub-topic sub-sub-topic ...
Topic may be any top-level help file name. A topic-path is
a path of topics and their subtopics, down into the tree.
Topic and subtopic names may be abbreviated, but no wild-
cards are recognized.
The options are:
c<#> The number will be used as the number of columns for the
Topic/Subtopic listings.
d<str> Next argument is the help root directory. Default is
what ever $HELPDIR is set to or /usr/help.
h<#> The number will be used as the maximum number of help
topics/subtopics which will ever occur at any level.
This is usually set up in the HELP.RC file.
v This triggers vertical instead of horizontal printing
of the help topics/subtopics.
w<#> The number will be used as the maximum number of help
topics/subtopics which will be requested during an
ambiguous helprequest.
This is usually set up in the HELP.RC file.
The help interactive mode asks the user what help he would
like next. The prompt looks like this:
Topic?
or like this:
vi commands deletion Subtopic?
Where "vi commands deletion" is the help tree path. This
path is printed for each prompt, and as a header for each
help text.
The following commands are meaningful in to the "topic?"
prompt:
? Print current introduction and subtopic-list again.
# Print current introduction again.
$ Print current subtopic-list again.
!<CR>
To shell to the current setting of $COMSPEC.
!command
To run the 'command' under $COMSPEC.
Return <CR>
Exit this level of help. If at top level, goes back to
calling program.
<subtopic-name>
Read the documentation for this subtopic, or all subto-
pics for which this is a legal abbreviation. Wildcards
are not permitted, but a short abbreviation matches
everything longer.
^Z Exit the help program.
HELP FILES
Help files are the text and directories of the help documen-
tation tree. There are four kinds of help files: topic directory,
introduction file, and subtopic file.
The usual way of calling help is to just type
% help
in the shell. This brings up help in interactive mode at the
top level of topics. The user can always abort with ctrl/Z.
GENERAL ENVIRONMENT VARIABLES
SWITCHAR - is used to detect which character you wish to use for
the command line option trigger. Usually it is '/' but
if you are a UNIXer you can set it to '-'.
GETSOPTS - is used to locate the HELP.RC file which can be used
to change some of the defaults for the command line
switches. Usually it is used to increase the number
of help topics/subtopics which can be available at
any one level.
COMSPEC - this is used to locate the COMMAND shell.
ENVIRONMENT VARIABLES
HELPOPTS - is used to override the HELP.RC file and set up personal
command line preferences.
HELPDIR - is the root of the help system.
HELPDISPLAY1 - can be set to a program (such as more) which will be
used to display the introductory text file if there
is one.
HELPDISPLAY2 - can be set to a program (such as more) which will be
used to display the help files.
EXAMPLE
HELPDIR = J:/HELP
Thie disk structure would look like this
J:\HELP\INTRO.TXT Introduction which will be display when
the topics at this level are displayed
J:\HELP\AUTOEXEC.HLP Help Text
J:\HELP\GNUPLOT.HLD Subtopic Directory
J:\HELP\GNUPLOT.HLD\PLOT.HLP Subtopic Help Text
J:\HELP\GNUPLOT.HLD\EXPR.HLD SubSubtopic Directory
...
AUTHOR
Michael A. Shiels ( mshiels at electrical.watstar.waterloo.EDU )
604 Bridle Wood
Burlington, Ontario
CANADA, L7L 4C7
FILES
$GETSOPTS/HELP.RC
$HELPDIR/...
NANSI.SYS
NOTES
This program will use the 'RAW' mode of the NANSI.SYS driver if it
is loaded, but it can still be run with ANSI.SYS.
All user prompting is read using 'cgets' so CED will work at the
help prompts.
SEE ALSO
more, pc-more, smore, list, nansi, ced.
DIAGNOSTICS
Error messages are printed whenever a request is made to get
documentation that does not exists, or is not accessible.
BUGS
The file naming conventions are very strict.
@//E*O*F help.man//
chmod u=rw,g=r,o=r help.man
echo x - help.rc
sed 's/^@//' > "help.rc" <<'@//E*O*F help.rc//'
h500,dj:\help
@//E*O*F help.rc//
chmod u=rw,g=r,o=r help.rc
echo x - helpdir.c
sed 's/^@//' > "helpdir.c" <<'@//E*O*F helpdir.c//'
/* Help: (C) Copyright 1986 Michael A. Shiels
This program is Copyright by Michael Shiels and may be given away and
used in other programs as long as the Copyright notices are not removed
or altered. No profit can be made from the distribution of this product
except by the author.
*/
#define LINT_ARGS
#include <stdio.h>
#include <ctype.h>
#include <dos.h>
#include "masdos.h"
#include "helpdir.h"
#include "cpy.x"
#include "next.x"
#include "cptolow.x"
#include "ssort.x"
#define iswhite(c) ((c) == ' ' || (c) == '\t')
int haswild(s)
register char *s;
{
for( ; *s ; s++)
if( *s == '*' || *s == '?' )
return 1;
return 0;
}
/*----------------------------------------------------------------------*/
static int dirtoa( target, infop )
register char *target ;
register struct FILEINFO *infop ;
{
char *startstr = target;
target = cptodlower( target, infop->fi_name );
return( target - startstr );
}
/*----------------------------------------------------------------------*/
static int add_entry( infop, dp )
struct FILEINFO *infop ;
register HDIRECTORY *dp ;
{
char buf[128] ;
register int len ;
if( IS_HIDDEN(infop->fi_attrib) || *infop->fi_name == '.' )
return 1;
if( dp->maxdirs <= 0 ) /* No more room in dirv. return */
return 0; /* error status */
if( IS_SUBDIR(infop->fi_attrib) )
{
if( dp->dirs )
dp->ndirs++ ;
else
return 1;
}
else
{
if( dp->files )
dp->nfiles++ ;
else
return 1;
}
len = dirtoa( buf, infop );
if( len > dp->width )
dp->width = len ;
if( *dp->lastdir = malloc(len + 1) )
{
strcpy( *dp->lastdir++, buf ) ;
--dp->maxdirs;
return 1;
}
return 0;
}
static int cmp( pp1, pp2 )
char **pp1, **pp2;
{
register char *p1 = *pp1;
register char *p2 = *pp2;
int num1, num2;
while( (num1 = (isdigit(*p1) && isdigit(*p2))) || (*p1 == *p2 && *p1) )
{
if( !num1 )
{
p1++;
p2++;
}
else
{
num1 = num2 = 0;
do {
num1 = (num1 * 10) + ( *p1++ - '0');
} while( isdigit(*p1) );
do {
num2 = (num2 * 10) + ( *p2++ - '0');
} while( isdigit(*p2) );
if( num1 != num2 )
return( num1 - num2 );
}
}
return( *p1 - *p2 );
}
/*----------------------------------------------------------------------*/
HDIRECTORY *mk_hdir( size )
register unsigned size;
{
register HDIRECTORY *dp;
register unsigned amt_mem;
amt_mem = sizeof(HDIRECTORY) + (size * sizeof(char *));
if( !( dp = (HDIRECTORY *) malloc(amt_mem) ))
return 0;
memset( dp, 0, amt_mem ); /* Initialize *dp to zeros */
dp->maxdirs = size ;
dp->lastdir = dp->dirv;
return dp;
}
/*----------------------------------------------------------------------*/
del_hdir( dp )
register HDIRECTORY *dp;
{
register char **v;
for( v = dp->dirv; v < dp->lastdir ; free( *v++ ) )
;
free( dp );
}
/*----------------------------------------------------------------------*/
hdir( spec, dp )
char *spec;
HDIRECTORY *dp;
{
struct FILEINFO info;
char **firstdir;
fchgdta( &info );
firstdir = dp->lastdir;
if( !ffind_first( spec, A_ALL) )
{
if( !add_entry(&info, dp ) )
goto aborted;
if( haswild(spec) )
{
while( !ffind_next() )
if( !add_entry(&info, dp ) )
goto aborted;
}
}
if( dp->sort )
ssort( (char *)firstdir, dp->lastdir - firstdir,
sizeof(char*), cmp);
goto abort;
aborted:
E( "Help:hdir: unable to add entries - increase the appropriate parameter\n" );
abort:
frstdta(); /* Restore the original dta */
}
@//E*O*F helpdir.c//
chmod u=rw,g=r,o=r helpdir.c
echo x - helpdir.h
sed 's/^@//' > "helpdir.h" <<'@//E*O*F helpdir.h//'
/* Help: (C) Copyright 1986 Michael A. Shiels
This program is Copyright by Michael Shiels and may be given away and
used in other programs as long as the Copyright notices are not removed
or altered. No profit can be made from the distribution of this product
except by the author.
*/
typedef struct
{
char **lastdir ; /* Most recent addition to dirv */
int maxdirs ; /* # of free slots in dirv */
int nfiles ; /* # of used slots that are files */
int ndirs ; /* # of used slots that are directories */
unsigned width : 7 ; /* Width of widest element in dirv */
unsigned files : 1 ; /* Include files in list */
unsigned dirs : 1 ; /* Include directories in list */
unsigned sort : 1 ; /* Sort added entries */
char *dirv[1]; /* The first of the dirv entries */
}
HDIRECTORY;
@//E*O*F helpdir.h//
chmod u=rw,g=r,o=r helpdir.h
echo x - intro.txt
sed 's/^@//' > "intro.txt" <<'@//E*O*F intro.txt//'
Welcome to the Help system.
The following commands can be used at the Topic/Subtopic prompt:
? - to redisplay the most recent introduction and topic listing
# - to redisplay the most recent introdcution only
$ - to redisplay the most recent topic listing only
! - to shell to DOS
!cmd - to execute the 'cmd'
Any questions or problems mail
MSHIELS at ELECTRICAL
@//E*O*F intro.txt//
chmod u=rw,g=r,o=r intro.txt
echo x - make.ini
sed 's/^@//' > "make.ini" <<'@//E*O*F make.ini//'
# This is a sample `make.ini' file for NDMAKE v3.1. You will probably want
# to customize it for your system.
# Prints a help message.
# The order to search for rules and files is specified by .SUFFIXES
@.SUFFIXES :
@.SUFFIXES : .exe .com .obj .c .asm
# A few macros.
LIB = N:\1
INCLUDE = N:\1
MODEL = S
CFLAGS = /A$(MODEL)
CDEFINES =
CLIBS =
AFLAGS = /mx
ALIBS =
SETARGV = $(LIB)\$(MODEL)SETARGV
BINMODE = $(LIB)\$(MODEL)BINMODE
LFLAGS = /NOIGNORE
# A few universally useful targets. This first target is here in case
# you are using NDMAKE without a makefile and you type "make" with no
# arguments.
clean:
+-erase *.bak
+-erase *.map
@.BEFORE:
@+echo NDMake: For help with make, use the command `make -h'
@.AFTER:
@+echo NDMake: All done.
ASM = masm
CC = msc
CL = cl
LINK = link
EXE2BIN = exe2bin
CCMP = $(CC) $(CFLAGS) $(CDEFINES) /Fo$@ $?
CLINK = $(LINK) $<, $@, nul, $(LFLAGS) $(CLIBS)
# DEFAULT RULES
# To produce a `.obj' file from a `.asm' file.
@.asm.obj:
$(ASM) $(AFLAGS) $*.asm;
# To produce a `.obj' file from a `.c' file.
@.c.obj:
$(CCMP);
@.obj.exe:
$(CLINK);
# To produce a `.exe' file from a `.asm' file.
@.asm.exe:
$(ASM) $(AFLAGS) $*.asm;
$(LINK) $*.obj, $@, nul, $(ALIBS);
@.asm.com:
$(ASM) $(AFLAGS) $*.asm;
$(LINK) $*.obj, $@, nul, $(ALIBS);
$(EXE2BIN) $*.exe $*.com
@.exe.com:
$(EXE2BIN) $*.exe $*.com
# To produce a `.exe' file from a `.c' file.
@.c.exe:
cl $(CFLAGS) $(CDEFINES) $*.c -link $(LFLAGS) $(CLIBS)
@//E*O*F make.ini//
chmod u=rw,g=r,o=r make.ini
echo x - makefile
sed 's/^@//' > "makefile" <<'@//E*O*F makefile//'
#/* Help: (C) Copyright 1986 Michael A. Shiels
#
# This program is Copyright by Michael Shiels and may be given away and
# used in other programs as long as the Copyright notices are not removed
# or altered. No profit can be made from the distribution of this product
# except by the author.
#*/
# HELP Makefile
#
help.exe : help.obj helpdir.obj
$(CLINK) mshiels;
# Dependants
help.obj : help.c
helpdir.obj : helpdir.c
help.c : helpdir.h
helpdir.c : helpdir.h
@//E*O*F makefile//
chmod u=rw,g=r,o=r makefile
echo x - masdos.h
sed 's/^@//' > "masdos.h" <<'@//E*O*F masdos.h//'
#ifndef MASDOS_INCLUDED
#define MASDOS_INCLUDED
/*
*
* D_ debuging
* A_ attributes for files
* P_ print characteristics
* Q_ characters
* B_ BDOS interupt parameters
*
*/
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define abs(a) (((a) < 0) ? -(a) : (a))
#define EOS(s) while(*s) s++
#define ISQUOTE(c) ((c)=='\"' || (c)=='\'')
#define ISSQUOTE(c) ((c)=='\'')
#define ISDQUOTE(c) ((c)=='\"')
#define ISWILD(c) ((c)=='*' || (c)=='?' )
#define ISVSBRACE(c) ((c)=='{' || (c)=='(' )
#define ISVEBRACE(c) ((c)=='}' || (c)==')' )
#define SKIPWHITE(p) while( isspace(*p) ) p++
#define ROUND(n,u) ( !((n) % (u)) ? (n) : (((n) / (u)) + 1) * (u))
#define E(x) fprintf( stderr, x )
#define E2(x,y) fprintf( stderr, x, y )
#if (!defined(M_I86CM) && !defined(M_I86LM))
#define NullS (char *)0
#else
#define NullS (char *)0L
#endif
#ifdef DEBUGGING
#ifdef THIS_IS_MAIN
int Lev = -1;
#else
extern int Lev;
#endif
#define TRACE(p) fprintf( stderr, "%*s{ entering %s\n" , ++Lev * 2, "", p )
#define END_TRACE(p) fprintf( stderr, "%*s} exiting %s\n" , Lev-- * 2, "", p )
#define P_TRACE(p,q) fprintf( stderr, "%*s| %s=%s\n", Lev * 2, "", p, q )
#define DIAG(f,a) fprintf( stderr, "%*s| ", Lev * 2, "" );\
fprintf( stderr, f, a )
#else
#define TRACE(p)
#define END_TRACE(p)
#define P_TRACE(p)
#define DIAG(f,a)
#endif
#ifdef DEBUGGING
#define D_IN(p) fprintf(stderr,"(%s) In\n",p)
#define D_OUT(p) fprintf(stderr,"(%s) Out\n",p)
#define D_PRT(p,q) fprintf(stderr,"(%s) %s\n",p,q)
#define D_S(p,q,r) fprintf(stderr,"(%s) %s %s\n",p,q,r)
#define D_I(p,q,r) fprintf(stderr,"(%s) %s %d\n",p,q,r)
#else
#define D_IN(p)
#define D_OUT(p)
#define D_PRT(p,q)
#define D_S(p,q,r)
#define D_I(p,q,r)
#endif
#define NNULL 1
struct FILEINFO
{
unsigned char fi_resv[21]; /* Reserved by DOS */
unsigned char fi_attrib; /* File Attributes */
unsigned int fi_time; /* Create/Update time */
unsigned int fi_date; /* Create/Update date */
unsigned long fi_fsize; /* File Size (bytes) */
char fi_name[13]; /* File Name & Extension */
};
#define A_READONLY 0x01
#define A_HIDDEN 0x02
#define A_SYSTEM 0x04
#define A_LABEL 0x08
#define A_SUBDIR 0x10
#define A_DIRTY 0x20
#define A_ALL 0xff
#define A_ALL_FILES (A_HIDDEN&A_SYSTEM)
#define A_NORM_FILES 0x00
#define IS_READONLY(p) ((p) & A_READONLY)
#define IS_HIDDEN(p) ((p) & A_HIDDEN)
#define IS_SYSTEM(p) ((p) & A_SYSTEM)
#define IS_LABEL(p) ((p) & A_LABEL)
#define IS_SUBDIR(p) ((p) & A_SUBDIR)
#define IS_DIRTY(p) ((p) & A_DIRTY)
#define C_HOUR(p) (((p) >> 11) & 0x1f)
#define C_MIN(p) (((p) >> 5) & 0x3f)
#define C_SEC(p) (((p) << 1) & 0x3e)
#define C_YEAR(p) ((((p) >> 9) & 0x7f) + 1980)
#define C_MONTH(p) (((p) >> 5) & 0x0f)
#define C_DAY(p) (((p)) & 0x1f)
#define Q_ESC 0x1b
#define P_ALL_OFF "\033[0m"
#define P_BOLDFACE "\033[1m"
#define P_UNDERLINE "\033[4m"
#define P_BLINKING "\033[5m"
#define P_REVERSE "\033[7m"
#define B_PRGTRM 0x0000
#define B_KBDINP 0x0100
#define B_DSPOUT 0x0200
#define B_AUXINP 0x0300
#define B_AUXOUT 0x0400
#define B_PRNOUT 0x0500
#define B_CONIO 0x0600
#define B_CONDIN 0x0700
#define B_CONINN 0x0800
#define B_PRTSTR 0x0900
#define B_KBDBIN 0x0a00
#define B_SEL_DISK 0x0e00
#define B_SETDTA 0x1a00
#define B_GETDTA 0x2f00
#define B_IOCTL 0x4400
#define B_FINDFIRST 0x4e00
#define B_FINDNEXT 0x4f00
#define IO_CTRL 0x4000
#define IO_ISDEV 0x0080
#define IO_EOF 0x0040
#define IO_RAW 0x0020
#define IO_ISCLK 0x0008
#define IO_ISNUL 0x0004
#define IO_ISCOT 0x0002
#define IO_ISCIN 0x0001
#define CARRY 0x01
#endif /* MASDOS_INCLUDED */
@//E*O*F masdos.h//
chmod u=rw,g=r,o=r masdos.h
echo x - maserr.h
sed 's/^@//' > "maserr.h" <<'@//E*O*F maserr.h//'
#ifndef MASERR_I_
#define MASERR_I_
/*
*
* E_ error codes
*
*/
#define E_OK 0
#define E_USAGE 200
#define E_FNDENV 201
#define E_ENVFULL 202
#define E_CTLC 254
#define E_STACK 255
#endif /* MASERR_I_ */
@//E*O*F maserr.h//
chmod u=rw,g=r,o=r maserr.h
echo x - mynewlin.x
sed 's/^@//' > "mynewlin.x" <<'@//E*O*F mynewlin.x//'
extern int mynewline( FILE * );
@//E*O*F mynewlin.x//
chmod u=rw,g=r,o=r mynewlin.x
echo x - mynewline.def
sed 's/^@//' > "mynewline.def" <<'@//E*O*F mynewline.def//'
#include <stdio.h>
mynewline( where )
FILE *where;
{
fputs( "\n", where );
return( 0 );
}
@//E*O*F mynewline.def//
chmod u=rw,g=r,o=r mynewline.def
echo x - next.c
sed 's/^@//' > "next.c" <<'@//E*O*F next.c//'
/*
* NEXT.C:
*
* Skip to the next delimiter seperated object
*
*/
#define iswhite(c) ( (c) == ' ' || (c) == '\t' || (c) == '\n' )
char *next( linep, delim, esc )
char **linep;
{
/* Linep is the address of a character pointer that points to
* a string containing a series of delim seperated objects.
* Next will return a pointer to the first non-white object in
* *linep, replace the first delimiter it finds with a null, and
* advance *linep to point past the null (provided that it's not
* at end of string). 0 is returned when an empty string is passed
* to next(). White space may be used as a delimiter but
* in this case whitespace won't be skipped. A delimiter preceeded
* by "esc" is ignored. Quoted strings are copied verbatum.
*/
register char *start, *end ;
int inquote = 0;
if( !**linep )
return 0;
start = *linep;
if( !iswhite(delim) )
for( ; iswhite(*start) ; start++ )
;
for( end = start; *end && (*end != delim || inquote) ; end++ )
{
if( *end == esc && *(end+1) )
end++;
else if( *end == '"' || *end == '\'' )
inquote = ~inquote;
}
if( *end )
*end++ = '\0';
*linep = end;
return start;
}
@//E*O*F next.c//
chmod u=rw,g=r,o=r next.c
echo x - next.x
sed 's/^@//' > "next.x" <<'@//E*O*F next.x//'
extern char *next( char **, int, int );
@//E*O*F next.x//
chmod u=rw,g=r,o=r next.x
echo x - reargv.c
sed 's/^@//' > "reargv.c" <<'@//E*O*F reargv.c//'
#define REARGV_C
#define LINT_ARGS
#include <stdio.h>
#include <ctype.h>
/* Re-assemble the argv/argc string using the CMDLINE environment.
* Note that the environment string itself is destroyed by this
* process.
*/
#define MAXARGC ((unsigned)128)
#define isquote(c) ( (c)=='\"' || (c)=='\'')
extern char *getmenv( char* );
static int Envlen;
/*----------------------------------------------------------------------*/
static char *nextarg( pp )
char **pp;
{
register char *p;
char *start;
register int term;
if( !*(p = *pp) ) /* No more args to get , return 0 */
return (char *) 0;
while( isspace(*p) ) /* Skip white space */
p++;
term = isquote(*p) ? *p++ : ' ' ;
for( start = p; *p ; p++)
{
if( *p == term && *(p-1) != '\\' )
{
*p++ = '\0';
break;
}
}
*pp = p;
return start;
}
/*----------------------------------------------------------------------*/
int reargv( argcp, argvp )
char ***argvp;
int *argcp;
{
char **argv ;
register int argc = 0 ;
register int maxc = MAXARGC ;
static char *vects[MAXARGC];
char *p ;
if( !(p = getmenv("CMDLINE")) || !*p )
return 0;
Envlen = strlen(p);
argv = vects;
for( maxc=MAXARGC; --maxc >= 0 && (*argv++ = nextarg(&p)); argc++)
;
if( maxc < 0 )
fprintf(stderr, "Library:reargv: Command line truncated\n");
*argcp = argc;
*argvp = vects;
return 1;
}
/*----------------------------------------------------------------------*/
envlen() /* Returns the original length of the CMDLINE environment */
{
return Envlen;
}
/*----------------------------------------------------------------------*/
#ifdef DEBUGMAIN
main( argc, argv )
char **argv;
{
printf("Original command line is: |");
while( --argc >= 0 )
printf("%s|", *argv++ );
if( !reargv( &argc, &argv ) )
printf("\nCMDLINE not present\n");
else
{
printf("New argc = %d\n", argc );
printf("\nModified command line is: |");
while( --argc >= 0 )
printf("%s|", *argv++ );
printf("\n");
}
}
#endif
@//E*O*F reargv.c//
chmod u=rw,g=r,o=r reargv.c
echo x - reargv.x
sed 's/^@//' > "reargv.x" <<'@//E*O*F reargv.x//'
extern int reargv( int *, char *** );
extern int reargvwv( int *, char *** );
@//E*O*F reargv.x//
chmod u=rw,g=r,o=r reargv.x
echo x - setraw2.c
sed 's/^@//' > "setraw2.c" <<'@//E*O*F setraw2.c//'
/*------ setraw.lc ----------------------------------------------
Lattice C routines which get and set the current raw/cooked state
of a file, given its Lattice file descriptor.
Useful when trying to obtain high console output speeds.
----------------------------------------------------------------*/
#include <dos.h>
#define CARRY 0x1
#define ERROR (-1)
#define TRUE 1
#define FALSE 0
extern _oserr;
/*---- getraw --------------------------------------------------
Returns TRUE if file fd is a device in raw mode; FALSE otherwise.
Returns ERROR, puts errorcode in _oserr, if DOS error.
----------------------------------------------------------------*/
getraw(fd)
int fd;
{
union REGS inregs;
union REGS outregs;
int flags;
inregs.x.bx = fd;
inregs.x.ax = 0x4400; /* get file attributes */
flags = intdos( &inregs, &outregs );
return (outregs.x.dx & 0x20) ? TRUE : FALSE;
}
/*---- setraw --------------------------------------------------
Sets Raw state of file fd to raw_on (if file is not a device, does nothing).
Returns zero if successful.
Returns ERROR & errorcode in _oserr if DOS error.
----------------------------------------------------------------*/
setraw(fd, raw_on)
int fd, raw_on;
{
union REGS inregs;
union REGS outregs;
int flags;
inregs.x.ax = 0x4400; /* get file attributes */
inregs.x.bx = fd;
flags = intdos(&inregs, &outregs);
if ((outregs.x.ax & 0x80) == 0) /* return zero if not device */
return 0;
outregs.x.ax = 0x4401; /* set file attributes */
outregs.x.bx = fd;
outregs.x.dx &= 0xcf; /* clear old raw bit & hi byte */
if (raw_on) outregs.x.dx |= 0x20; /* maybe set new raw bit */
flags = intdos(&outregs, &inregs);
return 0;
}
/*-- end of setraw.lc --*/
@//E*O*F setraw2.c//
chmod u=rw,g=r,o=r setraw2.c
echo x - ssort.c
sed 's/^@//' > "ssort.c" <<'@//E*O*F ssort.c//'
/* SSORT.C Works just like qsort() except that a shell
* sort, rather than a quick sort, is used. This
* is more efficient than quicksort for small numbers of elements
* and it's not recursive so will use much less stack space.
* This routine started out as the one in K&R.
*
* 12/13/85: Modified to select a gap from the series
* 1, 4, 13, 40, 121 ... as per Knuth.
*
* Copyright (C) 1985, Allen I. Holub. All rights reserved
*/
void ssort( base, nel, width, cmp )
char *base;
int nel, width;
int (*cmp)();
{
register int i, j;
int gap, k, tmp ;
char *p1, *p2;
for( gap=1; gap <= nel; gap = 3*gap + 1 )
;
for( gap /= 3; gap > 0 ; gap /= 3 )
for( i = gap; i < nel; i++ )
for( j = i-gap; j >= 0 ; j -= gap )
{
p1 = base + ( j * width);
p2 = base + ((j+gap) * width);
if( (*cmp)( p1, p2 ) <= 0 )
break;
for( k = width; --k >= 0 ;)
{
tmp = *p1;
*p1++ = *p2;
*p2++ = tmp;
}
}
}
@//E*O*F ssort.c//
chmod u=rw,g=r,o=r ssort.c
echo x - ssort.x
sed 's/^@//' > "ssort.x" <<'@//E*O*F ssort.x//'
extern void ssort( char *, int, int, int (*)() );
@//E*O*F ssort.x//
chmod u=rw,g=r,o=r ssort.x
echo x - unargv.c
sed 's/^@//' > "unargv.c" <<'@//E*O*F unargv.c//'
#define UNARGV_C
#define LINT_ARGS
#include <stdio.h>
/* UNARGV.C Concatantate all argv entries into a single
* string.
*/
int unargv( argc, argv, dest, maxcount )
char **argv, *dest;
register int maxcount;
{
/* Turn argv into a single string, with a single ' ' seperating
* each entry. maxcount is the maximum size of dest. Return
* the number of characters put into dest.
*/
register char *src;
char *sdest = dest;
while( --argc >= 0 && maxcount > 0 )
{
for( src = *argv++; *src && --maxcount > 0; )
*dest++ = *src++ ;
if( --maxcount > 0 && argc > 0 )
*dest++ = ' ';
}
*dest = 0;
return( dest - sdest );
}
@//E*O*F unargv.c//
chmod u=rw,g=r,o=r unargv.c
echo x - unargv.x
sed 's/^@//' > "unargv.x" <<'@//E*O*F unargv.x//'
extern int unargv( int, char **, char *, int );
@//E*O*F unargv.x//
chmod u=rw,g=r,o=r unargv.x
exit 0
--
Michael A. Shiels
UUCP: ...path...!watmath!watale!broehl
EDU: broehl at watale.waterloo.EDU
More information about the Comp.sources.unix
mailing list