更新履歴 (ChangeLog)¶
各版の変更点です。原文は英語のまま載せています。
Phase 9.2.0 (Core 4.2.0) (2026/10/23)¶
- Phase 9 can replace Phase 8 (8.2.x) as it is: the dictionaries, the SAORI modules and the baseware link of a Phase 8 ghost work by only replacing shiori.dll. There is no incompatible change like the one from Phase 7 to 8. The intended differences are the UTF-8 (BOM) files written by
save/savecrypt(8.2.9 and earlier cannot read them), the Charset header, and the Unicode code point order (see 9.0.0 below) dateandmktimeuse 64 bit seconds (the year 2038 problem). The 32-bit mingw-w64 (msvcrt) has a 32 bit time_t, so the 64 bit CRT functions (_time64, _localtime64, _mktime64) are called directly."date %s 4102444800"and"mktime 2100 1 1 0 0 0"work. The limits of the C runtime of the Windows build (msvcrt) remain: a time before 1970 and a time after about the end of the year 3000 (dategives an empty string,mktimegives -1; measured:dateup to 3001/01/01 00:00:00 UTC,mktimeup to 3001 but not 3100). The POSIX build follows the time_t of the OS. The integers of the expressions ($[ ]) are still 32 bit, so a calculation with seconds of 2038 or later (a difference of two $(date %s)) is not correct yet. (misc: Int64ToString / StringToInt64)-
diagnostics: every error and warning of the compiler, the interpreter, the dictionary and the KIS commands/SAORI now has a code and a location, in one format:
file(line): error K-E0028: undefined function "foo" called. in $(foo) at file(line) in ${OnBoot} at file(line)- the codes are
K-E<number>/K-W<number>; the numbers are listed in kawari_log.h (enum DiagCode) and are never changed or reused - the compile errors used to be
"file line: error: message"(the format changed; the text of the messages is the same). The location of a runtime diagnostic is the dictionary file and the line of the word being run, found by (entry, word): a word that is shared by several entries has one location per entry. Words made at run time (adddict, set) have no location, and the location of a word that was freed is forgotten (IDs are reused). The statements of"=kis"zones have their own lines, and afunction/lambdamade there is located at its statement - the call chain (up to 8 frames) is printed under the diagnostic:
"in ${entry}"for a word,"in $(name)"for a user function,"in <kis zone>"for the =kis zone being loaded.declwarnings print only the innermost frame - nothing is printed or recorded for a level that
logleveldoes not enable (quiet is still the default), and the meaning of a dictionary is not changed: an undefined entry is still empty. Running cost: a push and a pop of a small frame per word run, not measurable in the hot path "too few/many arguments"of KIS commands are K-W1001 / K-W1002; the errors of regex_* are K-E1100..1102; other KIS errors are K-E1000 and SAORI errors are K-E1200 (the same text as before)- the lexer used the EOL message also for a quoted string that reaches the end of the file; it now uses the EOF one (K-E0002). The preprocessor adds a final newline, so a quote left open in a file is still reported as K-E0001 and K-E0002 is rarely reached
"load/save failed"has a space before the path- add
"kosui --check": loads the dictionary in the sandbox, reports the diagnostics and quits, without reading the standard input
kosui --check [--format text|json] [--werror] [--decl] [--eval <script>]... [--seed <n>] [<rcfile>]- exit code: 0 = nothing, 1 = warnings only, 2 = errors (--werror makes warnings errors), 3 = could not run (the rcfile cannot be read)
- the output is only diagnostics (a line
"check: N error(s), M warning(s)"at the end); theechoof KIS andloglevel/logfiledo not change it. json prints one JSON document in UTF-8 whatever the console is - --eval runs a script after the load (as typed in kosui), so the diagnostics of the events can be found; it samples random choices, use --seed to repeat. --decl also reports reads of empty entries (K-W0003)
- the sandbox (engine->SetSandbox) stops everything that reaches out of the dictionary: files are not written (save, textsave, logfile... succeed without writing), SAORI modules are not loaded (a call to a registered or internal_* module answers Result: 0), and the baseware is not reached (Direct SSTP). It is for static checking only:
"=kis"is really run, so a loop that never ends hangs --check - add the static check (lint) to
"kosui --check": after the load (and before --eval) it walks every word of the dictionary and every"=kis"zone, and warns about what is wrong without running it.--no-lintturns it off - K-W2001: a reference to an entry that is defined nowhere (${x}, ${a + x}, $x[0]), which is silently empty at run time
- K-W2002: a command that is neither built in, nor defined by
function(or asSystem.Function.<name>), nor a forced built-in call (.name) - K-W2003: a regex_* command with an unquoted ( ) in an argument. The parentheses of a bare word are the block syntax of Kawari and are removed, so the regular expression never sees them: regex_match (a) x matches
awithout a group. Quote the pattern: regex_match"(a)"x. This one is found by the compiler (the tree keeps no trace of the parentheses) while it loads the dictionary, only when checking - K-W2004: regex_replace / regex_replace_first with an unquoted ${N} in the replacement string. It is expanded as a history reference before the command runs, so the back reference never reaches the regex
- a comment line
"# lint:disable-next-line=K-W2001, K-W2003"suppresses the listed lint warnings (K-W2xxx) on the next line of the file. Only a whole-line"#"is a comment in Kawari, so there is no end-of-line form. A warning in a multi-line word is located at the first line of the word, so the comment goes above the entry - to keep false positives down, these names count as defined: entries that exist after the load, any literal given as an argument of a statement (set / adddict / foreach variables...) or written in a
"$(...)"inside a string, a name whose head is a literal and whose tail is built at run time (launch_a_${n}), System.* and @local. Names built by ${...} are not checked at all. These are warnings: --werror makes them errors - the entries of the warnings are sorted by file and line. A multi-line word is located at its first line
- the compiled
"=kis"zones are kept (engine->SetKeepZones) until the check is done; they are freed right after the run as before otherwise - TKVMCode_base::GetChildren() lists the children of a code node, for the walk. It is not used when running
- add the check suite to test/run.ps1 and test/run_posix.py (test/check/*)
- the codes are
Phase 9.1.1 (Core 4.1.1) (2026/10/22)¶
- add
textload_charset,textsave_charsetandtextappend_charset: the same astextload,textsaveandtextappendwith the charset of the file as an argument (textload_charset Entry File Charset, textsave_charset File Charset Entry...). The charsets are Shift_JIS, UTF-8, EUC-JP, ISO-2022-JP, EUC-KR and GB2312 (Windows uses the code pages 20932, 50220, 949 and 936, so GB2312 is GBK and EUC-KR is UHC; POSIX uses iconv).autois also accepted by textload_charset. An unknown or unsupported charset is an error: the entry is not changed and the file is not overwritten.textload,textsaveandtextappendare unchanged - fixed crashes:
- a dictionary word with
"$"not followed by a substitution (x : ${$}) put a NULL code into the word and crashed on evaluation orsave "$[ (-2147483647-1) / -1 ]"(and"%") raised a division faultdatewith a time that localtime() cannot convert (a negative value) dereferenced NULL- an exception in
load,requestorunload(and the so_* object interface) went out of the module into the host; GlobalAlloc failure is now checked
- a dictionary word with
- fixed bugs in the interpreter:
- after a word of the form ${entry} was collected and its ID reused, the new word was dropped from the set operations (${a+b}, size etc.)
char_aton an empty string returned a NUL characterinc/decoverflowed at the int limits; they now stop at the limit- an integer value of INT_MIN was printed as garbage, and
-alone was taken as the integer 0 - numbers out of the int range are now clamped also where long is 64 bit
mktimeignored daylight saving time (now the same asdate)save/savecrypt/textsavegiven an absolute path wrote the file name into the current directory of the host; it is now written into the ghost's directory, as with a relative path.textsavelogged"load failed"on a write error"$(if cond)"without a body leaked the condition- the lexer could read the last character again at the end of a file
- the message table is built when the module is loaded, not on its first use from possibly several threads
- fixed bugs in SAORI and the platform layer:
- loading the same SAORI DLL twice left an extra LoadLibrary reference, so the DLL stayed loaded after the last unload
- a SAORI without
requestgotunloadwithoutload; on POSIX, dlclose(NULL) was called for a library that failed to open - POSIX: an unencodable character in ISO-2022-JP output was written in the kanji shift state and garbled the rest; errno was read too late
- POSIX: Direct SSTP to ninix could die by SIGPIPE, and failed when the 4-byte length header arrived in pieces
- Windows: environment variables are read with GetEnvironmentVariableW, so the values set by the host after start are seen
- a base path at the root (
/or/awith../b) lost the root
- fixed bugs in the tools:
- kosui no longer loops forever at the end of its input without
exit - kosui (Direct SSTP mode) read past the WM_COPYDATA data, could keep the mutex, and lost replies that came after SendMessageTimeout returned
- kawari_encode / kawari_encode2 / kawari_decode2 took a
.in a folder name as the extension, and could overwrite the input file with the output (such a file is now skipped) - the ghost list of kosui read the FMO size with sign extension
- shiori/py_shiori.cpp passed the handle with a wrong format code
- kosui no longer loops forever at the end of its input without
- merged the pull requests #7 and #8 of the upstream (Narazaka):
- MACH_TYPE = js exports the utility functions of Emscripten (ccall, cwrap, intArrayFromString and intArrayToString), which newer Emscripten does not export unless it is told to (and the build is -Os)
- add MACH_TYPE = wasm (WebAssembly, loaded asynchronously)
- the JavaScript API is changed:
Kawariis replaced by"newKawari (onRuntimeInitialized)", which calls the callback with { Module, FS, PATH, ERRNO_CODES, NODEFS, IDBFS, WORKERFS } once the runtime is ready
Phase 9.1.0 (Core 4.1.0) (2026/10/19)¶
- add
lambda: defines an anonymous function and returns its name (System.Lambda.<n>, never the same as a defined function). The body is written like that offunction, and the returned name is used as a command name ($(${f} args)) or passed to another function. It is not a closure: the local entries (@arg etc.) of the place where it was defined are not carried. Remove it withrmfunc - updated uka_regexp (build/src/uka_regexp):
- (*UCP) at the head of a pattern makes \d \w \s \b and the POSIX classes use the Unicode properties (the default is still ASCII only)
- where wchar_t is 16 bit (Windows), a surrogate pair is one character in a pattern (. and [^a] match a whole emoji, and a match never starts or ends in the middle of a pair). The positions given to KIS are still counted in wchar_t
- a{,m} is accepted as a{0,m}, \K in a lookaround is rejected, and catastrophic backtracking now ends in polynomial time
- fixed the output string aliasing the subject or the template in Replace(), and the capacity overflow of the internal buffers (it now throws ERR_MEMORY); a start offset inside a surrogate pair is moved to the next character boundary
- removed the notes of the unimplemented
exprandtestfrom the manual, and the finished or abandoned items (boost regex, rexpr, SAORI/2.0, i18n patch) from the plan in README.md
Phase 9.0.0 beta4 (Core 4.0.0) (2026/10/18)¶
- add the regular expression commands
regex_match,regex_find,regex_findall,regex_count,regex_replace,regex_replace_first,regex_erase,regex_erase_first,regex_splitandregex_escape, on the engine uka_regexp (build/src/uka_regexp, a git submodule; clone with --recursive or run"git submodule update --init"). The syntax is close to PCRE2; \d \w \s \b match ASCII only. The matches, the groups and the pieces are stored to the entry given as an argument - a subroutine call in a pattern, (?&name) or
\g<name>, whose name the pattern does not define is replaced with the expansion of the entry ${name}. A pattern with parentheses must be quoted (...) in the dictionary and the script - makedepend.rb resolves #include
foo.hof the same folder (needed by uka_regexp) and is converted from CP932 to EUC-JP
Phase 9.0.0 beta3 (Core 4.0.0) (2026/10/18)¶
- fixed: the module names of SAORI over DirectSSTP were lowercased with towlower(), which depends on the LC_CTYPE of the host (with tr_TR,
Ibecame U+0131 andINTERNAL_...was not recognized). Only ASCII letters are lowercased now - fixed the misuse of the STL:
- the destructor of the unique SAORI module factory used an iterator after erase()
- the result of find() was kept in
"unsigned int"and compared with npos. On 64-bit POSIX the comparison never became true, sogsub(when no more match is left) threw an exception,trread out of bounds, andisexistdid not append the separator.split, thematchfamily and the status line of SAORI are changed to size_type too (no change of behavior). On 32-bit Windows nothing changes - the length given to
substrcould overflow - decoding a broken Base64 text with more
"="than the decoded length threw an exception - internal only (not reachable from KIS so far): TEntry::Pop on an entry emptied by Clear() called back() on an empty vector, and TEntry::Replace accepted the index just past the last word
Phase 9.0.0 beta2 (Core 4.0.0) (2026/10/18)¶
- add
getproperty,setpropertyandexecutesstp/executesstpx: property system and SSTP EXECUTE commands sent to the baseware (SSP, ninix) by Direct SSTP. The window of the baseware is taken from"NOTIFY hwnd". The response code is stored to System.SSTP.ResponseCode and the additional data to System.SSTP.Data (executesstpxalso stores it to the given entry) - SAORI over DirectSSTP: the modules built in the baseware (internal_*, and the compatible ones such as houchi/httpc/string) can be called with
callsaorilike a SAORI without a DLL.saoriregista name without a DLL file, or call an unregistered"internal_*"name (checked with ListModules of internal_system). A DLL file, if it exists, is loaded as before - the commands above are refused for requests whose SecurityLevel is not local
- Linux: link with -lrt -lpthread (FMO of ninix)
- fixed: System.Sender.Path was never set, so
callsaorialways sent"SecurityLevel: Local"to SAORI. It is now set for every request (local / external / unknown) and used as the SecurityLevel of the SAORI request
Phase 9.0.0 beta1 (Core 4.0.0) (2026/10/18)¶
- changed the internal strings to wchar_t (UTF-16 on Windows, UTF-32 on POSIX). Characters outside the BMP (e.g. emoji) count as 2 characters on Windows
- fixed the file/folder name problem with Shift_JIS characters whose second byte is 0x5C etc. and with IBM/NEC extension characters (isdir, isexist, readdir...)
- changed string comparison (
compare,"<"">"in expression, the order of entry enumeration) to Unicode code point order instead of Shift_JIS byte order (no change for ASCII) - dictionary files: auto-detect UTF-8 (BOM, or valid UTF-8 as a whole) and Shift_JIS (CP932). Encrypted lines (!KAWA0000/!KAWA0001) are read as UTF-8 when the file has a BOM, otherwise as Shift_JIS
save/savecryptnow write UTF-8 with BOM (a dictionary saved bysaveorsavecryptcannot be read correctly by 8.2.9 or earlier: the BOM breaks the first line and Japanese text is read as Shift_JIS)textloaddetects UTF-8/Shift_JIS automatically.textsave/textappendwrite UTF-8 without BOM (textappendappends UTF-8 even to a Shift_JIS file)- kawari_encode/kawari_encode2 add a BOM to the output when the input is UTF-8. kawari_decode2 adds a BOM when the input has a BOM
- SHIORI: interpret the request by its Charset header and answer in the same charset (Shift_JIS when absent or unknown). Every response has a Charset header; System.Response.Charset (Shift_JIS/UTF-8) can select it
- SHIORI: export
loadu(load with a UTF-8 path) - SAORI: start with UTF-8, follow the Charset of the GET Version response (Shift_JIS when absent), interpret responses by their Charset, and call
loaduof the SAORI DLL if it is exported rccharsetaccepts UTF-8 as well as Shift_JIS (Japanese messages)logfilewrites UTF-8 without BOM. kosui console I/O uses the ANSI code page (UTF-8 on POSIX)chr,toupper/tolowerandescapekeep their behavior (ASCII only / Shift_JIS code interpretation)- Win32 API: W versions (UNICODE), WINVER=0x0500 (Windows 2000)
- non-Windows builds use iconv for charset conversion (-liconv on FreeBSD/darwin)
Phase 8.2.9 (2026/10/17)¶
- add the Win32 version information resource to the mingw binaries
- speed up: small-object allocator (mingw only, FASTALLOC option in gcc.mak) and cheaper word comparison in the dictionary
Phase 8.2.8 (2008/03/30)¶
- fixed
textsavecommand (ignore 3rd,4th... argument) (Thanks: Don, ukya, xenon)
Phase 8.2.7 (2008/02/16)¶
- fixed
insertstrcommand (work asinsertcommand) (Thanks: Phantom 9) - fixed
entrycountcommand (answer wrong number) (Thanks: Phantom 9)
Phase 8.2.6 (2008/01/27)¶
- fixed
gsubcommand (the substitution leakage when consecutive pattern is substituted by null) (Thanks: C.Ponapalt)
Phase 8.2.5 (2008/01/26)¶
- fixed the midpoint(0xa5) problem in Japanese character code (gcc optimize option: -Os => -O1. enbuged by UPX!)
- fixed
isexistcommand (do not work in root directory) - add
quietmode option for kosui (--quiet). After the initialization file is read, kosui ends at once when quiet mode. - fixed compile error for ninix-aya environment (Thanks: paulliu)
Phase 8.2.4 (2005/10/30)¶
- fixed
rfindcommand (do not work) - add project files for Visual C++ 7.1(Thanks: Shiba-yan)
- fixed compile problem for Visual C++ 7.1 in 'misc/l10.cpp ctow' function (Thanks: Shiba-yan)
- fixed a typo in 'gcc.mak' for 'ninix-aya' (Thanks: jado)
Phase 8.2.3 (2005/07/03)¶
- arranged the index management code of dictionary commands
- changed
inc/deccommands to enable to use the index value which likes dictionary commands
Phase 8.2.3RC (closed) (2005/06/21)¶
- fixed auto type judgement feature(number or character) in expression
- release compiler: MinGW 2.0.0-3 -> MinGW 4.1.0(gcc.3.4.2)
- built shiori.dll binary by 'gcc -shared' instead of 'dllwrap'
- supported gcc3.x(warning messages)
- fixed
splitcommand (NULL pointer violation!) - fixed
inc/deccommand (freezed when using the negative index value) - added
mktimecommand
Phase8.2.2 (2004/09/05)¶
- fixed dictionary commands which cannot use the negative index value from Phase 8.2.1
Phase8.2.1 (2004/09/04)¶
- fixed dictionary commands which cannot use some S-JIS characters for entry name when using index (Thanks 89@OpenKEEPS thread)
- include patches for 'ninix-aya' and 'Nise-Ringo' (Thanks ABE, phonohawk)
Phase8.2.0 (2004/02/01)¶
- changed
datecommand to enable to format a second from the Epoc - fixed
splitcommand (NULL string separator problem) - changed
splitcommand. When you omit 3rd argument or set "", it splits by char. - changed
joincommand. You chan omit 3rd argument. - fixed
listsubcommand (ghostentrytree problem) - fixed string search/replace commands. (fix differences from specification)
- fixed string search/replace commands. (illegular index problem)
- added
rsubcommand - added
getenvcommand - added
textappendcommand - added
continuesyntax. It can execute in loop syntax only. - changed
breaksyntax. It can execute in loop syntax only.