ホーム ざれごと ワシントン州 ツール NT豆知識 Win32プログラミングノート 私的用語 ジョーク いろいろ ゲーム雑記 Favorites 掲示板 Mail
1: | // htmlList.cpp |
2: | // |
3: | // CプログラムのHTML形式でのリスティング |
4: | // |
5: | // Copyright (C) 1998 by Hirofumi Yamamoto |
6: | // |
7: | |
8: | #include <stdio.h> |
9: | #include <stdlib.h> |
10: | #include <string.h> |
11: | #include <ctype.h> |
12: | #include <locale.h> |
13: | |
14: | #pragma hdrstop |
15: | |
16: | // |
17: | // ロードモジュールの大きさを小さくするには、MSVCRT.DLLを使う。 |
18: | // |
19: | // コンパイル時に"_MT"と"_DLL"のdefineが必要 |
20: | // リンク時に"デフォルトライブラリをすべて無視"を指定、 |
21: | // ライブラリに"msvcrt.lib"を指定することが必要 |
22: | // |
23: | |
24: | // |
25: | // カラー指定 |
26: | // |
27: | unsigned int colors[2] = { |
28: | 0xd0eeef, 0xd0f7ef |
29: | }; |
30: | unsigned int color_comment = 0x228b22; |
31: | unsigned int color_string = 0x6666ff; |
32: | |
33: | // |
34: | // オプション |
35: | // |
36: | bool nobr = false; |
37: | bool linenumber = false; |
38: | bool coloring = false; |
39: | bool beautify = false; |
40: | int tab = 4; |
41: | |
42: | // |
43: | // 各カラムのモディファイヤ(もしあれば) |
44: | // |
45: | const char* modifier[2]; |
46: | |
47: | void usage() |
48: | { |
49: | puts("usage: htmlList [-rny] [-t#] [-b:RRGGBB:RRGGBB] [-c[:RRGGBB:RRGGBB]] [-#:\"tag\"] [--] [filename]"); |
50: | puts(" -b:color1:color2"); |
51: | puts(" -c:color_comment:color_string if colors are not specified, default colors are used."); |
52: | puts(" -r: nobr"); |
53: | puts(" -n: line number"); |
54: | puts(" -t#: tab default is 4."); |
55: | puts(" -y: beautify output (just a little bit)"); |
56: | puts("note: -#:\"tag\" # is 0 or 1."); |
57: | exit(EXIT_FAILURE); |
58: | } |
59: | |
60: | // |
61: | // オプション解析 |
62: | // オプションの最後なら true を返す |
63: | // |
64: | bool option(const char* arg) |
65: | { |
66: | for (; *arg; ++arg) { |
67: | if (isdigit(*arg)) { |
68: | // モディファイヤ指定 |
69: | char* end; |
70: | int n = strtoul(arg, &end, 10); |
71: | if (n < 0 || n >= sizeof modifier / sizeof modifier[0]) { |
72: | usage(); |
73: | } |
74: | if (*end == ':') { |
75: | ++end; |
76: | } |
77: | modifier[n] = end; |
78: | return false; |
79: | } |
80: | |
81: | switch (*arg) { |
82: | case 'b': |
83: | { |
84: | char* end; |
85: | colors[0] = strtoul(arg + 2, &end, 16); |
86: | if (end) { |
87: | ++end; |
88: | colors[1] = strtoul(end, NULL, 16); |
89: | } |
90: | } |
91: | return false; |
92: | case 'c': |
93: | coloring = true; |
94: | if (arg[1]) { |
95: | char* end; |
96: | color_comment = strtoul(arg + 2, &end, 16); |
97: | if (end) { |
98: | ++end; |
99: | color_string = strtoul(end, NULL, 16); |
100: | } |
101: | } |
102: | break; |
103: | case 'n': |
104: | linenumber = true; |
105: | break; |
106: | case 'r': |
107: | nobr = true; |
108: | break; |
109: | case 't': |
110: | tab = atoi(arg + 1); |
111: | if (tab == 0) { |
112: | tab = 4; |
113: | } |
114: | return false; |
115: | case 'y': |
116: | beautify = true; |
117: | break; |
118: | case '-': |
119: | return true; |
120: | case '?': |
121: | default: |
122: | usage(); |
123: | } |
124: | } |
125: | return false; |
126: | } |
127: | |
128: | |
129: | // |
130: | // タブその他を解釈して出力 |
131: | // |
132: | void myputs(const char* p) |
133: | { |
134: | int col = 0; |
135: | |
136: | if (*p == '\n') { |
137: | fputs(" \n", stdout); |
138: | return; |
139: | } |
140: | |
141: | bool isKanji = false; |
142: | bool inString = false; |
143: | bool isTailComment = false; |
144: | bool isContinuousSpace = false; |
145: | |
146: | char c; |
147: | while (c = *p++) { |
148: | if (isleadbyte(c)) { |
149: | putchar(c); |
150: | c = *p++; |
151: | putchar(c); |
152: | col += 2; |
153: | continue; |
154: | } |
155: | if (coloring && !isTailComment && c == '/' && *p == '/') { |
156: | // "//"コメント |
157: | printf("<font color=#%x>", color_comment); |
158: | isTailComment = true; |
159: | } |
160: | if (c == ' ') { |
161: | if (!isContinuousSpace && *p == ' ') { |
162: | isContinuousSpace = true; |
163: | } |
164: | if (isContinuousSpace) { |
165: | fputs(" ", stdout); |
166: | ++col; |
167: | continue; |
168: | } |
169: | } |
170: | else { |
171: | isContinuousSpace = false; |
172: | } |
173: | switch (c) { |
174: | case '&': |
175: | fputs("&", stdout); |
176: | break; |
177: | case '<': |
178: | fputs("<", stdout); |
179: | break; |
180: | case '>': |
181: | fputs(">", stdout); |
182: | break; |
183: | case '\t': |
184: | do { |
185: | fputs(" ", stdout); |
186: | } while (++col % tab); |
187: | continue; |
188: | case '\\': |
189: | putchar(c); |
190: | if (*p && *p != '\n') { |
191: | c = *p++; |
192: | ++col; |
193: | putchar(c); |
194: | } |
195: | break; |
196: | case '\n': |
197: | goto exit_loop; |
198: | case '"': |
199: | if (coloring && !isTailComment) { |
200: | if (inString = !inString) { |
201: | printf("<font color=#%x>", color_string); |
202: | } |
203: | putchar(c); |
204: | if (!inString) { |
205: | fputs("</font>", stdout); |
206: | } |
207: | break; |
208: | } |
209: | // fall down |
210: | default: |
211: | putchar(c); |
212: | break; |
213: | } |
214: | ++col; |
215: | } |
216: | |
217: | exit_loop: |
218: | if (coloring && isTailComment) { |
219: | fputs("</font>", stdout); |
220: | } |
221: | if (beautify && c == '\n') { |
222: | putchar(c); |
223: | } |
224: | } |
225: | |
226: | // |
227: | // 出力メイン |
228: | // |
229: | void process(const char* fname) |
230: | { |
231: | FILE* fp; |
232: | |
233: | if (fname == NULL) { |
234: | fp = stdin; |
235: | } |
236: | else { |
237: | fp = fopen(fname, "rt"); |
238: | if (fp == NULL) { |
239: | perror(fname); |
240: | exit(EXIT_FAILURE); |
241: | } |
242: | } |
243: | |
244: | // |
245: | // テーブル出力開始 |
246: | // |
247: | printf("<table cellspacing=0 border=0 cellpadding=0 " |
248: | //width=100%% |
249: | "bgcolor=#%x>\n", colors[1]); |
250: | |
251: | // 行バッファ |
252: | // BOGUS BOGUS BOGUS |
253: | char buf[4096]; // 1行は4096バイトまでと仮定 |
254: | // BOGUS BOGUS BOGUS |
255: | |
256: | // 行番号 |
257: | int lines = 0; |
258: | |
259: | while (fgets(buf, sizeof buf, fp)) { |
260: | // 行開始 |
261: | if (lines++ % 2) { |
262: | printf("<tr bgcolor=#%x>", colors[lines % 2]); |
263: | } |
264: | else { |
265: | printf("<tr>"); |
266: | } |
267: | if (beautify) { |
268: | putchar('\n'); |
269: | } |
270: | |
271: | // 行番号表示 |
272: | if (linenumber) { |
273: | if (modifier[0]) { |
274: | printf(beautify ? "\t<td %s><tt>%d; </tt></td>\n" : |
275: | "<td %s><tt>%d; </tt></td>", modifier[0], lines); |
276: | } |
277: | else { |
278: | printf(beautify ? "\t<td align=right><tt>%d: </tt></td>\n" : |
279: | "<td align=right><tt>%d: </tt></td>", lines); |
280: | } |
281: | } |
282: | |
283: | // リスティング |
284: | int col = 0; |
285: | fputs(beautify ? "\t<td" : "<td", stdout); |
286: | if (modifier[col]) { |
287: | printf(" %s", modifier[col]); |
288: | } |
289: | if (nobr) { |
290: | fputs(" nowrap", stdout); |
291: | } |
292: | if (modifier[1]) { |
293: | putchar(' '); |
294: | fputs(modifier[1], stdout); |
295: | } |
296: | fputs(beautify ? ">\n\t<tt>\n" : "><tt>", stdout); |
297: | if (beautify) { |
298: | fputs("\t\t", stdout); |
299: | } |
300: | myputs(buf); |
301: | fputs(beautify ? "\t</tt>\n\t</td>\n" : "</tt></td>", stdout); |
302: | printf("</tr>\n"); |
303: | } |
304: | |
305: | // |
306: | // テーブル終わり |
307: | // |
308: | puts("</table>"); |
309: | |
310: | if (fname) { |
311: | fclose(fp); |
312: | } |
313: | } |
314: | |
315: | int main(int argc, char** argv) |
316: | { |
317: | // |
318: | // ロケールをシステム標準のものに設定 |
319: | // |
320: | setlocale(LC_ALL, ""); |
321: | |
322: | bool optend = false; |
323: | int files = 0; |
324: | |
325: | while (--argc > 0) { |
326: | if (!optend && **++argv == '-') { |
327: | optend = option(++*argv); |
328: | } |
329: | else { |
330: | if (strcmp(*argv, "-") == 0) { |
331: | process(NULL); |
332: | } |
333: | else { |
334: | process(*argv); |
335: | } |
336: | ++files; |
337: | } |
338: | } |
339: | if (files == 0) { |
340: | process(NULL); |
341: | } |
342: | return EXIT_SUCCESS; |
343: | } |
[ 作者へのメール ]
ホーム ざれごと ワシントン州 ツール NT豆知識 Win32プログラミングノート 私的用語 ジョーク いろいろ ゲーム雑記 Favorites 掲示板 Mail