Skip to content

Instantly share code, notes, and snippets.

@Hamayama
Created July 16, 2023 09:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Hamayama/da0b4cada629cf8bf39d79590a7acf8e to your computer and use it in GitHub Desktop.
Save Hamayama/da0b4cada629cf8bf39d79590a7acf8e to your computer and use it in GitHub Desktop.
Gauche による C のコード置換のサンプル
gosh 1100_replace_code.scm setting.c setting_changed.c
gosh 1100_replace_code.scm settingData.txt settingData_changed.txt
pause
(use gauche.charconv)
(use gauche.sequence)
(use util.match)
;; file encoding
(define *file-encoding* "utf-8")
(define *check-utf-8-bom* #t)
;; make newline to crlf
(define *crlf* "\r\n")
(define (newline :optional (port (current-output-port))) (display *crlf* port))
(define (print . args) (for-each display args) (newline))
;; ===== data =====
(define *data*
#(
#(#/Parameter1/ FunctionsA_param1)
#(#/Parameter2/ FunctionsB_param1 "file:xxxxx.c")
#(#/Parameter3/ FunctionsC_param1)
#(#/settingData.txt/ settingData_changed.txt "file:setting.c")
))
;; ===== function =====
(define (check-and-output-utf-8-bom)
(when (and (ces-equivalent? *file-encoding* "utf-8")
*check-utf-8-bom*)
(let ((b1 (read-byte))
(b2 (read-byte))
(b3 (read-byte)))
(cond
((and (= b1 #xef) (= b2 #xbb) (= b3 #xbf))
(write-byte b1)
(write-byte b2)
(write-byte b3))
(else
(set-port-position! (current-input-port) 0))))))
(define (get-one-data-values one-data)
(define pattern (vector-ref one-data 0))
(define replaced (x->string (vector-ref one-data 1)))
(define option (vector-ref one-data 2 #f))
(values pattern replaced option))
(define (get-option-list option)
;(display option (standard-error-port))(display " " (standard-error-port))
(if (not option)
'()
(string-split (x->string option) ":")))
(define (check-option-file option infile)
(let ((option-list (get-option-list option)))
(if (not (equal? (list-ref option-list 0 #f) "file"))
#t
(equal? (list-ref option-list 1 #f) infile))))
(define (convert-line line infile)
(define line1 line)
(for-each
(lambda (one-data)
(receive (pattern replaced option) (get-one-data-values one-data)
(when (check-option-file option infile)
(set! line1 (regexp-replace-all pattern line1 replaced)))
))
*data*)
(print line1))
(define (convert-file infile outfile)
(with-input-from-file infile
(lambda ()
(with-output-to-file outfile
(lambda ()
(check-and-output-utf-8-bom)
(for-each
(lambda (line)
(convert-line line infile))
(generator->lseq read-line)))
:encoding *file-encoding*))
:encoding *file-encoding*))
(define (usage out code)
(display "Usage: gosh 1100_replace_code.scm infile outfile\n" out)
(exit code))
;; ===== main =====
(define (main args)
(match args
((_ infile outfile) (convert-file infile outfile))
(_ (usage (current-error-port) 1)))
0)
@set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\local\bin;C:\msys64\usr\bin;C:\msys64\bin;%PATH%
set MSYSTEM=MINGW64
for %%i in (
setting
setting_changed
) do (
gcc -g -O2 -Wall -Wextra -o %%i.exe %%i.c
)
pause
@rem set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\local\bin;C:\msys64\usr\bin;C:\msys64\bin;%PATH%
@rem set MSYSTEM=MINGW64
@rem gdb setting.exe
setting.exe
setting_changed.exe
pause
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// 設定ファイル
#define SETTING_FILE "settingData.txt"
// 設定データ構造体
typedef struct {
bool IsUseFunctionA;
int Parameter1;
float Parameter2;
double Parameter3;
} SettingData;
// 設定データ
SettingData SettingData1;
// 行バッファサイズ
#define LINE_BUF_SIZE 1000
// 設定ファイル読み込み
// 戻り値 0 : 正常
// -1 : ファイルオープンエラー
// -2 : ファイルフォーマットエラー
int LoadSettingFile(const char *filePath, SettingData *settingDataPtr)
{
printf("ReadSettingFile()\n");
printf(" filePath=%s\n", filePath);
// キーテーブル
const char *keyTable[] =
{
"IsUseFunctionA",
"Parameter1",
"Parameter2",
"Parameter3",
};
const int keyTableSize = sizeof(keyTable) / sizeof(keyTable[0]);
printf(" keyTableSize=%d\n", keyTableSize);
// 値テーブル
char valueTable[keyTableSize][LINE_BUF_SIZE];
// 値の存在チェック用フラグ
bool valueExistsTable[keyTableSize];
for (int i = 0; i < keyTableSize; i++) { valueExistsTable[i] = false; }
// ファイルオープン
FILE *file;
file = fopen(filePath, "r");
if (file == NULL) { return -1; }
// ファイル読み込み
char buf[LINE_BUF_SIZE];
while (fgets(buf, LINE_BUF_SIZE, file) != NULL)
{
// 改行を削除
char *p1 = strchr(buf, '\n');
if (p1 != NULL) { *p1 = '\0'; }
printf(" %s\n", buf);
// コメント行をスキップ
if (buf[0] == ';') { continue; }
// キーと値に分離
char *p2 = strchr(buf, '=');
if (p2 == NULL) { continue; }
*p2 = '\0';
char *key = buf;
char *value = p2 + 1;
// キーに対応する値を取得
for (int i = 0; i < keyTableSize; i++)
{
if (strcmp(key, keyTable[i]) == 0)
{
strcpy(valueTable[i], value);
valueExistsTable[i] = true;
printf(" key=%s, value=%s\n", key, value);
}
}
}
// ファイルクローズ
fclose(file);
// 値の存在をチェック
for (int i = 0; i < keyTableSize; i++)
{
if (!valueExistsTable[i]) { return -2; }
}
// 値を構造体に格納
int count = 0;
settingDataPtr->IsUseFunctionA = (atoi(valueTable[count]) != 0); count++;
settingDataPtr->Parameter1 = atoi(valueTable[count]); count++;
settingDataPtr->Parameter2 = (float)atof(valueTable[count]); count++;
settingDataPtr->Parameter3 = atof(valueTable[count]); count++;
return 0;
}
// メイン処理
// 戻り値 0 : 正常
// 1 : エラー
int main(void)
{
// 設定ファイル読み込み
int ret = LoadSettingFile(SETTING_FILE, &SettingData1);
if (ret < 0)
{
printf("Setting file load error! (ret=%d)\n", ret);
return 1;
}
// 設定データ表示
printf("\n");
printf("SettingData1\n");
printf(" IsUseFunctionA=%d\n", (int)SettingData1.IsUseFunctionA);
printf(" Parameter1=%d\n", SettingData1.Parameter1);
printf(" Parameter2=%g\n", SettingData1.Parameter2);
printf(" Parameter3=%g\n", SettingData1.Parameter3);
return 0;
}
;; Setting data
IsUseFunctionA=1
Parameter1=12345
Parameter2=1.2345
Parameter3=1.2345e-10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment