ホーム  ざれごと  ワシントン州  ツール  NT豆知識  Win32プログラミングノート  私的用語  ジョーク  いろいろ  ゲーム雑記  Favorites  掲示板   Mail

TOOLS / hmtllist

Last modified: Sat Apr 05 04:42:08 2003 PDT

一つ上へ

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("&nbsp;\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("&nbsp;", stdout);
166:                 ++col;
167:                 continue;
168:             }
169:         }
170:         else {
171:             isContinuousSpace = false;
172:         }
173:         switch (c) {
174:         case '&':
175:             fputs("&amp;", stdout);
176:             break;
177:         case '<':
178:             fputs("&lt;", stdout);
179:             break;
180:         case '>':
181:             fputs("&gt;", stdout);
182:             break;
183:         case '\t':
184:             do {
185:                 fputs("&nbsp;", 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;&nbsp;</tt></td>\n" :
275:                                 "<td %s><tt>%d;&nbsp;</tt></td>", modifier[0], lines);
276:             }
277:             else {
278:                 printf(beautify ? "\t<td align=right><tt>%d:&nbsp;</tt></td>\n" :
279:                                 "<td align=right><tt>%d:&nbsp;</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: }


[ 作者へのメール ]

Since 1996

一つ上へ

ホーム  ざれごと  ワシントン州  ツール  NT豆知識  Win32プログラミングノート  私的用語  ジョーク  いろいろ  ゲーム雑記  Favorites  掲示板   Mail