src/c2html.c

Wed, 31 Aug 2016 14:41:56 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 31 Aug 2016 14:41:56 +0200
changeset 55
bf54085ce341
parent 53
5e47a26a16f0
child 57
eba880c1705c
permissions
-rw-r--r--

adds appropriate public API

/*
 * 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, "<span class=\"c2html-lineno\">"
                    "<a name=\"l%d\" href=\"#l%d\">%*d </a></span> ",
                    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_copy(inputbuffer, content, rfnc, (write_func) ucx_buffer_write,
            ibuf, ibuflen, (size_t)-1);

    UcxList *lines = ucx_list_append(NULL, content->space);
    for (size_t i = 1 ; i < content->size ; i++) {
        if (content->space[i] == '\r') {
            content->space[i] = '\n'; i++;
        }
        if (content->space[i] == '\n' && i+1 < content->size) {
            ucx_list_append(lines, content->space+i+1);
        }
    }
    
    size_t n = formatlines(hltr, lines, outputbuffer, wfnc, maxlen, 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_format_file(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_fformat_file(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);
}

mercurial