src/c2html.c

changeset 39
ac35daceb24c
parent 38
77c158821738
child 40
903b46fc4214
--- a/src/c2html.c	Tue Aug 23 12:06:46 2016 +0200
+++ b/src/c2html.c	Tue Aug 23 13:49:38 2016 +0200
@@ -28,77 +28,9 @@
  */
 #include "c2html.h"
 
-inputfile_t *inputfilebuffer(size_t capacity) {
-    inputfile_t *inputfile = (inputfile_t*) malloc(sizeof(inputfile_t));
-    inputfile->lines = (char**) malloc(capacity * sizeof(char*));
-    inputfile->capacity = capacity;
-    inputfile->count = 0;
-    inputfile->maxlinewidth = 0;
-
-    return inputfile;
-}
-
-void addline(inputfile_t *inputfile, char* line, size_t width) {
-    char *l = (char*) malloc(width+1);
-    memcpy(l, line, width);
-    l[width] = 0;
-    if (inputfile->count >= inputfile->capacity) {
-        inputfile->capacity <<= 1;
-        inputfile->lines = realloc(inputfile->lines,
-            sizeof(char*)*inputfile->capacity);
-    }
-    inputfile->lines[inputfile->count] = l;
-    inputfile->maxlinewidth =
-        width > inputfile->maxlinewidth ? width : inputfile->maxlinewidth;
-    inputfile->count++;
-}
-
-void freeinputfilebuffer(inputfile_t *inputfile) {
-    for (int i = 0 ; i < inputfile->count ; i++) {
-        free(inputfile->lines[i]);
-    }
-    free(inputfile->lines);
-    free(inputfile);
-}
-
-inputfile_t *readinput(char *filename) {
-
-    int fd = open(filename, O_RDONLY);
-    if (fd == -1) return NULL;
-
-    inputfile_t *inputfile = inputfilebuffer(512);
-
-    char buf[INPUTBUF_SIZE];
-    ssize_t r;
-
-    size_t maxlinewidth = 256;
-    char *line = (char*) malloc(maxlinewidth);
-    size_t col = 0;
-
-    while ((r = read(fd, buf, INPUTBUF_SIZE)) > 0) {
-        for (size_t i = 0 ; i < r ; i++) {
-            if (col >= maxlinewidth-4) {
-                maxlinewidth <<= 1;
-                line = realloc(line, maxlinewidth);
-            }
-
-            if (buf[i] == '\n') {
-                line[col++] = '\n';
-                line[col] = 0;
-                addline(inputfile, line, col);
-                col = 0;
-            } else {
-                line[col++] = buf[i];
-            }
-        }
-    }
-
-    free(line);
-
-    close(fd);
-
-    return inputfile;
-}
+#include "ucx/buffer.h"
+#include "ucx/list.h"
+#include "ucx/utils.h"
 
 void printhelp() {
     printf("Formats source code using HTML.\n\nUsage:\n"
@@ -115,12 +47,6 @@
         "\n");
 }
 
-int lnint(size_t lnc) {
-    int w = 1, p = 1;
-    while ((p*=10) < lnc) w++;
-    return w;
-}
-
 int copyfile(char *filename, FILE *dest) {
     if (!filename) {
         return 0;
@@ -136,60 +62,71 @@
         fclose(src);
         return 0;
     } else {
-        return -1;
+        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,
+        UcxList *in,
+        write_func out,
         void *stream,
-        _Bool showln) {
-    // formats an input file and writes the result to out
+        int showlineno) {
+    size_t lines = ucx_list_size(in);
     
-    char *line = malloc(in->maxlinewidth*64);
+    UcxBuffer *line = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND);
     if(!line) {
         return 1;
     }
     WRITECONST(stream, out, "<pre>\n");
     
-    int lnw = lnint(in->count);
-    for (int i = 0 ; i < in->count ; i++) {
+    int lnw;
+    {
+        lnw = 1;
+        int p = 1;
+        while ((p*=10) < lines) lnw++;
+    }
+
+    size_t lineno = 0;
+    UCX_FOREACH(sourceline, in) {
+        lineno++;
+        /* TODO: backwards compatibility: replace line->space in all occasions
+         * and use UcxBuffer functions
+         */
         if (highlighter) {
-            highlighter->parser(in->lines[i], line, highlighter);
+            highlighter->parser(sourceline->data, line->space, highlighter);
         } else {
-            char *c = in->lines[i];
+            char *c = sourceline->data;
             size_t dp = 0;
             while (*c) {
-                dp = writeescapedchar(line, dp, *c);
+                dp = writeescapedchar(line->space, dp, *c);
                 c++;
             }
-            line[dp] = '\0';
+            line->space[dp] = '\0';
         }
 
         // write line number
-        if (showln) {
+        if (showlineno) {
             WRITECONST(stream, out, "<span class=\"c2html-lineno\">");
             char lnbuf[128];
             int len;
             // line number link
             len = snprintf(lnbuf, 128, "<a name=\"l%d\" href=\"#l%d\">",
-                i+1, i+1);
+                lineno, lineno);
             out(lnbuf, 1, len, stream);
             // justified line number
-            len = snprintf(lnbuf, 128, "%*d ", lnw, i+1);
+            len = snprintf(lnbuf, 128, "%*d ", lnw, lineno);
             out(lnbuf, 1, len, stream);
             WRITECONST(stream, out, "</a></span> ");
         }
         
         // write formated (or plain) code line
-        out(line, 1, strlen(line), stream);
+        out(line->space, 1, strlen(line->space), stream);
     }
     
     WRITECONST(stream, out, "</pre>\n");
-    free(line);
+    ucx_buffer_free(line);
     return 0;
 }
 
@@ -209,15 +146,20 @@
     highlighter->parser = jparseline;
 }
 
+enum source_type {
+    SOURCE_C,
+    SOURCE_JAVA,
+    SOURCE_PLAIN
+};
+
 int main(int argc, char** argv) {
     int retcode = EXIT_SUCCESS;
     
-    settings_t settings;
+    Settings settings;
     memset(&settings, 0, sizeof(settings));
-    settings.highlight = 1;
     settings.showlinenumbers = 1;
     
-    int lang = C2HTML_C;
+    enum source_type sourcetype = SOURCE_C;
 
     char optc;
     while ((optc = getopt(argc, argv, "hljo:pH:F:vV")) != -1) {
@@ -234,10 +176,10 @@
                 settings.headerfile = optarg;
                 break;
             case 'j':
-                lang = C2HTML_JAVA;
+                sourcetype = SOURCE_JAVA;
                 break;
             case 'p':
-                settings.highlight = 0;
+                sourcetype = SOURCE_PLAIN;
                 break;
             case 'l':
                 settings.showlinenumbers = 0;
@@ -282,30 +224,53 @@
         
         highlighter_t highlighter;
         highlighter_t *hptr = &highlighter;
-        switch (lang) {
-            case C2HTML_C:
+        switch (sourcetype) {
+            case SOURCE_C:
                 init_c_highlighter(&highlighter);
                 break;
-            case C2HTML_JAVA:
+            case SOURCE_JAVA:
                 init_java_highlighter(&highlighter);
                 break;
-            default:
+            case SOURCE_PLAIN:
                 hptr = NULL;
                 break;
-        }
-        if (!settings.highlight) {
-            hptr = NULL;
+            default: /* should be unreachable */
+                fprintf(stderr, "error in enum source_type\n");
+                retcode = EXIT_FAILURE;
+                goto prog_end;
         }
 
-        inputfile_t *inputfile = readinput(settings.infilename);
+        FILE *inputfile = fopen(settings.infilename, "r");
         if (inputfile) {
+            UcxBuffer *filebuf = ucx_buffer_new(NULL,
+                    2048, UCX_BUFFER_AUTOEXTEND);
+            {
+                const size_t tmpbufsize = 512;
+                char *tmpbuf = malloc(tmpbufsize);
+                ucx_stream_copy(inputfile, filebuf, (read_func) fread,
+                        (write_func) ucx_buffer_write,
+                        tmpbuf, tmpbufsize, (size_t)-1);
+                free(tmpbuf);
+            }
+            fclose(inputfile);
+            
+            UcxList *inputlines = ucx_list_append(NULL, filebuf->space);
+            for (size_t i = 1 ; i < filebuf->size ; i++) {
+                if (filebuf->space[i] == '\r') {
+                    filebuf->space[i] = '\n'; i++;
+                }
+                if (filebuf->space[i] == '\n' && i+1 < filebuf->size) {
+                    ucx_list_append(inputlines, filebuf->space+i+1);
+                }
+            }
+            
             formatfile(
                     hptr,
-                    inputfile,
-                    (fmt_write_func)fwrite,
+                    inputlines,
+                    (write_func) fwrite,
                     fout,
                     settings.showlinenumbers);
-            freeinputfilebuffer(inputfile);
+            ucx_buffer_free(filebuf);
         } else {
             perror("Error opening input file");
             retcode = EXIT_FAILURE;

mercurial