home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / windows / help / help.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-03-10  |  11.3 KB  |  492 lines

  1. /* Help: (C) Copyright 1986 Michael A. Shiels
  2.    
  3.    This program is Copyright by Michael Shiels and may be given away and
  4.    used in other programs as long as the Copyright notices are not removed
  5.    or altered.  No profit can be made from the distribution of this product
  6.    except by the author.
  7. */
  8.  
  9. #include    <stdio.h>
  10. #include    <stdlib.h>
  11. #include    <io.h>
  12. #include    <conio.h>
  13. #include    <direct.h>
  14. #include    <process.h>
  15. #include    <signal.h>
  16. #include    <string.h>
  17.  
  18. #include    "getargs.h"
  19. #include    "masdos.h"
  20. #include    "maserr.h"
  21.  
  22. #include    "helpdir.h"
  23.  
  24. #include    "denv.x"
  25. #include    "unargv.x"
  26. #include    "getargs.x"
  27. #include    "reargv.x"
  28. #include    "mynewlin.x"
  29. #include    "fptext.x"
  30.  
  31. extern    int        Lusage( char * );
  32.  
  33. static    int     Arg_Copy        = 1;
  34. static    int        Arg_Max_Wild    = 100;
  35. static    int        Arg_Max_Help    = 100;
  36. static    char    *Arg_Help_Dir    = "";
  37. static    int        Arg_Num_Cols    = 5;
  38. static    int        Arg_Vert_Prt    = 0;
  39.  
  40.  
  41. ARG Argtab[] =
  42. {
  43.     { 'c', ARG_INTEGER,        &Arg_Num_Cols,        "Number of columns for Topics" },
  44.     { 'd', ARG_STRING,        (int *)&Arg_Help_Dir,    "Help Directory" },
  45.     { 'h', ARG_INTEGER,        &Arg_Max_Help,        "Maximum number of help Topics" },
  46.     { 'v', ARG_SBOOLEAN,    &Arg_Vert_Prt,        "Print Topics Vertically" },
  47.     { 'w', ARG_INTEGER,        &Arg_Max_Wild,        "Maximum number of wildcard searchs" },
  48.     { '(', ARG_SBOOLEAN,    &Arg_Copy,            "Print Copyright Notice" },
  49.     { '!', ARG_PROCESS,        Lusage,                "Long Usage" }
  50. };
  51.  
  52. #define ARG_TABSIZE ( sizeof(Argtab) / sizeof(ARG) )
  53.  
  54. void usage()
  55. {
  56.     E( "Usage: Help [Topic [Subtopic]...]\n" );
  57.     E( "\n" );
  58.     E( "Version 1.00 Copyright (c) 1986, Michael A. Shiels\n");
  59.     E( "\n" );
  60. }
  61.  
  62. Lusage( dum )
  63. char *dum;
  64. {
  65.     E( "Usage: Help [Topic [Subtopic]...]\n" );
  66.     E( "\n");
  67.     E( "Set the environment variable SWITCHAR to the character\n");
  68.     E( "you wish to use for the Switch Character.\n");
  69.     E( "\n" );
  70.     E( "Set the environment variable HELPOPTS to the standard options\n");
  71.     E( "you wish to have Help use every time.  These can be overidden\n");
  72.     E( "with the command line switches. (eg. HELPOPTS=( will cause it to\n");
  73.     E( "suppress the copyright notice)\n");
  74.     E( "\n" );
  75.     E( "Set the environment variable GETSOPTS to the directory where\n");
  76.     E( "you wish to store the .RC file for Help to use.  These can be overidden\n");
  77.     E( "with the command line switches. (eg. HELP.RC contains ( will\n");
  78.     E( "cause it to supress the copyright notice)\n");
  79.     E( "\n" );
  80.     E2( "Case of the command line switches %s important\n", ARG_ICase ? "is not" : "is" );
  81.     E( "\n" );
  82.     E( "Version 1.00 Copyright (c) 1986, Michael A. Shiels. All rights reserved.\n" );
  83.     E( "\n" );
  84.     exit( E_USAGE );
  85. }
  86.  
  87. #define HELPDIR "/usr/help"
  88.  
  89. char    olddir[101];
  90.  
  91. static    char    helplev[101], *helplevp = helplev;
  92. static    FILE    *stderrR;
  93. static    int        oldraw;
  94. static    int        helpctrlchit = 0;
  95. static    int        helpwild = 0;
  96.  
  97. extern    helpreset();
  98. extern    char *helpprompt();
  99. extern    void    helplevel();
  100. extern    void    helptopics();
  101. extern    void    helpdisplay1( char * );
  102. extern    void    helpdisplay2( char * );
  103. extern    void    helpr( char * );
  104.  
  105. mynewline( where )
  106. FILE    *where;
  107. {
  108.     static    int    linenum = 0;
  109.     int    oldraw;
  110.  
  111.     fputs( "\n", where );
  112.     if( !(++linenum % 24) )
  113.     {
  114.         fflush( where );
  115.         oldraw = getraw( fileno( where ) );
  116.         setraw( fileno( where ), 0 );
  117.         fputs( P_REVERSE, stderr );
  118.         fputs( P_BLINKING, stderr );
  119.         fputs("<Hit any character for next page>",stderr);
  120.         fputs( P_ALL_OFF, stderr );
  121.         getch();
  122.         setraw( fileno( where ), oldraw );
  123.  
  124.         fputs("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b",where);
  125.         fputs("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", where );
  126.         fputs("                                 ",where);
  127.         fputs("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b",where);
  128.         fputs("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", where );
  129.         fflush( where );
  130.     }
  131.     return( 0 );
  132. }
  133.  
  134. helpctrlc()
  135. {
  136.     helpctrlchit = 1;
  137.     signal( SIGINT, helpctrlc );
  138. }
  139.  
  140. helpreset()
  141. {
  142.     cd( olddir );
  143.     setraw( fileno( stderrR ), 0 );
  144.     fclose( stderrR );
  145.     exit( 0 );
  146. }
  147.  
  148. char *helpprompt()
  149. {
  150.     static    char        tmpstr[103], *tmpstrp = tmpstr;
  151.  
  152.     tmpstr[0] = 100;
  153. redo:
  154.     mynewline( stderrR );
  155.     if( helplevp == NULL || *helplevp == NULL )
  156.         fprintf( stderrR, "Topic? " );
  157.     else
  158.         fprintf( stderrR, "%s %s", helplevp, "Subtopic? " );
  159.     fflush( stderrR );
  160.     oldraw = getraw( fileno( stderrR ) );
  161.     setraw( fileno( stderrR ), 0 );
  162.     tmpstrp = cgets( tmpstr );
  163.     setraw( fileno( stderrR ), 1 );
  164.     mynewline( stderrR );
  165.     if( tmpstr[2] == 26 )
  166.         helpreset();
  167.     if( tmpstr[2] == '?' && tmpstr[3] == '\0' )
  168.     {
  169.         helplevel( NULL );
  170.         if( access( "intro.txt", 0 ) >= 0 )
  171.             helpdisplay1( "intro.txt" );
  172.         helptopics();
  173.         goto redo;
  174.     }
  175.     else if( tmpstr[2] == '#' && tmpstr[3] == '\0' )
  176.     {
  177.         helplevel( NULL );
  178.         if( access( "intro.txt", 0 ) >= 0 )
  179.             helpdisplay1( "intro.txt" );
  180.         goto redo;
  181.     }
  182.     else if( tmpstr[2] == '$' && tmpstr[3] == '\0' )
  183.     {
  184.         helplevel( NULL );
  185.         helptopics();
  186.         goto redo;
  187.     }
  188.     else if( tmpstr[2] == '!' && tmpstr[3] == '\0' )
  189.     {
  190.         spawnl( P_WAIT, getenv("COMSPEC"), getenv("COMSPEC"), NULL );
  191.         goto redo;
  192.     }
  193.     else if( tmpstr[2] == '!' )
  194.     {
  195.         system( tmpstrp + 1 );
  196.         goto redo;
  197.     }
  198.     else if( tmpstr[1] > 0 )
  199.         return( tmpstrp );
  200.     else
  201.         return( NULL );
  202. }
  203.  
  204. void    helplevel( level )
  205. char    *level;
  206. {
  207.     if( (level != NULL && *level != NULL) || (helplevp != NULL && *helplevp != NULL) )
  208.     {
  209.         mynewline( stderrR );
  210.     }
  211.     if( helplevp != NULL && *helplevp != NULL )
  212.         fprintf( stderrR, "%s%s%s", P_REVERSE, helplevp, P_ALL_OFF );
  213.     if( level != NULL && *level != NULL )
  214.         fprintf( stderrR, " %s%s%s", P_REVERSE, level, P_ALL_OFF );
  215.     if( (level != NULL && *level != NULL) || (helplevp != NULL && *helplevp != NULL) )
  216.     {
  217.         mynewline( stderrR );
  218.         mynewline( stderrR );
  219.     }
  220.     fflush( stderrR );
  221. }
  222.  
  223. static  void  printdir(dirc, dirv, maxwidth)
  224. int    dirc   ;
  225. char    **dirv ;
  226. {
  227.     if( !Arg_Num_Cols )
  228.         Arg_Num_Cols = 79 / (maxwidth+1) ;
  229.  
  230.     mynewline( stderrR );
  231.     if( Arg_Vert_Prt )
  232.         fptextv( dirc, dirv, Arg_Num_Cols, 79 / Arg_Num_Cols,
  233.             (dirc/Arg_Num_Cols) + (dirc % Arg_Num_Cols != 0), stderrR );
  234.     else
  235.         fptexth( dirc, dirv, Arg_Num_Cols, 79 / Arg_Num_Cols,
  236.             (dirc/Arg_Num_Cols) + (dirc % Arg_Num_Cols != 0), stderrR );
  237.     mynewline( stderrR );
  238. }
  239.  
  240. void    helptopics()
  241. {
  242.     char    tmpstr[101], *tmpstrp = tmpstr;
  243.     int        i;
  244.     HDIRECTORY    *hdp1 = 0;
  245.     char    *nexthelp;
  246.     
  247.     if( (hdp1 = mk_hdir( Arg_Max_Help )) )
  248.     {
  249.         hdp1->sort  = 1;
  250.         hdp1->dirs    = 1;
  251.         hdp1->files    = 1;
  252.         hdir( "*.hl*" , hdp1 );
  253.         if( (hdp1->ndirs + hdp1->nfiles) )
  254.         {
  255.             mynewline( stderrR );
  256.             if( helplevp == NULL || *helplevp == NULL )
  257.                 fprintf( stderrR, "Topics Available." );
  258.             else
  259.                 fprintf( stderrR, "Subtopics Available." );
  260.             mynewline( stderrR );
  261.             fflush( stderrR );
  262.             printdir( hdp1->nfiles + hdp1->ndirs, hdp1->dirv, hdp1->width);
  263.         }
  264.         del_hdir( hdp1 );
  265.     }
  266.     else
  267.     {
  268.         E( "Help:helptopics: unable to create hdir structure for topic searching\n" );
  269.     }
  270. }
  271.  
  272. void    helpdisplay1( filename )
  273. char    *filename;
  274. {
  275.     register FILE    *fp;
  276.     char        buf[1024];
  277.     int        (*oldsignal)();
  278.  
  279.     if( getenv("HELPDISPLAY1") )
  280.     {
  281.         putenv("CMDLINE");
  282.         spawnlp( P_WAIT, getenv("HELPDISPLAY1"), getenv("HELPDISPLAY1"), filename, NULL );
  283.     }
  284.     else
  285.     {
  286.         helpctrlchit = 0;
  287.         oldsignal = signal( SIGINT, helpctrlc );
  288.         if( (fp = fopen( filename, "r")) )
  289.         {
  290.             while( fgets(buf, 1024, fp) != NULL && !helpctrlchit )
  291.             {
  292.                 buf[strlen(buf)-1] = '\0';
  293.                 fputs( buf, stderrR );
  294.                 mynewline( stderrR );
  295.             }
  296.             fflush( stderrR );
  297.             fclose( fp );
  298.             signal( SIGINT, oldsignal );
  299.             helpctrlchit = 0;
  300.         }
  301.     }
  302. }
  303.  
  304. void    helpdisplay2( filename )
  305. char    *filename;
  306. {
  307.     register FILE    *fp;
  308.     char        buf[1024];
  309.     int        (*oldsignal)();
  310.  
  311.     if( getenv("HELPDISPLAY2") )
  312.     {
  313.         putenv("CMDLINE");
  314.         spawnlp( P_WAIT, getenv("HELPDISPLAY2"), getenv("HELPDISPLAY2"), filename, NULL );
  315.     }
  316.     else
  317.     {
  318.         helpctrlchit = 0;
  319.         oldsignal = signal( SIGINT, helpctrlc );
  320.         if( (fp = fopen( filename, "r")) )
  321.         {
  322.             while( fgets(buf, 1024, fp) != NULL && !helpctrlchit )
  323.             {
  324.                 buf[strlen(buf)-1] = '\0';
  325.                 fputs( buf, stderrR );
  326.                 mynewline( stderrR );
  327.             }
  328.             fflush( stderrR );
  329.             fclose( fp );
  330.             signal( SIGINT, oldsignal );
  331.             helpctrlchit = 0;
  332.         }
  333.     }
  334. }
  335.  
  336. dohelp( retstr )
  337. char    *retstr;
  338. {
  339.     char    tmpstr[101], *tmpstrp = tmpstr;
  340.     char    tmpstr2[101], *tmpstr2p = tmpstr2;
  341.     int        i;
  342.     HDIRECTORY    *hdp = 0;
  343.     char    *nexthelp;
  344.     char    *tmpp;
  345.     int        (*oldsignal)();
  346.     
  347.     nexthelp = next( &retstr, ' ', 0 );
  348.     strcpy( tmpstr, nexthelp );
  349.     strcat( tmpstr, ".hlp" );
  350.     strcpy( tmpstr2, nexthelp );
  351.     strcat( tmpstr2, ".hld" );
  352.     if( chdir( tmpstr2 ) >= 0 )
  353.     {
  354.         strcat( helplevp, " " );
  355.         strcat( helplevp, nexthelp );
  356.         helpr( retstr );
  357.         chdir( ".." );
  358.         tmpp = strrchr( helplevp, ' ' );
  359.         *tmpp = '\0';
  360.     }
  361.     else if( access( tmpstr, 0 ) >= 0 )
  362.     {
  363.         helplevel( nexthelp );
  364.         if( retstr != NULL && *retstr != NULL )
  365.         {
  366.             fprintf( stderrR, "Help: reached end of help tree - ignoring '%s'", retstr );
  367.             mynewline( stderrR );
  368.         }
  369.         helpdisplay2( tmpstr );
  370.     }
  371.     else
  372.     {
  373.         if( (hdp = mk_hdir( Arg_Max_Wild ) ) )
  374.         {
  375.             strcpy( tmpstr, nexthelp );
  376.             strcat( tmpstr, "*.hl*" );
  377.             hdp->files = 1;
  378.             hdp->dirs  = 1;
  379.             hdp->sort  = 1;
  380.             hdir( tmpstr, hdp );
  381.             if( ( hdp->ndirs + hdp->nfiles ) == 1 )
  382.             {
  383.                 strcpy( tmpstr, hdp->dirv[0] );
  384.                 strcat( tmpstr, retstr );
  385.                 dohelp( tmpstrp );
  386.             }
  387.             else if( ( hdp->ndirs + hdp->nfiles ) == 0 )
  388.             {
  389.                 fprintf( stderrR, "Help: unable to find help for '%s'", nexthelp );
  390.                 mynewline( stderrR );
  391.             }
  392.             else
  393.             {
  394.                 i = 0;
  395.                 helpwild = 1;
  396.                 helpctrlchit = 0;
  397.                 oldsignal = signal( SIGINT, helpctrlc );
  398.                 while( i <= ( hdp->ndirs + hdp->nfiles - 1 ) && !helpctrlchit )
  399.                 {
  400.                     strcpy( tmpstr, hdp->dirv[i++] );
  401.                     strcat( tmpstr, retstr );
  402.                     dohelp( tmpstrp );
  403.                     tmpstrp = tmpstr;
  404.                 }
  405.                 signal( SIGINT, oldsignal );
  406.                 helpctrlchit = 0;
  407.                 helpwild = 0;
  408.             }
  409.             del_hdir( hdp );
  410.         }
  411.         else
  412.         {
  413.             E( "Help:dohelp: Unable to create hdir structure for multiple help requests\n" );
  414.         }
  415.     }
  416. }
  417.  
  418. void    helpr( topic )
  419. char    *topic;
  420. {
  421.     char    *retstr = 1;
  422.     
  423.     if( topic == NULL || *topic == NULL )
  424.     {
  425.         helplevel( NULL );
  426.         if( access( "intro.txt", 0 ) >= 0 )
  427.             helpdisplay1( "intro.txt" );
  428.         helptopics();
  429.     }
  430.     else
  431.     {
  432.         dohelp( topic );
  433.     }
  434.     while( retstr != NULL && !helpwild )
  435.     {
  436.         retstr = helpprompt();
  437.         if( retstr != NULL && *retstr != NULL )
  438.         {
  439.             dohelp( retstr );
  440.         }
  441.     }
  442. }
  443.  
  444. main(argc, argv)
  445. int argc;
  446. char *argv[];
  447. {
  448.     char    helpstr[128], *helpstrp = helpstr;
  449.     
  450.     reargv( &argc, &argv );
  451.     getsopts( Argtab, ARG_TABSIZE, "HELP.RC" );
  452.     Arg_Copy = 1;
  453.     getopts( Argtab, ARG_TABSIZE, "HELPOPTS" );
  454.     argc = getargs( argc, argv, Argtab, ARG_TABSIZE );
  455.  
  456.     if( Arg_Copy )
  457.         E( "Help Version 1.00 Copyright (c) 1986, Michael A. Shiels. All rights reserved.\n" );
  458.  
  459.     signal( SIGINT, helpreset );
  460.  
  461.     stderrR = fopen( "con", "w" );
  462.     if (stderrR == NULL)
  463.     {
  464.         E( "Help: can't open 'con' for rawmode\n");
  465.         exit( 100 );
  466.     }
  467.     setraw( fileno( stderrR ), 1 );
  468.  
  469.     getcwd( olddir, 101 );
  470.  
  471.     if( Arg_Help_Dir == NULL || *Arg_Help_Dir == NULL )
  472.         Arg_Help_Dir = getdenv("HELPDIR");
  473.         if( Arg_Help_Dir == NULL || *Arg_Help_Dir == NULL )
  474.             Arg_Help_Dir = HELPDIR;
  475.  
  476.     if( cd( Arg_Help_Dir ) < 0)
  477.     {
  478.         E2( "Help: Help root directory not found for %s.\n", Arg_Help_Dir );
  479.         exit(100);
  480.     }
  481.  
  482.     *argv++;
  483.     unargv( argc-1, argv, helpstrp, 128 );
  484.  
  485.     if (argc >= 1)
  486.         helpr( helpstr );
  487.     else
  488.         helpr( NULL );
  489.  
  490.     helpreset();
  491. }
  492.