/*
* $Id: c.html,v 1.1.1.1 1999/09/28 16:43:44 sbooth Exp $
*
* Copyright (C) 1998, 1999 Stephen F. Booth
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <string.h>
#include "markup.h"
#include "getopt.h"
/* Externs from flex */
extern int c_yylex();
extern int cpp_yylex();
extern int java_yylex();
extern FILE *cpp_yyout, *cpp_yyin;
extern FILE *c_yyout, *c_yyin;
extern FILE *java_yyout, *java_yyin;
/* Formatting modes */
#define DEFAULT_MODE 0
#define C_MODE 1
#define CPP_MODE 2
#define JAVA_MODE 3
/* Long options */
#define LONGOPT_VERSION 1
#define LONGOPT_HELP 2
#define LONGOPT_C_MODE 3
#define LONGOPT_CPP_MODE 4
#define LONGOPT_JAVA_MODE 5
/* Indicates which long option was selected */
static int gLongOption;
/* List of short options accepted */
static const char sShortOpts [] = "vhcCj";
/* List of long options accepted */
static const struct option sLongOpts [] = {
{ "version", no_argument, &gLongOption, LONGOPT_VERSION },
{ "help", no_argument, &gLongOption, LONGOPT_HELP },
{ "c-mode", no_argument, &gLongOption, LONGOPT_C_MODE },
{ "cpp-mode", no_argument, &gLongOption, LONGOPT_CPP_MODE },
{ "java-mode", no_argument, &gLongOption, LONGOPT_JAVA_MODE },
{0, 0, 0, 0}
};
/* The program name */
static const char *gProgName;
/* A lex/flex lexer function */
typedef int (*lexer_func) (void);
/* A filename extension/mode mapping */
struct extension {
char *name;
int mode;
};
static const struct extension sExtensions [] = {
{ ".c", C_MODE },
{ ".h", C_MODE },
{ ".cc", CPP_MODE },
{ ".cpp", CPP_MODE },
{ ".cp", CPP_MODE },
{ ".C", CPP_MODE },
{ ".hh", CPP_MODE },
{ ".hpp", CPP_MODE },
{ ".hp", CPP_MODE },
{ ".H", CPP_MODE },
{ ".java", JAVA_MODE },
{ "", DEFAULT_MODE },
{ 0, 0 }
};
/* Print version of src2html */
static void printVersion()
{
printf("src2html version %s, by Stephen F. Booth.\n", VERSION);
puts("Copyright (C) 1998, 1999 Stephen F. Booth");
puts("This is free software; see the source for copying conditions.");
puts("There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A");
puts("PARTICULAR PURPOSE.");
puts("");
puts("Report bugs to <sbooth@saaba.lmi.net>");
}
/* Usage information */
static void usage()
{
printf("Usage: %s [OPTIONS] [FILES]\n", gProgName);
puts("Options:");
puts(" -h, --help Print this message and exit.");
puts(" -v, --version Print the version number of src2html and exit.");
puts(" -c, --c-mode Format source as C code.");
puts(" -C, --cpp-mode Format source as C++ code.");
puts(" -j, --java-mode Format source as Java code.");
}
/* Format a file */
static void formatFile(const char *filename,
int mode,
FILE *out)
{
FILE *f;
int use_stdin = 0;
lexer_func lexer;
/* open the file */
if(strcmp(filename, "-") == 0) {
use_stdin = 1;
filename = "stdin";
f = stdin;
}
else {
f = fopen(filename, "r");
if(f == 0) {
printf("%s: Error opening file \"%s\"\n", gProgName, filename);
exit(1);
}
}
/* setup input/output and lexer */
switch(mode) {
case DEFAULT_MODE: cpp_yyin = f; cpp_yyout = out; lexer = cpp_yylex; break;
case CPP_MODE: cpp_yyin = f; cpp_yyout = out; lexer = cpp_yylex; break;
case C_MODE: c_yyin = f; c_yyout = out; lexer = c_yylex; break;
case JAVA_MODE: java_yyin = f; java_yyout = out; lexer = java_yylex;break;
}
/* format the file */
fprintf(out, "<!-- HTML generated by src2html from %s -->\n", filename);
fputs(START_TEXT, out);
(*lexer)();
fputs(END_TEXT, out);
if(use_stdin == 0)
fclose(f);
}
/* Main Street, USA */
int main(int argc,
char **argv)
{
int i = 0;
int c = 0;
char *ext = 0;
int curlen = 0;
int extlen = 0;
int showVersion = 0;
int showUsage = 0;
int curarg = 0;
int mode = DEFAULT_MODE;
/* setup params */
gLongOption = 0;
gProgName = argv[0];
/* parse the command-line arguments */
while( (c = getopt_long(argc, argv, sShortOpts, sLongOpts, (int*)0)) != -1) {
/* handle single-character switches */
switch(c) {
case '?': showUsage = 1; break;
case 'h': showUsage = 1; break;
case 'v': showVersion = 1; break;
case 'c': mode = C_MODE; break;
case 'C': mode = CPP_MODE; break;
case 'j': mode = JAVA_MODE; break;
}
/* handle long-style options */
switch(gLongOption) {
case LONGOPT_VERSION: showVersion = 1; break;
case LONGOPT_HELP: showUsage = 1; break;
case LONGOPT_C_MODE: mode = C_MODE; break;
case LONGOPT_CPP_MODE: mode = CPP_MODE; break;
case LONGOPT_JAVA_MODE: mode = JAVA_MODE; break;
}
/* reset params */
gLongOption = 0;
}
/* show usage */
if(showUsage) {
usage();
exit(0);
}
/* show version */
if(showVersion) {
printVersion();
exit(0);
}
/* if no files specified, use stdin */
if(optind == argc) {
formatFile("-", mode, stdout);
}
else {
/* format the files specified on command line */
for(curarg = optind; curarg < argc; ++curarg) {
/* determine the file type by extension */
for(i = 0; sExtensions[i].name != 0; ++i) {
curlen = strlen(argv[curarg]);
extlen = strlen(sExtensions[i].name);
ext = argv[curarg] + curlen - extlen;
if(curlen > extlen && strcmp(ext, sExtensions[i].name) == 0) {
formatFile(argv[curarg],
(mode == DEFAULT_MODE ? sExtensions[i].mode : mode),
stdout);
break;
}
}
}
}
exit(0);
}