1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <errno.h>
6 
7 #include <starlet.h>
8 #include <lib$routines.h>
9 #include <ssdef.h>
10 #include <descrip.h>
11 #include <rms.h>
12 
13 typedef struct manl{
14     struct manl *next;
15     char *filename;
16 }man, *manPtr;
17 
18 typedef struct pf_fabnam{
19     struct FAB dfab;
20     struct RAB drab;
21     struct namldef dnam;
22     char   expanded_filename[NAM$C_MAXRSS + 1];
23 } pfn, *pfnPtr;
24 
25 /*----------------------------------------------------------*/
26 
fpcopy(char * output,char * input,int len)27 fpcopy( char *output, char *input, int len )
28 {
29 char    *is, *os;
30 int i;
31 
32 if ( len ){
33     for ( is = input, os = output, i = 0; i < len ; ++i, ++is, ++os){
34             *os = *is;
35     }
36     *os = 0;
37 }else{
38     output[0] = 0;
39 }
40 }
41 
42 
43 /*----------------------------------------------------------*/
44 /* give part of ilename in partname. See code for proper
45    value of i ( 0 = node, 1 = dev, 2 = dir,3 = name etc.
46 */
47 
fnamepart(char * inputfile,char * part,int whatpart)48 int fnamepart( char *inputfile, char *part, int whatpart )
49 {
50 pfnPtr pf;
51 int     status;
52 char    ipart[6][256], *i, *p;
53 
54 pf = calloc( 1, sizeof( pfn ) );
55 
56 pf->dfab = cc$rms_fab;
57 pf->drab = cc$rms_rab;
58 pf->dnam = cc$rms_naml;
59 
60 pf->dfab.fab$l_naml = &pf->dnam;
61 
62 pf->dfab.fab$l_fna = (char *) -1;
63 pf->dfab.fab$l_dna = (char *) -1;
64 pf->dfab.fab$b_fns = 0;
65 pf->dfab.fab$w_ifi = 0;
66 
67 pf->dnam.naml$l_long_defname = NULL; //inputfile;
68 pf->dnam.naml$l_long_defname_size = 0;//strlen( inputfile );
69 
70 pf->dnam.naml$l_long_filename = inputfile;
71 pf->dnam.naml$l_long_filename_size = strlen( inputfile);
72 
73 pf->dnam.naml$l_long_expand = pf->expanded_filename;
74 pf->dnam.naml$l_long_expand_alloc = NAM$C_MAXRSS ;
75 
76 pf->dnam.naml$b_nop |= NAML$M_SYNCHK | NAML$M_PWD;
77 
78 status = sys$parse( &pf->dfab, 0,0);
79 if ( !(status&1) ){
80     free( pf );
81     return( status );
82 }
83 
84 fpcopy ( ipart[0], pf->dnam.naml$l_long_node , pf->dnam.naml$l_long_node_size);
85 fpcopy ( ipart[1], pf->dnam.naml$l_long_dev , pf->dnam.naml$l_long_dev_size);
86 fpcopy ( ipart[2], pf->dnam.naml$l_long_dir , pf->dnam.naml$l_long_dir_size);
87 fpcopy ( ipart[3], pf->dnam.naml$l_long_name , pf->dnam.naml$l_long_name_size);
88 fpcopy ( ipart[4], pf->dnam.naml$l_long_type , pf->dnam.naml$l_long_type_size);
89 fpcopy ( ipart[5], pf->dnam.naml$l_long_ver , pf->dnam.naml$l_long_ver_size);
90 
91 for( i = ipart[ whatpart ], p = part; *i; ++i, ++p){
92    if ( p == part ){
93       *p = toupper( *i );
94    }else{
95       *p = tolower( *i );
96    }
97 }
98 *p = 0;
99 
100 free( pf );
101 return(1);
102 }
103 /*----------------------------------------------------------*/
104 
find_file(char * filename,char * gevonden,int * findex)105 int find_file(char *filename,char *gevonden,int *findex)
106 {
107 int     status;
108 struct  dsc$descriptor gevondend;
109 struct  dsc$descriptor filespec;
110 char    gevonden_file[NAM$C_MAXRSS + 1];
111 
112 filespec.dsc$w_length = strlen(filename);
113 filespec.dsc$b_dtype  = DSC$K_DTYPE_T;
114 filespec.dsc$b_class  = DSC$K_CLASS_S;
115 filespec.dsc$a_pointer = filename;
116 
117 gevondend.dsc$w_length = NAM$C_MAXRSS;
118 gevondend.dsc$b_dtype  = DSC$K_DTYPE_T;
119 gevondend.dsc$b_class  = DSC$K_CLASS_S;
120 gevondend.dsc$a_pointer = gevonden_file;
121 
122 status=lib$find_file(&filespec,&gevondend,findex,0,0,0,0);
123 
124 if ( (status & 1) == 1 ){
125        strcpy(gevonden,strtok(gevonden_file," "));
126 }else{
127        gevonden[0] = 0;
128 }
129 
130 return(status);
131 }
132 
133 
134 /*--------------------------------------------*/
135 
addman(manPtr * manroot,char * filename)136 manPtr addman( manPtr *manroot,char *filename )
137 {
138 manPtr m,f;
139 
140 m = calloc( 1, sizeof( man) );
141 if ( !m ) return( NULL );
142 
143 m->filename = strdup( filename );
144 
145 if ( *manroot == NULL ){
146    *manroot = m;
147 }else{
148    for( f = *manroot; f->next ; f = f->next );
149    f->next = m;
150 }
151 return(m);
152 }
153 
154 /*--------------------------------------------*/
freeman(manPtr * manroot)155 void freeman( manPtr *manroot )
156 {
157 manPtr m,n;
158 
159 for( m = *manroot; m ; m = n ){
160      free( m->filename );
161      n = m->next;
162      free ( m );
163 }
164 *manroot = NULL;
165 }
166 
167 /*--------------------------------------------*/
168 
listofmans(char * filespec,manPtr * manroot)169 int listofmans( char *filespec, manPtr *manroot )
170 {
171 manPtr  r;
172 int     status;
173 int     ffindex=0;
174 char    gevonden[NAM$C_MAXRSS + 1];
175 
176 while(1){
177     status = find_file( filespec, gevonden, &ffindex );
178 
179     if ( (status&1) ){
180         r = addman( manroot, gevonden );
181         if ( r == NULL ) return(2);
182     }else{
183         if ( !( status&1)) break;
184     }
185 }
186 
187 lib$find_file_end( &ffindex);
188 if ( status == RMS$_NMF) status = 1;
189 
190 
191 return( status );
192 }
193 
194 /*--------------------------------------------*/
195 
convertman(char * filespec,FILE * hlp,int base_level,int add_parentheses)196 int convertman ( char *filespec, FILE *hlp , int base_level, int add_parentheses )
197 {
198 FILE    *man;
199 char    *in, *uit;
200 char    *m,*h;
201 size_t  len, thislen, maxlen= 50000;
202 int     bol,mode, return_status=1;
203 char subjectname[ NAM$C_MAXRSS + 1 ];
204 
205 in  = calloc( 1, maxlen + 1 );
206 uit = calloc( 1, maxlen + 1 );
207 
208 if ( in == NULL || uit == NULL ) return(2);
209 
210 man = fopen( filespec, "r");
211 if ( man == NULL ) return(vaxc$errno);
212 
213 for( len = 0; !feof( man ) && len < maxlen ; len += thislen ){
214     thislen = fread( in + len, 1, maxlen - len, man );
215 }
216 
217 fclose (man);
218 
219 m = in;
220 h = uit;
221 
222 *(m + len ) = 0;
223 
224 for ( mode = 0, bol = 1 ; *m; ++m ){
225 
226     switch ( mode ){
227         case 0:
228           switch(*m){
229             case '.':
230                 if ( bol ){
231                     mode = 1;
232                 }else{
233                     *h = *m;
234                     ++h;
235                 }
236                 break;
237             case '\\':
238                 if ( bol ){
239                    *h = ' ';++h;
240                    *h = ' ';++h;
241                 }
242                 mode = 2;
243                 break;
244             default:
245                 if ( bol ){
246                    *h = ' ';++h;
247                    *h = ' ';++h;
248                 }
249                 *h = *m;
250                 ++h;
251                 break;
252           }
253           break;
254         case 1: /* after . at bol */
255 
256           switch(*m){
257             case '\\':
258                 while( *m != '\n' && *m != '\r' && *m )++m;
259                 mode = 0;
260                 break;
261             case 'B':
262                    ++m;
263                    *h = ' ';++h;
264                    mode = 0;
265                    break;
266             case 'I':
267                     /* remove preceding eol */
268                     if ( *(m+1) != 'P' ){
269                         --h;
270                         while ( (*h == '\n' || *h == '\r') && h > uit )--h;
271                         ++h;
272                     }
273 
274                     /* skip .Ix */
275                     for(;*m != ' ' && *m != '\n' && *m != '\r'; ++m);
276 
277                     /* copy line up to EOL */
278 
279                     for(;*m != '\n' && *m != '\r' && *m; ++m, ++h)*h = *m;
280 
281                     /* if line ends in ., this is an EOL */
282 
283                     if ( *(h-1) == '.'){
284                          --h;
285                          --m;
286                     }else{
287                         /* if line does not end in ., skip EOL in source */
288 
289                         if ( *(m+1) == '\n' || *(m+1) == '\r')++m;
290                     }
291                     mode = 0;
292                     break;
293             case 'S':
294                  if ( *(m+1) == 'H' ){
295                     *h = '\n';++h;
296                     if ( strncmp( m+3 ,"NAME",4) == 0 ||
297                          strncmp( m+3 ,"SYNOPSIS",8) == 0 ||
298                          strncmp( m+3 ,"DESCRIPTION",11) == 0 ){
299                         while( *m != '\n' && *m != '\r')++m;
300                         mode = 0;
301                     }else{
302                         ++m;
303 
304                         /* write help level, and flag it */
305 
306                         *h = '0' + base_level + 1;++h;
307                         return_status |= 2;
308 
309                         *h = ' ';++h;
310 
311                         /* skip H (or whatever after S) and blank */
312                         ++m;++m;
313 
314                         for(;*m != '\n' && *m != '\r' && *m; ++m, ++h){
315 
316                            /* write help label in lowercase, skip quotes */
317                            /* fill blanks with underscores */
318 
319                            if ( *m != '\"' ){
320                                 *h = tolower( *m );
321                                 if (*h == ' ') *h = '_';
322                            }else{
323                                 --h;
324                            }
325                         }
326 
327                         /* Add a linefeed or two */
328 
329                         *h = *m;++h;
330                         *h = *m;++h;
331 
332                         mode = 0;
333                     }
334                  }
335                  break;
336             case 'T':
337                  if ( *(m+1) == 'H' ){
338                     *h = '0' + base_level; ++h;
339                     return_status |= 2;
340                     *h = ' ';++h;
341                     for ( m = m + 3; *m != ' ' && *m ; ++m, ++h ){
342                           *h = *m;
343                     }
344 					if ( add_parentheses ){
345 						 *h = '(';++h;
346 						 *h = ')';++h;
347 					}
348                     while( *m != '\n' && *m != '\r' && *m )++m;
349                     mode = 0;
350                  }
351                  break;
352             default:
353                 ++m;
354                 mode = 0;
355                 break;
356            }
357            break;
358         case 2: /* after \ skip two characters or print the backslash */
359           switch(*m){
360             case '\\':
361                 *h = *m;
362                 ++h;
363                 mode = 0;
364                 break;
365             default:
366                 ++m;
367                 mode = 0;
368                 break;
369            }
370            break;
371     } /*end switch mode */
372 
373     bol = 0;
374     if ( *m == '\n' || *m == '\r') bol = 1;
375 
376 }/* end for mode */
377 
378 *h = 0;
379 
380 
381 if ( (return_status&2) ){
382     fprintf( hlp, "%s\n\n", uit);
383 }else{
384     fnamepart( filespec, subjectname,3);
385     if ( *subjectname ){
386         fprintf( hlp, "%d %s\n\n%s\n\n", base_level, subjectname, uit);
387     }else{
388         /* No filename (as is the case with a logical), use first word as subject name */
389         char *n,*s;
390 
391         for(n = in; isspace( *n );++n);
392         for(s = subjectname; !(isspace( *n )); ++n,++s)*s = *n;
393         *s = 0;
394 
395         fprintf( hlp, "%d %s\n\n%s\n\n", base_level, subjectname, uit);
396     }
397 }
398 
399 /*
400  printf( "read %d from %s, written %d to helpfile, return_status = %d\n",
401     len, filespec, strlen(uit), return_status );
402 */
403 
404 free( m );
405 free( h );
406 
407 return ( 1);
408 }
409 
410 /*--------------------------------------------*/
411 
convertmans(char * filespec,char * hlpfilename,int base_level,int append,int add_parentheses)412 int convertmans( char *filespec, char *hlpfilename, int base_level, int append, int add_parentheses )
413 {
414 int status=1;
415 manPtr  manroot=NULL, m;
416 FILE    *hlp;
417 
418 if ( append ){
419     hlp = fopen( hlpfilename,"a+");
420 }else{
421     hlp = fopen( hlpfilename,"w");
422 }
423 
424 if ( hlp == NULL ) return( vaxc$errno );
425 
426 status = listofmans( filespec, &manroot );
427 if ( !(status&1) ) return( status );
428 
429 for ( m = manroot ; m ; m = m->next ){
430     status = convertman( m->filename, hlp , base_level, add_parentheses );
431     if ( !(status&1) ){
432         fprintf(stderr,"Convertman of %s went wrong\n", m->filename);
433         break;
434     }
435 }
436 freeman( &manroot );
437 return( status );
438 }
439 
440 /*--------------------------------------------*/
print_help()441 void print_help()
442 {
443    fprintf( stderr, "Usage: [-a] [-b x] convertman <manfilespec> <helptextfile>\n" );
444    fprintf( stderr, "       -a append <manfilespec> to <helptextfile>\n" );
445    fprintf( stderr, "       -b <baselevel> if no headers found create one with level <baselevel>\n" );
446    fprintf( stderr, "          and the filename as title.\n" );
447    fprintf( stderr, "       -p add parentheses() to baselevel help items.\n" );
448 
449 }
450 /*--------------------------------------------*/
451 
main(int argc,char ** argv)452 main ( int argc, char **argv )
453 {
454 int     status;
455 int     i,j;
456 int     append, base_level, basechange, add_parentheses;
457 char    *manfile=NULL;
458 char    *helpfile=NULL;
459 
460 if ( argc < 3 ){
461    print_help();
462    return( 1 ) ;
463 }
464 
465 append     = 0;
466 base_level = 1;
467 basechange = 0;
468 add_parentheses = 0;
469 
470 for ( i = 1; i < argc; ++i){
471     if ( argv[i][0] == '-' ){
472         for( j = 1; argv[i][j] ; ++j ){
473             switch( argv[i][j] ){
474                 case 'a':
475                     append = 1;
476                     break;
477                 case 'b':
478                     if ( (i+1) < argc ){
479                         base_level = atoi( argv[ i + 1 ] );
480                         basechange = 1;
481                     }
482                     break;
483                 case 'p':
484                     add_parentheses = 1;
485                     break;
486             }
487         }
488         if ( basechange){
489             basechange = 0;
490             i = i + 1;
491         }
492     }else{
493         if ( manfile == NULL ){
494             manfile = strdup( argv[i]);
495         } else if ( helpfile == NULL ){
496             helpfile = strdup( argv[i]);
497         } else {
498             fprintf( stderr, "Unrecognized parameter : %s\n", argv[i]);
499         }
500     }
501 }
502 
503 
504 /* fprintf( stderr,"manfile: %s, helpfile: %s, append: %d, base_level : %d\n",
505         manfile, helpfile, append, base_level);
506 */
507 
508 status = convertmans( manfile, helpfile, base_level, append, add_parentheses );
509 
510 free( manfile );
511 free( helpfile );
512 
513 return( status );
514 }
515 
516 
517