home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Hack-Phreak Scene Programs
/
cleanhpvac.zip
/
cleanhpvac
/
POVHELP.ZIP
/
source
/
phe2rtf.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-29
|
24KB
|
918 lines
/****************************************************************************
* PHLP2RTF.C - version 1.0
*
* This module implements the POV-Help database to Rich Text Format converter
*
* WARNING WARNING WARNING WARNING WARNING WARNING
*
* THIS PROGRAM IS NOT FINISHED AND THE RTF PRODUCED IS NOT EVEN *MEANT* TO WORK
* IT IS A ROUGH DRAFT OF A FIRST ATTEMPT AND IS PROVIDED AS IT FORMS A GOOD
* BASIS FOR PORTING POV-HELP'S OUTPUT TO ANOTHER TEXT FORMAT.
*
* from Persistence of Vision Raytracer
* Copyright 1994 Persistence of Vision Team
* Copyright 1994 Christopher J. Cason.
*---------------------------------------------------------------------------
* NOTICE: This source code file is provided so that users may experiment
* with enhancements to POV-Ray and to port the software to platforms other
* than those supported by the POV-Ray Team. There are strict rules under
* which you are permitted to use this file. The rules are in the file
* named POVLEGAL.DOC which should be distributed with this file. If
* POVLEGAL.DOC is not available or for more info please contact the POV-Ray
* Team Coordinator by leaving a message in CompuServe's Graphics Developer's
* Forum. The latest version of POV-Ray may be found there as well.
*
* POV-Ray files may also be obtained from ftp.uwa.edu.au in pub/povray.
*
* This program was written in its entirety by Christopher J. Cason.
* Its use is freely and permanently granted to the POV-Team and POV users
* under the conditions specified in POVLEGAL.DOC.
*
* Author : C. J. Cason (cjcason@yarrow.wt.uwa.edu.au, CIS 100032,1644)
*
*****************************************************************************/
/*---------------------------------------------------------------------------*/
/* NOTE : If you're porting this to another architecture, don't forget that */
/* the POV-Help database stores words and dwords in LSB-first format. */
/*---------------------------------------------------------------------------*/
#include <stdio.h>
#include <mem.h>
#include <string.h>
#include <alloc.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <bios.h>
#include <ctype.h>
#include "help.h"
typedef unsigned char uchar ;
#define MAX_REF 512
#define MAX_FRAGMENT 16
#define MAX_LINK 64
#define VSIZE_Y 128
#define VSIZE_X 128
#define TITLE 0x01
#define COPYRIGHT 0x02
#define AUTHOR 0x03
#define FAQ 0x04
#define CONTENTS 0x100
#define PRESERVE (preserve_formatting || code_fragment || line_drawing)
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
#define max(a,b) ((int) (a) > (int) (b) ? (a) : (b))
#define min(a,b) ((int) (a) < (int) (b) ? (a) : (b))
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
typedef struct
{
unsigned char start_vx ;
unsigned char end_vx ;
unsigned short id ;
unsigned short start_vy ;
unsigned short end_vy ;
} viewer_reference ;
typedef struct
{
unsigned char start_vx ;
unsigned char end_vx ;
unsigned short start_vy ;
unsigned short end_vy ;
} viewer_code_fragment ;
typedef struct
{
/* these first three entries must not be changed/moved */
unsigned long section ;
unsigned long section_length ;
unsigned char is_appendix ;
unsigned char number [16] ;
unsigned char title [80] ;
unsigned index ;
} viewer_toc ;
uchar *title ;
uchar *reference_strings ;
uchar **reference_string_index ;
unsigned char reference ;
unsigned char highlight ;
unsigned char bold ;
unsigned char code_fragment ;
unsigned char heading ;
unsigned char line_drawing ;
unsigned char preserve_formatting ;
unsigned char table ;
unsigned char list ;
unsigned char list_entry ;
unsigned char *toc ;
unsigned char *section ;
unsigned long links [MAX_LINK] ;
unsigned long *reference_index ;
unsigned short reference_count ;
unsigned short code_fragment_count ;
unsigned short TOCsize ;
unsigned short link_count ;
unsigned short noFAQ = 1 ;
unsigned short justifyOn = 1 ;
FILE *inF ;
FILE *outF ;
viewer_toc tc ;
viewer_reference *references ;
viewer_code_fragment *code_fragments ;
help_file_header header ;
char *rtf_header [] =
{
"{\\rtf1\\ansi \\deff0\\deflang1024\n",
"{\\fonttbl\n",
"{\\f0\\froman Times New Roman;}\n",
"{\\f1\\froman Symbol;}\n",
"{\\f2\\fswiss Arial;}\n",
"{\\f3\\froman CG Times (W1);}\n",
"{\\f4\\fswiss Univers (W1);}\n",
"{\\f5\\froman Tms Rmn;}\n",
"{\\f6\\fswiss Helv;}\n",
"{\\f7\\fmodern pica;}\n",
"{\\f8\\fmodern Courier;}\n",
"{\\f9\\fmodern Modern;}\n",
"{\\f10\\froman Roman;}\n",
"{\\f11\\fmodern Courier New;}}\n",
"{\\colortbl;\n",
"\\red0\\green0\\blue0;\n",
"\\red0\\green0\\blue255;\n",
"\\red0\\green255\\blue255;\n",
"\\red0\\green255\\blue0;\n",
"\\red255\\green0\\blue255;\n",
"\\red255\\green0\\blue0;\n",
"\\red255\\green255\\blue0;\n",
"\\red255\\green255\\blue255;\n",
"\\red0\\green0\\blue127;\n",
"\\red0\\green127\\blue127;\n",
"\\red0\\green127\\blue0;\n",
"\\red127\\green0\\blue127;\n",
"\\red127\\green0\\blue0;\n",
"\\red127\\green127\\blue0;\n",
"\\red127\\green127\\blue127;\n",
"\\red192\\green192\\blue192;\n",
"}\n",
"{\\stylesheet\n",
"{\\s242\\tqc\\tx4320\\tqr\\tx8640 \\f5\\fs20\\lang1033 \\sbasedon0\\snext242 footer;}\n",
"{\\s244 \\f5\\fs16\\up6\\lang1033 \\sbasedon0\\snext0 footnote reference;}\n",
"{\\s245 \\f5\\fs20\\lang1033 \\sbasedon0\\snext245 footnote text;}\n",
"{\\s252\\li360 \\b\\f5\\lang1033 \\sbasedon0\\snext255 heading 3;}\n",
"{\\s253\\sb120 \\b\\f6\\lang1033 \\sbasedon0\\snext0 heading 2;}\n",
"{\\s254\\sb240 \\b\\f6\\ul\\lang1033 \\sbasedon0\\snext0 heading 1;}\n",
"{\\s255\\li720 \\f5\\fs20\\lang1033 \\sbasedon0\\snext255 Normal Indent;}\n",
"{\\f5\\fs20\\lang1033 \\snext0 Normal;}\n",
"{\\info{\\title help.exe Project: help.exe Help}\n",
"{\\subject help.exe Help Index}\n",
"{\\author PHE2RTF converter copyright (c) 1994 Christopher J. Cason}\n",
"{\\doccomm help.exe Main help index.}\n",
"{\\creatim\\yr1994\\mo7\\dy9}\n",
"{\\revtim\\yr1994\\mo7\\dy9\\hr0\\min0}\n",
"{\\version1}\n",
"{\\edmins0}\n",
"{\\nofpages0}\n",
"{\\nofwords0}\n",
"{\\nofchars0}\n",
"{\\vern0}\n",
"}}\n",
"\\paperw12240\n",
"\\paperh15840\n",
"\\margl1800\n",
"\\margr1800\n",
"\\margt1440\n",
"\\margb1440\n",
"\\gutter0\n",
"\\ftnbj\n",
"{\\ftnsep \\pard\\plain \\f5\\fs20\\lang1033 \\par }\n",
"\\sectd \\linex576\\endnhere \\pard\\plain \\sl240 \\f5\\fs20\\lang1033\n",
NULL
} ;
/* in device_setup, do whatever setup is needed for your output medium */
void device_open (void)
{
char **s = rtf_header ;
while (*s)
fprintf (outF, "%s", *s++) ;
}
void device_close (void)
{
fprintf (outF, "}\n") ;
}
void process_section (unsigned start)
{
fprintf (outF, "%s", start ? "{\\f2 \n" : "\\page }\n") ;
}
void process_end (void)
{
fprintf (outF, "}") ;
}
void set_paragraph (void)
{
fprintf (outF, "\\par ") ;
}
void set_indent (void)
{
/* fprintf (outF, "\\li60 ") ; */
}
void set_highlight (unsigned state)
{
fprintf (outF, "\\%s ", state ? "ul" : "ul0") ;
}
void set_bold (unsigned state)
{
fprintf (outF, "\\%s ", state ? "b" : "b0") ;
}
void set_code_fragment (unsigned state)
{
fprintf (outF, "%s", state ? "{\\keep\\f11 " : "}") ;
}
void set_heading (unsigned state)
{
fprintf (outF, "%s", state ? "{\\qc " : "}") ;
}
void set_line_drawing (unsigned state)
{
fprintf (outF, "%s", state ? "{\\keep\\f11 " : "}") ;
}
void set_preserve (unsigned state)
{
fprintf (outF, "%s", state ? "{\\keep\\f11 " : "}") ;
}
void set_table (unsigned state)
{
set_preserve (state) ;
}
void set_reference (unsigned state, viewer_reference *r)
{
fprintf (outF, "\\%s ", state ? "ul" : "ul0") ;
}
void set_list (unsigned state, unsigned count)
{
}
void set_list_entry (unsigned state, unsigned count)
{
}
void vputchar (char ch)
{
if ((unsigned char) ch < 0x80 && strchr ("\\{}", ch) == NULL)
fprintf (outF, "%c", ch) ;
else
fprintf (outF, "\\'%02x", ch) ;
}
void vputstr (char *s)
{
while (*s)
vputchar (*s++) ;
}
unsigned pointcount (char *s)
{
unsigned count = 0 ;
while (*s)
if (*s++ == '.')
count++ ;
return (count) ;
}
unsigned ustrcmp (char *s1, char *s2)
{
while (*s1 && *s2)
if (toupper (*s1++) != toupper (*s2++))
return (1) ;
return (*s1 || *s2) ;
}
viewer_reference *create_reference (unsigned short id)
{
if (reference_count == MAX_REF) return (NULL) ;
references [reference_count].id = id ;
return (references + reference_count++) ;
}
void clear_references (void)
{
reference_count = 0 ;
}
viewer_code_fragment *create_code_fragment (void)
{
if (code_fragment_count == MAX_FRAGMENT) return (NULL) ;
return (code_fragments + code_fragment_count++) ;
}
void clear_code_fragments (void)
{
code_fragment_count = 0 ;
}
viewer_toc *getTC (unsigned index)
{
uchar *s ;
static viewer_toc result ;
if (index >= header.section_count + header.appendix_count) index = 0 ;
s = toc + (unsigned) ((unsigned long) TOCsize * index) ;
memcpy (&result, s, sizeof (TOC_entry)) ;
s += sizeof (TOC_entry) ;
strcpy (result.number, s) ;
strcpy (result.title, s + header.sec_number_len) ;
result.index = index ;
return (&result) ;
}
viewer_toc *findTCfromOffset (unsigned long offset)
{
unsigned i ;
static viewer_toc result ;
for (i = 0 ; i < header.section_count + header.appendix_count ; i++)
{
result = *getTC (i) ;
if (result.section > offset) continue ;
if (result.section + result.section_length <= offset) continue ;
return (&result) ;
}
return (NULL) ;
}
char *get_section (viewer_toc *tc, unsigned number)
{
uchar *section ;
unsigned count ;
*tc = *getTC (number) ;
fseek (inF, tc->section, SEEK_SET) ;
if (tc->section_length + 1 > 65534U)
{
printf ("section too big for present allocation code") ;
return (NULL) ;
}
if ((section = calloc ((unsigned) tc->section_length + 1, 1)) == NULL)
{
printf ("error - cannot allocate enough memory for section %s", tc->number) ;
return (NULL) ;
}
if (fread (section, (unsigned) tc->section_length + 1, 1, inF) == 0)
{
printf ("could not read section") ;
return (NULL) ;
}
count = (unsigned) tc->section_length ;
while (section [count - 1] == '\n' || section [count - 1] == PARAGRAPH) count-- ;
section [count] = '\0' ;
return (section) ;
}
unsigned findSection (char *s)
{
unsigned i ;
viewer_toc result ;
for (i = 0 ; i < header.section_count + header.appendix_count ; i++)
{
result = *getTC (i) ;
if (ustrcmp (s, result.number)) continue ;
return (i) ;
}
return (-1) ;
}
unsigned findTitle (char *s)
{
static char str [80] ;
unsigned i ;
viewer_toc result ;
strupr (s) ;
for (i = 0 ; i < header.section_count + header.appendix_count ; i++)
{
result = *getTC (i) ;
if (ustrcmp (s, result.title)) continue ;
return (i) ;
}
for (i = 0 ; i < header.section_count + header.appendix_count ; i++)
{
result = *getTC (i) ;
strcpy (str, result.title) ;
strupr (str) ;
if (strstr (str, s) == NULL) continue ;
return (i) ;
}
return (-1) ;
}
void format_section (viewer_toc *tc, unsigned char *section)
{
unsigned id ;
unsigned escape = 0 ;
unsigned char *s ;
viewer_reference *r ;
clear_references () ;
clear_code_fragments () ;
process_section (TRUE) ;
if (tc)
{
set_heading (TRUE) ;
if (tc->is_appendix) vputstr ("APPENDIX ") ;
vputstr (tc->number) ;
vputstr ("\t") ;
vputstr (tc->title) ;
set_heading (FALSE) ;
}
while (*section == '\n' || *section == PARAGRAPH) section++ ;
for (s = section ; *s ; s++)
{
if (escape == 0)
{
switch (*s)
{
case ESCAPE :
escape++ ;
break ;
case PARAGRAPH :
set_paragraph () ;
break ;
case INDENT :
set_indent () ;
break ;
case REFERENCE :
id = *++s ;
id += (unsigned) *++s * 256 ;
r = create_reference (id) ;
break ;
case TARGET :
break ;
case REFERENCE_ON :
if (r == NULL) break ;
set_reference (TRUE, r) ;
break ;
case REFERENCE_OFF :
if (r == NULL) break ;
set_reference (FALSE, r) ;
r = NULL ;
break ;
case HIGHLIGHT_ON :
case HIGHLIGHT_OFF :
set_highlight (*s == HIGHLIGHT_ON) ;
break ;
case BOLD_ON :
case BOLD_OFF :
set_bold (*s == BOLD_ON) ;
break ;
case CODE_ON :
code_fragment++ ;
set_code_fragment (TRUE) ;
break ;
case CODE_OFF :
code_fragment = 0 ;
set_code_fragment (FALSE) ;
break ;
case HEADING_ON :
case HEADING_OFF :
set_heading (*s == HEADING_ON) ;
break ;
case LINE_ON :
case LINE_OFF :
set_line_drawing (*s == LINE_ON) ;
break ;
case PRESERVE_ON :
case PRESERVE_OFF :
set_preserve (*s == PRESERVE_ON) ;
break ;
case TABLE_ON :
case TABLE_OFF :
set_table (*s == TABLE_ON) ;
break ;
case LIST_ON :
if ((list = *++s) == 1) list++ ;
set_list (TRUE, list) ;
break ;
case LIST_OFF :
set_list (FALSE, list) ;
break ;
case LIST_ENTRY_ON :
list_entry++ ;
set_list_entry (TRUE, list) ;
break ;
case LIST_ENTRY_OFF :
list_entry = 0 ;
while (*s == ' ') s++ ;
set_list_entry (FALSE, list) ;
break ;
default :
vputchar (*s) ;
break ;
}
}
else
{
vputchar (*s) ;
escape = 0 ;
}
}
if (reference)
{
reference_count-- ;
reference = 0 ;
}
process_section (FALSE) ;
}
void format_authors (char *s)
{
clear_references () ;
vputstr ("AUTHORS\r\n") ;
vputstr (s) ;
}
void load_links (void)
{
unsigned child_count ;
link_count = 0 ;
fseek (inF, reference_index [references [0].id], SEEK_SET) ;
fread (&child_count, 2, 1, inF) ;
if (child_count >= MAX_LINK - 1) child_count = MAX_LINK - 1 ;
fread (links, 4, link_count = child_count + 1, inF) ;
}
void display_text (unsigned what)
{
char *text ;
char *s ;
unsigned i ;
unsigned long offset ;
unsigned long length ;
process_section (TRUE) ;
switch (what)
{
case COPYRIGHT :
offset = header.copyright ;
length = header.copyright_length ;
break ;
case AUTHOR :
offset = header.authors ;
length = header.author_length ;
break ;
default :
return ;
}
if (length > 65534U)
{
printf ("section too big for present allocation code\r\n") ;
return ;
}
if ((text = calloc ((unsigned) length + 1, 1)) == NULL)
{
printf ("cannot allocate memory for text\r\n") ;
return ;
}
fseek (inF, offset, SEEK_SET) ;
if (fread (text, (unsigned) length + 1, 1, inF) == 0)
{
printf ("could not read text\r\n") ;
free (text) ;
return ;
}
text [(unsigned) length] = 0 ;
for (s = text, i = (unsigned) length ; i ; i--, s++)
if (*s == '\0')
*s = '\n' ;
if (what == AUTHOR)
format_authors (text) ;
else
format_section (NULL, text) ;
free (text) ;
process_section (FALSE) ;
}
void display_contents (void)
{
unsigned i ;
unsigned offset ;
viewer_toc tc ;
clear_references () ;
process_section (TRUE) ;
vputstr (title) ;
for (i = 0 ; i < header.section_count + header.appendix_count ; i++)
{
if (i == header.section_count)
{
vputstr ("*** APPENDICES ***") ;
}
tc = *getTC (i) ;
if (noFAQ && strstr (tc.title, "FREQUENTLY ASKED QUESTIONS") != NULL) break ;
offset = pointcount (tc.number) * 3 ;
vputstr (tc.number) ;
vputstr ("\t") ;
vputstr (tc.title) ;
}
process_section (FALSE) ;
}
unsigned load_strings (void)
{
char *s ;
char str [81] ;
unsigned i ;
unsigned count ;
if ((reference_strings = farcalloc ((unsigned) header.reference_string_length, 1)) == NULL) return (1) ;
if ((reference_string_index = farcalloc (header.reference_count * 4, 1)) == NULL) return (1) ;
s = reference_strings ;
for (i = 0 ; i < header.reference_count ; i++)
{
fseek (inF, reference_index [i], SEEK_SET) ;
fread (&count, 2, 1, inF) ;
fseek (inF, (count + 1) * 4, SEEK_CUR) ;
if (fgets (str, 80, inF) == NULL) break ;
strcpy (s, str) ;
reference_string_index [i] = s ;
s += strlen (str) + 1 ;
}
return (0) ;
}
void init (void)
{
if ((references = calloc (sizeof (viewer_reference), MAX_REF)) == NULL)
{
printf ("cannot allocate memory for references\r\n") ;
exit (1) ;
}
if ((code_fragments = calloc (sizeof (viewer_code_fragment), MAX_FRAGMENT)) == NULL)
{
printf ("cannot allocate memory for code fragments\r\n") ;
exit (1) ;
}
if ((toc = malloc ((unsigned) header.table_of_contents_length)) == NULL)
{
printf ("cannot allocate memory for table of contents\r\n") ;
exit (1) ;
}
TOCsize = sizeof (TOC_entry) + header.sec_number_len + header.sec_title_len ;
if ((reference_index = malloc ((unsigned) header.reference_index_length)) == NULL)
{
printf ("cannot allocate memory for reference index\r\n") ;
exit (1) ;
}
fseek (inF, header.reference_index, SEEK_SET) ;
if (fread (reference_index, (unsigned) header.reference_index_length, 1, inF) == 0)
{
printf ("could not read reference index\r\n") ;
exit (1) ;
}
if ((title = calloc ((unsigned) header.title_length + 1, 1)) == NULL)
{
printf ("cannot allocate memory for title\r\n") ;
exit (1) ;
}
fseek (inF, header.title, SEEK_SET) ;
if (fread (title, (unsigned) header.title_length + 1, 1, inF) == 0)
{
printf ("could not read title\r\n") ;
exit (1) ;
}
title [(unsigned) header.title_length] = 0 ;
if (load_strings ())
{
printf ("could not load reference strings\r\n") ;
exit (1) ;
}
}
unsigned main (unsigned argc, char *argv [])
{
int number = -1 ;
int count = -1 ;
char *s1 = "HELP.PHE" ;
char *s2 = "" ;
char gotoSection [16] = "1.0" ;
char gotoTitle [80] = "" ;
while (++argv, --argc)
{
if (**argv == '-' || **argv == '+')
{
switch (toupper ((*argv) [1]))
{
case 'I' :
s1 = *argv + 2 ;
break ;
case 'O' :
s2 = *argv + 2 ;
break ;
case 'F' :
noFAQ = 0 ;
break ;
case 'N' :
number = atoi (*argv + 2) ;
if (count == -1) count = 0 ;
break ;
case 'S' :
strncpy (gotoSection, *argv + 2, 15) ;
if (count == -1) count = 0 ;
break ;
case 'T' :
strncpy (gotoTitle, *argv + 2, 79) ;
if (count == -1) count = 0 ;
break ;
case 'C' :
count = atoi (*argv + 2) ;
break ;
case 'J' :
justifyOn = (*argv) [2] != '-' ;
break ;
case '?' :
case 'H' :
printf ("\r\nPHE2RTF : POV-Help to Rich Text Format\r\n\n") ;
printf ("-i : set input file name (default HELP.PHE)\r\n") ;
printf ("-o : set output file name (default stdout)\r\n") ;
printf ("-j[-] : justify ON (default), -j- to turn off\r\n") ;
printf ("-f : include FAQ section (if present) in output (default omit)\r\n") ;
printf ("-sX.Y : start from section X.Y (default 1.0)\r\n") ;
printf ("-tABC : start from section with title ABC\r\n") ;
printf ("-nn : start from the nth section (first = 0)\r\n") ;
printf ("-cn : process 'n' sections (default all unless -s, -t or -n, where 'n' = 1)\r\n") ;
printf ("\r\n") ;
return (0) ;
default :
printf ("unknown option '%s'\r\n", *argv) ;
return (1) ;
}
}
}
if ((inF = fopen (s1, "rb")) == NULL)
{
printf ("could not open input file '%s'\r\n", s1) ;
printf ("use phe2rtf -h for help\r\n") ;
return (1) ;
}
if (*s2)
{
if ((outF = fopen (s2, "wt")) == NULL)
{
printf ("could not open output file '%s'\r\n", s2) ;
printf ("use phe2rtf -h for help\r\n") ;
return (1) ;
}
}
else
outF = stdout ;
if (fread (&header, sizeof (help_file_header), 1, inF) == 0)
{
printf ("could not read header\r\n") ;
return (1) ;
}
if (memcmp (header.signature, "POV-Help", 8) != 0)
{
printf ("header ID failed consistency check\r\n") ;
return (1) ;
}
if (header.reader_version > VERSION)
{
printf ("version error ! database is not compatible [needs version %d.%d of reader]\r\n",
header.reader_version / 100, header.reader_version % 100) ;
return (1) ;
}
init () ;
fseek (inF, header.table_of_contents, SEEK_SET) ;
if (fread (toc, (unsigned) header.table_of_contents_length, 1, inF) == 0)
{
printf ("could not read table of contents\r\n") ;
return (1) ;
}
device_open () ;
if (*gotoTitle) number = findTitle (gotoTitle) ;
if (*gotoSection) number = findSection (gotoSection) ;
if (number == -1)
{
number = 0 ;
count = header.appendix_count + header.section_count ;
}
else
if (count == 0)
count = 1 ;
if (count == -1)
count = header.appendix_count + header.section_count - number ;
if (number + count > header.appendix_count + header.section_count)
count = header.appendix_count + header.section_count - number ;
/*display_contents () ;*/
while (count--)
{
section = get_section (&tc, number++) ;
if (noFAQ && strstr (tc.title, "FREQUENTLY ASKED QUESTIONS") != NULL) break ;
format_section (&tc, section) ;
free (section) ;
}
/*clear_references () ;*/
/*display_text (AUTHOR) ;*/
device_close () ;
farfree (reference_string_index) ;
farfree (reference_strings) ;
free (toc) ;
free (code_fragments) ;
free (references) ;
free (title) ;
fclose (inF) ;
return (0) ;
}