2019年5月11日土曜日

Test the message arrow of PlantUML sequence diagram.

Test the message arrow of PlantUML sequence diagram.



The definition file for these figures was generated by script.

  • arrowsTest.bat
  1. @if(0)==(0) echo off
  2. @rem http://computer-technology.hateblo.jp/entry/20131025/p1
  3. setlocal
  4. setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
  5.  
  6. @rem Description:
  7. @rem Test the message arrow of PlantUML sequence diagram.
  8.  
  9. @rem Usage:
  10. @rem arrowsTest.bat <arrowGroupNumber>
  11.  
  12. @rem Options:
  13. @rem arrowGroupNumber
  14. @rem 1 : "->" group.
  15. @rem 2 : "-/" group.
  16. @rem 3 : "-\" group.
  17.  
  18. @rem ####################
  19. @rem Batch.
  20. @rem ####################
  21.  
  22. set "DebugPrint=false"
  23.  
  24. @rem ....................
  25. @rem Batch main.
  26. @rem ....................
  27. set rv=11
  28. if "!DebugPrint!"=="true" call :L_BAT_Output_Args %*
  29. call :Lc_JS %*
  30.  
  31. @rem ....................
  32. @rem Exit.
  33. @rem ....................
  34. @rem echo.
  35. @rem pause
  36. @rem echo Press any key to exit.
  37. @rem pause>nul
  38. exit /b !rv!
  39. goto :eof
  40.  
  41.  
  42. @rem ....................
  43. @rem Output Args.
  44. @rem ....................
  45. :L_BAT_Output_Args
  46. @rem echo BAT %0 %* ....................
  47. set /a y=0
  48. for %%z in (
  49. %*
  50. ) do (
  51. set /a y=!y!+1
  52. echo BAT %%!y!=%%~z.
  53. )
  54. set /a rv=0
  55. goto :eof
  56.  
  57.  
  58. @rem ....................
  59. @rem Call JScript.
  60. @rem ....................
  61. :Lc_JS
  62. if "!DebugPrint!"=="true" echo BAT %0 %* ....................j
  63. set "jsargs=%*"
  64. if "!jsargs!"=="" (
  65. cscript.exe //nologo //e:JScript "%~f0"
  66. ) else (
  67. cscript.exe //nologo //e:JScript "%~f0" !jsargs!
  68. )
  69. if "!DebugPrint!"=="true" call :L_echoErrorLevel
  70. goto :eof
  71.  
  72.  
  73. @rem ....................
  74. @rem Echo ErrorLevel.
  75. @rem ....................
  76. :L_echoErrorLevel
  77. @rem echo BAT L_echoErrorLevel ....................
  78. echo BAT %0 errorlevel=!errorlevel!
  79. @rem echo.
  80. goto :eof
  81.  
  82.  
  83. @end
  84.  
  85.  
  86. // ####################
  87. // JScript.
  88. // ####################
  89.  
  90.  
  91. var DebugPrint = false;
  92.  
  93. var fso = new ActiveXObject("Scripting.FileSystemObject");
  94.  
  95.  
  96. // ....................
  97. // Output Args.
  98. // ....................
  99. function Output_Args(jsargs) {
  100. // WScript.Echo("JS Output_Args ....................");
  101. WScript.Echo("JS [" + jsargs.length + "]" + jsargs + ".");
  102. for (var idx = 0; idx < jsargs.length; ++idx) {
  103. WScript.Echo("JS Args[" + idx + "]=" + jsargs[idx] + ".");
  104. }
  105. return 0;
  106. }
  107.  
  108.  
  109. // ....................
  110. // Unknown arg.
  111. // ....................
  112. function UnknownArg(jsargs) {
  113. WScript.Echo("JS UnknownArg ....................");
  114. Output_Args(jsargs);
  115. return 1;
  116. }
  117.  
  118.  
  119. // ....................
  120. // arrowsTest : Test the message arrow of PlantUML sequence diagram.
  121. // ....................
  122. function arrowsTest(jsargs) {
  123. if (DebugPrint == true) {
  124. WScript.Echo("JS arrowsTest ....................");
  125. Output_Args(jsargs);
  126. }
  127.  
  128. // message arrow shape pattern.
  129. var arrowGroups = [
  130. [],
  131. [ // arrowGroup 1.
  132. [ // arrowType
  133. "->",
  134. "<-",
  135. "<->",
  136. ],
  137. [
  138. "->>",
  139. "<<-",
  140. "<<->>",
  141. ],
  142. ],
  143. [ // arrowGroup 2.
  144. [
  145. "-/",
  146. "/-",
  147. "/-/",
  148. ],
  149. [
  150. "-//",
  151. "//-",
  152. "//-//",
  153. ],
  154. ],
  155. [ // arrowGroup 3.
  156. [
  157. "-\\",
  158. "\\-",
  159. "\\-\\",
  160. ],
  161. [
  162. "-\\\\",
  163. "\\\\-",
  164. "\\\\-\\\\",
  165. ],
  166. ],
  167. ];
  168.  
  169. // message arrow symbol pattern.
  170. var symbols = [
  171. ["", "" ],
  172. ["o", "" ],
  173. ["", "o"],
  174. ["o", "o"],
  175. ["x", "" ],
  176. ["", "x"],
  177. ["x", "x"],
  178. ["o", "x"],
  179. ["x", "o"],
  180. ];
  181.  
  182. // Classes at both ends of the arrow.
  183. var classes = {
  184. "" : ["Bob", "Alice" ],
  185. "o" : ["Bob_o", "Alice_o"],
  186. "x" : ["Bob_x", "Alice_x"]
  187. };
  188.  
  189.  
  190. // Start definition of sequence diagram.
  191. WScript.Echo("@startuml");
  192.  
  193. WScript.Echo("participant Bob_x");
  194. WScript.Echo("participant Bob_o");
  195. WScript.Echo("participant Bob");
  196. WScript.Echo("participant Alice");
  197. WScript.Echo("participant Alice_o");
  198. WScript.Echo("participant Alice_x");
  199. WScript.Echo("");
  200.  
  201. WScript.Echo("note over Bob_x, Alice_x");
  202. WScript.Echo(" There are no arrows starting with x in the sequence diagram.");
  203. WScript.Echo(" PlantUML will follow the instructions.");
  204. WScript.Echo("end note");
  205. WScript.Echo("");
  206.  
  207. // for (var arrowGroupNumber in arrowGroups) {
  208. var arrowGroupNumber = jsargs[0];
  209. for (var arrowTypeIdx in arrowGroups[arrowGroupNumber]) {
  210. WScript.Echo("== " + arrowGroups[arrowGroupNumber][arrowTypeIdx][0].replace(/\\/g, "\\\\") + " ==");
  211. for (var symbolIdx in symbols) {
  212. for (var arrowShapeIdx in arrowGroups[arrowGroupNumber][arrowTypeIdx]) {
  213. var arrowShape = ""
  214. + symbols[symbolIdx][0]
  215. + arrowGroups[arrowGroupNumber][arrowTypeIdx][arrowShapeIdx]
  216. + symbols[symbolIdx][1]
  217. ;
  218.  
  219. var msgCmd = sprintf("%-9s %-9s %-9s",
  220. classes[symbols[symbolIdx][0]][0],
  221. arrowShape,
  222. classes[symbols[symbolIdx][1]][1]);
  223. var msgTxt = msgCmd.replace(/ +/g, " ");
  224.  
  225. WScript.Echo(sprintf("%s : %d-%d-%d : %s",
  226. msgCmd,
  227. (parseInt(arrowGroupNumber) - 1) * 2 + 1 + parseInt(arrowTypeIdx),
  228. symbolIdx, arrowShapeIdx, msgTxt));
  229. }
  230. }
  231. // }
  232. WScript.Echo("|||");
  233. WScript.Echo("");
  234. }
  235.  
  236. WScript.Echo("note over Bob_x, Alice_x");
  237. WScript.Echo("Drawn by PlantUML version:");
  238. WScript.Echo(getPlantUmlVersion());
  239. WScript.Echo("end note");
  240. WScript.Echo("");
  241.  
  242. // Finish defining the sequence diagram.
  243. WScript.Echo("@enduml");
  244.  
  245. return 0;
  246. }
  247.  
  248.  
  249. // https://kujirahand.com/blog/index.php?JScript%E3%81%A7%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E5%AE%9F%E8%A1%8C
  250. function getPlantUmlVersion() {
  251. var shell = new ActiveXObject("WScript.Shell");
  252. // コマンドを実行
  253. var oe = shell.Exec("java -jar plantuml.jar -v");
  254. var r = oe.StdErr.ReadAll();
  255. return r;
  256. }
  257.  
  258.  
  259. // https://qiita.com/akinomyoga/items/ccd58731743aa37e0538
  260. // agh.sprintf.js
  261. /* ----------------------------------------------------------------------------
  262.  
  263. Author: K. Murase (akinomyoga)
  264.  
  265. Changes
  266.  
  267. * 2015-05-29 KM created git repository
  268. * 2014-12-25 KM 様々な言語での実装を確認
  269. * 2013-09-05 KM added descriptions
  270. * 2013-09-01 KM first version
  271. * 2013-09-01 KM created
  272.  
  273. ------------------------------------------------------------------------------
  274.  
  275. License: The MIT License (MIT)
  276.  
  277. Copyright (c) 2013-2015 K. Murase (akinomyoga)
  278.  
  279. Permission is hereby granted, free of charge, to any person obtaining a copy
  280. of this software and associated documentation files (the "Software"), to deal
  281. in the Software without restriction, including without limitation the rights
  282. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  283. copies of the Software, and to permit persons to whom the Software is
  284. furnished to do so, subject to the following conditions:
  285.  
  286. The above copyright notice and this permission notice shall be included in
  287. all copies or substantial portions of the Software.
  288.  
  289. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  290. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  291. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  292. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  293. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  294. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  295. THE SOFTWARE.
  296.  
  297. ----------------------------------------------------------------------------*/
  298.  
  299. /**
  300. * @section sprintf.format 書式指定
  301. * 書式は以下の形式で指定する。
  302. * '%' \<pos\>? \<flag\> \<width\> \<precision\>? \<type\>? \<conv\>
  303. *
  304. * 位置指定子 \<pos\> は引数の番号を指定する。
  305. * フラグ \<flag\> は出力の見た目を細かく指定する。
  306. * 幅 \<width\> は出力時の最小文字数を指定する。
  307. * 精度 \<precision\> は内容をどれだけ詳しく出力するかを指定する。
  308. * サイズ指定子 \<type\> は引数のサイズ・型を指定する。
  309. * 変換指定子 \<conv\> は出力する形式を指定する。
  310. *
  311. * @subsection sprintf.format.pos 位置指定子 (POSIX)
  312. * 位置指定子は以下の形式を持つ。
  313. * \<pos\> := /\d+\$/
  314. * 整数で引数の番号を指定する。書式指定文字列の次に指定した引数の番号が 1 である。
  315. *
  316. * @subsection sprintf.format.flag フラグ
  317. * フラグは以下の形式を持つ。
  318. * \<flag\> := ( /[-+ 0#']/ | /\=./ ) +
  319. *
  320. * '-' (標準) 左寄せを意味する。既定では右寄せである。
  321. * '+' (標準) 非負の数値に正号を付ける事を意味する。
  322. * '#' (標準) 整数の場合、リテラルの基数を示す接頭辞を付ける。
  323. * 但し、値が 0 の時は接頭辞を付けない。
  324. * conv = o, x, X のそれぞれに対して "0", "0x", "0X" が接頭辞となる。
  325. *
  326. * 浮動小数点数 conv = f, F, e, E, g, G, a, A の場合は、
  327. * 整数 (precision = 0) に対しても小数点を付ける (例 "123.") 事を意味する。
  328. * conv = g, G については小数末尾の 0 の連続を省略せずに全て出力する。
  329. * ' ' (標準) 非負の数値の前に空白を付ける事を意味する。
  330. * これは出力幅が width で指定した幅を超えても必ず出力される空白である。
  331. * '0' (標準) 左側の余白を埋めるのに 0 を用いる。但し、空白と異なり 0 は符号や基数接頭辞の右側に追加される。
  332. * "'" (SUSv2) conv = d, i, f, F, g, G の整数部で桁区切 (3桁毎の ",") を出力する事を意味する。
  333. * 但し、flag 0 で指定される zero padding の部分には区切は入れない。
  334. *
  335. * 参考: 野良仕様で以下の様なものもあるが、ここでは実装しない。
  336. * '=?' (strfmon) 余白に使う文字の指定
  337. * ',' (Python) 桁区切。→ "'" (SUSv2) に同じ
  338. * (+ Java, Python-3.1)
  339. * '<' (Python) 左寄せ。'?<' として余白文字を指定できる。
  340. * → '-' (標準) に同じ
  341. * '>' (Python) 右寄せ。'?>' として余白文字を指定できる。
  342. * → 既定 (標準)
  343. * '^' (Python) 中央揃え。'?^' として余白文字を指定できる。
  344. * '=' (Python) 整数型において、符号の後に padding を挿入する
  345. * →これは %.3d 等とする事に等価である。
  346. * '-' (Python) 負号のみ表示 → 既定 (標準)
  347. * "'?" (PHP) 余白文字の指定。
  348. * '(' (Java) 負の数を "()" で括る。
  349. *
  350. * @subsection sprintf.format.width 幅指定子
  351. * 幅指定子は以下の形式を持つ。
  352. * \<width\> := /\d+/ | '*' | '*' /\d+/ '$'
  353. *
  354. * /\d+/ (標準) 最小幅を整数で指定する。
  355. * '*' (標準) 次の引数を読み取って最小幅とする。
  356. * '*' /\d+/ '$' (POSIX) 指定した番号の引数を最小幅とする。
  357. *
  358. * @subsection sprintf.format.precision 精度指定子
  359. * 精度指定子は以下の形式を持つ。
  360. * \<precision\> := /\d+/ | '*' | '*' /\d+/ '$'
  361. *
  362. * /\d+/ (標準) 精度を整数で指定する。
  363. * '*' (標準) 次の引数を読み取って精度とする。
  364. * '*' /\d+/ '$' (POSIX) 指定した番号の引数を精度とする。
  365. *
  366. * 整数の場合は精度で指定した桁だけ必ず整数を出力する。例えば、精度 4 の場合は "0001" など。
  367. * 精度を指定した時はフラグで指定した '0' は無視される。
  368. *
  369. * 浮動小数点数 conv = f, F, e, E, a, A の場合は小数点以下の桁数を指定する。
  370. * 浮動小数点数 conv = g, G の場合は有効桁数を指定する。
  371. * conv = f, F, e, E, g, G に対しては既定値は 6 である。
  372. * conv = a, A については倍精度浮動小数点数の16進桁数である 13 が既定値である。
  373. *
  374. * 文字列の場合は最大出力文字数を指定する。この文字数に収まらない部分は出力されずに無視される。
  375. *
  376. * @subsection sprintf.format.type サイズ指定子
  377. * サイズ指定子は以下の何れかである。
  378. *
  379. * + --------- 整数 ---------- + ------- 浮動小数点数 ------- + -------- 文字 ---------- +
  380. * | 本来 (規格) 実装 註 | 本来 (規格) 実装 註 | 本来 (規格) 実装 註 |
  381. * ----- + ------------------------- + ---------------------------- + ------------------------ +
  382. * 既定 | int (標準) double#1 | 既定 (標準) double | 既定 (標準) unicode |
  383. * 'hh' | char (C99) 8bit | float (agh) float#4 | char (agh) ascii |
  384. * 'h' | short (標準) 16bit | float (agh) float#4 | char (MSVC) ascii |
  385. * 'l' | long (標準) 32bit | double (C99) double | wint_t (C99) unicode#6 |
  386. * 'll' | long long (C99) 32bit | long double (agh) double#5 | -- -- -- |
  387. * 't' | ptrdiff_t (C99) 32bit#2 | -- -- -- | -- -- -- |
  388. * 'z' | size_t (C99) 32bit#2 | -- -- -- | -- -- -- |
  389. * 'I' | ptrdiff_t (MSVC) 32bit#2 | -- -- -- | -- -- -- |
  390. * | size_t | -- -- -- | -- -- -- |
  391. * 'I32' | 32bit (MSVC) 32bit | -- -- -- | -- -- -- |
  392. * 'q' | 64bit (BSD) 64bit#3 | -- -- -- | -- -- -- |
  393. * 'I64' | 64bit (MSVC) 64bit#3 | -- -- -- | -- -- -- |
  394. * 'j' | intmax_t (C99) double#1 | -- -- -- | -- -- -- |
  395. * 'L' | -- -- -- | long double (標準) double#5 | -- -- -- |
  396. * 'w' | -- -- -- | long double (agh) double#5 | wchar_t (MSVC) unicode |
  397. * ----- + ------------------------- + ---------------------------- + ------------------------ +
  398. *
  399. * #1 JavaScript の数値は内部的には double なので、
  400. * サイズ指定子を省略した場合はこの double で表現される整数として変換を行う。
  401. * #2 JavaScript で 64bit 整数は厳密に取り扱う事が出来ないので、32bit を native な整数とする。
  402. * #3 JavaScript では 64bit 整数は厳密に取り扱う事が出来ない。
  403. * 取り敢えず 64bit 整数として出力はするものの、巨大な整数では下の方の桁が正確ではない。
  404. *
  405. * #4 規格にないが独自拡張で、h/hh が指定された時は float の精度に落としてから出力する。
  406. * (C 言語では float の可変長引数は double に変換されるからそもそも float で指定できない)。
  407. * #5 規格上は long double だが JavaScript では long double は取り扱えないので、
  408. * double と同じ取扱とする。
  409. *
  410. * #6 POSIX を見ると %lc の引数は wchar_t[2] { wint_t(), null } と書かれている気がする? [要確認]
  411. *
  412. * 参考: 以下の様な野良サイズ指定子もある。
  413. * 'n' (Ocaml) native int
  414. *
  415. * @subsection sprintf.format.conv 変換指定子
  416. * 引数の型及び出力の形式を指定する。以下の何れかの値を取る。
  417. *
  418. * 'd', 'i' (標準) 10進符号付き整数
  419. * 'o' (標準) 8進符号無し整数
  420. * 'u' (標準) 10進符号無し整数
  421. * 'x', 'X' (標準) 16進符号無し整数 (lower/upper case, 0xa/0XA など)
  422. * 'f', 'F' (標準) 浮動小数点数 (lower/upper case, inf/INF など)
  423. * 'e', 'E' (標準) 浮動小数点数指数表記 (lower/upper case, 1e+5/1E+5 など)
  424. * 'g', 'G' (標準) 浮動小数点数短い表記 (lower/upper case, 1e+5/1E+5 など)
  425. * 'a', 'A' (C99) 浮動小数点数16進表現 (lower/upper case, 1p+5/1P+5 など)
  426. * 'c' (標準) 文字
  427. * 'C' (XSI) 文字 (本来 wchar_t 用だがこの実装では c と区別しない)
  428. * 's' (標準) 文字列
  429. * 'S' (XSI) 文字列 (本来 wchar_t 用だがこの実装では s と区別しない)
  430. * 'p' (標準) ポインタ値。この実装では upper hexadecimal number で出力。
  431. * 'n' (標準) 今迄の出力文字数を value[0] に格納
  432. * '%' (標準) "%" を出力
  433. *
  434. * 参考: 野良仕様で以下の様なものもあるが、ここでは実装しない。
  435. * 'b' (Ruby) 2進符号付き整数。(+ Python, Perl, PHP, D, Haskell)
  436. * (Go) では浮動小数点数に対して decimalless scientific notation with 2進指数
  437. * 'B' (Ruby) 2進符号付き整数。(+ Python, Perl)
  438. * 'n' (Python) 数値。ロカールに従った出力を行う(桁区切など)。
  439. * '%' (Python) 百分率。数値を百倍して解釈し 'f' 変換指定子で出力する。
  440. * 'D' (Perl) 'ld' に同じ。
  441. * 'U' (Perl) 'lu' に同じ。
  442. * 'O' (Perl) 'lo' に同じ。
  443. * 'U' (Go) 'U+%04d' に同じ。Unicode code point の為。
  444. * 't' (Go) true/false
  445. * 'b', 'B' (Java) true/false (+ OCaml)
  446. * 'h', 'H' (Java) null/'%x'
  447. *
  448. * 'q' (Bash) 文字/文字列をリテラル (quoted string) として出力。 (+ Go Lua)
  449. * Go では文字(整数)は '' で、文字列は "" で囲む。Lua では '' で囲む。
  450. * 'C' (OCaml) 文字リテラル '' として出力
  451. * 'S' (OCaml) 文字列リテラル "" として出力
  452. * 'T' (Go) typename
  453. * 'v' (Go) default format (+ Haskell)
  454. * 'p' (Ruby) Object#inspect の結果を載せる。
  455. *
  456. * 'n' (Java) 改行
  457. * 'a', 't' (OCaml) ? (二つ引数を取って、引数2を引数1に対し出力?)
  458. * ',' (OCaml) 何も出力しない
  459. * '@' (OCaml) '@' を出力。
  460. * '!' (OCaml) 出力先を flush する。
  461. *
  462. * @subsection sprintf.format.ref References
  463. * Wikipedia en <a href="https://en.wikipedia.org/wiki/Printf_format_string">printf format string - Wikipedia</a>
  464. * POSIX printf(1) <a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html">printf</a>
  465. * POSIX printf(1) <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap05.html#tag_05">File Format Notation</a>
  466. * POSIX printf(3) <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html">fprintf</a>
  467. * MSC 位置指定子 <a href="http://msdn.microsoft.com/ja-jp/library/bt7tawza(v=vs.90).aspx">printf_p の位置指定パラメータ</a>
  468. * MSC サイズ指定子 <a href="http://msdn.microsoft.com/ja-jp/library/vstudio/tcxf1dw6.aspx">サイズ指定</a>
  469. *
  470. * Python [[6.1. string ? 一般的な文字列操作 ? Python 3.4.2 ドキュメント>http://docs.python.jp/3/library/string.html#format-specification-mini-language]]
  471. * PHP [[PHP: sprintf - Manual>http://php.net/manual/ja/function.sprintf.php]]
  472. * Perl [[sprintf - perldoc.perl.org>http://perldoc.perl.org/functions/sprintf.html]]
  473. * D言語 [[std.format - D Programming Language - Digital Mars>http://dlang.org/phobos/std_format.html#format-string]]
  474. * Lua [[Lua 5.1 Reference Manual>http://www.lua.org/manual/5.1/manual.html#pdf-string.format]]
  475. * Haskell [[Text.Printf>http://hackage.haskell.org/package/base-4.7.0.2/docs/Text-Printf.html]]
  476. * Go [[fmt - The Go Programming Language>http://golang.org/pkg/fmt/]]
  477. * Java [[Formatter (Java Platform SE 7 )>http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax]]
  478. * R (wrapper for C printf) [[sprintf {base} | inside-R | A Community Site for R>http://www.inside-r.org/r-doc/base/sprintf]]
  479. * OCaml [[Printf>http://caml.inria.fr/pub/docs/manual-ocaml/libref/Printf.html]]
  480. */
  481.  
  482. /*
  483. * その他の書式指定の文法について
  484. * - terminfo の setaf 等で使われている文法について
  485. * %? %t %e %; 条件分岐
  486. * %| %! %- %< 演算子
  487. * %{ ... } リテラル
  488. * - date コマンド
  489. * - strfmod
  490. * - zsh PS1
  491. * - GNU screen
  492. */
  493.  
  494. // 実装:
  495. // * 解析は正規表現を使えば良い。
  496. // * 出力結果の構成
  497. // <左余白> <符号> <ゼロ> <中身> <右余白>
  498. // 計算の順番としては、<符号>+<中身> のペアを決定してから、<ゼロ> または <余白> を付加すれば良い。
  499.  
  500. (function(__exports) {
  501. // 本来 this にグローバルオブジェクトが入るはず。
  502. // もし空だった場合はこのスクリプトを呼び出したときの this を入れる。
  503. var __global = this || __exports || {};
  504. if (typeof __global.agh !== 'undefined')
  505. __exports = __global.agh;
  506. else if (typeof __global.module !== 'undefined' && typeof __global.module.exports != 'undefined')
  507. __exports = __global.module.exports;
  508. else if (__exports == null)
  509. __exports = __global.agh = {};
  510.  
  511. function repeatString(s, len) {
  512. if (len <= 0) return "";
  513. var ret = "";
  514. do if (len & 1) ret += s; while ((len >>= 1) >= 1 && (s += s));
  515. return ret;
  516. }
  517.  
  518. //---------------------------------------------------------------------------
  519. // サイズ指定子達
  520.  
  521. var INT32_MOD = 0x100000000;
  522. var INT32_MIN = -0x80000000;
  523. var INT32_MAX = +0x7FFFFFFF;
  524. var INT64_MOD = INT32_MOD * INT32_MOD;
  525. var INT64_MIN = -INT64_MOD / 2.0;
  526. var INT64_MAX = -INT64_MIN - 1;
  527.  
  528. function roundTowardZero(value) {
  529. return value < 0 ? Math.ceil(value) : Math.floor(value);
  530. }
  531.  
  532. function getIntegerValue(value, type) {
  533. // 整数は内部的には double で表現されている。
  534. // ビット演算は 32bit 符号付整数として実行される。
  535. value = roundTowardZero(value);
  536. switch (type) {
  537. case 'hh': // C99 char (8bit signed)
  538. value &= 0xFF;
  539. return value >= 0x80 ? value - 0x100 : value;
  540. case 'h': // short (16bit signed)
  541. value &= 0xFFFF;
  542. return value >= 0x8000 ? value - 0x10000 : value;
  543. case 'l': // C89 long (32bit signed) (ビット演算を使うと変になる)
  544. case 'z': // C99 size_t
  545. case 't': // C99 ptrdiff_t
  546. case 'I32': // MSVC __int32
  547. case 'I': // MSVC ptrdiff_t/size_t
  548. value %= INT32_MOD;
  549. if (value < INT32_MIN)
  550. value += INT32_MOD;
  551. else if (value > INT32_MAX)
  552. value -= INT32_MOD;
  553. return value;
  554. case 'll': // C99 long long (64bit signed)
  555. case 'I64': // MSVC __int32
  556. case 'q': // BSD quad word
  557. case 'L': // agh exntesion
  558. value %= INT64_MOD;
  559. if (value < INT64_MIN)
  560. value += INT64_MOD;
  561. else if (value > INT64_MAX)
  562. value -= INT64_MOD;
  563. return value;
  564. case 'j': default: // 変換無し (double の整数)
  565. return value;
  566. }
  567. }
  568.  
  569. function getUnsignedValue(value, type) {
  570. // 整数は内部的には double で表現されている。
  571. // ビット演算は 32bit 符号付整数として実行される。
  572. value = roundTowardZero(value);
  573. switch (type) {
  574. case 'hh': // 8bit unsigned
  575. value &= 0xFF;
  576. return value;
  577. case 'h': // 16bit unsigned
  578. value &= 0xFFFF;
  579. return value;
  580. case 'l': // C89 long (32bit unsigned) (ビット演算を使うと変になる)
  581. case 'z': // C99 size_t
  582. case 't': // C99 ptrdiff_t
  583. case 'I32': // MSVC __int32
  584. case 'I': // MSVC ptrdiff_t/size_t
  585. value %= INT32_MOD;
  586. return value < 0 ? value + INT32_MOD : value;
  587. case 'll': // C99 long long (64bit unsigned)
  588. case 'I64': // MSVC __int32
  589. case 'q': // BSD quad word
  590. case 'L': // agh exntesion
  591. value %= INT64_MOD;
  592. return value < 0 ? value + INT64_MOD : value;
  593. case 'j': default: // double の整数の 2 の補数??
  594. if (value < 0) {
  595. // 例 -0x80 ~ -0x41 → 7 ~ 6+epsilon → nbits = 8, mod = 0x100
  596. var nbits = value < INT32_MIN ? 1 + Math.ceil(Math.LOG2E * Math.log(-value)) : 32;
  597. var mod = Math.pow(2, nbits);
  598. value += mod;
  599. }
  600. return value;
  601. }
  602. }
  603.  
  604. function getFloatValue(value, type) {
  605. if (type === 'h' || type === 'hh') {
  606. var sgn = value < 0 ? -1 : 1;
  607. var exp = Math.floor(Math.LOG2E * Math.log(sgn * value));
  608. var scale = Math.pow(2, exp - 23); // float (exp = 0) は小数点以下2進23桁まで有効
  609. value = (0 | value / scale) * scale;
  610. }
  611.  
  612. return value;
  613. }
  614.  
  615. function getCharValue(value, type) {
  616. value |= 0;
  617. if (type === 'h' || type === 'hh') {
  618. value &= 0xFF;
  619. }
  620. return value;
  621. }
  622.  
  623. //---------------------------------------------------------------------------
  624. // 変換指定子達
  625.  
  626. /**
  627. * @section \<conv\>
  628. * 引数の型及び出力の形式を指定します。
  629. * - 'd', 'i' 10進符号付き整数
  630. * - 'o' 8進符号無し整数
  631. * - 'u' 10進符号無し整数
  632. * - 'x', 'X' 16進符号無し整数
  633. */
  634.  
  635. var groupIntegerRegs = [
  636. /(...)(?!$)/g,
  637. /(^.|...)(?!$)/g,
  638. /(^..|...)(?!$)/g
  639. ];
  640. function groupInteger(text, flag) {
  641. if (text.length < 4 || !/\'/.test(flag))
  642. return text;
  643. else
  644. return text.replace(groupIntegerRegs[text.length % 3], "$1,");
  645. }
  646.  
  647. var xdigits = "0123456789abcdef";
  648. function convertInteger(value, flag, precision, base) {
  649. var out = '';
  650. do {
  651. out = xdigits.charAt(value % base) + out;
  652. value = Math.floor(value / base);
  653. } while (value > 0);
  654.  
  655. if (precision != null)
  656. out = repeatString('0', precision - out.length) + out;
  657.  
  658. return out;
  659. }
  660. function convertDecimal(value, flag, precision, type) {
  661. return groupInteger(convertInteger(value, flag, precision, 10), flag);
  662. }
  663. function convertOctal(value, flag, precision, type) {
  664. return convertInteger(value, flag, precision, 8);
  665. }
  666. function convertLowerHex(value, flag, precision, type) {
  667. return convertInteger(value, flag, precision, 16);
  668. }
  669. function convertUpperHex(value, flag, precision, type) {
  670. return convertInteger(value, flag, precision, 16).toUpperCase();
  671. }
  672.  
  673. /**
  674. * - 'f', 'F' 浮動小数点数 (lower/upper case, inf/INF など)
  675. * - 'e', 'E' 浮動小数点数指数表記 (lower/upper case, 1e+5/1E+5 など)
  676. * - 'g', 'G' 浮動小数点数短い表記 (lower/upper case, 1e+5/1E+5 など)
  677. * - 'a', 'A' 浮動小数点数16進表現 (lower/upper case, 1p+5/1P+5 など)
  678. */
  679.  
  680. var logTable = [];
  681. logTable[ 2] = Math.LOG2E;
  682. logTable[10] = Math.LOG10E;
  683. logTable[16] = Math.LOG2E / 4;
  684. function frexp(value, base) {
  685. if (value === 0) return [0, 0];
  686.  
  687. var exp = 1 + Math.floor(logTable[base] * Math.log(value));
  688. value = value * Math.pow(base, -exp);
  689.  
  690. // 際どいずれが起きるので補正
  691. if (value * base < 1) {
  692. value *= base;
  693. exp--;
  694. } else if (value >= 1) {
  695. value /= base;
  696. exp++;
  697. }
  698.  
  699. return [value, exp];
  700. }
  701.  
  702. var regCarryReach = []; // 末尾の 9 の並び, 繰上到達距離測定用
  703. regCarryReach[10] = /9*$/;
  704. regCarryReach[16] = /f*$/;
  705. function generateFloatingSequence(value, precision, base) {
  706. // value [0, 1) の数値
  707. var seq = '';
  708. while (--precision > 0)
  709. seq += xdigits.charAt(0 | (value = value * base % base));
  710.  
  711. // 最後の数字は四捨五入
  712. // (0-10 の整数になるので繰り上がり処理が必要)
  713. var last = Math.round(value * base % base);
  714. if (last == base) {
  715. var cd = regCarryReach[base].exec(seq)[0].length;
  716. if (cd < seq.length) {
  717. // 繰り上がり
  718. var iinc = seq.length - cd - 1;
  719. seq = seq.slice(0, iinc) + xdigits.charAt(1 + (0 | seq.charAt(iinc))) + repeatString('0', cd + 1);
  720. } else {
  721. // 全て 9 の時 → exp更新, seq = 1000...
  722. seq = '1' + repeatString('0', cd + 1);
  723. }
  724. } else {
  725. seq += xdigits.charAt(last);
  726. }
  727. return seq;
  728. }
  729.  
  730. function omitTrailingZero(text, flag) {
  731. return text.replace(/(\.[\da-f]*?)0+$/, function($0, $1) {
  732. if ($1 && $1.length > 1)
  733. return $1;
  734. else
  735. return /#/.test(flag) ? '.' : '';
  736. });
  737. }
  738. function omitTrailingZeroE(text, flag) {
  739. return text.replace(/(\.\d*?)0+e/, function($0, $1) {
  740. if ($1 && $1.length > 1)
  741. return $1 + 'e';
  742. else
  743. return /#/.test(flag) ? '.e' : 'e';
  744. });
  745. }
  746.  
  747. function convertScientific(value, flag, precision, type) { // conv = e E
  748. if (isNaN(value))
  749. return 'nan';
  750. else if (!isFinite(value))
  751. return 'inf';
  752.  
  753. if (precision == null) precision = 6;
  754.  
  755. var buff = frexp(value, 10);
  756. var fr = buff[0], exp = buff[1] - 1;
  757. var man = generateFloatingSequence(fr, 1 + precision, 10);
  758. if (man.length > precision + 1) {
  759. // 99..99 から 100..00 に繰り上がった時
  760. man = man.slice(0, -1);
  761. exp++;
  762. }
  763.  
  764. if (precision > 0 || /#/.test(flag))
  765. man = man.slice(0, 1) + '.' + man.slice(1);
  766.  
  767. if (exp < 0)
  768. exp = 'e-' + (1000 - exp).toString().slice(1);
  769. else
  770. exp = 'e+' + (1000 + exp).toString().slice(1);
  771. return man + exp;
  772. }
  773. function convertScientificHex(value, flag, precision, type) { // conv = a A
  774. if (isNaN(value))
  775. return 'nan';
  776. else if (!isFinite(value))
  777. return 'inf';
  778.  
  779. if (precision == null)
  780. precision = type === 'h' || type === 'hh' ? 6 : 13;
  781.  
  782. var buff = frexp(value, 2);
  783. var fr = buff[0], exp = buff[1] - 1;
  784. var man = generateFloatingSequence((1 / 8) * fr, precision + 1, 16);
  785. if (man.length > precision + 1) {
  786. man = man.slice(0, -1);
  787. exp++;
  788. }
  789.  
  790. if (man.length > 1 || /#/.test(flag))
  791. man = man.slice(0, 1) + '.' + man.slice(1);
  792.  
  793. man = omitTrailingZero(man, flag);
  794.  
  795. if (exp < 0)
  796. exp = 'p-' + (1000 - exp).toString().slice(1);
  797. else
  798. exp = 'p+' + (1000 + exp).toString().slice(1);
  799. return man + exp;
  800. }
  801. function convertFloating(value, flag, precision, type) { // conv = f F
  802. if (isNaN(value))
  803. return 'nan';
  804. else if (!isFinite(value))
  805. return 'inf';
  806.  
  807. if (precision == null) precision = 6;
  808.  
  809. if (value >= 1.0) {
  810. var buff = frexp(value, 10);
  811. var fr = buff[0], exp = buff[1];
  812. } else {
  813. var fr = value / 10, exp = 1;
  814. }
  815.  
  816. var man = generateFloatingSequence(fr, exp + precision, 10);
  817. if (precision > 0 || /#/.test(flag)) {
  818. var point = man.length - precision;
  819. man = groupInteger(man.slice(0, point), flag) + '.' + man.slice(point);
  820. } else
  821. man = groupInteger(man, flag);
  822.  
  823. return man;
  824. }
  825. function convertCompact(value, flag, precision, type) { // conv = g G
  826. if (isNaN(value))
  827. return 'nan';
  828. else if (!isFinite(value))
  829. return 'inf';
  830.  
  831. if (precision == null)
  832. precision = 6;
  833. else if (precision < 1)
  834. precision = 1;
  835.  
  836. if (value < 1e-4 || Math.pow(10, precision) <= value + 0.5) {
  837. // scientific
  838. var result = convertScientific(value, flag, precision - 1, type);
  839. if (/#/.test(flag))
  840. return result;
  841. else
  842. return omitTrailingZeroE(result, flag);
  843. } else {
  844. // floating point
  845. var buff = frexp(value, 10);
  846. var fr = buff[0], exp = buff[1];
  847.  
  848. if (precision < 1) precision = 1;
  849. var man = generateFloatingSequence(fr, precision, 10);
  850. var point = man.length - (precision - exp); // 小数点挿入位置。末端からの位置が繰り上がり不変。
  851. // assert(exp <= precision);
  852. // assert(man.length == precision || man.length == precision + 1)
  853. // assert(point <= man.length);
  854. if (point > 0) {
  855. if (point < man.length || /#/.test(flag))
  856. man = groupInteger(man.slice(0, point), flag) + '.' + man.slice(point, precision);
  857. } else {
  858. man = '0.' + repeatString('0', -point) + man.slice(0, precision);
  859. }
  860.  
  861. if (/#/.test(flag))
  862. return man;
  863. else
  864. return omitTrailingZero(man, flag);
  865. }
  866. }
  867.  
  868. function convertCompactU (value, flag, precision, type) { return convertCompact (value, flag, precision, type).toUpperCase(); }
  869. function convertFloatingU (value, flag, precision, type) { return convertFloating (value, flag, precision, type).toUpperCase(); }
  870. function convertScientificU (value, flag, precision, type) { return convertScientific (value, flag, precision, type).toUpperCase(); }
  871. function convertScientificHexU(value, flag, precision, type) { return convertScientificHex(value, flag, precision, type).toUpperCase(); }
  872.  
  873. /**
  874. * - 'c', 'C' 文字
  875. * - 's', 'S' 文字列
  876. * - 'n' 今迄の出力文字数を value[0] に格納
  877. * - '%' % を出力
  878. */
  879.  
  880. function convertChar(value, flag, precision, type) {
  881. return String.fromCharCode(value);
  882. }
  883. function convertString(value, flag, precision, type) {
  884. if (value == null)
  885. value = value === undefined ? '(undefined)' : '(null)';
  886. else
  887. value = value.toString();
  888.  
  889. if (precision != null)
  890. value = value.slice(0, precision);
  891.  
  892. return value;
  893. }
  894. function convertOutputLength(value, flag, precision, type, outputLength) { // conv = n
  895. value[0] = getIntegerValue(outputLength, type);
  896. return '';
  897. }
  898. function convertEscaped(value, flag, precision, type) { return '%'; }
  899.  
  900. //---------------------------------------------------------------------------
  901.  
  902. function prefixOctal(flag) { return /#/.test(flag) ? '0' : ''; }
  903. function prefixLHex(flag) { return /#/.test(flag) ? '0x' : ''; }
  904. function prefixUHex(flag) { return /#/.test(flag) ? '0X' : ''; }
  905. function prefixFloatLHex(flag) { return '0x'; }
  906. function prefixFloatUHex(flag) { return '0X'; }
  907. function prefixPointerHex(flag) { return '0x'; }
  908.  
  909. var conversions = {
  910. d: {getv: getIntegerValue , integral: true , signed: true , prefix: null , conv: convertDecimal },
  911. i: {getv: getIntegerValue , integral: true , signed: true , prefix: null , conv: convertDecimal },
  912. u: {getv: getUnsignedValue, integral: true , signed: false, prefix: null , conv: convertDecimal },
  913. o: {getv: getUnsignedValue, integral: true , signed: false, prefix: prefixOctal , conv: convertOctal },
  914. x: {getv: getUnsignedValue, integral: true , signed: false, prefix: prefixLHex , conv: convertLowerHex },
  915. X: {getv: getUnsignedValue, integral: true , signed: false, prefix: prefixUHex , conv: convertUpperHex },
  916. e: {getv: getFloatValue , integral: false, signed: true , prefix: null , conv: convertScientific },
  917. E: {getv: getFloatValue , integral: false, signed: true , prefix: null , conv: convertScientificU },
  918. f: {getv: getFloatValue , integral: false, signed: true , prefix: null , conv: convertFloating },
  919. F: {getv: getFloatValue , integral: false, signed: true , prefix: null , conv: convertFloatingU },
  920. g: {getv: getFloatValue , integral: false, signed: true , prefix: null , conv: convertCompact },
  921. G: {getv: getFloatValue , integral: false, signed: true , prefix: null , conv: convertCompactU },
  922. a: {getv: getFloatValue , integral: false, signed: true , prefix: prefixFloatLHex , conv: convertScientificHex },
  923. A: {getv: getFloatValue , integral: false, signed: true , prefix: prefixFloatUHex , conv: convertScientificHexU},
  924. c: {getv: getCharValue , integral: false, signed: false, prefix: null , conv: convertChar },
  925. C: {getv: getCharValue , integral: false, signed: false, prefix: null , conv: convertChar },
  926. s: {getv: null , integral: false, signed: false, prefix: null , conv: convertString },
  927. S: {getv: null , integral: false, signed: false, prefix: null , conv: convertString },
  928. p: {getv: getUnsignedValue, integral: false, signed: false, prefix: prefixPointerHex, conv: convertUpperHex },
  929. n: {getv: null , integral: false, signed: false, prefix: null , conv: convertOutputLength },
  930. '%': {noValue: true , integral: false, signed: false, prefix: null , conv: convertEscaped }
  931. };
  932.  
  933. function printf_impl(fmt) {
  934. // ※arguments の fmt を除いた部分の番号は 1 から始まり、
  935. // 位置指定子も 1 から始まるので、位置番号はそのまま arguments の添字に指定して良い。
  936.  
  937. var args = arguments;
  938. var aindex = 1;
  939. var lastIndex = 0;
  940. var outputLength = 0;
  941. var output = fmt.replace(/%(?:(\d+)\$)?([-+ 0#']*)(\d+|\*(?:\d+\$)?)?(\.(?:\d+|\*(?:\d+\$)?)?)?(hh|ll|I(?:32|64)?|[hlLjztqw])?(.|$)/g, function($0, pos, flag, width, precision, type, conv, index) {
  942. outputLength += index - lastIndex;
  943. lastIndex = index + $0.length;
  944.  
  945. if ((conv = conversions[conv]) == null) {
  946. var ret = '(sprintf:error:' + $0 + ')';
  947. outputLength += ret.length;
  948. return ret;
  949. }
  950.  
  951. pos =
  952. (pos == null || pos === "") ? null :
  953. pos === '*' ? 0 | args[aindex++] :
  954. 0 | pos;
  955.  
  956. width =
  957. (width == null || width === "") ? 0 :
  958. width === '*' ? 0 | args[aindex++]:
  959. width.charAt(0) === '*' ? args[0 | width.slice(1, -1)] :
  960. 0 | width;
  961.  
  962. precision =
  963. (precision == null || precision === "") ? null:
  964. precision === '.*' ? 0 | args[aindex++]:
  965. precision.charAt(1) === '*' ? args[0 | precision.slice(2, -1)] :
  966. 0 | precision.slice(1);
  967.  
  968. var value = conv.noValue ? null: pos === null ? args[aindex++] : args[pos];
  969. if (conv.getv) value = conv.getv(value, type);
  970.  
  971. var prefix = '';
  972. if (conv.signed) {
  973. if (value < 0) {
  974. prefix = '-';
  975. value = -value;
  976. } else if (/\+/.test(flag))
  977. prefix = '+';
  978. else if (/ /.test(flag))
  979. prefix = ' ';
  980. }
  981. if (conv.prefix && value != 0)
  982. prefix += conv.prefix(flag);
  983.  
  984. var body = conv.conv(value, flag, precision, type, outputLength);
  985.  
  986. var lpad = '', zero = '', rpad = '';
  987. width -= prefix.length + body.length;
  988. if (width >= 1) {
  989. if (/-/.test(flag)) {
  990. // POSIX に従うと - の方が優先
  991. rpad = repeatString(' ', width);
  992. } else if (/0/.test(flag) && (!conv.integral || precision == null)) {
  993. zero = repeatString('0', width);
  994. } else
  995. lpad = repeatString(' ', width);
  996. }
  997.  
  998. var ret = lpad + prefix + zero + body + rpad;
  999. outputLength += ret.length;
  1000. return ret;
  1001. });
  1002. outputLength += fmt.length - lastIndex;
  1003.  
  1004. return [outputLength, output];
  1005. }
  1006.  
  1007. __exports.sprintf = function sprintf() {
  1008. var result = printf_impl.apply(this, arguments);
  1009. return result[1];
  1010. };
  1011.  
  1012. __exports.vsprintf = function vsprintf(fmt, args) {
  1013. var result = printf_impl.apply(this, [fmt].concat(args));
  1014. return result[1];
  1015. };
  1016.  
  1017. var stdout = null;
  1018. if (__global.agh && __global.printh)
  1019. stdout = function(text) { printh(agh.Text.Escape(text, 'html')); };
  1020. else if (__global.process && __global.process.stdout)
  1021. stdout = function(text) { process.stdout.write(text); };
  1022. else if (__global.console && __global.console.log)
  1023. stdout = function(text) { console.log(text); };
  1024. else
  1025. stdout = function(text) { document.write(text); };
  1026.  
  1027. __exports.printf = function printf() {
  1028. var result = printf_impl.apply(this, arguments);
  1029. stdout(result[1]);
  1030. return result[0];
  1031. };
  1032.  
  1033. if (__global.agh && __global.agh.scripts)
  1034. __global.agh.scripts.register("agh.sprintf.js");
  1035.  
  1036. })(this);
  1037.  
  1038. // test
  1039. //
  1040. // printf("%2$d行目のコマンド %1$sは不正です", "hoge", 20);
  1041. // printf("%d(1234) %o(2322) %x(4d2)\n", 1234, 1234, 1234);
  1042. // printf("%s(abc) %c(x)\n", "abc", 'x'.charCodeAt(0));
  1043. // printf("%*d( 10)", 5, 10);
  1044. // printf("%.*s(3)", 3, "abcdef");
  1045. // printf("%2d( 3) %02d(03)", 3, 3);
  1046. // printf("%1$d:%2$.*3$d:%4$.*3$d(15:035:045)\n", 15, 35, 3, 45);
  1047. //
  1048. // printf("%%d: [%+10d][%+ 10d][% +10d][%d]", 10, 10, 10, 1e10);
  1049. // printf("%%u: [%u][%u][%+u][% u][%-u][%+10u][%-10u]", -1, 10, 10, 10, 10, 10, 10);
  1050. // printf("%%x,%%u: %x %o", -1, -1);
  1051. // printf("%%a: %a %a %a %a %a %a %a %a %a", 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9);
  1052. // printf("%%A: %A %.3A %#.3A", 1e10, 1e10, 1e10);
  1053. // printf("%%A: %A %A %A %A", 4096, 2048, 1024, 512);
  1054. //
  1055. // printf("%%e: %#.3e %#.3e %#.3e", 1e1000, 1e100, 1e10);
  1056. // printf("%%e: %#.3e %#.6e %#.10e %#.20e\n", 1.234, 1.234, 1.234, 1.234);
  1057. // printf("%%e: %#.1e %#.5e %#.10e %#.100e", 9.999, 9.999, 9.999, 9.999);
  1058. // printf("%%f: %f %#g %#f %#.g %f %'f", 1, 1, 1, 1, 1e100, 1e100);
  1059. // printf("%%g: %.15g %.15g %#.15g", 1, 1.2, 1.2);
  1060. // printf("%%g: %g %.g %#g %#.g", 15, 15, 15, 15);
  1061. // printf("%%g: %g %g %g %g %g", 1e-1, 1e-3, 1e-4, 1e-5, 9e-5, 9e-4, 1e10);
  1062. // printf("%%#g: %#g %#g %#g %#2g %#6g", 0.1, 1e-5, 1e-4, 1e-4, 1e-4);
  1063. // printf("%%#.g: %#.2g %#.2g", 1e-4, 1e-5);
  1064. // printf("%%.g: %.g %.g %.g; %.1g %.1g %.1g; %.2g %.3g", 0.1, 0.999, 9.999, 9, 9.9, 9.999, 9.999, 9.999)
  1065. //
  1066. // printf("%%c: [%c][%c][%c]\n", 1e100, 65, 8);
  1067. // printf("%05s %05s\n", 123, "aaa");
  1068. // printf("%%p: %p", 512);
  1069. // printf("pi: [%1$a][%1$g][%1$'20.9g][%1$020.9g][%1$'020.9g][%2$'020.9g]", Math.PI, Math.PI * 1e3);
  1070.  
  1071.  
  1072. // --------------------
  1073. // JScript main.
  1074. // --------------------
  1075. var rv = 0;
  1076. var jsargs = new Array();
  1077. for (var idx = 0; idx < WScript.Arguments.length; ++idx) {
  1078. jsargs[idx] = WScript.Arguments(idx);
  1079. }
  1080. var ary = new Array();
  1081. ary = jsargs.slice(0, jsargs.length);
  1082. if (0 == 1) {
  1083. rv = rv + 1;
  1084. } else if (WScript.Arguments.length == 1) {
  1085. rv = rv + arrowsTest(ary);
  1086. } else {
  1087. rv = rv + UnknownArg(ary);
  1088. }
  1089.  
  1090. WScript.quit(rv);
  • arrowsTest.bat 1
@startuml
participant Bob_x
participant Bob_o
participant Bob
participant Alice
participant Alice_o
participant Alice_x

note over Bob_x, Alice_x
  There are no arrows starting with x in the sequence diagram.
  PlantUML will follow the instructions.
end note

== -> ==
Bob       ->        Alice     : 1-0-0 : Bob -> Alice 
Bob       <-        Alice     : 1-0-1 : Bob <- Alice 
Bob       <->       Alice     : 1-0-2 : Bob <-> Alice 
Bob_o     o->       Alice     : 1-1-0 : Bob_o o-> Alice 
Bob_o     o<-       Alice     : 1-1-1 : Bob_o o<- Alice 
Bob_o     o<->      Alice     : 1-1-2 : Bob_o o<-> Alice 
Bob       ->o       Alice_o   : 1-2-0 : Bob ->o Alice_o 
Bob       <-o       Alice_o   : 1-2-1 : Bob <-o Alice_o 
Bob       <->o      Alice_o   : 1-2-2 : Bob <->o Alice_o 
Bob_o     o->o      Alice_o   : 1-3-0 : Bob_o o->o Alice_o 
Bob_o     o<-o      Alice_o   : 1-3-1 : Bob_o o<-o Alice_o 
Bob_o     o<->o     Alice_o   : 1-3-2 : Bob_o o<->o Alice_o 
Bob_x     x->       Alice     : 1-4-0 : Bob_x x-> Alice 
Bob_x     x<-       Alice     : 1-4-1 : Bob_x x<- Alice 
Bob_x     x<->      Alice     : 1-4-2 : Bob_x x<-> Alice 
Bob       ->x       Alice_x   : 1-5-0 : Bob ->x Alice_x 
Bob       <-x       Alice_x   : 1-5-1 : Bob <-x Alice_x 
Bob       <->x      Alice_x   : 1-5-2 : Bob <->x Alice_x 
Bob_x     x->x      Alice_x   : 1-6-0 : Bob_x x->x Alice_x 
Bob_x     x<-x      Alice_x   : 1-6-1 : Bob_x x<-x Alice_x 
Bob_x     x<->x     Alice_x   : 1-6-2 : Bob_x x<->x Alice_x 
Bob_o     o->x      Alice_x   : 1-7-0 : Bob_o o->x Alice_x 
Bob_o     o<-x      Alice_x   : 1-7-1 : Bob_o o<-x Alice_x 
Bob_o     o<->x     Alice_x   : 1-7-2 : Bob_o o<->x Alice_x 
Bob_x     x->o      Alice_o   : 1-8-0 : Bob_x x->o Alice_o 
Bob_x     x<-o      Alice_o   : 1-8-1 : Bob_x x<-o Alice_o 
Bob_x     x<->o     Alice_o   : 1-8-2 : Bob_x x<->o Alice_o 
|||

== ->> ==
Bob       ->>       Alice     : 2-0-0 : Bob ->> Alice 
Bob       <<-       Alice     : 2-0-1 : Bob <<- Alice 
Bob       <<->>     Alice     : 2-0-2 : Bob <<->> Alice 
Bob_o     o->>      Alice     : 2-1-0 : Bob_o o->> Alice 
Bob_o     o<<-      Alice     : 2-1-1 : Bob_o o<<- Alice 
Bob_o     o<<->>    Alice     : 2-1-2 : Bob_o o<<->> Alice 
Bob       ->>o      Alice_o   : 2-2-0 : Bob ->>o Alice_o 
Bob       <<-o      Alice_o   : 2-2-1 : Bob <<-o Alice_o 
Bob       <<->>o    Alice_o   : 2-2-2 : Bob <<->>o Alice_o 
Bob_o     o->>o     Alice_o   : 2-3-0 : Bob_o o->>o Alice_o 
Bob_o     o<<-o     Alice_o   : 2-3-1 : Bob_o o<<-o Alice_o 
Bob_o     o<<->>o   Alice_o   : 2-3-2 : Bob_o o<<->>o Alice_o 
Bob_x     x->>      Alice     : 2-4-0 : Bob_x x->> Alice 
Bob_x     x<<-      Alice     : 2-4-1 : Bob_x x<<- Alice 
Bob_x     x<<->>    Alice     : 2-4-2 : Bob_x x<<->> Alice 
Bob       ->>x      Alice_x   : 2-5-0 : Bob ->>x Alice_x 
Bob       <<-x      Alice_x   : 2-5-1 : Bob <<-x Alice_x 
Bob       <<->>x    Alice_x   : 2-5-2 : Bob <<->>x Alice_x 
Bob_x     x->>x     Alice_x   : 2-6-0 : Bob_x x->>x Alice_x 
Bob_x     x<<-x     Alice_x   : 2-6-1 : Bob_x x<<-x Alice_x 
Bob_x     x<<->>x   Alice_x   : 2-6-2 : Bob_x x<<->>x Alice_x 
Bob_o     o->>x     Alice_x   : 2-7-0 : Bob_o o->>x Alice_x 
Bob_o     o<<-x     Alice_x   : 2-7-1 : Bob_o o<<-x Alice_x 
Bob_o     o<<->>x   Alice_x   : 2-7-2 : Bob_o o<<->>x Alice_x 
Bob_x     x->>o     Alice_o   : 2-8-0 : Bob_x x->>o Alice_o 
Bob_x     x<<-o     Alice_o   : 2-8-1 : Bob_x x<<-o Alice_o 
Bob_x     x<<->>o   Alice_o   : 2-8-2 : Bob_x x<<->>o Alice_o 
|||

note over Bob_x, Alice_x
Drawn by PlantUML version:
(0.000 - 15 Mo) 12 Mo - PlantUML Version 1.2019.06beta18
(0.010 - 15 Mo) 12 Mo - GraphicsEnvironment.isHeadless() false
(0.010 - 15 Mo) 12 Mo - Found 0 files
No diagram found

end note

@enduml
  • arrowsTest.bat 2
@startuml
participant Bob_x
participant Bob_o
participant Bob
participant Alice
participant Alice_o
participant Alice_x

note over Bob_x, Alice_x
  There are no arrows starting with x in the sequence diagram.
  PlantUML will follow the instructions.
end note

== -/ ==
Bob       -/        Alice     : 3-0-0 : Bob -/ Alice 
Bob       /-        Alice     : 3-0-1 : Bob /- Alice 
Bob       /-/       Alice     : 3-0-2 : Bob /-/ Alice 
Bob_o     o-/       Alice     : 3-1-0 : Bob_o o-/ Alice 
Bob_o     o/-       Alice     : 3-1-1 : Bob_o o/- Alice 
Bob_o     o/-/      Alice     : 3-1-2 : Bob_o o/-/ Alice 
Bob       -/o       Alice_o   : 3-2-0 : Bob -/o Alice_o 
Bob       /-o       Alice_o   : 3-2-1 : Bob /-o Alice_o 
Bob       /-/o      Alice_o   : 3-2-2 : Bob /-/o Alice_o 
Bob_o     o-/o      Alice_o   : 3-3-0 : Bob_o o-/o Alice_o 
Bob_o     o/-o      Alice_o   : 3-3-1 : Bob_o o/-o Alice_o 
Bob_o     o/-/o     Alice_o   : 3-3-2 : Bob_o o/-/o Alice_o 
Bob_x     x-/       Alice     : 3-4-0 : Bob_x x-/ Alice 
Bob_x     x/-       Alice     : 3-4-1 : Bob_x x/- Alice 
Bob_x     x/-/      Alice     : 3-4-2 : Bob_x x/-/ Alice 
Bob       -/x       Alice_x   : 3-5-0 : Bob -/x Alice_x 
Bob       /-x       Alice_x   : 3-5-1 : Bob /-x Alice_x 
Bob       /-/x      Alice_x   : 3-5-2 : Bob /-/x Alice_x 
Bob_x     x-/x      Alice_x   : 3-6-0 : Bob_x x-/x Alice_x 
Bob_x     x/-x      Alice_x   : 3-6-1 : Bob_x x/-x Alice_x 
Bob_x     x/-/x     Alice_x   : 3-6-2 : Bob_x x/-/x Alice_x 
Bob_o     o-/x      Alice_x   : 3-7-0 : Bob_o o-/x Alice_x 
Bob_o     o/-x      Alice_x   : 3-7-1 : Bob_o o/-x Alice_x 
Bob_o     o/-/x     Alice_x   : 3-7-2 : Bob_o o/-/x Alice_x 
Bob_x     x-/o      Alice_o   : 3-8-0 : Bob_x x-/o Alice_o 
Bob_x     x/-o      Alice_o   : 3-8-1 : Bob_x x/-o Alice_o 
Bob_x     x/-/o     Alice_o   : 3-8-2 : Bob_x x/-/o Alice_o 
|||

== -// ==
Bob       -//       Alice     : 4-0-0 : Bob -// Alice 
Bob       //-       Alice     : 4-0-1 : Bob //- Alice 
Bob       //-//     Alice     : 4-0-2 : Bob //-// Alice 
Bob_o     o-//      Alice     : 4-1-0 : Bob_o o-// Alice 
Bob_o     o//-      Alice     : 4-1-1 : Bob_o o//- Alice 
Bob_o     o//-//    Alice     : 4-1-2 : Bob_o o//-// Alice 
Bob       -//o      Alice_o   : 4-2-0 : Bob -//o Alice_o 
Bob       //-o      Alice_o   : 4-2-1 : Bob //-o Alice_o 
Bob       //-//o    Alice_o   : 4-2-2 : Bob //-//o Alice_o 
Bob_o     o-//o     Alice_o   : 4-3-0 : Bob_o o-//o Alice_o 
Bob_o     o//-o     Alice_o   : 4-3-1 : Bob_o o//-o Alice_o 
Bob_o     o//-//o   Alice_o   : 4-3-2 : Bob_o o//-//o Alice_o 
Bob_x     x-//      Alice     : 4-4-0 : Bob_x x-// Alice 
Bob_x     x//-      Alice     : 4-4-1 : Bob_x x//- Alice 
Bob_x     x//-//    Alice     : 4-4-2 : Bob_x x//-// Alice 
Bob       -//x      Alice_x   : 4-5-0 : Bob -//x Alice_x 
Bob       //-x      Alice_x   : 4-5-1 : Bob //-x Alice_x 
Bob       //-//x    Alice_x   : 4-5-2 : Bob //-//x Alice_x 
Bob_x     x-//x     Alice_x   : 4-6-0 : Bob_x x-//x Alice_x 
Bob_x     x//-x     Alice_x   : 4-6-1 : Bob_x x//-x Alice_x 
Bob_x     x//-//x   Alice_x   : 4-6-2 : Bob_x x//-//x Alice_x 
Bob_o     o-//x     Alice_x   : 4-7-0 : Bob_o o-//x Alice_x 
Bob_o     o//-x     Alice_x   : 4-7-1 : Bob_o o//-x Alice_x 
Bob_o     o//-//x   Alice_x   : 4-7-2 : Bob_o o//-//x Alice_x 
Bob_x     x-//o     Alice_o   : 4-8-0 : Bob_x x-//o Alice_o 
Bob_x     x//-o     Alice_o   : 4-8-1 : Bob_x x//-o Alice_o 
Bob_x     x//-//o   Alice_o   : 4-8-2 : Bob_x x//-//o Alice_o 
|||

note over Bob_x, Alice_x
Drawn by PlantUML version:
(0.000 - 15 Mo) 12 Mo - PlantUML Version 1.2019.06beta18
(0.010 - 15 Mo) 12 Mo - GraphicsEnvironment.isHeadless() false
(0.010 - 15 Mo) 12 Mo - Found 0 files
No diagram found

end note

@enduml
  • arrowsTest.bat 3
@startuml
participant Bob_x
participant Bob_o
participant Bob
participant Alice
participant Alice_o
participant Alice_x

note over Bob_x, Alice_x
  There are no arrows starting with x in the sequence diagram.
  PlantUML will follow the instructions.
end note

== -\\ ==
Bob       -\        Alice     : 5-0-0 : Bob -\ Alice 
Bob       \-        Alice     : 5-0-1 : Bob \- Alice 
Bob       \-\       Alice     : 5-0-2 : Bob \-\ Alice 
Bob_o     o-\       Alice     : 5-1-0 : Bob_o o-\ Alice 
Bob_o     o\-       Alice     : 5-1-1 : Bob_o o\- Alice 
Bob_o     o\-\      Alice     : 5-1-2 : Bob_o o\-\ Alice 
Bob       -\o       Alice_o   : 5-2-0 : Bob -\o Alice_o 
Bob       \-o       Alice_o   : 5-2-1 : Bob \-o Alice_o 
Bob       \-\o      Alice_o   : 5-2-2 : Bob \-\o Alice_o 
Bob_o     o-\o      Alice_o   : 5-3-0 : Bob_o o-\o Alice_o 
Bob_o     o\-o      Alice_o   : 5-3-1 : Bob_o o\-o Alice_o 
Bob_o     o\-\o     Alice_o   : 5-3-2 : Bob_o o\-\o Alice_o 
Bob_x     x-\       Alice     : 5-4-0 : Bob_x x-\ Alice 
Bob_x     x\-       Alice     : 5-4-1 : Bob_x x\- Alice 
Bob_x     x\-\      Alice     : 5-4-2 : Bob_x x\-\ Alice 
Bob       -\x       Alice_x   : 5-5-0 : Bob -\x Alice_x 
Bob       \-x       Alice_x   : 5-5-1 : Bob \-x Alice_x 
Bob       \-\x      Alice_x   : 5-5-2 : Bob \-\x Alice_x 
Bob_x     x-\x      Alice_x   : 5-6-0 : Bob_x x-\x Alice_x 
Bob_x     x\-x      Alice_x   : 5-6-1 : Bob_x x\-x Alice_x 
Bob_x     x\-\x     Alice_x   : 5-6-2 : Bob_x x\-\x Alice_x 
Bob_o     o-\x      Alice_x   : 5-7-0 : Bob_o o-\x Alice_x 
Bob_o     o\-x      Alice_x   : 5-7-1 : Bob_o o\-x Alice_x 
Bob_o     o\-\x     Alice_x   : 5-7-2 : Bob_o o\-\x Alice_x 
Bob_x     x-\o      Alice_o   : 5-8-0 : Bob_x x-\o Alice_o 
Bob_x     x\-o      Alice_o   : 5-8-1 : Bob_x x\-o Alice_o 
Bob_x     x\-\o     Alice_o   : 5-8-2 : Bob_x x\-\o Alice_o 
|||

== -\\\\ ==
Bob       -\\       Alice     : 6-0-0 : Bob -\\ Alice 
Bob       \\-       Alice     : 6-0-1 : Bob \\- Alice 
Bob       \\-\\     Alice     : 6-0-2 : Bob \\-\\ Alice 
Bob_o     o-\\      Alice     : 6-1-0 : Bob_o o-\\ Alice 
Bob_o     o\\-      Alice     : 6-1-1 : Bob_o o\\- Alice 
Bob_o     o\\-\\    Alice     : 6-1-2 : Bob_o o\\-\\ Alice 
Bob       -\\o      Alice_o   : 6-2-0 : Bob -\\o Alice_o 
Bob       \\-o      Alice_o   : 6-2-1 : Bob \\-o Alice_o 
Bob       \\-\\o    Alice_o   : 6-2-2 : Bob \\-\\o Alice_o 
Bob_o     o-\\o     Alice_o   : 6-3-0 : Bob_o o-\\o Alice_o 
Bob_o     o\\-o     Alice_o   : 6-3-1 : Bob_o o\\-o Alice_o 
Bob_o     o\\-\\o   Alice_o   : 6-3-2 : Bob_o o\\-\\o Alice_o 
Bob_x     x-\\      Alice     : 6-4-0 : Bob_x x-\\ Alice 
Bob_x     x\\-      Alice     : 6-4-1 : Bob_x x\\- Alice 
Bob_x     x\\-\\    Alice     : 6-4-2 : Bob_x x\\-\\ Alice 
Bob       -\\x      Alice_x   : 6-5-0 : Bob -\\x Alice_x 
Bob       \\-x      Alice_x   : 6-5-1 : Bob \\-x Alice_x 
Bob       \\-\\x    Alice_x   : 6-5-2 : Bob \\-\\x Alice_x 
Bob_x     x-\\x     Alice_x   : 6-6-0 : Bob_x x-\\x Alice_x 
Bob_x     x\\-x     Alice_x   : 6-6-1 : Bob_x x\\-x Alice_x 
Bob_x     x\\-\\x   Alice_x   : 6-6-2 : Bob_x x\\-\\x Alice_x 
Bob_o     o-\\x     Alice_x   : 6-7-0 : Bob_o o-\\x Alice_x 
Bob_o     o\\-x     Alice_x   : 6-7-1 : Bob_o o\\-x Alice_x 
Bob_o     o\\-\\x   Alice_x   : 6-7-2 : Bob_o o\\-\\x Alice_x 
Bob_x     x-\\o     Alice_o   : 6-8-0 : Bob_x x-\\o Alice_o 
Bob_x     x\\-o     Alice_o   : 6-8-1 : Bob_x x\\-o Alice_o 
Bob_x     x\\-\\o   Alice_o   : 6-8-2 : Bob_x x\\-\\o Alice_o 
|||

note over Bob_x, Alice_x
Drawn by PlantUML version:
(0.000 - 15 Mo) 12 Mo - PlantUML Version 1.2019.06beta18
(0.010 - 15 Mo) 12 Mo - GraphicsEnvironment.isHeadless() false
(0.010 - 15 Mo) 12 Mo - Found 0 files
No diagram found

end note

@enduml

2019年5月10日金曜日

In a sequence diagram, should I not include the same file repeatedly?

In a sequence diagram, should I not include the same file repeatedly?

Alice has replied four times. But why does Bob hear only twice?

  • Bob.sd.txt
@startuml
Bob -> Alice : Where are you? 1
Alice -> Bob : I'm here!


Bob -> Alice : Where are you? 2
!include Alice.replyToBob.sd.txt


Bob -> Alice : Where are you? 3
!include Alice.replyToBob.sd.txt


Bob -> Alice : Where are you? 4
!include Alice.replyToBob.sd.txt

@enduml

  • Alice.replyToBob.sd.txt
Alice -> Bob : I'm here!

  • Result





  • Answer
!include_many  Alice.replyToBob.sd.txt