AngelScript2.17.2をSHIFT-JISに対応したソースを参考(参考サイトは下記サイト)
コメントはSHIFT-JIS版を作成したUeSyu氏のそのままにしてあります。AngelScript2.18.0をShift-JIS対応をする。AngelScript2.18.1でも直す場所は同じ。変更部分は[Shift-JIS対応ここから]、 [Shift-JIS対応ここまで]
とコメントをいれて修正部分を明確にしておく。
上記の対応から二つ関数がいらなくなっていました。
でも[プロプロセッサの定義]にAS_DOUBLEBYTE_CHARSETは必要。
実際にanglescriptをリンクするプロジェクトでは下記を設定しないと日本語は使えない。
理由はasCScriptEngine::asCScriptEngine()で 下記のように定義されているから。
ep.scanner = 1; // utf8. 0 = ascii
angelscriptを使用するプロジェクトでの設定
asIScriptEngine *lpEngine=asCreateScriptEngine(ANGELSCRIPT_VERSION);
lpEngine->SetEngineProperty(asEP_SCRIPT_SCANNER ,0);
日本語を使用した結果
anglescript内で日本語、カタカナを使用した結果
修正ファイル関数一覧
as_tokenizer.h
as_tokenizer.cpp::asCTokenizer
as_tokenizer.cpp::IsConstant
as_compiler.cpp::ProcessStringConstant
as_parserr.cpp::asCParse
as_tokeniser.hの修正箇所(engine->ep.scanner が定義されてないエラー修正)
<form><textarea readonly="readonly" cols="75" rows="8">///SHIFT-JIS 対応ここから //Add By UeSyu ------------------------- #include "as_scriptengine.h" //-------------------------------------- ///SHIFT-JIS 対応ここまで class asCTokenizer { public: asCTokenizer(); ~asCTokenizer(); ///SHIFT-JIS 対応ここから //Add By UeSyu ------------------------- asCTokenizer(asCScriptEngine *lpEngine); //ヘッダでは実態を持たず定義だけにしたいので修正 //void SetScriptEngine(asCScriptEngine *lpEngine); //{ // m_lpEngine=lpEngine; //} void SetScriptEngine(asCScriptEngine *lpEngine); asCScriptEngine *m_lpEngine; //-------------------------------------- ///SHIFT-JIS 対応ここまで </textarea>
</form>as_tokenizer.cpp::asCTokenizerの修正箇所(原因は上記と同じ)
<form><textarea readonly="readonly" cols="75" rows="8">///SHIFT-JIS 対応ここから asCTokenizer::asCTokenizer() : m_lpEngine(NULL) { } asCTokenizer::asCTokenizer(asCScriptEngine *lpEngine) : m_lpEngine(lpEngine) { } void asCTokenizer::SetScriptEngine(asCScriptEngine *lpEngine) { m_lpEngine=lpEngine; } //asCTokenizer::asCTokenizer() //orignal //{ //} ///SHIFT-JIS 対応ここまで </textarea>
</form><form>
as_tokenizer.cpp::IsConstantの修正箇所(原因は上記と同じ)
<textarea rows="8" cols="75" readonly="readonly">bool asCTokenizer::IsConstant() { // Starting with number if( source[0] >= '0' && source[0] <= '9' ) { // Is it a hexadecimal number? if( source[0] == '0' && sourceLength >= 1 && (source[1] == 'x' || source[1] == 'X') ) { size_t n; for( n = 2; n < sourceLength; n++ ) { if( !(source[n] >= '0' && source[n] <= '9') && !(source[n] >= 'a' && source[n] <= 'f') && !(source[n] >= 'A' && source[n] <= 'F') ) break; } tokenType = ttBitsConstant; tokenLength = n; return true; } size_t n; for( n = 1; n < sourceLength; n++ ) { if( source[n] < '0' || source[n] > '9' ) break; } if( n < sourceLength && source[n] == '.' ) { n++; for( ; n < sourceLength; n++ ) { if( source[n] < '0' || source[n] > '9' ) break; } if( n < sourceLength && (source[n] == 'e' || source[n] == 'E') ) { n++; if( n < sourceLength && (source[n] == '-' || source[n] == '+') ) n++; for( ; n < sourceLength; n++ ) { if( source[n] < '0' || source[n] > '9' ) break; } } if( n < sourceLength && (source[n] == 'f' || source[n] == 'F') ) { tokenType = ttFloatConstant; tokenLength = n + 1; } else { #ifdef AS_USE_DOUBLE_AS_FLOAT tokenType = ttFloatConstant; #else tokenType = ttDoubleConstant; #endif tokenLength = n; } return true; } tokenType = ttIntConstant; tokenLength = n; return true; } // String constant between double or single quotes if( source[0] == '"' || source[0] == '\'' ) { // Is it a normal string constant or a heredoc string constant? if( sourceLength >= 6 && source[0] == '"' && source[1] == '"' && source[2] == '"' ) { // Heredoc string constant (spans multiple lines, no escape sequences) // Find the length size_t n; for( n = 3; n < sourceLength-2; n++ ) { if( source[n] == '"' && source[n+1] == '"' && source[n+2] == '"' ) break; } tokenType = ttHeredocStringConstant; tokenLength = n+3; } else { // Normal string constant tokenType = ttStringConstant; char quote = source[0]; bool evenSlashes = true; size_t n; for( n = 1; n < sourceLength; n++ ) { #ifdef AS_DOUBLEBYTE_CHARSET // Double-byte characters are only allowed for ASCII //if( (source[n] & 0x80) && engine->ep.scanner == 0 ) //Release版でエラー発生 ///SHIFT-JIS 対応ここから if( (source[n] & 0x80) && m_lpEngine->ep.scanner == 0 ) ///SHIFT-JIS 対応ここまで { // This is a leading character in a double byte character, // include both in the string and continue processing. n++; continue; } #endif if( source[n] == '\n' ) tokenType = ttMultilineStringConstant; if( source[n] == quote && evenSlashes ) { tokenLength = n+1; return true; } if( source[n] == '\\' ) evenSlashes = !evenSlashes; else evenSlashes = true; } tokenType = ttNonTerminatedStringConstant; tokenLength = n; } return true; } return false; } </textarea>
</form><form>
as_compiler.cpp::ProcessStringConstant(原因は上記と同じ)
<textarea readonly="readonly" cols="75" rows="8">///SHIFT-JIS対応 ここから #include "mbCheck.h" ///SHIFT-JIS対応 ここまで asUINT asCCompiler::ProcessStringConstant(asCString &cstr, asCScriptNode *node, bool processEscapeSequences) { int charLiteral = -1; // Process escape sequences asCArray<char> str((int)cstr.GetLength()); ///SHIFT-JIS 対応ここから #ifdef AS_DOUBLEBYTE_CHARSET bool isCheckedMB=(engine->ep.scanner == 0); #endif ///SHIFT-JIS 対応ここまで for( asUINT n = 0; n < cstr.GetLength(); n++ ) { #ifdef AS_DOUBLEBYTE_CHARSET // Double-byte charset is only allowed for ASCII and not UTF16 encoded strings ///SHIFT-JIS 対応ここから if( IsLeadByte(cstr[n]) && isCheckedMB) ///SHIFT-JIS 対応ここまで // if( (cstr[n] & 0x80) && engine->ep.scanner == 0 && engine->ep.stringEncoding != 1 ) //Release版ではエラーになる { // This is the lead character of a double byte character // include the trail character without checking it's value. str.PushLast(cstr[n]); n++; str.PushLast(cstr[n]); continue; } #endif </textarea>
</form><form>
as_parserr.cpp::asCParser修正箇所(tokeniserにengineをセット)
<textarea readonly="readonly" cols="75" rows="8">asCParser::asCParser(asCBuilder *builder) { this->builder = builder; this->engine = builder->engine; ///SHIFT-JIS 対応ここから tokenizer.SetScriptEngine(builder->engine); ///SHIFT-JIS 対応ここまで script = 0; scriptNode = 0; checkValidTypes = false; isParsingAppInterface = false; } </textarea>
</form><form>
mbCheck.hの中身(下記サイトでのチェック関数)
<textarea readonly="readonly" cols="75" rows="8">#ifndef __MB_CHECK_DEFINED__ #define __MB_CHECK_DEFINED__ #ifdef AS_DOUBLEBYTE_CHARSET ///----[ Check Lead Byte ]---- ///@param c [in] 1バイト目の値 ///@return 2バイト文字の1バイト目ならtrue、そうでなければfalse inline bool IsLeadByte(char c) { //Japanese ShiftJIS return (('\x81'<=c && c<='\x9f') || ('\xe0'<=c && c<='\xfc')); } #endif #endif </textarea>
</form>
mbCheck.hの中身(新規作成) 判定方法変更 (sjisの1バイト目の判定)
この関数の意味を詳しく図解しているサイト
<textarea readonly="readonly" cols="75" rows="8">#ifndef __MB_CHECK_DEFINED__ #define __MB_CHECK_DEFINED__ #ifdef AS_DOUBLEBYTE_CHARSET ///----[ Check Lead Byte ]---- ///@param c [in] 1バイト目の値 ///@return 2バイト文字の1バイト目ならtrue、そうでなければfalse inline bool IsLeadByte(char c) { //Japanese ShiftJIS return((unsigned int) (c ^ 0x20) - 0xa1 < 0x3c); } #endif #endif </textarea>
参考にしたサイト
http://plaza.rakuten.co.jp/OldStyleFactory/diary/?ctgy=4