| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <ctype.h> |
| #include <errno.h> |
| |
| #include <starlet.h> |
| #include <lib$routines.h> |
| #include <ssdef.h> |
| #include <descrip.h> |
| #include <rms.h> |
| |
| typedef struct manl{ |
| struct manl *next; |
| char *filename; |
| }man, *manPtr; |
| |
| typedef struct pf_fabnam{ |
| struct FAB dfab; |
| struct RAB drab; |
| struct namldef dnam; |
| char expanded_filename[NAM$C_MAXRSS + 1]; |
| } pfn, *pfnPtr; |
| |
| /*----------------------------------------------------------*/ |
| |
| fpcopy( char *output, char *input, int len ) |
| { |
| char *is, *os; |
| int i; |
| |
| if ( len ){ |
| for ( is = input, os = output, i = 0; i < len ; ++i, ++is, ++os){ |
| *os = *is; |
| } |
| *os = 0; |
| }else{ |
| output[0] = 0; |
| } |
| } |
| |
| |
| /*----------------------------------------------------------*/ |
| /* give part of ilename in partname. See code for proper |
| value of i ( 0 = node, 1 = dev, 2 = dir,3 = name etc. |
| */ |
| |
| int fnamepart( char *inputfile, char *part, int whatpart ) |
| { |
| pfnPtr pf; |
| int status; |
| char ipart[6][256], *i, *p; |
| |
| pf = calloc( 1, sizeof( pfn ) ); |
| |
| pf->dfab = cc$rms_fab; |
| pf->drab = cc$rms_rab; |
| pf->dnam = cc$rms_naml; |
| |
| pf->dfab.fab$l_naml = &pf->dnam; |
| |
| pf->dfab.fab$l_fna = (char *) -1; |
| pf->dfab.fab$l_dna = (char *) -1; |
| pf->dfab.fab$b_fns = 0; |
| pf->dfab.fab$w_ifi = 0; |
| |
| pf->dnam.naml$l_long_defname = NULL; //inputfile; |
| pf->dnam.naml$l_long_defname_size = 0;//strlen( inputfile ); |
| |
| pf->dnam.naml$l_long_filename = inputfile; |
| pf->dnam.naml$l_long_filename_size = strlen( inputfile); |
| |
| pf->dnam.naml$l_long_expand = pf->expanded_filename; |
| pf->dnam.naml$l_long_expand_alloc = NAM$C_MAXRSS ; |
| |
| pf->dnam.naml$b_nop |= NAML$M_SYNCHK | NAML$M_PWD; |
| |
| status = sys$parse( &pf->dfab, 0,0); |
| if ( !(status&1) ){ |
| free( pf ); |
| return( status ); |
| } |
| |
| fpcopy ( ipart[0], pf->dnam.naml$l_long_node , pf->dnam.naml$l_long_node_size); |
| fpcopy ( ipart[1], pf->dnam.naml$l_long_dev , pf->dnam.naml$l_long_dev_size); |
| fpcopy ( ipart[2], pf->dnam.naml$l_long_dir , pf->dnam.naml$l_long_dir_size); |
| fpcopy ( ipart[3], pf->dnam.naml$l_long_name , pf->dnam.naml$l_long_name_size); |
| fpcopy ( ipart[4], pf->dnam.naml$l_long_type , pf->dnam.naml$l_long_type_size); |
| fpcopy ( ipart[5], pf->dnam.naml$l_long_ver , pf->dnam.naml$l_long_ver_size); |
| |
| for( i = ipart[ whatpart ], p = part; *i; ++i, ++p){ |
| if ( p == part ){ |
| *p = toupper( *i ); |
| }else{ |
| *p = tolower( *i ); |
| } |
| } |
| *p = 0; |
| |
| free( pf ); |
| return(1); |
| } |
| /*----------------------------------------------------------*/ |
| |
| int find_file(char *filename,char *gevonden,int *findex) |
| { |
| int status; |
| struct dsc$descriptor gevondend; |
| struct dsc$descriptor filespec; |
| char gevonden_file[NAM$C_MAXRSS + 1]; |
| |
| filespec.dsc$w_length = strlen(filename); |
| filespec.dsc$b_dtype = DSC$K_DTYPE_T; |
| filespec.dsc$b_class = DSC$K_CLASS_S; |
| filespec.dsc$a_pointer = filename; |
| |
| gevondend.dsc$w_length = NAM$C_MAXRSS; |
| gevondend.dsc$b_dtype = DSC$K_DTYPE_T; |
| gevondend.dsc$b_class = DSC$K_CLASS_S; |
| gevondend.dsc$a_pointer = gevonden_file; |
| |
| status=lib$find_file(&filespec,&gevondend,findex,0,0,0,0); |
| |
| if ( (status & 1) == 1 ){ |
| strcpy(gevonden,strtok(gevonden_file," ")); |
| }else{ |
| gevonden[0] = 0; |
| } |
| |
| return(status); |
| } |
| |
| |
| /*--------------------------------------------*/ |
| |
| manPtr addman( manPtr *manroot,char *filename ) |
| { |
| manPtr m,f; |
| |
| m = calloc( 1, sizeof( man) ); |
| if ( !m ) return( NULL ); |
| |
| m->filename = strdup( filename ); |
| |
| if ( *manroot == NULL ){ |
| *manroot = m; |
| }else{ |
| for( f = *manroot; f->next ; f = f->next ); |
| f->next = m; |
| } |
| return(m); |
| } |
| |
| /*--------------------------------------------*/ |
| void freeman( manPtr *manroot ) |
| { |
| manPtr m,n; |
| |
| for( m = *manroot; m ; m = n ){ |
| free( m->filename ); |
| n = m->next; |
| free ( m ); |
| } |
| *manroot = NULL; |
| } |
| |
| /*--------------------------------------------*/ |
| |
| int listofmans( char *filespec, manPtr *manroot ) |
| { |
| manPtr r; |
| int status; |
| int ffindex=0; |
| char gevonden[NAM$C_MAXRSS + 1]; |
| |
| while(1){ |
| status = find_file( filespec, gevonden, &ffindex ); |
| |
| if ( (status&1) ){ |
| r = addman( manroot, gevonden ); |
| if ( r == NULL ) return(2); |
| }else{ |
| if ( !( status&1)) break; |
| } |
| } |
| |
| lib$find_file_end( &ffindex); |
| if ( status == RMS$_NMF) status = 1; |
| |
| |
| return( status ); |
| } |
| |
| /*--------------------------------------------*/ |
| |
| int convertman ( char *filespec, FILE *hlp , int base_level, int add_parentheses ) |
| { |
| FILE *man; |
| char *in, *uit; |
| char *m,*h; |
| size_t len, thislen, maxlen= 50000; |
| int bol,mode, return_status=1; |
| char subjectname[ NAM$C_MAXRSS + 1 ]; |
| |
| in = calloc( 1, maxlen + 1 ); |
| uit = calloc( 1, maxlen + 1 ); |
| |
| if ( in == NULL || uit == NULL ) return(2); |
| |
| man = fopen( filespec, "r"); |
| if ( man == NULL ) return(vaxc$errno); |
| |
| for( len = 0; !feof( man ) && len < maxlen ; len += thislen ){ |
| thislen = fread( in + len, 1, maxlen - len, man ); |
| } |
| |
| fclose (man); |
| |
| m = in; |
| h = uit; |
| |
| *(m + len ) = 0; |
| |
| for ( mode = 0, bol = 1 ; *m; ++m ){ |
| |
| switch ( mode ){ |
| case 0: |
| switch(*m){ |
| case '.': |
| if ( bol ){ |
| mode = 1; |
| }else{ |
| *h = *m; |
| ++h; |
| } |
| break; |
| case '\\': |
| if ( bol ){ |
| *h = ' ';++h; |
| *h = ' ';++h; |
| } |
| mode = 2; |
| break; |
| default: |
| if ( bol ){ |
| *h = ' ';++h; |
| *h = ' ';++h; |
| } |
| *h = *m; |
| ++h; |
| break; |
| } |
| break; |
| case 1: /* after . at bol */ |
| |
| switch(*m){ |
| case '\\': |
| while( *m != '\n' && *m != '\r' && *m )++m; |
| mode = 0; |
| break; |
| case 'B': |
| ++m; |
| *h = ' ';++h; |
| mode = 0; |
| break; |
| case 'I': |
| /* remove preceding eol */ |
| if ( *(m+1) != 'P' ){ |
| --h; |
| while ( (*h == '\n' || *h == '\r') && h > uit )--h; |
| ++h; |
| } |
| |
| /* skip .Ix */ |
| for(;*m != ' ' && *m != '\n' && *m != '\r'; ++m); |
| |
| /* copy line up to EOL */ |
| |
| for(;*m != '\n' && *m != '\r' && *m; ++m, ++h)*h = *m; |
| |
| /* if line ends in ., this is an EOL */ |
| |
| if ( *(h-1) == '.'){ |
| --h; |
| --m; |
| }else{ |
| /* if line does not end in ., skip EOL in source */ |
| |
| if ( *(m+1) == '\n' || *(m+1) == '\r')++m; |
| } |
| mode = 0; |
| break; |
| case 'S': |
| if ( *(m+1) == 'H' ){ |
| *h = '\n';++h; |
| if ( strncmp( m+3 ,"NAME",4) == 0 || |
| strncmp( m+3 ,"SYNOPSIS",8) == 0 || |
| strncmp( m+3 ,"DESCRIPTION",11) == 0 ){ |
| while( *m != '\n' && *m != '\r')++m; |
| mode = 0; |
| }else{ |
| ++m; |
| |
| /* write help level, and flag it */ |
| |
| *h = '0' + base_level + 1;++h; |
| return_status |= 2; |
| |
| *h = ' ';++h; |
| |
| /* skip H (or whatever after S) and blank */ |
| ++m;++m; |
| |
| for(;*m != '\n' && *m != '\r' && *m; ++m, ++h){ |
| |
| /* write help label in lowercase, skip quotes */ |
| /* fill blanks with underscores */ |
| |
| if ( *m != '\"' ){ |
| *h = tolower( *m ); |
| if (*h == ' ') *h = '_'; |
| }else{ |
| --h; |
| } |
| } |
| |
| /* Add a linefeed or two */ |
| |
| *h = *m;++h; |
| *h = *m;++h; |
| |
| mode = 0; |
| } |
| } |
| break; |
| case 'T': |
| if ( *(m+1) == 'H' ){ |
| *h = '0' + base_level; ++h; |
| return_status |= 2; |
| *h = ' ';++h; |
| for ( m = m + 3; *m != ' ' && *m ; ++m, ++h ){ |
| *h = *m; |
| } |
| if ( add_parentheses ){ |
| *h = '(';++h; |
| *h = ')';++h; |
| } |
| while( *m != '\n' && *m != '\r' && *m )++m; |
| mode = 0; |
| } |
| break; |
| default: |
| ++m; |
| mode = 0; |
| break; |
| } |
| break; |
| case 2: /* after \ skip two characters or print the backslash */ |
| switch(*m){ |
| case '\\': |
| *h = *m; |
| ++h; |
| mode = 0; |
| break; |
| default: |
| ++m; |
| mode = 0; |
| break; |
| } |
| break; |
| } /*end switch mode */ |
| |
| bol = 0; |
| if ( *m == '\n' || *m == '\r') bol = 1; |
| |
| }/* end for mode */ |
| |
| *h = 0; |
| |
| |
| if ( (return_status&2) ){ |
| fprintf( hlp, "%s\n\n", uit); |
| }else{ |
| fnamepart( filespec, subjectname,3); |
| if ( *subjectname ){ |
| fprintf( hlp, "%d %s\n\n%s\n\n", base_level, subjectname, uit); |
| }else{ |
| /* No filename (as is the case with a logical), use first word as subject name */ |
| char *n,*s; |
| |
| for(n = in; isspace( *n );++n); |
| for(s = subjectname; !(isspace( *n )); ++n,++s)*s = *n; |
| *s = 0; |
| |
| fprintf( hlp, "%d %s\n\n%s\n\n", base_level, subjectname, uit); |
| } |
| } |
| |
| /* |
| printf( "read %d from %s, written %d to helpfile, return_status = %d\n", |
| len, filespec, strlen(uit), return_status ); |
| */ |
| |
| free( m ); |
| free( h ); |
| |
| return ( 1); |
| } |
| |
| /*--------------------------------------------*/ |
| |
| int convertmans( char *filespec, char *hlpfilename, int base_level, int append, int add_parentheses ) |
| { |
| int status=1; |
| manPtr manroot=NULL, m; |
| FILE *hlp; |
| |
| if ( append ){ |
| hlp = fopen( hlpfilename,"a+"); |
| }else{ |
| hlp = fopen( hlpfilename,"w"); |
| } |
| |
| if ( hlp == NULL ) return( vaxc$errno ); |
| |
| status = listofmans( filespec, &manroot ); |
| if ( !(status&1) ) return( status ); |
| |
| for ( m = manroot ; m ; m = m->next ){ |
| status = convertman( m->filename, hlp , base_level, add_parentheses ); |
| if ( !(status&1) ){ |
| fprintf(stderr,"Convertman of %s went wrong\n", m->filename); |
| break; |
| } |
| } |
| freeman( &manroot ); |
| return( status ); |
| } |
| |
| /*--------------------------------------------*/ |
| void print_help() |
| { |
| fprintf( stderr, "Usage: [-a] [-b x] convertman <manfilespec> <helptextfile>\n" ); |
| fprintf( stderr, " -a append <manfilespec> to <helptextfile>\n" ); |
| fprintf( stderr, " -b <baselevel> if no headers found create one with level <baselevel>\n" ); |
| fprintf( stderr, " and the filename as title.\n" ); |
| fprintf( stderr, " -p add parentheses() to baselevel help items.\n" ); |
| |
| } |
| /*--------------------------------------------*/ |
| |
| main ( int argc, char **argv ) |
| { |
| int status; |
| int i,j; |
| int append, base_level, basechange, add_parentheses; |
| char *manfile=NULL; |
| char *helpfile=NULL; |
| |
| if ( argc < 3 ){ |
| print_help(); |
| return( 1 ) ; |
| } |
| |
| append = 0; |
| base_level = 1; |
| basechange = 0; |
| add_parentheses = 0; |
| |
| for ( i = 1; i < argc; ++i){ |
| if ( argv[i][0] == '-' ){ |
| for( j = 1; argv[i][j] ; ++j ){ |
| switch( argv[i][j] ){ |
| case 'a': |
| append = 1; |
| break; |
| case 'b': |
| if ( (i+1) < argc ){ |
| base_level = atoi( argv[ i + 1 ] ); |
| basechange = 1; |
| } |
| break; |
| case 'p': |
| add_parentheses = 1; |
| break; |
| } |
| } |
| if ( basechange){ |
| basechange = 0; |
| i = i + 1; |
| } |
| }else{ |
| if ( manfile == NULL ){ |
| manfile = strdup( argv[i]); |
| } else if ( helpfile == NULL ){ |
| helpfile = strdup( argv[i]); |
| } else { |
| fprintf( stderr, "Unrecognized parameter : %s\n", argv[i]); |
| } |
| } |
| } |
| |
| |
| /* fprintf( stderr,"manfile: %s, helpfile: %s, append: %d, base_level : %d\n", |
| manfile, helpfile, append, base_level); |
| */ |
| |
| status = convertmans( manfile, helpfile, base_level, append, add_parentheses ); |
| |
| free( manfile ); |
| free( helpfile ); |
| |
| return( status ); |
| } |
| |
| |