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: }