--- 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;