scsc
の編集
https://khfdpl.osask.jp:443/wiki/?scsc
[
トップ
] [
編集
|
差分
|
バックアップ
|
添付
|
リロード
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
-- 雛形とするページ --
2016_10
2016_11
2016_12
BracketName
Essen
Essen0
Essen1
Essen2
Essen3
Essen4
EssenMemo0001
EssenMemo0002
EssenMemo0003
EssenMemo0004
EssenMemo0005
EssenMemo0006
EssenMemo0007
EssenMemo0008
EssenMemo0009
EssenMemo0010
EssenMemo0011
EssenR2
EssenR2_ess03f
EssenR2_ess03h
EssenR2_ess03i
EssenR2_ideas
EssenR2_jit00
EssenR2_jit01
FormattingRules
FrontPage
Help
IP
InterWiki
InterWikiName
InterWikiSandBox
K
KHPC
KHPC_v000doc01
KHPC_v001doc01
KHPC_v002doc01
KHPC_v003doc01
MenuBar
OSC
OSC20181027
OSC20190222
OSC20191123
OSC20230401
OSC20230528
OSC20231021
OSC20240310
OSC20241026
PHP
PukiWiki
PukiWiki/1.4
PukiWiki/1.4/Manual
PukiWiki/1.4/Manual/Plugin
PukiWiki/1.4/Manual/Plugin/A-D
PukiWiki/1.4/Manual/Plugin/E-G
PukiWiki/1.4/Manual/Plugin/H-K
PukiWiki/1.4/Manual/Plugin/L-N
PukiWiki/1.4/Manual/Plugin/O-R
PukiWiki/1.4/Manual/Plugin/S-U
PukiWiki/1.4/Manual/Plugin/V-Z
RecentDeleted
SandBox
SltVA
VariableArray
WikiEngines
WikiName
YukiWiki
advcal20161205
advcal20161206
advcal20161209
advcal20161210
advcal20161215
eoml0001
eoml0002
essen_ex01_0001
impressions
kcl_malloc
khfdpl_result1
members
memo0001
memo0002
note0001
note0002
note0003
note0004
note0005
note0006
oldworks
oldworks00
oldworks06
oldworks12
oldworks13
osaskjp_index
persistent_C
populars
pr20161105
pr20161105b
scsc
seccamp2017
spam_test
uxf
uxf_01
uxf_02
uxp
* scsc について -(by [[K]], 2016.10.04) ** 動機 -C言語で書かれたプログラムが複数ある時に、どちらが長いのか、何倍くらい長いのかという比較をしたいことがある。 -そういう比較をしたいときは処理内容で比較をしたいので、コメントが多いか少ないかとか、変数名や関数名が長くて分かりやすいか1文字になっていて分かりにくいかとかで差が出ないほうが望ましい。 -こういう時、コンパイルしてバイナリの長さで比較するという手法は有効であるが、コンパイラは使ってない変数を削除するなどもやってくれて書いてあることがそのままには反映しない場合もあり、またコンパイラの最適化性能やターゲットのCPUの命令セットの優劣で左右されるのも不本意なので、もっとシンプルなものがあったらいいのにと[[K]]は考えた。 ** 基本的な仕組み -ソースコードのサイズを測れます。 -基本的にはバイト数です。 -コメントはカウントしません。 -変数名や関数名や構造体名が長くても短くてもカウントには影響しません(すべて1文字換算でカウント)。 -スペースやタブや改行もカウントしません。 -()や{}もカウントしません。 -#if 0 ~ #endif もカウントしません。 -以下は左右どちらの書き方でも同じスコアになります |if (a != 0) { ... }|if (a) { ... }| |if (a == 0) { ... }|if (!a) { ... }| |if (p != NULL) { ... }|if (p) { ... }| |if (p == NULL) { ... }|if (!p) { ... }| |'\0'|0| |'\b'|8| |'\t'|9| |'\n'|10| |'\r'|13| |0x3|3| |0x00ab|0xab| |*(a+1)|a[1]| -constはカウントしません(constを省略して危険なことをやってほしいわけではないので)。 -#include行はカウントしません(ソース分割を妨げたくないので)。 ** ソースコード // source code size counter #include <stdio.h> #include <string.h> #include <stdlib.h> char cmp(const char *s, int j, int j1, const char *t) { char c = 0; int l = strlen(t); if (j + l <= j1 && strncmp(s + j, t, l - 1) == 0) { char ct = t[l - 1], cs = s[j + l - 1]; if (ct == ' ' && cs <= ' ') c = 1; else if (ct == '&' && strchr(" )&|;", cs) != NULL) c = 1; else if (cs == ct) c = 1; } return c; } char isAlpha(char c) { return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || (strchr("_@", c) != NULL); } char isNum(char c) { return ('0' <= c && c <= '9'); } char isAlpNum(char c) { return isAlpha(c) | isNum(c); } #define MAXSIZ 16 * 1024 * 1024 #define C buf[j] #define CMP(t) cmp(buf, j, j1, t) #define INC_SC sc++, j++; #define WHILE_J(cond) while (j < j1 && (cond)) #define SKIP(t) else if (CMP(t + 2) != 0) { sc += *t - '0'; j += t[1] - '0'; } int main(int argc, const char **argv) { char *buf = malloc(MAXSIZ); int i, j, j1 = 0, sc, tsc = 0; puts(" <scsc03a>"); for (i = 1; i < argc; i++) { char *errmsg = "", c, cc; FILE *fp = fopen(argv[i], "rb"); sc = j = 0; if (fp == NULL) { errmsg = " -- fopen error"; } else { j1 = fread(buf, 1, MAXSIZ - 2, fp); fclose(fp); if (j1 >= MAXSIZ - 2) errmsg = " -- file too large"; } if (*errmsg == '\0') { while (j < j1) { c = C; if (c <= ' ' || strchr("{}()", c) != NULL) { j++; } SKIP("05const ") // constはカウントしない. SKIP("14'\\0'") // '\0' を 0 と同一視してやる. SKIP("14'\\b'") // '\b' を 8 と同一視してやる. SKIP("14'\\t'") // '\t' を 9 と同一視してやる. SKIP("24'\\n'") // '\n' を 10 と同一視してやる. SKIP("24'\\r'") // '\r' を 13 と同一視してやる. SKIP("04!= 0&") // != 0 はカウントしない. SKIP("14== 0&") // == 0 は ! に読み替えてやる. SKIP("07!= NULL&") // != NULL はカウントしない. SKIP("17== NULL&") // == NULL は ! に読み替えてやる. SKIP("15!= -1&") // != -1 は ~ に読み替えてやる. SKIP("16!= EOF&") // != EOF は ~ に読み替えてやる. else if (isAlpha(c) != 0) { INC_SC WHILE_J (isAlpNum(C) != 0) j++; } else if (CMP("//") + CMP("#include") != 0) { WHILE_J (C != '\n') j++; } else if (CMP("/*") != 0) { while (CMP("*/") == 0) j++; j += 2; } else if (strchr("\"\'", c) != NULL) { cc = c; INC_SC WHILE_J (1) { c = C; INC_SC if (c == cc) break; if (j < j1 && c == '\\' && strchr("\"\'\\", C) != NULL) { INC_SC } } } else if (isNum(c) != 0 || (j + 1 < j1 && c == '.' && isNum(buf[j + 1]) != 0)) { if (CMP("0x") != 0) { j += 2; while (j + 1 < j1 && strchr("0_", C) != NULL && isAlpNum(buf[j + 1]) != 0) j++; } WHILE_J (isAlpNum(C) != 0 || C == '.') { INC_SC } } else if (CMP("#if 0 ") != 0) { cc = 1; do { j++; if (CMP("#if 0 ") != 0) cc++; if (CMP("#endif ") != 0) { cc--; j += 6; } } while (cc > 0); } else { INC_SC } } } printf("%9d : %s%s\n", sc, argv[i], errmsg); tsc += sc; } printf("%9d : [total]\n", tsc); return 0; } * こめんと欄 #comment
タイムスタンプを変更しない
* scsc について -(by [[K]], 2016.10.04) ** 動機 -C言語で書かれたプログラムが複数ある時に、どちらが長いのか、何倍くらい長いのかという比較をしたいことがある。 -そういう比較をしたいときは処理内容で比較をしたいので、コメントが多いか少ないかとか、変数名や関数名が長くて分かりやすいか1文字になっていて分かりにくいかとかで差が出ないほうが望ましい。 -こういう時、コンパイルしてバイナリの長さで比較するという手法は有効であるが、コンパイラは使ってない変数を削除するなどもやってくれて書いてあることがそのままには反映しない場合もあり、またコンパイラの最適化性能やターゲットのCPUの命令セットの優劣で左右されるのも不本意なので、もっとシンプルなものがあったらいいのにと[[K]]は考えた。 ** 基本的な仕組み -ソースコードのサイズを測れます。 -基本的にはバイト数です。 -コメントはカウントしません。 -変数名や関数名や構造体名が長くても短くてもカウントには影響しません(すべて1文字換算でカウント)。 -スペースやタブや改行もカウントしません。 -()や{}もカウントしません。 -#if 0 ~ #endif もカウントしません。 -以下は左右どちらの書き方でも同じスコアになります |if (a != 0) { ... }|if (a) { ... }| |if (a == 0) { ... }|if (!a) { ... }| |if (p != NULL) { ... }|if (p) { ... }| |if (p == NULL) { ... }|if (!p) { ... }| |'\0'|0| |'\b'|8| |'\t'|9| |'\n'|10| |'\r'|13| |0x3|3| |0x00ab|0xab| |*(a+1)|a[1]| -constはカウントしません(constを省略して危険なことをやってほしいわけではないので)。 -#include行はカウントしません(ソース分割を妨げたくないので)。 ** ソースコード // source code size counter #include <stdio.h> #include <string.h> #include <stdlib.h> char cmp(const char *s, int j, int j1, const char *t) { char c = 0; int l = strlen(t); if (j + l <= j1 && strncmp(s + j, t, l - 1) == 0) { char ct = t[l - 1], cs = s[j + l - 1]; if (ct == ' ' && cs <= ' ') c = 1; else if (ct == '&' && strchr(" )&|;", cs) != NULL) c = 1; else if (cs == ct) c = 1; } return c; } char isAlpha(char c) { return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || (strchr("_@", c) != NULL); } char isNum(char c) { return ('0' <= c && c <= '9'); } char isAlpNum(char c) { return isAlpha(c) | isNum(c); } #define MAXSIZ 16 * 1024 * 1024 #define C buf[j] #define CMP(t) cmp(buf, j, j1, t) #define INC_SC sc++, j++; #define WHILE_J(cond) while (j < j1 && (cond)) #define SKIP(t) else if (CMP(t + 2) != 0) { sc += *t - '0'; j += t[1] - '0'; } int main(int argc, const char **argv) { char *buf = malloc(MAXSIZ); int i, j, j1 = 0, sc, tsc = 0; puts(" <scsc03a>"); for (i = 1; i < argc; i++) { char *errmsg = "", c, cc; FILE *fp = fopen(argv[i], "rb"); sc = j = 0; if (fp == NULL) { errmsg = " -- fopen error"; } else { j1 = fread(buf, 1, MAXSIZ - 2, fp); fclose(fp); if (j1 >= MAXSIZ - 2) errmsg = " -- file too large"; } if (*errmsg == '\0') { while (j < j1) { c = C; if (c <= ' ' || strchr("{}()", c) != NULL) { j++; } SKIP("05const ") // constはカウントしない. SKIP("14'\\0'") // '\0' を 0 と同一視してやる. SKIP("14'\\b'") // '\b' を 8 と同一視してやる. SKIP("14'\\t'") // '\t' を 9 と同一視してやる. SKIP("24'\\n'") // '\n' を 10 と同一視してやる. SKIP("24'\\r'") // '\r' を 13 と同一視してやる. SKIP("04!= 0&") // != 0 はカウントしない. SKIP("14== 0&") // == 0 は ! に読み替えてやる. SKIP("07!= NULL&") // != NULL はカウントしない. SKIP("17== NULL&") // == NULL は ! に読み替えてやる. SKIP("15!= -1&") // != -1 は ~ に読み替えてやる. SKIP("16!= EOF&") // != EOF は ~ に読み替えてやる. else if (isAlpha(c) != 0) { INC_SC WHILE_J (isAlpNum(C) != 0) j++; } else if (CMP("//") + CMP("#include") != 0) { WHILE_J (C != '\n') j++; } else if (CMP("/*") != 0) { while (CMP("*/") == 0) j++; j += 2; } else if (strchr("\"\'", c) != NULL) { cc = c; INC_SC WHILE_J (1) { c = C; INC_SC if (c == cc) break; if (j < j1 && c == '\\' && strchr("\"\'\\", C) != NULL) { INC_SC } } } else if (isNum(c) != 0 || (j + 1 < j1 && c == '.' && isNum(buf[j + 1]) != 0)) { if (CMP("0x") != 0) { j += 2; while (j + 1 < j1 && strchr("0_", C) != NULL && isAlpNum(buf[j + 1]) != 0) j++; } WHILE_J (isAlpNum(C) != 0 || C == '.') { INC_SC } } else if (CMP("#if 0 ") != 0) { cc = 1; do { j++; if (CMP("#if 0 ") != 0) cc++; if (CMP("#endif ") != 0) { cc--; j += 6; } } while (cc > 0); } else { INC_SC } } } printf("%9d : %s%s\n", sc, argv[i], errmsg); tsc += sc; } printf("%9d : [total]\n", tsc); return 0; } * こめんと欄 #comment
テキスト整形のルールを表示する