universe@23: /* universe@23: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. universe@23: * universe@35: * Copyright 2016 Mike Becker. All rights reserved. universe@23: * universe@23: * Redistribution and use in source and binary forms, with or without universe@23: * modification, are permitted provided that the following conditions are met: universe@23: * universe@23: * 1. Redistributions of source code must retain the above copyright universe@23: * notice, this list of conditions and the following disclaimer. universe@23: * universe@23: * 2. Redistributions in binary form must reproduce the above copyright universe@23: * notice, this list of conditions and the following disclaimer in the universe@23: * documentation and/or other materials provided with the distribution. universe@23: * universe@23: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" universe@23: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE universe@23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE universe@23: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE universe@23: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR universe@23: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF universe@23: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS universe@23: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN universe@23: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) universe@23: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE universe@23: * POSSIBILITY OF SUCH DAMAGE. universe@23: * universe@23: */ universe@52: universe@22: #include "c2html.h" universe@1: universe@39: #include "ucx/list.h" universe@55: #include "ucx/utils.h" universe@1: universe@55: #define try_write(wfnc, str, n, buf, written, maxlen) \ universe@55: { \ universe@55: size_t m = maxlen-written; \ universe@55: written += wfnc(str, 1, n > m ? m : n, buf); \ universe@53: } universe@53: universe@55: static size_t formatlines(c2html_highlighter_func highlighter, UcxList *in, universe@55: void *outbuf, write_func wfnc, size_t maxlen, int showlineno) { universe@55: /* total written bytes */ universe@55: size_t written = 0; olaf@24: universe@44: /* compute width of line numbering */ universe@53: int lnw = 0; universe@44: if (showlineno) { universe@44: size_t lines = ucx_list_size(in); universe@53: for (size_t p = 1; p < lines ; p*=10) lnw++; universe@44: } universe@44: universe@44: /* start monospace formatting */ universe@55: try_write(wfnc, "
\n", 6, outbuf, written, maxlen);
universe@39: 
universe@44:     /* process lines */
universe@39:     size_t lineno = 0;
universe@55:     c2html_highlighter_data* hd = malloc(sizeof(c2html_highlighter_data));
universe@55:     hd->multiline_comment = 0;
universe@55:     hd->primary_buffer = ucx_buffer_new(NULL, 256, UCX_BUFFER_AUTOEXTEND);
universe@55:     hd->secondary_buffer = ucx_buffer_new(NULL, 32, UCX_BUFFER_AUTOEXTEND);
universe@51:     UcxBuffer *line = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND);
universe@46:     
universe@39:     UCX_FOREACH(sourceline, in) {
universe@44:         /* increase line number and clean line buffer */
universe@39:         lineno++;
universe@44:         ucx_buffer_clear(line);
universe@44:         
universe@44:         /* write line number */
universe@44:         if (showlineno) {
universe@44:             ucx_bprintf(line, ""
universe@44:                     "%*d  ",
universe@44:                     lineno, lineno, lnw, lineno);
universe@44:         }
universe@44:         
universe@45:         /* process code line */
universe@51:         highlighter(sourceline->data, line, hd);
olaf@24:         
universe@50:         /* write code line */
universe@55:         try_write(wfnc, line->space, line->size, outbuf, written, maxlen);
universe@55:         
universe@55:         if (written == maxlen) break;
olaf@24:     }
olaf@24:     
universe@44:     /* end monospace formatting */
universe@55:     try_write(wfnc, "
\n", 7, outbuf, written, maxlen); universe@44: universe@44: /* cleanup and return */ universe@55: ucx_buffer_free(hd->primary_buffer); universe@55: ucx_buffer_free(hd->secondary_buffer); universe@55: free(hd); universe@39: ucx_buffer_free(line); universe@55: universe@55: return written; olaf@24: } olaf@24: universe@55: size_t c2html_formatn(void* inputbuffer, read_func rfnc, universe@55: char* ibuf, size_t ibuflen, void* outputbuffer, write_func wfnc, universe@55: size_t maxlen, c2html_highlighter_func hltr, int showln) { universe@55: universe@55: UcxBuffer *content = ucx_buffer_new(NULL, ibuflen*2, UCX_BUFFER_AUTOEXTEND); universe@55: ucx_stream_copy(inputbuffer, content, rfnc, (write_func) ucx_buffer_write, universe@55: ibuf, ibuflen, (size_t)-1); universe@42: universe@55: UcxList *lines = ucx_list_append(NULL, content->space); universe@55: for (size_t i = 1 ; i < content->size ; i++) { universe@55: if (content->space[i] == '\r') { universe@55: content->space[i] = '\n'; i++; universe@55: } universe@55: if (content->space[i] == '\n' && i+1 < content->size) { universe@55: ucx_list_append(lines, content->space+i+1); universe@11: } universe@19: } universe@55: universe@55: size_t n = formatlines(hltr, lines, outputbuffer, wfnc, maxlen, showln); universe@55: universe@55: ucx_buffer_free(content); universe@55: return n; universe@1: } universe@1: universe@55: size_t c2html_format(void* inputbuffer, read_func rfnc, universe@55: char* ibuf, size_t ibuflen, void* outputbuffer, write_func wfnc, universe@55: c2html_highlighter_func hltr, int showln) { universe@55: return c2html_formatn(inputbuffer, rfnc, ibuf, ibuflen, universe@55: outputbuffer, wfnc, (size_t)-1, hltr, showln); universe@55: } universe@55: universe@55: size_t c2html_format_file(FILE* inputfile, char *ibuf, size_t ibuflen, universe@55: void* outputbuffer, write_func wfnc, universe@55: c2html_highlighter_func hltr, int showln) { universe@55: return c2html_format(inputfile, (read_func) fread, ibuf, ibuflen, universe@55: outputbuffer, wfnc, hltr, showln); universe@55: } universe@55: universe@55: void c2html_fformat_file(FILE *inputfile, char *ibuf, size_t ibuflen, universe@55: FILE* outputfile, c2html_highlighter_func hltr, int showln) { universe@55: c2html_format(inputfile, (read_func) fread, ibuf, ibuflen, universe@55: outputfile, (write_func) fwrite, hltr, showln); universe@55: }