src/c2html.c

changeset 55
bf54085ce341
parent 53
5e47a26a16f0
child 57
eba880c1705c
--- a/src/c2html.c	Wed Aug 31 12:58:48 2016 +0200
+++ b/src/c2html.c	Wed Aug 31 14:41:56 2016 +0200
@@ -27,47 +27,21 @@
  *
  */
 
-#include <unistd.h>
-
 #include "c2html.h"
-#include "highlighter.h"
 
 #include "ucx/list.h"
-
-static int appendfile(const char *filename, FILE *fout,
-        char *copybuf, size_t copybuflen, const char *errmsg) {
-    FILE *headerfile = fopen(filename, "r");
-    if (!headerfile) {
-        perror(errmsg);
-        if (fout != stdout) {
-            fclose(fout);
-        }
-        return 1;
-    }
-    ucx_stream_copy(headerfile, fout,
-            (read_func) fread, (write_func) fwrite,
-            copybuf, copybuflen, (size_t)-1);
-    fclose(headerfile);
-    return 0;
-}
+#include "ucx/utils.h"
 
-static void printhelp() {
-    printf("Formats source code using HTML.\n\nUsage:\n"
-        "  c2html [Options] FILE\n\n"
-        " Options:\n"
-        "  -h                    Prints this help message\n"
-        "  -j                    Highlight Java instead of C source code\n"
-        "  -o <output>           Output file (stdout, if not specified)\n"
-        "  -H <header>           Prepend header file\n"
-        "  -F <footer>           Append footer file\n"
-        "  -p                    Disable highlighting (plain text)\n"
-        "  -l                    Disable line numbers\n"
-        "  -V, -v                Prints version and exits\n"
-        "\n");
-}
+#define try_write(wfnc, str, n, buf, written, maxlen) \
+    {                                              \
+        size_t m = maxlen-written;                    \
+        written += wfnc(str, 1, n > m ? m : n, buf);  \
+    }
 
-static void formatlines(highlighter_func highlighter,
-        UcxList *in, write_func out, void *stream, int showlineno) {
+static size_t formatlines(c2html_highlighter_func highlighter, UcxList *in,
+        void *outbuf, write_func wfnc, size_t maxlen, int showlineno) {
+    /* total written bytes */
+    size_t written = 0;
     
     /* compute width of line numbering */
     int lnw = 0;
@@ -77,16 +51,15 @@
     }
     
     /* start monospace formatting */
-    out("<pre>\n", 1, 6, stream);
+    try_write(wfnc, "<pre>\n", 6, outbuf, written, maxlen);
 
     /* process lines */
     size_t lineno = 0;
-    HighlighterData *hd = new_highlighter_data();
+    c2html_highlighter_data* hd = malloc(sizeof(c2html_highlighter_data));
+    hd->multiline_comment = 0;
+    hd->primary_buffer = ucx_buffer_new(NULL, 256, UCX_BUFFER_AUTOEXTEND);
+    hd->secondary_buffer = ucx_buffer_new(NULL, 32, UCX_BUFFER_AUTOEXTEND);
     UcxBuffer *line = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND);
-    if(!line || !hd) {
-        perror("Error allocating buffer for output");
-        return;
-    }
     
     UCX_FOREACH(sourceline, in) {
         /* increase line number and clean line buffer */
@@ -104,163 +77,63 @@
         highlighter(sourceline->data, line, hd);
         
         /* write code line */
-        out(line->space, 1, line->size, stream);
+        try_write(wfnc, line->space, line->size, outbuf, written, maxlen);
+        
+        if (written == maxlen) break;
     }
     
     /* end monospace formatting */
-    out("</pre>\n", 1, 7, stream);
+    try_write(wfnc, "</pre>\n", 7, outbuf, written, maxlen);
     
     /* cleanup and return */
-    free_highlighter_data(hd);
+    ucx_buffer_free(hd->primary_buffer);
+    ucx_buffer_free(hd->secondary_buffer);
+    free(hd);
     ucx_buffer_free(line);
+    
+    return written;
 }
 
-#define FILEBUF_SIZE 4096
-
-enum source_type {
-    SOURCE_C,
-    SOURCE_JAVA,
-    SOURCE_PLAIN
-};
-
-int main(int argc, char** argv) {
-
-    /* Default settings */
-    Settings settings;
-    memset(&settings, 0, sizeof(settings));
-    settings.showlinenumbers = 1;
-    enum source_type sourcetype = SOURCE_C;
+size_t c2html_formatn(void* inputbuffer, read_func rfnc,
+        char* ibuf, size_t ibuflen, void* outputbuffer, write_func wfnc,
+        size_t maxlen, c2html_highlighter_func hltr, int showln) {
+    
+    UcxBuffer *content = ucx_buffer_new(NULL, ibuflen*2, UCX_BUFFER_AUTOEXTEND);
+    ucx_stream_copy(inputbuffer, content, rfnc, (write_func) ucx_buffer_write,
+            ibuf, ibuflen, (size_t)-1);
 
-    /* Parse command line */
-    char optc;
-    while ((optc = getopt(argc, argv, "hljo:pH:F:vV")) != -1) {
-        switch (optc) {
-            case 'o':
-                if (!(optarg[0] == '-' && optarg[1] == 0)) {
-                    settings.outfilename = optarg;
-                }
-                break;
-            case 'F':
-                settings.footerfile = optarg;
-                break;
-            case 'H':
-                settings.headerfile = optarg;
-                break;
-            case 'j':
-                sourcetype = SOURCE_JAVA;
-                break;
-            case 'p':
-                sourcetype = SOURCE_PLAIN;
-                break;
-            case 'l':
-                settings.showlinenumbers = 0;
-                break;
-            case 'h':
-                printhelp();
-                return EXIT_SUCCESS;
-            case 'v':
-            case 'V':
-#ifdef VERSION_DEVELOP
-                printf("%d.%d (unstable)\n", VERSION_MAJOR, VERSION_MINOR);
-#else
-                printf("%d.%d\n", VERSION_MAJOR, VERSION_MINOR);
-#endif
-                return EXIT_SUCCESS;
-            default:
-                return EXIT_FAILURE;
+    UcxList *lines = ucx_list_append(NULL, content->space);
+    for (size_t i = 1 ; i < content->size ; i++) {
+        if (content->space[i] == '\r') {
+            content->space[i] = '\n'; i++;
+        }
+        if (content->space[i] == '\n' && i+1 < content->size) {
+            ucx_list_append(lines, content->space+i+1);
         }
     }
-
-    if (optind != argc-1) {
-        printhelp();
-        return EXIT_FAILURE;
-    } else {
-        /* Choose highlighter */
-        highlighter_func hltr = NULL;
-        switch (sourcetype) {
-            case SOURCE_C:
-                hltr = c_highlighter;
-                break;
-            case SOURCE_JAVA:
-                hltr = java_highlighter;
-                break;
-            case SOURCE_PLAIN:
-                hltr = plain_highlighter;
-                break;
-            default: /* should be unreachable */
-                fprintf(stderr, "error in enum source_type\n");
-                return EXIT_FAILURE;
-        }
-        
-        /* Open output file */
-        settings.infilename = argv[optind];
-        FILE *fout;
-        if (settings.outfilename) {
-            fout = fopen(settings.outfilename, "w");
-            if (!fout) {
-                perror("Error opening output file");
-                return EXIT_FAILURE;
-            }
-        } else {
-            fout = stdout;
-        }
-        
-        /* Allocate file buffer  */
-        char *filebuf = malloc(FILEBUF_SIZE);
-        if (!filebuf) {
-            perror("Error allocating file buffer");
-            return EXIT_FAILURE;
-        }
-        
-        /* Prepend header file */
-        if (appendfile(settings.headerfile, fout, filebuf, FILEBUF_SIZE,
-                "Error opening header file")) {
-            return EXIT_FAILURE;
-        }
-
-        /* Process input file */
-        FILE *inputfile = fopen(settings.infilename, "r");
-        if (inputfile) {
-            UcxBuffer *content = ucx_buffer_new(NULL,
-                    FILEBUF_SIZE*2, UCX_BUFFER_AUTOEXTEND);
-            {
-                ucx_stream_copy(inputfile, content, (read_func) fread,
-                        (write_func) ucx_buffer_write,
-                        filebuf, FILEBUF_SIZE, (size_t)-1);
-            }
-            fclose(inputfile);
-            
-            UcxList *inputlines = ucx_list_append(NULL, content->space);
-            for (size_t i = 1 ; i < content->size ; i++) {
-                if (content->space[i] == '\r') {
-                    content->space[i] = '\n'; i++;
-                }
-                if (content->space[i] == '\n' && i+1 < content->size) {
-                    ucx_list_append(inputlines, content->space+i+1);
-                }
-            }
-            
-            formatlines(hltr, inputlines,
-                    (write_func) fwrite, fout, settings.showlinenumbers);
-            
-            ucx_buffer_free(content);
-        } else {
-            perror("Error opening input file");
-            if (fout != stdout) {
-                fclose(fout);
-            }
-            return EXIT_FAILURE;
-        }
-        
-        /* Append footer file */
-        if (appendfile(settings.footerfile, fout, filebuf, FILEBUF_SIZE,
-                "Error opening footer file")) {
-            return EXIT_FAILURE;
-        }
-        
-        free(filebuf);
-
-        return EXIT_SUCCESS;
-    }
+    
+    size_t n = formatlines(hltr, lines, outputbuffer, wfnc, maxlen, showln);
+    
+    ucx_buffer_free(content);
+    return n;
 }
 
+size_t c2html_format(void* inputbuffer, read_func rfnc,
+        char* ibuf, size_t ibuflen, void* outputbuffer, write_func wfnc,
+        c2html_highlighter_func hltr, int showln) {
+    return c2html_formatn(inputbuffer, rfnc, ibuf, ibuflen,
+            outputbuffer, wfnc, (size_t)-1, hltr, showln);
+}
+
+size_t c2html_format_file(FILE* inputfile, char *ibuf, size_t ibuflen,
+        void* outputbuffer, write_func wfnc,
+        c2html_highlighter_func hltr, int showln) {
+    return c2html_format(inputfile, (read_func) fread, ibuf, ibuflen,
+            outputbuffer, wfnc, hltr, showln);
+}
+
+void c2html_fformat_file(FILE *inputfile, char *ibuf, size_t ibuflen,
+        FILE* outputfile, c2html_highlighter_func hltr, int showln) {
+    c2html_format(inputfile, (read_func) fread, ibuf, ibuflen,
+            outputfile, (write_func) fwrite, hltr, showln);
+}

mercurial