/************************************************************************ * * * MAKE_README.C * * * * MAKE_README.C contains the code for constructing the formatted * * README file from the Citation Database. The functions reformat * * the "refer" (or "bib") entries to a more presentable format. * * * ************************************************************************/ /************************************************************************ *** *** *** INTERFACE of file: *** *** *** ************************************************************************/ /*********************************************** */ /* Header files and libraries utilized: */ #include #include #include #include #include #include "techrep.h" #include "sitespec.h" #include "util.h" #include "citation.h" #include "make_readme.h" #include "com-util.h" /*********************************************** */ /* constant definitions: */ #define NIL '\0' #define SPACE ' ' /* maximum string lengths: */ #define MAXFIELD 300 #define MAXAUTH 200 #define SH_FIELD 80 #define MAXSTRING 500 #define WORDLENGTH 50 #define STD_STRING_SIZE 80 /* special unique delimiter to separate tech. rep. number from other * * fields: */ #define LEFT_MARKER_STR "[" #define LEFT_MARKER_CHAR '[' #define RIGHT_MARKER_STR "]" #define RIGHT_MARKER_CHAR ']' /* offset to beginning of actual string, leading off header info... */ #define OFFSET 3 /* maximum line length for formatted output */ #define MAX_LINE 80 /********************************************** */ /* Internal function declarations: */ void append_author ( char *, char *, char * ); void make_field ( char *, char * ); void convert_format ( char *, char * ); void construct_file ( char *, char * ); void make_formatted_citation_list(char *, char *); /************************************************************************ *** *** *** IMPLEMENTATION follows: *** *** *** ************************************************************************/ /* void append_author(char *, char *, char *) is a funct. that updates * * the temporary author lists automatically. We maintain two author * * structures for later formatting. "authors" is a comma delimited * * list of all authors up to but not including the most recent one. * * "last_author" is the most recent author that will be appended at * * the end of the citation with an "and". This allows for * * appropriate formatting. */ void append_author ( char *authors, char *last_author, char *buffer) { /* if this is the first author encountered: */ if ( last_author[0] == NIL ) { /* make last_author equal to the new "input author" */ strcpy ( last_author, buffer ); return; } /* otherwise, check to see if authors contains any elements: */ if ( authors[0] == NIL ) { /* move the old author into the "authors" string and update * * the "last_author" field: */ strcpy ( authors, last_author ); strcpy ( last_author, buffer ); return; } /* otherwise, we have the general case of third or greater author */ else { /* in general, we move the old "last_author" to the "author" * * list by adding it on in a comma-delimited fashion. We then * * can update the last_author field. */ strcat ( authors, ", "); strcat ( authors, last_author ); strcpy ( last_author, buffer ); } } /* void make_field(char *, char *) is a procedure that simply copies * the buffer to the appropriate field passed in to "field". */ void make_field ( char *field, char *buffer ) { strcpy ( field, buffer ); } /* void skip_info ( FILE * ) is a procedure that skips over the * * multi-line informational segments that contain abstracts (%X), and * * credits (%x). */ /* void convert_format (char *) takes the name of the Citation Database * * file as input and produces a README-style output file to use for * * screen output in the file by the name out_fname. */ void convert_format ( char *cit_fname, char *out_fname ) { FILE *cit_file; /* the input citation file (in "refer" format) */ FILE *out_file; /* the README style output file */ char buffer[MAXFIELD]; /* buffer to hold a line temporarily */ char authors[MAXFIELD]; /* list of authors, delimited "," or "and" */ char rec_auth[MAXAUTH]; /* most recent author encountered */ char title[MAXFIELD]; /* title of report... */ char trnum[SH_FIELD]; /* tech report number (for sorting)... */ char date[SH_FIELD]; /* date of tech report... */ char out_string[MAXSTRING]; /* output for each entry for sorting */ short done = FALSE; /* boolean variable that is set to true on EOF */ if ( ( cit_file = fopen ( cit_fname, "r" ) ) == NULL ) { printf("Could not find citation database file..."); return; } if ( ( out_file = fopen ( out_fname, "w" ) ) == NULL ) { printf("Not enough room to create output file in CONVERT_FORMAT..."); return; } /* loop through all citation entries... */ while ( fgets ( buffer, MAXFIELD, cit_file ) ) { /* initialize all of our strings to NIL: */ authors[0] = rec_auth[0] = title[0] = trnum[0] = date[0] = rec_auth[0] = NIL; /* loop until we reach a NEWLINE (end of citation entry) or the * * end of the database... */ while ( ( buffer[0] != '\n' ) && !done) { /* strip the newline character off of the string: */ buffer[ strlen(buffer) - 1 ] = NIL; /* find out the type of entry: */ switch ( buffer[1] ) { case REF_AUTHOR: if ( buffer[0] == '%') append_author ( authors, rec_auth, buffer + OFFSET ); break; case REF_TITLE: if ( buffer[0] == '%') make_field ( title, buffer + OFFSET ); break; case REF_REPORT: if ( buffer[0] == '%') make_field ( trnum, buffer + OFFSET ); break; case REF_DATE: if ( buffer[0] == '%') make_field ( date, buffer + OFFSET ); break; case REF_ABSTRACT: case REF_KEYWORDS: case REF_LASTMOD: default: break; } /* check to see if we have reached the end-of-file */ if ( !fgets ( buffer, MAXFIELD, cit_file ) ) done = TRUE; } /* we now create the appropriate output string for sorting: */ /* place the tech. rep. number in appropriate format: */ /* delimit the technical report number appropriately: */ strcpy ( out_string, LEFT_MARKER_STR ); strcat ( out_string, trnum ); strcat ( out_string, RIGHT_MARKER_STR ); /* print remaining fields with appropriate format: */ if ( ( authors[0] != NIL ) && ( authors[0] != '\n' ) ) { strcat ( out_string, authors ); strcat ( out_string, " and " ); strcat ( out_string, rec_auth ); } else { strcat ( out_string, rec_auth ); } strcat ( out_string, ", " ); strcat ( out_string, title ); strcat ( out_string, ", " ); strcat ( out_string, date ); strcat ( out_string, ".\n" ); /* print this string to a file for sorting... */ fprintf( out_file, "%s", out_string ); } fclose( cit_file ); fclose( out_file ); } /* void construct_file(char *) is the file that actually constructs the * * README file. It first prints out the header "instruction text", and * * then it prints out the sorted list from the file whose name is * * passed in as a parameter. We print out the technical report number * * on one line, and then the rest of the string is printed on following * * lines, wrapped around at spaces between words. */ void construct_file ( char *source_name, char *dest_name ) { FILE *source_file; /* sorted list whose name was passed in */ FILE *dest_file; /* dest_file is README... */ char buffer[MAXSTRING]; /* buffer holding individual report names */ char temp_buff[WORDLENGTH]; /* buffer to hold individual words */ int counter, index, length; /* dummy counters keeping track of where * * we are in the procedure. "counter" * * keeps track of where we are in the main * * string, "index" where we are in the * * current word, and "length" how far down * * the line of text we are => newline... */ if ( ( source_file = fopen ( source_name, "r" ) ) == NULL ) { printf("Could not find file in CONSTRUCT_FILE..."); return; } if ( ( dest_file = fopen ( dest_name, "w" ) ) == NULL ) { printf("Not enough room to create README file in CONSTRUCT_FILE..."); return; } /* the following is the header information of the README file... */ /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */ /* loop while there are more citations to be printed */ while ( fgets ( buffer, MAXSTRING, source_file ) ) { /* set the counter (keeping track within "buffer") to 0. */ counter = 0; /* read the technical report number... */ while ( buffer [counter] != RIGHT_MARKER_CHAR ) { temp_buff [counter] = buffer [counter]; counter++; } /* read the right delimiter in... */ temp_buff [counter] = buffer [counter]; counter++; /* close off the temporary string... */ temp_buff [counter] = NIL; /* write the tech report number to file */ fprintf ( dest_file, "\n%s\n ", temp_buff ); /* this is the standard starting length at beginning of line */ length = 10 ; /* loop until we have no more input: */ while ( buffer [counter] != '\n' ) { /* set the word length to 0 */ index = 0; /* read characters until we get to the end of the word: */ while ( ( buffer [counter] != SPACE ) && ( buffer [counter] != '\n' ) ) { temp_buff [index++] = buffer [counter++]; length++; } /* again, close off the temporary string */ temp_buff [index] = NIL; /* check to see if we need a new line */ if ( length >= MAX_LINE ) { fprintf ( dest_file, "\n %s ", temp_buff ); length = 10 + strlen ( temp_buff ) + 1; } else { fprintf ( dest_file, "%s ", temp_buff ); length++; } /* check to see if there are more words... */ if ( buffer [counter] == SPACE ) counter++; } fprintf ( dest_file,"\n"); } fclose ( source_file ); fclose ( dest_file ); } void find_single_entry ( char *fname, char *dest_name ) { FILE *source_file; /* sorted list whose name was passed in */ FILE *dest_file; /* dest_file is README... */ char buffer[MAXSTRING]; /* buffer holding individual report names */ char temp_buff[WORDLENGTH]; /* buffer to hold individual words */ int counter, index, length; /* dummy counters keeping track of where * * we are in the procedure. "counter" * * keeps track of where we are in the main * * string, "index" where we are in the * * current word, and "length" how far down * * the line of text we are => newline... */ if ( ( source_file = fopen ( fname, "r" ) ) == NULL ) { printf("Could not find file in FIND_SINGLE_ENTRY..."); return; } if ( ( dest_file = fopen ( dest_name, "w" ) ) == NULL ) { printf("Not enough room to create README file in CONSTRUCT_FILE..."); return; } if ( fgets ( buffer, MAXSTRING, source_file ) ) { /* set the counter (keeping track within "buffer") to 0. */ counter = 0; /* read the technical report number... */ while ( buffer [counter] != RIGHT_MARKER_CHAR ) { temp_buff [counter] = buffer [counter]; counter++; } /* read the right delimiter in... */ temp_buff [counter] = buffer [counter]; counter++; temp_buff [counter] = NIL; /* write the tech report number to file */ fprintf ( dest_file, "%s\n ", temp_buff ); /* this is the standard starting length at beginning of line */ length = 25 ; /* loop until we have no more input: */ while ( buffer [counter] != '\n' ) { /* set the word length to 0 */ index = 0; /* read characters until we get to the end of the word: */ while ( ( buffer [counter] != SPACE ) && ( buffer [counter] != '\n' ) ) { temp_buff [index++] = buffer [counter++]; length++; } /* again, close off the temporary string */ temp_buff [index] = NIL; /* check to see if we need a new line */ if ( length >= MAX_LINE ) { fprintf ( dest_file, "\n %s ", temp_buff ); length = 25 + strlen ( temp_buff ) + 1; } else { fprintf ( dest_file, "%s ", temp_buff ); length++; } /* check to see if there are more words... */ if ( buffer [counter] == SPACE ) counter++; } fprintf ( dest_file,"\n"); } else printf ("Error in find_single_entry: no data in %s", fname); fclose ( source_file ); fclose ( dest_file ); } /* void make_formatted_citation_list(char *) takes the name of the * * Citation Database file as input and constructs the a sorted file by * * using the convert_format function. */ void make_formatted_citation_list(char *cit_dbase, char *dest_dbase) { /* start mods - CLV 22 Oct 92 */ char tmpFile1[STD_STRING_SIZE]; char tmpFile2[STD_STRING_SIZE]; char command[MAXSTRING]; sprintf (tmpFile1, "/tmp/tr.FormCit.XXXXXX"); mktemp (tmpFile1); /* unique temporary filename */ convert_format ( cit_dbase, tmpFile1 ); sprintf (tmpFile2, "%s.sorted", tmpFile1); sprintf (command, "sort -o %s %s", tmpFile2, tmpFile1); system( command ); construct_file ( tmpFile2, dest_dbase ); unlink ( tmpFile1 ); unlink ( tmpFile2 ); /* end mods */ /* convert_format ( cit_dbase, "README.temp" ); system( "sort -o README.temp.sorted README.temp"); construct_file ( "README.temp.sorted", dest_dbase ); unlink ( "README.temp" ); unlink ( "README.temp.sorted"); */ } /* void make_single_citation ( char *, int) makes a list of all the * * citations by taking the Citation Database file as input and then * * find_single_entry () finds the proper entry and produces it. */ void make_single_citation ( char *cit_entry, char *one_cit ) { /* start mods - CLV 22 Oct 92 */ char tmpFile1[STD_STRING_SIZE]; sprintf (tmpFile1, "/tmp/tr.SingCit.XXXXXX"); mktemp (tmpFile1); /* unique temporary filename */ convert_format ( cit_entry, tmpFile1 ); find_single_entry ( tmpFile1, one_cit ); unlink ( tmpFile1 ); /* end mods */ /* convert_format ( cit_entry, "README.temp" ); find_single_entry ( "README.temp", one_cit ); unlink ( "README.temp" ); */ } /* * updates the formatted citation file. */ int update_readme() { FILE *indexFp, *tmpIndexFp; char citDbase[STRING_SIZE]; char reportDir[STRING_SIZE]; char indexName[STRING_SIZE]; char tmpName[STRING_SIZE]; char line[STRING_SIZE]; char genHtmlCommand[STRING_SIZE]; int c, x, blankline; strcpy(reportDir, getReportDirectoryPath()); /* copy readme header to ftp README file */ sprintf(indexName, "%sREADME", reportDir); fileCopy(indexName, getIndexHeaderPath(), 0644); /* create index in tmp file */ strcpy(citDbase, getCitationDataFilePath()); sprintf(tmpName, "/tmp/%d-readme-tmp", (int)getpid()); make_formatted_citation_list(citDbase, tmpName); /* concatenate index onto readme header eliminating leading blanks */ if ((indexFp = fopen(indexName, "a")) == NULL) { fclose(indexFp); return (NO_README); } if ((tmpIndexFp = fopen(tmpName, "r")) == NULL) { fclose(indexFp); fclose(tmpIndexFp); return (NO_TMP_README); } fprintf(indexFp, HEADER_DELIMITER); while ((c = fgetc(tmpIndexFp)) != EOF) /* eliminate leading blanks */ if (isspace(c) == 0) break; /* concatenate rest onto readme */ if (c >= 0) { fputc(c, indexFp); while ((fgets(line, STRING_SIZE, tmpIndexFp)) != NULL) { blankline = TRUE; for (x = 0; x < strlen(line); x++) /* eliminate blank lines */ if (isspace(line[x]) == 0) blankline = FALSE; if (strlen(line) == 3) blankline = TRUE; if (!blankline) { if (line[0] == '[') fprintf(indexFp, "\n%s", line); else fprintf(indexFp, "%s", line); } } } fclose(indexFp); fclose(tmpIndexFp); /* delete tmp files */ unlink(tmpName); sprintf (genHtmlCommand, "%s", getGenHtmlPath()); system (genHtmlCommand); return (0); } #ifdef STANDALONETEST int main (int argc, char **argv) { if (argc < 2) { fprintf (stderr, "usage: make_readme referFormatFile outputFile\n"); exit (1); } make_single_citation (argv[1], argv[2]); } #endif #ifdef STANDALONETEST2 int main (int argc, char **argv) { FILE *fp; CitationPtr C; if (argc < 2) { fprintf (stderr, "usage: make_readme referFormatFile\n"); exit (1); } fp = fopen (argv[1], "r"); while ((C = read_one_citation (fp)) != NULL) { printf ("Number : %s\n", getTrId (C) ); printf ("Author : %s\n", getAuthor (C) ); printf ("Title : %s\n", getTitle (C) ); printf ("Poster : %s\n", getPoster (C) ); printf ("Date : %s\n", getDate (C) ); printf ("KWords : %s\n", getKeywords (C) ); printf ("KWords : %s\n", getCategories (C) ); printf ("Attrib : %s\n", getAttrib (C) ); printf ("Abstract : %s\n\n", getAbstract(C) ); freeCitation (C); } fclose (fp); } #endif