 /*
  * Khoros: $Id: gw_man1.c,v 1.3 1991/12/18 09:07:23 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: gw_man1.c,v 1.3 1991/12/18 09:07:23 dkhoros Exp $";
#endif

 /*
  * $Log: gw_man1.c,v $
 * Revision 1.3  1991/12/18  09:07:23  dkhoros
 * HellPatch3
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 * 
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *----------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "writer.h"

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>    Ghostwriter Routines to Generate *.1 file          <<<<
   >>>>                                                       <<<<
   >>>>                gw_generate_man1file()                 <<<<
   >>>>                gw_print_man1_req_args()               <<<<
   >>>>                gw_print_man1_io_conv()                <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */


/************************************************************
*
*  Routine Name: gw_generate_man1file
*
*       Purpose: This routine creates a man1 file 
*
*         Input: database -  pointer to the internal database struct
* 		 prog_spec-  pointer to the internal specification struct
*		 name     -  name of the program being generated
*
*    Called by: lwriter()
*
*   Written By:  Danielle Argiro
*
*************************************************************/

int  gw_generate_man1file(database, prog_spec, name, path, type)
char **database;
char **prog_spec;
char *name;
char *path;
char *type;
{
     int i;
     char c, datestring[27], month[5], nummonth[5], day[4], year[4];
     time_t  clock;
     FILE *file, *tmpfile;
     char  manfile[15], temp[MaxLength], *fullpath, resp, *cprght_file; 
     char *copyright;

     /*
      *  determine name of man1 file 
      */
     sprintf(manfile, "%s.1", name);

     /*
      *  see if man1 file already exists.  If so, prompt to over-write,
      *  return true if the answer is NO
      */
     fullpath = vfullpath(manfile, path, NULL);
     if (!writer->force)
     {
        if (tmpfile = fopen(fullpath, "r"))
        {
            fprintf(stderr, "\nOverwrite file '%s'?  [y/n]: ", fullpath);
	    fgets(temp, MaxLength, stdin); 
	    sscanf(temp, "%c", &resp);
	    if ((resp != 'y') && (resp != 'Y')) return(true);
        }
     }

     /*
      *  create & open man1 file  
      */
     if ((file = fopen(fullpath, "w"))== NULL)
     {
          fprintf(stderr, "\nghostwriter:\n");
          fprintf(stderr, "  Could not create file '%s'\n", fullpath);
          return(false);
     }

     if ((writer->cp_flag) && (writer->cp != NULL))
        cprght_file = xvf_strcpy(writer->cp);
     else
	cprght_file = xvf_strcpy("KHOROS_HOME/repos/utils/cpright.ghost");  
     /* 
      * print out first line of man1 page with time & date
      */
     clock = (time_t) time(NULL);
     strcpy (datestring, ctime(&clock));
     month[0]=datestring[4]; month[1]=datestring[5]; 
     month[2]=datestring[6]; month[3]='\0';
     if (strcmp (month, "Jan") == 0)
         strcpy (nummonth, "01");
     if (strcmp (month, "Feb") == 0)
         strcpy (nummonth, "02");
     if (strcmp (month, "Mar") == 0)
         strcpy (nummonth, "03");
     if (strcmp (month, "Apr") == 0)
         strcpy (nummonth, "04");
     if (strcmp (month, "May") == 0)
         strcpy (nummonth, "05");
     if (strcmp (month, "Jun") == 0)
         strcpy (nummonth, "06");
     if (strcmp (month, "Jul") == 0)
         strcpy (nummonth, "07");
     if (strcmp (month, "Aug") == 0)
         strcpy (nummonth, "08");
     if (strcmp (month, "Sep") == 0)
         strcpy (nummonth, "09");
     if (strcmp (month, "Oct") == 0)
         strcpy (nummonth, "10");
     if (strcmp (month, "Nov") == 0)
         strcpy (nummonth, "11");
     if (strcmp (month, "Dec") == 0)
         strcpy (nummonth, "12");
     day[0]=datestring[8]; day[1]=datestring[9]; day[2]='\0';
     year[0]=datestring[22]; year[1]=datestring[23]; year[2]='\0';

     sprintf(temp, ".TH %s 1  %s/%s/%s", name, nummonth, day, year);
     temp[(xvf_strlen(temp))-1] = '\0';

     fprintf(file, "%s", temp);

     /* 
      * print out name and description 
      */
     fprintf(file, "\n.SH PROGRAM\n");
     if (writer->format == NO_TEXT_FORMATTER)
	fprintf(file, ".nf\n");
     fprintf(file, "%s \\- ", name);

     /*
      * This part eats the white space at the beginning of the short
      * description and then prints the description minus the space.
      */
     if (xvf_strlen(prog_spec[ShortProgDesc]) > 0)  {
        i=0;
        c = (prog_spec[ShortProgDesc])[0];
        while ((c == ' ')||(c == '\t')||(c == '\n')) {
           i = i+1;
           c = (prog_spec[ShortProgDesc])[i];
        }
        if (xvf_strlen( &(prog_spec[ShortProgDesc][i]) ) > 0)  {
           fprintf(file, "%s", &(prog_spec[ShortProgDesc][i]) ); 
        }
     }
     else {
         fprintf(file, "\n");
     }

     if (writer->format == NO_TEXT_FORMATTER)
        fprintf(file, ".fi\n");


     /* 
      * print out syntax
      */
     fprintf(file, ".SH SYNTAX\n");
     fprintf(file, ".LP\n");
     gw_print_syntax(file, database, name, Man1Usage); 

     if ((strcmp(type, "xprog") == 0) || (strcmp(type, "fxprog") == 0))
     {
         fprintf(file, ".IP [-fn] 15 \nSpecifies the font for %s (use %% xlsfonts for available fonts)\n", name);
         fprintf(file, ".IP \"[-jr file.jp]\" 15 \nCreates a journal recording for %s\n", name);
         fprintf(file, ".IP \"[-jp file.jp]\" 15 \nExecutes a journal playback for %s\n", name);
     }
     fprintf(file, ".IP [-V]  \nGives the version for %s\n", name);
     fprintf(file, ".IP [-U]  \nGives the usage for %s\n", name);
     fprintf(file, ".IP [-P]  \nPrompts for command line options\n");
     fprintf(file, ".IP \"[-A [file1]]\"  \nCreates the answer file called %s.ans or file1\n", name);
     fprintf(file, ".IP \"[-a [file1]]\"  \nUses %s.ans or file1 as the answer file\n",name);

     /* 
      * print out description
      */
     fprintf(file, ".SH DESCRIPTION\n");
     if (writer->format == NO_TEXT_FORMATTER) {
	fprintf(file, ".nf\n");
        fprintf(file, "%s :\n", name);
     }
     if (xvf_strlen(prog_spec[Man1LongDesc]) > 0) 
         fprintf(file, "%s", prog_spec[Man1LongDesc]);
     if (writer->format == NO_TEXT_FORMATTER)
        fprintf(file, ".fi\n");

     /* 
      * print out required arguments
      */
     fprintf(file, ".SH REQUIRED ARGUMENTS\n");
     if ((gw_num_req > 0)    || 
	 (gw_num_me_req > 0) || 
	 (gw_num_tog_req > 0))
         gw_print_man1_req_args(file, database); 
     else
	 fprintf(file, "none\n.sp\n");
     
     /* 
      * print out optional arguments
      */
     fprintf(file, ".SH OPTIONAL ARGUMENTS\n");
     if ((gw_num_opt > 0)    || 
	 (gw_num_me_opt > 0) || 
	 (gw_num_tog_opt > 0))
         gw_print_man1_opt_args(file, database);  
     else
	 fprintf(file, "none\n.sp\n");

     /* 
      * print out I/O conventions
      */

     /* fprintf(file, ".SH INPUT/OUTPUT CONVENTIONS:\n");
        gw_print_man1_io_conv(file, name);  */
     
     /* 
      * print out examples
      */
     fprintf(file, ".SH EXAMPLES\n");
     if (writer->format == NO_TEXT_FORMATTER)
	fprintf(file, ".nf\n~~~~~~\n");
     if (xvf_strlen(prog_spec[Man1Examples]) > 0) 
         fprintf(file, "%s", prog_spec[Man1Examples]);
     if (writer->format == NO_TEXT_FORMATTER)
        fprintf(file, ".fi\n");

     /* 
      * print out "see also"
      */
     fprintf(file, ".SH SEE ALSO\n");
     sprintf (temp, "l%s", name);
     if ((xvf_strlen(prog_spec[MainLibCall]) > 0) &&
          (gw_find_string(prog_spec[MainLibCall], temp) == 0))
            fprintf(file,"intro(1), verror(3), vgparms(3), vutils(3), l%s(3)\n"
                    ,name);
     else
            fprintf(file,"intro(1), verror(3), vgparms(3), vutils(3)\n");
     if (writer->format == NO_TEXT_FORMATTER)
        fprintf(file, ".nf\n-and-\n");
     if (xvf_strlen(prog_spec[Man1SeeAlso]) > 0) 
        fprintf(file, "%s", prog_spec[Man1SeeAlso]);
     else
 	fprintf(file, "\n");
     if (writer->format == NO_TEXT_FORMATTER)
        fprintf(file, ".fi\n");

     /* 
      * print out restrictions
      */
     fprintf(file, ".SH RESTRICTIONS \n");
     if (writer->format == NO_TEXT_FORMATTER)
	fprintf(file, ".nf\n+++++\n");
     if (xvf_strlen(prog_spec[Man1Restrictions]) > 0) 
         fprintf(file, "%s", prog_spec[Man1Restrictions]);
     if (writer->format == NO_TEXT_FORMATTER)
        fprintf(file, ".fi\n");

     fprintf (file, ".SH COPYRIGHT\n");
     copyright = gw_copyright(cprght_file, "short");
     if (copyright != NULL) 
         fprintf(file, "%s\n", copyright);

     fclose(file);

     fprintf(stderr, "ghostwriter:  done generating '%s'\n", fullpath);
     return(true);
}





/************************************************************
*
*  Routine Name: gw_print_man1_req_args
*
*      Purpose:  This routine prints the required arguments to the man1 file 
*
*        Input:  file     - open stream to man1 page
*	 	 database - internal database struct
*
*	Output:  prints the required arguments to the man1 file
*
*    Called by:  gw_generate_man1file()
*
*   Written By:  Danielle Argiro
*
*************************************************************/

gw_print_man1_req_args(file, database)
FILE *file;
char **database;
{
    int index = 0, mut_excl_count = 0, toggle_count = 0;
    Line_Info line_info;
    mut_excl_link *mut_excl_ptr;
    gw_toggle_struct *toggle_ptr;
    char *mut_excl_def_var = NULL, *mut_excl_def_val = NULL;

    xvf_clear_line_info(&line_info);
    
    /* 
     * print out required arguments 
     */
    while (index < gw_num_req)
    {
        xvf_gen_parse(database[gw_req_args[index]], &line_info);
        fprintf(file, ".IP -%s 7\n", line_info.variable);
	fprintf(file, "type: %s\n.br\n", ascii_name(line_info.typeflag));
	fprintf(file, "desc: %s\n.br\n", line_info.description);
	index++;
    }

    /* 
     * print out any required toggles
     */

    while(toggle_count < gw_toggle_num)
    {
	toggle_ptr = gw_toggle[toggle_count];
	if (toggle_ptr->req == true)
	{
             fprintf(file, ".IP -%s 7\n", toggle_ptr->variable);
	     if (toggle_ptr->type != LogicOpt)
	        fprintf(file, "type: %s\n.br\n", ascii_name(toggle_ptr->type));
	     else fprintf(file, "type: integer\n.br\n");
	     fprintf(file, "desc: %s\n.br\n", toggle_ptr->desc);
	     fprintf(file, "allowed values: \n.br\n");
	     gw_print_toggle_vals(file, toggle_ptr, Man1Usage);
	     fprintf(file, "\n.br\n");
	}
	toggle_count++;
    }

    /* 
     * if there is one or more mutually exclusive groups, 
     * print out the group(s) if they are required 
     */

    while (mut_excl_count < gw_mut_excl_num)
    {
        mut_excl_ptr = gw_mut_excl[mut_excl_count];
        if (mut_excl_ptr->type == true)  /* mut excl group is required */
        {
            fprintf(file, "\n.SH    \n");
	    fprintf(file, "***   These arguments are MUTUALLY EXCLUSIVE   *** \n.br\n");
	    fprintf(file, "       You MUST provide ONE AND ONLY ONE of:\n.br\n");
	    mut_excl_ptr = mut_excl_ptr->next;
	    while (mut_excl_ptr != NULL)
	    {
		index = mut_excl_ptr->index;
		xvf_gen_parse(database[index], &line_info);
                fprintf(file, ".IP -%s 7\n", line_info.variable);
	        fprintf(file, "type: %s\n.br\n", ascii_name(line_info.typeflag));
	        fprintf(file, "desc: %s\n.br\n", line_info.description);
		if (line_info.opt_sel == true)
		{
		    mut_excl_def_var = xvf_strcpy(line_info.variable);
		    if ((line_info.typeflag != InputFile) &&
			(line_info.typeflag != OutputFile)) 
	    	        mut_excl_def_val = ascii_def_val(&line_info);
		    else
			mut_excl_def_val = xvf_strcpy(" ");
			
		}
		mut_excl_ptr = mut_excl_ptr->next;
	    }
	    if ((mut_excl_def_var == NULL) || (mut_excl_def_val == NULL))
	    {
		fprintf(stderr, "Ghostwriter:\n");
		fprintf(stderr, "Error: No default set for mutually\n");
		fprintf(stderr, "exclusive group number %d.\n", 
			mut_excl_count+1);
	        fprintf(stderr, "Aborting code generation.\n");
	        fclose(file);
		exit(1);
	    }
            fprintf(file, ".SH\n");
	    fprintf(file, "Default argument of mutually exclusive group: ");
	    fprintf(file, "-%s %s\n", mut_excl_def_var, mut_excl_def_val); 
	    fprintf(file, "\n********\n.sp\n");

        }
	mut_excl_count++;
    }
    fprintf(file, ".sp\n");
}

/************************************************************
*
*  Routine Name: gw_print_man1_opt_args
*
*      Purpose:  This routine prints the optional arguments to the man1 file 
*
*        Input:  file     - open stream to man1 page
*	 	 database - internal database struct
*
*	Output:  prints the optional arguments to the man1 file
*
*    Called by:  gw_generate_man1file()
*
*   Written By:  Danielle Argiro
*
*************************************************************/

gw_print_man1_opt_args(file, database)
FILE *file;
char **database;
{

    int index = 0, mut_excl_count = 0, toggle_count = 0;
    Line_Info line_info;
    mut_excl_link *mut_excl_ptr;
    gw_toggle_struct *toggle_ptr;

    xvf_clear_line_info(&line_info);

    /* 
     * print out optional arguments 
     */
    while (index < gw_num_opt)
    {
       
        xvf_gen_parse(database[gw_opt_args[index]], &line_info);
        fprintf(file, ".IP -%s 7\n", line_info.variable);
	fprintf(file, "type: %s\n.br\n", ascii_name(line_info.typeflag));
	fprintf(file, "desc: %s\n.br\n", line_info.description);
	if ((line_info.typeflag != InputFile) && 
	    (line_info.typeflag != OutputFile))
	    fprintf(file, "default: %s\n.br\n", ascii_def_val(&line_info));
	
        if (line_info.typeflag == FloatOpt)
            gw_print_bounds_float(file, &line_info, Man1Usage);

	else if (line_info.typeflag == IntegerOpt)
            gw_print_bounds_int(file, &line_info, Man1Usage);

	index++;
    }
    fprintf(file, ".sp\n");

    /* 
     * print out any optional toggles
     */
    while(toggle_count < gw_toggle_num)
    {
	toggle_ptr = gw_toggle[toggle_count];
	if (toggle_ptr->req == false)
	{
             fprintf(file, ".IP -%s 7\n", toggle_ptr->variable);
	     if (toggle_ptr->type != LogicOpt)
	        fprintf(file, "type: %s\n.br\n", ascii_name(toggle_ptr->type));
	     else fprintf(file, "type: integer\n.br\n");
	     fprintf(file, "desc: %s\n.br\n", toggle_ptr->desc);
	     fprintf(file, "allowed values:  \n.br\n");
	     gw_print_toggle_vals(file, toggle_ptr, Man1Usage);
	     fprintf(file, "\n.br\n");
	}
	toggle_count++;
        fprintf(file, ".sp\n");
    }

    /* 
     * if there is one or more mutually exclusive groups, 
     * print out the group(s) if they are optional 
     */

    while (mut_excl_count < gw_mut_excl_num)
    {
        mut_excl_ptr = gw_mut_excl[mut_excl_count];
        if (mut_excl_ptr->type == false)  /* mut excl group is optional */
        {
            fprintf(file, "\n.SH    \n");
	    fprintf(file, "***   These arguments are MUTUALLY EXCLUSIVE   *** \n.br\n");
	    fprintf(file, " If desired, you may provide ONE AND ONLY ONE of:\n.br\n");
	    mut_excl_ptr = mut_excl_ptr->next;
	    while (mut_excl_ptr != NULL)
	    {
		index = mut_excl_ptr->index;
		xvf_gen_parse(database[index], &line_info);
                fprintf(file, ".IP -%s 7\n", line_info.variable);
	        fprintf(file, "desc: %s\n.br\n", line_info.description);

		if ((line_info.typeflag != InputFile) && 
		    (line_info.typeflag != OutputFile))
	        fprintf(file, "default: %s\n.br\n", ascii_def_val(&line_info));

		if (line_info.typeflag == FloatOpt)
            	    gw_print_bounds_float(file, &line_info, Man1Usage);
		else if (line_info.typeflag == IntegerOpt)
            	    gw_print_bounds_int(file, &line_info, Man1Usage);

		mut_excl_ptr = mut_excl_ptr->next;
	    }
	    fprintf(file, "\n********\n.sp\n");

        }
	mut_excl_count++;
    }
}



/************************************************************
*
*  Routine Name: gw_man1_print_io_conv
*
*      Purpose:  This routine prints the I/O conventions to the man1 file 
*
*        Input:  file     - open stream to man1 page
*		 name     - name of the program being generated
*
*	Output:  prints the required arguments to the man1 file
*
*    Called by:  gw_generate_man1file()
*
*   Written By:  Danielle Argiro
*
*************************************************************/

gw_print_man1_io_conv(file, name)
FILE *file;
char *name;
{
    /*
     *  print out hardwired I/O convention statements 
     */
    fprintf(file, ".LP\n");
    fprintf(file, "stdin can be used for any input file but must\n");
    fprintf(file, "be specified by using a \"-\" for the file name.\n");
    fprintf(file, ".LP\n");
    fprintf(file, "stdout can be used for any output file but must\n");
    fprintf(file, "be specified by using a \"-\" for the file name.\n");
    fprintf(file, ".LP\n");
    fprintf(file, "stderr can be used for an ascii output file but must\n");
    fprintf(file, "be specified using \"#\" for the file name\n");
    fprintf(file, ".LP\n");
    fprintf(file, "%s will log its execution occurrence into a command\n",name);
    fprintf(file, "log file if the KHOROS_LOG environment variable is set ");
    fprintf(file, "as follows:\n.br\n%% setenv KHOROS_LOG filename\n");
    fprintf(file, ".LP\n");
    fprintf(file, "%s will print out a warning message and a default\n", name);
    fprintf(file, "value for each option that is not used if the KHOROS_VERBOSE\n");
    fprintf(file, "environment variable is set as follows:\n.br\n");
    fprintf(file, "%% setenv KHOROS_VERBOSE on\br");
}

