src/c2html.c

Mon, 03 Oct 2022 12:14:53 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 03 Oct 2022 12:14:53 +0200
changeset 63
12d8f0f6ef06
parent 61
47a5fc33590a
child 67
5da2cb5aea6b
permissions
-rw-r--r--

update tests

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2016 Mike Becker. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "c2html.h"

#include <ucx/list.h>
#include <ucx/utils.h>

#define try_write(wfnc, str, n, buf, written, maxlen) \
    {                                              \
        size_t m = maxlen-written;                    \
        written += wfnc(str, 1, n > m ? m : n, buf);  \
    }

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

    /* 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) {
        /* increase line number and clean line buffer */
        lineno++;
        ucx_buffer_clear(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);
        }
        
        /* process code line */
        highlighter(sourceline->data, line, hd);
        
        /* write code line */
        try_write(wfnc, line->space, line->size, outbuf, written, maxlen);
        
        if (written == maxlen) break;
    }
    
    /* end monospace formatting */
    try_write(wfnc, "</pre>\n", 7, outbuf, written, maxlen);
    
    /* cleanup and return */
    ucx_buffer_free(hd->primary_buffer);
    ucx_buffer_free(hd->secondary_buffer);
    free(hd);
    ucx_buffer_free(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_bcopy(inputbuffer, content, rfnc, (write_func) ucx_buffer_write,
            ibuf, ibuflen);

    size_t n = c2html_bformatn(content->space, content->size,
            outputbuffer, wfnc, maxlen, hltr, showln);
    
    ucx_buffer_free(content);
    return n;
}

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);
        }
    }
    
    size_t n = formatlines(hltr, lines, outputbuffer, wfnc, maxlen, showln);
    
    ucx_list_free(lines);
    return n;
}

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

mercurial