src/c2html.c

changeset 66
1b12cf799fee
parent 60
9f25df78925e
child 67
5da2cb5aea6b
equal deleted inserted replaced
60:9f25df78925e 66:1b12cf799fee
27 * 27 *
28 */ 28 */
29 29
30 #include "c2html.h" 30 #include "c2html.h"
31 31
32 #include "ucx/list.h" 32 #include <cx/array_list.h>
33 #include "ucx/utils.h" 33 #include <cx/printf.h>
34 34
35 #define try_write(wfnc, str, n, buf, written, maxlen) \ 35 size_t c2html_format(
36 { \ 36 CxList const *lines,
37 size_t m = maxlen-written; \ 37 void *outbuf,
38 written += wfnc(str, 1, n > m ? m : n, buf); \ 38 cx_write_func wfnc,
39 c2html_highlighter_func highlighter,
40 int showln
41 ) {
42 /* total written bytes */
43 size_t written = 0;
44
45 /* compute width of line numbering */
46 int lnw = 0;
47 if (showln) {
48 size_t no_lines = cxListSize(lines);
49 for (size_t p = 1; p < no_lines; p *= 10) lnw++;
39 } 50 }
40 51
41 static size_t formatlines(c2html_highlighter_func highlighter, UcxList *in, 52 /* start code formatting */
42 void *outbuf, write_func wfnc, size_t maxlen, int showlineno) { 53 written += wfnc("<div class=\"c2html-code\">\n", 1, 26, outbuf);
43 /* total written bytes */
44 size_t written = 0;
45
46 /* compute width of line numbering */
47 int lnw = 0;
48 if (showlineno) {
49 size_t lines = ucx_list_size(in);
50 for (size_t p = 1; p < lines ; p*=10) lnw++;
51 }
52
53 /* start monospace formatting */
54 try_write(wfnc, "<pre>\n", 6, outbuf, written, maxlen);
55 54
56 /* process lines */ 55 /* process lines */
57 size_t lineno = 0; 56 int lineno = 0;
58 c2html_highlighter_data* hd = malloc(sizeof(c2html_highlighter_data)); 57 c2html_highlighter_data hd;
59 hd->multiline_comment = 0; 58 hd.multiline_comment = 0;
60 hd->primary_buffer = ucx_buffer_new(NULL, 256, UCX_BUFFER_AUTOEXTEND); 59 cxBufferInit(&hd.primary_buffer, NULL, 256, NULL, CX_BUFFER_AUTO_EXTEND);
61 hd->secondary_buffer = ucx_buffer_new(NULL, 32, UCX_BUFFER_AUTOEXTEND); 60 cxBufferInit(&hd.secondary_buffer, NULL, 32, NULL, CX_BUFFER_AUTO_EXTEND);
62 UcxBuffer *line = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND); 61 CxBuffer out_line;
63 62 cxBufferInit(&out_line, NULL, 128, NULL, CX_BUFFER_AUTO_EXTEND);
64 UCX_FOREACH(sourceline, in) { 63
64 CxIterator in_lines = cxListIterator(lines);
65 cx_foreach(char*, in_line, in_lines) {
65 /* increase line number and clean line buffer */ 66 /* increase line number and clean line buffer */
66 lineno++; 67 lineno++;
67 ucx_buffer_clear(line); 68 cxBufferClear(&out_line);
68 69
69 /* write line number */ 70 /* write line number */
70 if (showlineno) { 71 if (showln) {
71 ucx_bprintf(line, "<a class=\"c2html-lineno\" name=\"l%d\" " 72 cx_bprintf(&out_line, "<a class=\"c2html-lineno\" name=\"l%d\" "
72 "href=\"#l%d\">%*d </a>", 73 "href=\"#l%d\">%*d </a>",
73 lineno, lineno, lnw, lineno); 74 lineno, lineno, lnw, lineno);
74 } 75 }
75 76
76 /* process code line */ 77 /* process code line */
77 highlighter(sourceline->data, line, hd); 78 highlighter(in_line, &out_line, &hd);
78 79
79 /* write code line */ 80 /* write code line */
80 try_write(wfnc, line->space, line->size, outbuf, written, maxlen); 81 written += wfnc(out_line.space, 1, out_line.size, outbuf);
81
82 if (written == maxlen) break;
83 } 82 }
84 83
85 /* end monospace formatting */ 84 /* end code formatting */
86 try_write(wfnc, "</pre>\n", 7, outbuf, written, maxlen); 85 written += wfnc("</div>\n", 1, 7, outbuf);
87 86
88 /* cleanup and return */ 87 /* cleanup and return */
89 ucx_buffer_free(hd->primary_buffer); 88 cxBufferDestroy(&hd.primary_buffer);
90 ucx_buffer_free(hd->secondary_buffer); 89 cxBufferDestroy(&hd.secondary_buffer);
91 free(hd); 90 cxBufferDestroy(&out_line);
92 ucx_buffer_free(line); 91
93
94 return written; 92 return written;
95 } 93 }
96 94
97 size_t c2html_formatn(void* inputbuffer, read_func rfnc, 95 size_t c2html_bformat(
98 char* ibuf, size_t ibuflen, void* outputbuffer, write_func wfnc, 96 char const *inputbuffer,
99 size_t maxlen, c2html_highlighter_func hltr, int showln) { 97 size_t inputbuflen,
100 98 void *outbuf,
101 UcxBuffer *content = ucx_buffer_new(NULL, ibuflen*2, UCX_BUFFER_AUTOEXTEND); 99 cx_write_func wfnc,
102 ucx_stream_copy(inputbuffer, content, rfnc, (write_func) ucx_buffer_write, 100 c2html_highlighter_func highlighter,
103 ibuf, ibuflen, (size_t)-1); 101 int showln
102 ) {
103 /* a rough estimate for the number of lines */
104 size_t est_cap = 16 + inputbuflen / 40;
104 105
105 size_t n = c2html_bformatn(content->space, content->size, 106 /* create the line pointer array */
106 outputbuffer, wfnc, maxlen, hltr, showln); 107 CxList *lines = cxArrayListCreateSimple(CX_STORE_POINTERS, est_cap);
107 108 cxListAdd(lines, inputbuffer);
108 ucx_buffer_free(content); 109 for (size_t i = 1; i < inputbuflen; i++) {
110 if (inputbuffer[i] == '\n' && i + 1 < inputbuflen) {
111 cxListAdd(lines, inputbuffer + i + 1);
112 }
113 }
114
115 /* invoke the other function */
116 size_t n = c2html_format(lines, outbuf, wfnc, highlighter, showln);
117
118 /* cleanup and return */
119 cxListDestroy(lines);
109 return n; 120 return n;
110 } 121 }
111
112 size_t c2html_format(void* inputbuffer, read_func rfnc,
113 char* ibuf, size_t ibuflen, void* outputbuffer, write_func wfnc,
114 c2html_highlighter_func hltr, int showln) {
115 return c2html_formatn(inputbuffer, rfnc, ibuf, ibuflen,
116 outputbuffer, wfnc, (size_t)-1, hltr, showln);
117 }
118
119 size_t c2html_fformat(FILE* inputfile, char *ibuf, size_t ibuflen,
120 void* outputbuffer, write_func wfnc,
121 c2html_highlighter_func hltr, int showln) {
122 return c2html_format(inputfile, (read_func) fread, ibuf, ibuflen,
123 outputbuffer, wfnc, hltr, showln);
124 }
125
126 void c2html_fformatf(FILE *inputfile, char *ibuf, size_t ibuflen,
127 FILE* outputfile, c2html_highlighter_func hltr, int showln) {
128 c2html_format(inputfile, (read_func) fread, ibuf, ibuflen,
129 outputfile, (write_func) fwrite, hltr, showln);
130 }
131
132 size_t c2html_bformatn(const char* inputbuffer, size_t inputbuflen,
133 void* outputbuffer, write_func wfnc,
134 size_t maxlen, c2html_highlighter_func hltr, int showln) {
135 UcxList *lines = ucx_list_append(NULL, (char*)inputbuffer);
136 for (size_t i = 1 ; i < inputbuflen ; i++) {
137 if (inputbuffer[i] == '\n' && i+1 < inputbuflen) {
138 ucx_list_append(lines, (char*)inputbuffer+i+1);
139 }
140 }
141
142 size_t n = formatlines(hltr, lines, outputbuffer, wfnc, maxlen, showln);
143
144 ucx_list_free(lines);
145 return n;
146 }
147
148 size_t c2html_bformat(const char* inputbuffer, size_t inputbuflen,
149 void* outputbuffer, write_func wfnc,
150 c2html_highlighter_func hltr, int showln) {
151 return c2html_bformatn(inputbuffer, inputbuflen, outputbuffer, wfnc,
152 (size_t)-1, hltr, showln);
153 }
154
155 void c2html_bformatf(const char* inputbuffer, size_t inputbuflen,
156 FILE* outputfile, c2html_highlighter_func hltr, int showln) {
157 c2html_bformatn(inputbuffer, inputbuflen, outputfile,
158 (write_func) fwrite, (size_t)-1, hltr, showln);
159 }

mercurial