home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 24
/
CD_ASCQ_24_0995.iso
/
vrac
/
ged2ht23.zip
/
MAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-14
|
12KB
|
387 lines
/*
* Copyright (c) 1995 Eugene W. Stark
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eugene W. Stark.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* 5. No copying or redistribution in any form for commercial purposes is
* permitted without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY EUGENE W. STARK (THE AUTHOR) ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "node.h"
#include "read.h"
#include "database.h"
#include "output.h"
#include "tags.h"
#define VERSION "GEDCOM to HTML translator, version 2.3a (July 14 1995)\n" \
"by Gene Stark (stark@cs.sunysb.edu).\n"
#define COPYRIGHT "Copyright (c) 1995 Eugene W. Stark. All rights reserved.\n" \
"See file COPYRIGHT for copying information.\n"
#define USAGE "Usage: %s [-Hcgiv][-d <files-per-directory>][-n <indivs-per-file>][-s <individual> ...][-f <file-template>][-S <surname-template>][-t <individual-template>][-T <index-template>][-w <index-width>] [[--] <gedcom-file> ...]\n", argv[0]
#define OPTIONS " -H\t\t\tPrint a brief message listing the available options.\n" \
" -v\t\t\tPrint version number of program and copyright info.\n" \
" -c\t\t\tDisable automatic capitalization of surnames.\n" \
" -d files_per_directory\tSpecify number of files per subdirectory\n" \
"\t\t\t(0 means don't use subdirectories).\n" \
" -f file_template\tSpecify a template string for the names of the\n" \
"\t\t\tHTML files (default '%%s.html' or '%%s.htm').\n" \
" -g\t\t\tForce production of the textual index file (for use by\n" \
"\t\t\tautomatic indexers).\n" \
" -i\t\t\tDo not generate index files containing entries\n" \
"\t\t\tfor all the individuals and surnames in the input.\n" \
" -n indivs_per_file\tOutput files contain specified number of individuals\n" \
"\t\t\t(0 means don't put multiple individuals per file).\n" \
" -p depth\t\tInclude pedigree charts of the specified depth.\n" \
"\t\t\t(0 means don't include any pedigree charts).\n" \
" -s individuals ...\tLimit the production of output files to a specified\n" \
"\t\t\tlist of zero or more selected individuals.\n" \
" -S surname_template\tSpecify a template file for surname index.\n" \
" -t individual_template\tSpecify a template file for individuals.\n" \
" -T index_template\tSpecify a template file for individual index.\n" \
" -w index_width\t\tCreate hierarchical index of specified width\n" \
"\t\t\t(0 means put all individuals in one index file)\n"
int generate_index = 1;
int generate_gendex;
char print_template;
char **selected_individuals;
struct node head;
void must_be_number(char c, char *a);
main(int argc, char *argv[])
{
struct node *np;
int i, optc;
extern char *optarg;
extern int optind;
FILE *gedcom_file;
int serial = 0;
#ifdef MSDOS
int getopt(int argc, char *const *argv, const char *optstring);
extern char *optarg;
extern int optind;
#endif
validate_tags_tables();
#ifdef MSDOS
printf("%s\n", VERSION);
printf("%s\n", COPYRIGHT);
if(argc <= 1) {
#ifdef MSWINDOWS
fprintf(stderr, "Launch this program from the File Manager, using the\n");
fprintf(stderr, "'Run' item under the 'File' menu to specify command-line\n");
fprintf(stderr, "arguments.\n");
#endif
fprintf(stderr, USAGE);
exit(1);
}
#endif
while((optc = getopt(argc, argv, "Hvgiscd:f:S:t:T:n:p:w:")) != -1) {
FILE *tempf;
long size;
char *temps, *tempe, c;
switch(optc) {
case 'v': /* Version */
printf("%s\n", VERSION);
printf("%s", COPYRIGHT);
exit(0);
case 'c': /* Disable automatic capitalization of surnames */
capitalization = 0;
break;
case 'g': /* Generate limited-information GEDCOM file */
generate_gendex = 1;
break;
case 'i': /* Do not generate index */
generate_index = 0;
break;
case 's': /* Generate record(s) for selected individual(s) */
{
int i = 0;
int j;
while(argv[optind+i] && argv[optind+i][0] != '-')
i++;
if(!(selected_individuals = malloc((i+1) * sizeof(char *))))
out_of_memory();
for (j = 0; j < i; j++)
selected_individuals[j] = argv[optind+j];
selected_individuals[j]=NULL;
optind += i;
}
break;
case 't': /* Template file for individuals */
case 'T': /* Template file for the individual index */
case 'S': /* Template file for the surname index */
/*
* If filename starts with '-', print the internal template
* on the standard output. I got tired of trying to keep the
* sample templates in sync with the internal ones.
*/
if(*optarg == '-') {
print_template = optc;
break;
}
if((tempf = fopen(optarg, "r")) == NULL) {
fprintf(stderr, "Can't open template file '%s'\n", optarg);
break;
}
if(fseek(tempf, 0L, SEEK_END) == -1 || (size = ftell(tempf)) == -1){
fprintf(stderr, "Can't determine length of template file '%s'\n",
optarg);
fclose(tempf);
break;
}
rewind(tempf);
if((temps = malloc((size_t) size+1)) == NULL) {
fprintf(stderr, "Can't allocate memory for template string\n");
fclose(tempf);
break;
}
tempe = temps;
while((c = fgetc(tempf)) != EOF && tempe-temps <= size)
*tempe++ = c;
*tempe = '\0';
if(optc == 't')
individual_template = temps;
else if(optc == 'T')
index_template = temps;
else if(optc == 'S')
surname_template = temps;
break;
case 'd': /* Specify files per directory */
must_be_number('d', optarg);
if((files_per_directory = atoi(optarg)) < 0) {
fprintf(stderr,
"Number of individuals per directory must be nonnegative\n");
exit(1);
}
break;
case 'n': /* Specify number of individuals per output file */
must_be_number('n', optarg);
if((indivs_per_file = atoi(optarg)) < 0) {
fprintf(stderr,
"Number of individuals per file must be nonnegative\n");
exit(1);
}
break;
case 'p': /* Create pedigree files */
must_be_number('p', optarg);
if((pedigree_depth = atoi(optarg)) < 0 || pedigree_depth > 15) {
fprintf(stderr, "Pedigree chart depth must be between 0 and 15\n");
exit(1);
}
break;
case 'w': /* Specify width of hierarchical index */
must_be_number('w', optarg);
if((index_width = atoi(optarg)) < 0 || index_width == 1) {
fprintf(stderr, "Index width must be either 0 or greater than 1\n");
exit(1);
}
break;
case 'f': /* Template for file names */
file_template = optarg;
break;
case 'H':
printf(USAGE);
printf(OPTIONS);
exit(0);
case '?':
default:
fprintf(stderr, USAGE);
exit(1);
}
}
if(indivs_per_file)
indivs_per_directory = files_per_directory * indivs_per_file;
else
indivs_per_directory = files_per_directory;
if(individual_template == NULL) {
int size = 1;
if(indivs_per_directory)
individual_template_base[INDEX_ANCHOR_POS] = INDEX_ANCHOR_SUBDIR;
for(i = 0; i < individual_template_base_size; i++)
size += strlen(individual_template_base[i]);
if((individual_template = malloc(size)) == NULL)
out_of_memory();
*individual_template = '\0';
for(i = 0; i < individual_template_base_size; i++)
strcat(individual_template, individual_template_base[i]);
}
if(print_template != '\0') {
switch(print_template) {
case 't':
printf(individual_template);
break;
case 'T':
printf(index_template);
break;
case 'S':
printf(surname_template);
break;
default:
break;
}
exit(0);
}
if(optind == argc) {
current_gedcom = "stdin";
current_lineno = 0;
read_gedcom(stdin, &head, 0);
} else {
for(np = &head ; optind < argc; optind++) {
current_gedcom = argv[optind];
current_lineno = 0;
if((gedcom_file = fopen(argv[optind], "r")) == NULL) {
fprintf(stderr, "Can't open GEDCOM file '%s'.\n", argv[optind]);
continue;
}
read_gedcom(gedcom_file, np, 0);
fclose(gedcom_file);
while(np->siblings)
np = np->siblings;
}
}
if(head.siblings == NULL) {
fprintf(stderr, "No valid GEDCOM lines found\n");
exit(1);
}
process_records(head.siblings);
link_records(head.siblings);
fprintf(stderr, "Processed %ld GEDCOM lines", gedcom_lines);
if(total_individuals)
fprintf(stderr, ", %d individuals", total_individuals);
if(total_families)
fprintf(stderr, ", %d families", total_families);
if(total_events)
fprintf(stderr, ", %d events", total_events);
if(total_sources)
fprintf(stderr, ", %d sources", total_sources);
if(total_notes)
fprintf(stderr, ", %d notes", total_notes);
fprintf(stderr, "\n");
/*
* Determine individuals to be output, and assign them serial numbers.
*/
for(i = 0; i < total_individuals; i++) {
char **av;
if(selected_individuals != NULL) {
for(av = selected_individuals; *av != NULL; av++)
if(!strcmp(*av, all_individuals[i]->xref)) {
all_individuals[i]->serial = ++serial;
}
} else {
all_individuals[i]->serial = ++serial;
}
}
/*
* Generate index files
*/
if(index_width == 0)
index_depth = 1;
else {
for(index_depth = 1, i = total_individuals;
i > index_width;
index_depth++, i /= index_width);
}
if(generate_index) {
index_individuals();
index_surnames(index_root);
output_index(index_root);
output_surnames(surname_head);
}
if(generate_index || generate_gendex)
output_gendex(all_individuals[0]);
/*
* Output individuals
*/
for(i = 0; i < total_individuals; i++) {
if(all_individuals[i]->serial)
output_individual(all_individuals[i]);
}
exit(0);
}
/*
* This is probably easier than writing a decent getopt for MSDOS...
*/
void must_be_number(char c, char *a)
{
while(*a != '\0') {
if(*a < '0' || *a > '9') {
fprintf(stderr, "Option '-%c' requires a numeric argument "
"('%s' supplied)\n", c, a);
exit(1);
}
a++;
}
}
#ifdef MSDOS
char *optarg;
int optind = 1;
int getopt(int argc, char *const *argv, const char *optstring)
{
char c;
if(optind >= argc || *argv[optind] != '-')
return(-1);
if(argv[optind][1] == '-') {
optind++;
return(-1);
}
for( ; *optstring != '\0'; optstring++) {
c = *optstring;
if(c == argv[optind][1]) {
optstring++;
optind++;
if(*optstring == ':') {
if(optind >= argc) {
fprintf(stderr, "Option '%c' requires an argument.\n", c);
return(':');
} else {
optarg = argv[optind];
optind++;
return(c);
}
} else {
return(c);
}
}
}
fprintf(stderr, "Unrecognized option: '%c'.\n", argv[optind][1]);
optind++;
return('?');
}
#endif