/* * Copyright (C) 1999, 2000 Lorenzo Bettini, lorenzo.bettini@penteres.it * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <stdio.h> #include <string.h> #include <iostream.h> #include <fstream.h> #include "version.h" #include "main.h" #include "colors.h" #include "tags.h" #include "keys.h" #include "textgen.h" #include "decorators.h" #include "generators.h" #include "messages.h" #include "cmdline.h" #include "copyright.h" #define OUTPUT_EXTENSION ".html" /* global symbols */ char *inputFileName, *outputFileName ; /* what we're reading */ ostream* sout ; int tabSpaces = 0 ; // space to substitue to tabs int entire_doc = 0 ; // we want a real html doc int otherArgs ; short verbose = 0 ; char *cssUrl = 0 ; int use_css = 0 ; // Use CSS instead of font-tags char *programName = 0 ; char *programVersion = 0 ; extern int yylex() ; extern int parseTags() ; static char *read_file(char *fileName); static void file_error(const char *error, char *fileName); static void internal_error(const char *error); int main( int argc, char * argv[] ) { char *docTitle; char *docHeader; // the buffer with the header char *docFooter; // the buffer with the footer char *header_fileName = 0; char *footer_fileName = 0; gengetopt_args_info args_info ; // command line structure unsigned i; int v; if((v = cmdline_parser(argc, argv, &args_info)) != 0) // calls cmdline parser. The user gived bag args if it doesn't return -1 return 1; programName = PACKAGE ; programVersion = VERSION ; /* initialization of global symbols */ inputFileName = outputFileName = 0 ; sout = 0 ; docTitle = 0 ; docHeader = 0 ; docFooter = 0 ; // adjust flags for command line parameters otherArgs = 1; docTitle = args_info.title_arg ; header_fileName = args_info.header_arg ; footer_fileName = args_info.footer_arg ; verbose = args_info.verbose_given ; if ( args_info.tab_given > 0 ) tabSpaces = args_info.tab_arg ; if (header_fileName) docHeader = read_file (header_fileName); if (footer_fileName) docFooter = read_file (footer_fileName); cssUrl = args_info.css_arg ; use_css = ( cssUrl != 0 ) ; entire_doc = ( args_info.doc_given || (docTitle != 0) || use_css ) ; inputFileName = args_info.input_arg ; if ( inputFileName ) { outputFileName = args_info.output_arg ; if ( ! outputFileName ) { outputFileName = createOutputFileName( inputFileName ) ; } } if ( verbose ) setMessager( new DefaultMessages ) ; printMessage( PACKAGE " " VERSION ) ; parseTags() ; if( use_css ) { createGeneratorsForCSS() ; } else { createGenerators() ; } // let's start the translation :-) // first the --input file if ( ! args_info.inputs_num ) processFile( inputFileName, outputFileName, docTitle, docHeader, docFooter ) ; // let's process other files, if there are any if ( args_info.inputs_num ) { for ( i = 0 ; i < (args_info.inputs_num) ; ++i ) { processFile( args_info.inputs[i], createOutputFileName( args_info.inputs[i] ), docTitle, docHeader, docFooter ) ; cerr << "Processed " << args_info.inputs[i] << endl ; } } return (0 ); } char * read_file(char *fileName) { FILE *file; char *buffer = 0; long int char_count; // we open it as binary otherwise we may experience problems under // Windows system: when we fread, the number of char read can be // less then char_count, and thus we'd get an error... if ( (file = fopen(fileName,"rb") ) == 0 ) // The file does not exist :( file_error ("Error operning", fileName); else { // let's go to the end of the file... if (fseek (file, 0, SEEK_END) != 0) file_error ("Error positioning", fileName); // ...to read the dimension char_count = ftell (file); if (char_count < 0) file_error ("Error reading position", fileName); buffer = (char *) malloc (char_count +1); if (! buffer) internal_error ("Memory allocation failed"); // let's go back to the start rewind (file); if (fread ((void *) buffer, 1, char_count, file) < (size_t) char_count) file_error ("read error", fileName); buffer[char_count] = '\0'; fclose (file); } return buffer; } void file_error(const char *error, char *file) { fprintf (stderr, "%s: %s, file %s\n", PACKAGE, error, file); exit (1); } void internal_error(const char *error) { fprintf (stderr, "%s: Internal error: %s\n", PACKAGE, error); exit (1); } // output file name = input file name + ".html" char *createOutputFileName( char *inputFileName ) { char *outputFileName = new char[ strlen(inputFileName) + strlen(OUTPUT_EXTENSION) + 1 ] ; strcpy( outputFileName, inputFileName ) ; strcat( outputFileName, OUTPUT_EXTENSION ) ; return outputFileName ; } void processFile( char *inputFileName, char *outputFileName, char *docTitle, const char *docHeader, const char *docFooter) { FILE *in = 0; short deleteOStream = 1 ; if ( outputFileName ) { sout = new ofstream(outputFileName) ; if ( ! sout ) { cerr << "Error in creating " << outputFileName << " for output" << endl ; exit(1) ; } } if ( inputFileName ) { in = freopen (inputFileName, "r", stdin); if (!in) { cerr << "Error in opening " << inputFileName << " for input" << endl ; exit(1) ; } } /* * Use default values for any options not provided */ if (sout == 0) { sout = &cout; deleteOStream = 0 ; // we can't delete cout !!! } if (in == 0) { ; /* Well stdin already points to stdin so, .... */ } if (docTitle == 0) { docTitle = inputFileName; /* inputFileName may also be 0, this is OK. */ } if ( entire_doc ) { print_top( docTitle, cssUrl, docHeader ); } printMessage( "translating source code... ", cerr ) ; generateln( "<pre>" ) ; generateln( "<tt>" ) ; yylex() ; generateln( "</tt>" ) ; generateln( "</pre>" ) ; printMessage( "done !", cerr ) ; if ( entire_doc ) print_bottom( docFooter ) ; if ( deleteOStream ) delete sout ; } void print_top( char *docTitle, char *cssUrl , const char *docHeader) { if( cssUrl == 0 ) { generateln( "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">" ) ; } else { generateln( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\""); generateln( " \"http://www.w3.org/TR/REC-html40/strict.dtd\">"); } generateln( "<html>" ) ; generateln( "<head>" ) ; generateln( "<meta http-equiv=\"Content-Type\"" ) ; generateln( "content=\"text/html; charset=iso-8859-1\">" ) ; generate( "<meta name=\"GENERATOR\" content=\"" ) ; generate( PACKAGE " " VERSION ) ; generate( "\nby Lorenzo Bettini, bettini@gnu.org" ) ; generate( "\nhttp://w3.newnet.it/bettini" ) ; generate( "\nhttp://www.gnu.org/software/" PACKAGE "/" PACKAGE ".html" ) ; generateln( "\">" ) ; generate( "<title>" ) ; generate( ( docTitle ? docTitle : ( inputFileName ? inputFileName : "source file" ) ) ) ; generateln( "</title>" ) ; if( cssUrl != 0 ) { generate( "<link rel=\"stylesheet\" href=\"" ); generate( cssUrl ); generateln( "\" type=\"text/css\">"); } generateln( "</head>" ) ; if( cssUrl == 0 && docHeader == 0) { generate ("<body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000EE\" "); generateln ( "vlink=\"#551A8B\" alink=\"#FF0000\">" ); } else { generateln( "<body>" ) ; } if (docHeader) generateln (docHeader) ; } void print_bottom( const char *docFooter) { if ( docFooter ) generateln( docFooter ) ; generateln( "</body>" ) ; generateln( "</html>" ) ; } void generate( const char *s ) { GlobalGenerator->generate(s) ; } void generate( const char *s, int start, int end ) { GlobalGenerator->generate(s, start, end) ; } void generateln( const char *s ) { GlobalGenerator->generateln(s) ; } void generateNewLine() { generateln( "" ) ; } void generateTab() { if ( tabSpaces ) for ( register int i = 0 ; i < tabSpaces ; ++i ) generate( SPACE_CHAR ) ; else generate( "\t" ) ; } void startComment( const char *s ) { CommentGenerator->beginText(s) ; } void endComment( const char *s ) { CommentGenerator->endText(s) ; } void generateComment( const char *s ) { CommentGenerator->generateEntire(s) ; } void startString( const char *s ) { StringGenerator->beginText(s) ; } void endString( const char *s ) { StringGenerator->endText(s) ; } void generateString( const char *s ) { StringGenerator->generateEntire(s) ; } void generateKeyWord( const char *s ) { KeywordGenerator->generateEntire(s) ; } void generateBaseType( const char *s ) { TypeGenerator->generateEntire(s) ; } void generateNumber( const char *s ) { NumberGenerator->generateEntire(s) ; } void startTAG( const char *tag, const char *attr, const char *val ) { (*sout) << "<" << tag ; if ( attr && val ) (*sout) << " " << attr << "=" << val ; (*sout) << ">" ; } void endTAG( const char *tag ) { (*sout) << "</" << tag << ">" ; } void startColor( const char *color ) { startTAG( FONT_TAG, COLOR_TAG, color ) ; } void endColor() { endTAG( FONT_TAG ) ; }