--- a/src/c2html.c Thu Nov 10 18:44:48 2016 +0100 +++ b/src/c2html.c Mon Apr 24 20:54:38 2023 +0200 @@ -29,131 +29,93 @@ #include "c2html.h" -#include "ucx/list.h" -#include "ucx/utils.h" +#include <cx/array_list.h> +#include <cx/printf.h> -#define try_write(wfnc, str, n, buf, written, maxlen) \ - { \ - size_t m = maxlen-written; \ - written += wfnc(str, 1, n > m ? m : n, buf); \ +size_t c2html_format( + CxList const *lines, + void *outbuf, + cx_write_func wfnc, + c2html_highlighter_func highlighter, + int showln +) { + /* total written bytes */ + size_t written = 0; + + /* compute width of line numbering */ + int lnw = 0; + if (showln) { + size_t no_lines = cxListSize(lines); + for (size_t p = 1; p < no_lines; p *= 10) lnw++; } -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; - if (showlineno) { - size_t lines = ucx_list_size(in); - for (size_t p = 1; p < lines ; p*=10) lnw++; - } - - /* start monospace formatting */ - try_write(wfnc, "<pre>\n", 6, outbuf, written, maxlen); + /* start code formatting */ + written += wfnc("<div class=\"c2html-code\">\n", 1, 26, outbuf); /* process lines */ - size_t lineno = 0; - 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); - - UCX_FOREACH(sourceline, in) { + int lineno = 0; + c2html_highlighter_data hd; + hd.multiline_comment = 0; + cxBufferInit(&hd.primary_buffer, NULL, 256, NULL, CX_BUFFER_AUTO_EXTEND); + cxBufferInit(&hd.secondary_buffer, NULL, 32, NULL, CX_BUFFER_AUTO_EXTEND); + CxBuffer out_line; + cxBufferInit(&out_line, NULL, 128, NULL, CX_BUFFER_AUTO_EXTEND); + + CxIterator in_lines = cxListIterator(lines); + cx_foreach(char*, in_line, in_lines) { /* increase line number and clean line buffer */ lineno++; - ucx_buffer_clear(line); - + cxBufferClear(&out_line); + /* write line number */ - if (showlineno) { - ucx_bprintf(line, "<a class=\"c2html-lineno\" name=\"l%d\" " - "href=\"#l%d\">%*d </a>", - lineno, lineno, lnw, lineno); + if (showln) { + cx_bprintf(&out_line, "<a class=\"c2html-lineno\" name=\"l%d\" " + "href=\"#l%d\">%*d </a>", + lineno, lineno, lnw, lineno); } - + /* process code line */ - highlighter(sourceline->data, line, hd); - + highlighter(in_line, &out_line, &hd); + /* write code line */ - try_write(wfnc, line->space, line->size, outbuf, written, maxlen); - - if (written == maxlen) break; + written += wfnc(out_line.space, 1, out_line.size, outbuf); } - - /* end monospace formatting */ - try_write(wfnc, "</pre>\n", 7, outbuf, written, maxlen); - + + /* end code formatting */ + written += wfnc("</div>\n", 1, 7, outbuf); + /* cleanup and return */ - ucx_buffer_free(hd->primary_buffer); - ucx_buffer_free(hd->secondary_buffer); - free(hd); - ucx_buffer_free(line); - + cxBufferDestroy(&hd.primary_buffer); + cxBufferDestroy(&hd.secondary_buffer); + cxBufferDestroy(&out_line); + return written; } -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); - - size_t n = c2html_bformatn(content->space, content->size, - outputbuffer, wfnc, maxlen, hltr, showln); - - ucx_buffer_free(content); - return n; -} +size_t c2html_bformat( + char const *inputbuffer, + size_t inputbuflen, + void *outbuf, + cx_write_func wfnc, + c2html_highlighter_func highlighter, + int showln +) { + /* a rough estimate for the number of lines */ + size_t est_cap = 16 + inputbuflen / 40; -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_fformat(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_fformatf(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); -} - -size_t c2html_bformatn(const char* inputbuffer, size_t inputbuflen, - void* outputbuffer, write_func wfnc, - size_t maxlen, c2html_highlighter_func hltr, int showln) { - UcxList *lines = ucx_list_append(NULL, (char*)inputbuffer); - for (size_t i = 1 ; i < inputbuflen ; i++) { - if (inputbuffer[i] == '\n' && i+1 < inputbuflen) { - ucx_list_append(lines, (char*)inputbuffer+i+1); + /* create the line pointer array */ + CxList *lines = cxArrayListCreateSimple(CX_STORE_POINTERS, est_cap); + cxListAdd(lines, inputbuffer); + for (size_t i = 1; i < inputbuflen; i++) { + if (inputbuffer[i] == '\n' && i + 1 < inputbuflen) { + cxListAdd(lines, inputbuffer + i + 1); } } - - size_t n = formatlines(hltr, lines, outputbuffer, wfnc, maxlen, showln); - - ucx_list_free(lines); - return n; -} + + /* invoke the other function */ + size_t n = c2html_format(lines, outbuf, wfnc, highlighter, showln); -size_t c2html_bformat(const char* inputbuffer, size_t inputbuflen, - void* outputbuffer, write_func wfnc, - c2html_highlighter_func hltr, int showln) { - return c2html_bformatn(inputbuffer, inputbuflen, outputbuffer, wfnc, - (size_t)-1, hltr, showln); -} - -void c2html_bformatf(const char* inputbuffer, size_t inputbuflen, - FILE* outputfile, c2html_highlighter_func hltr, int showln) { - c2html_bformatn(inputbuffer, inputbuflen, outputfile, - (write_func) fwrite, (size_t)-1, hltr, showln); -} + /* cleanup and return */ + cxListDestroy(lines); + return n; +} \ No newline at end of file