src/c2html.c

changeset 24
e43dee5892f4
parent 23
f44a185b678b
child 25
f82aa7afe872
--- a/src/c2html.c	Thu Jan 23 14:44:20 2014 +0100
+++ b/src/c2html.c	Sun Apr 19 10:48:00 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2014 Mike Becker. All rights reserved.
+ * Copyright 2015 Mike Becker. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -26,8 +26,6 @@
  * POSSIBILITY OF SUCH DAMAGE.
  *
  */
-#include <errno.h>
-
 #include "c2html.h"
 
 inputfile_t *inputfilebuffer(size_t capacity) {
@@ -111,6 +109,7 @@
         "  -H <header>           Prepend header file\n"
         "  -F <footer>           Append footer file\n"
         "  -p                    Disable highlighting (plain text)\n"
+        "  -l                    Disable line numbers\n"
         "\n");
 
 
@@ -137,8 +136,66 @@
         fclose(src);
         return 0;
     } else {
-        return errno;
+        return -1;
+    }
+}
+
+#define WRITECONST(stream, out, cstr) out(cstr, 1, sizeof(cstr)-1, stream)
+int formatfile(
+        highlighter_t *highlighter,
+        inputfile_t *in,
+        fmt_write_func out,
+        void *stream,
+        _Bool showln) {
+    // formats an input file and writes the result to out
+    
+    char *line = malloc(in->maxlinewidth*64);
+    if(!line) {
+        return 1;
     }
+    WRITECONST(stream, out, "<pre>\n");
+    
+    int lnw = lnint(in->count);
+    for (int i = 0 ; i < in->count ; i++) {
+        char *ln = line;
+        if (highlighter) {
+            highlighter->parser(in->lines[i], line, highlighter);
+        } else {
+            ln = in->lines[i];
+        }
+        
+        // write line number
+        if (showln) {
+            WRITECONST(stream, out, "<span class=\"c2html-lineno\">");
+            char lnbuf[16];
+            int len = snprintf(lnbuf, 16, "%*d ", lnw, i+1);
+            out(lnbuf, 1, len, stream);
+            WRITECONST(stream, out, "</span> ");
+        }
+        
+        // write formated (or plain) code line
+        out(ln, 1, strlen(ln), stream);
+    }
+    
+    WRITECONST(stream, out, "</pre>\n");
+    free(line);
+    return 0;
+}
+
+void init_c_highlighter(highlighter_t *highlighter) {
+    memset(highlighter, 0, sizeof(highlighter_t));
+    highlighter->isdirective = iscdirective;
+    highlighter->istype = isctype;
+    highlighter->keywords = ckeywords;
+    highlighter->parser = cparseline;
+}
+
+void init_java_highlighter(highlighter_t *highlighter) {
+    memset(highlighter, 0, sizeof(highlighter_t));
+    highlighter->isdirective = isjdirective;
+    highlighter->istype = isjtype;
+    highlighter->keywords = jkeywords;
+    highlighter->parser = jparseline;
 }
 
 int main(int argc, char** argv) {
@@ -147,16 +204,12 @@
     settings_t settings;
     memset(&settings, 0, sizeof(settings));
     settings.highlight = 1;
+    settings.showlinenumbers = 1;
     
-    highlighter_t highlighter;
-    memset(&highlighter, 0, sizeof(highlighter));
-    highlighter.isdirective = iscdirective;
-    highlighter.istype = isctype;
-    highlighter.keywords = ckeywords;
-    highlighter.parser = cparseline;
+    int lang = C2HTML_C;
 
     char optc;
-    while ((optc = getopt(argc, argv, "hjo:pH:F:")) != -1) {
+    while ((optc = getopt(argc, argv, "hljo:pH:F:")) != -1) {
         switch (optc) {
             case 'o':
                 if (!(optarg[0] == '-' && optarg[1] == 0)) {
@@ -170,14 +223,14 @@
                 settings.headerfile = optarg;
                 break;
             case 'j':
-                highlighter.isdirective = isjdirective;
-                highlighter.istype = isjtype;
-                highlighter.keywords = jkeywords;
-                highlighter.parser = jparseline;
+                lang = C2HTML_JAVA;
                 break;
             case 'p':
                 settings.highlight = 0;
                 break;
+            case 'l':
+                settings.showlinenumbers = 0;
+                break;
             case 'h':
                 printhelp();
                 return 0;
@@ -196,7 +249,7 @@
             fout = fopen(settings.outfilename, "w");
             if (!fout) {
                 perror("Error opening output file");
-                return errno;
+                return -1;
             }
         } else {
             fout = stdout;
@@ -204,43 +257,43 @@
         
         if (copyfile(settings.headerfile, fout)) {
             perror("Error opening header file");
-            retcode = errno;
+            retcode = -1;
             goto prog_end;
         }
+        
+        highlighter_t highlighter;
+        highlighter_t *hptr = &highlighter;
+        switch (lang) {
+            case C2HTML_C:
+                init_c_highlighter(&highlighter);
+                break;
+            case C2HTML_JAVA:
+                init_java_highlighter(&highlighter);
+                break;
+            default:
+                hptr = NULL;
+                break;
+        }
+        if (!settings.highlight) {
+            hptr = NULL;
+        }
 
         inputfile_t *inputfile = readinput(settings.infilename);
         if (inputfile) {
-            char *line;
-            if (settings.highlight) {
-                line = (char*) malloc(inputfile->maxlinewidth*64);
-            } else {
-                line = NULL;
-            }
-            fprintf(fout, "<pre>\n");
-            int lnw = lnint(inputfile->count);
-            for (int i = 0 ; i < inputfile->count ; i++) {
-                if (settings.highlight) {
-                    highlighter.parser(inputfile->lines[i], line, &highlighter);
-                } else {
-                    line = inputfile->lines[i];
-                }
-                fprintf(fout, "<span class=\"c2html-lineno\">%*d:</span> %s",
-                    lnw, i+1, line);
-            }
-            if (settings.highlight) {
-                free(line);
-            }
-            fprintf(fout, "</pre>\n");
-
-            freeinputfilebuffer(inputfile);
-            
-            if (copyfile(settings.footerfile, fout)) {
-                perror("Error opening footer file");
-                retcode = errno;
-            }
+            formatfile(
+                    hptr,
+                    inputfile,
+                    (fmt_write_func)fwrite,
+                    fout,
+                    settings.showlinenumbers);
         } else {
             perror("Error opening input file");
-            retcode = errno;
+            retcode = -1;
+        }
+        
+        if (copyfile(settings.footerfile, fout)) {
+            perror("Error opening footer file");
+            retcode = -1;
         }
         
         prog_end:        

mercurial