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@66: #include universe@66: #include universe@70: #include universe@1: universe@66: size_t c2html_format( universe@66: CxList const *lines, universe@66: void *outbuf, universe@66: cx_write_func wfnc, universe@66: c2html_highlighter_func highlighter, universe@66: int showln universe@66: ) { universe@66: /* total written bytes */ universe@66: size_t written = 0; universe@66: universe@66: /* compute width of line numbering */ universe@66: int lnw = 0; universe@66: if (showln) { universe@66: size_t no_lines = cxListSize(lines); universe@66: for (size_t p = 1; p < no_lines; p *= 10) lnw++; universe@53: } universe@53: universe@66: /* start code formatting */ universe@66: written += wfnc("
\n", 1, 26, outbuf); universe@39: universe@44: /* process lines */ universe@66: int lineno = 0; universe@66: c2html_highlighter_data hd; universe@66: hd.multiline_comment = 0; universe@66: cxBufferInit(&hd.primary_buffer, NULL, 256, NULL, CX_BUFFER_AUTO_EXTEND); universe@66: cxBufferInit(&hd.secondary_buffer, NULL, 32, NULL, CX_BUFFER_AUTO_EXTEND); universe@66: CxBuffer out_line; universe@66: cxBufferInit(&out_line, NULL, 128, NULL, CX_BUFFER_AUTO_EXTEND); universe@66: universe@66: CxIterator in_lines = cxListIterator(lines); universe@66: cx_foreach(char*, in_line, in_lines) { universe@44: /* increase line number and clean line buffer */ universe@39: lineno++; universe@66: cxBufferClear(&out_line); universe@66: universe@44: /* write line number */ universe@66: if (showln) { universe@66: cx_bprintf(&out_line, "%*d ", universe@66: lineno, lineno, lnw, lineno); universe@44: } universe@66: universe@45: /* process code line */ universe@66: highlighter(in_line, &out_line, &hd); universe@66: universe@50: /* write code line */ universe@66: written += wfnc(out_line.space, 1, out_line.size, outbuf); olaf@24: } universe@66: universe@66: /* end code formatting */ universe@66: written += wfnc("
\n", 1, 7, outbuf); universe@66: universe@44: /* cleanup and return */ universe@66: cxBufferDestroy(&hd.primary_buffer); universe@66: cxBufferDestroy(&hd.secondary_buffer); universe@66: cxBufferDestroy(&out_line); universe@66: universe@55: return written; olaf@24: } olaf@24: universe@70: size_t c2html_textformat( universe@66: char const *inputbuffer, universe@66: void *outbuf, universe@66: cx_write_func wfnc, universe@66: c2html_highlighter_func highlighter, universe@66: int showln universe@66: ) { universe@66: /* a rough estimate for the number of lines */ universe@70: size_t inputbuflen = strlen(inputbuffer); universe@66: size_t est_cap = 16 + inputbuflen / 40; universe@42: universe@66: /* create the line pointer array */ universe@66: CxList *lines = cxArrayListCreateSimple(CX_STORE_POINTERS, est_cap); universe@66: cxListAdd(lines, inputbuffer); universe@71: for (size_t i = 0; i < inputbuflen; i++) { universe@66: if (inputbuffer[i] == '\n' && i + 1 < inputbuflen) { universe@66: cxListAdd(lines, inputbuffer + i + 1); universe@57: } universe@57: } universe@66: universe@66: /* invoke the other function */ universe@66: size_t n = c2html_format(lines, outbuf, wfnc, highlighter, showln); universe@66: universe@66: /* cleanup and return */ universe@66: cxListDestroy(lines); universe@57: return n; universe@66: }