ラベル JScript の投稿を表示しています。 すべての投稿を表示
ラベル JScript の投稿を表示しています。 すべての投稿を表示

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
@if(0)==(0) echo off
@rem http://computer-technology.hateblo.jp/entry/20131025/p1
setlocal
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

@rem Description:
@rem Test the message arrow of PlantUML sequence diagram.

@rem Usage:
@rem arrowsTest.bat <arrowGroupNumber>

@rem Options:
@rem   arrowGroupNumber
@rem     1 : "->" group.
@rem     2 : "-/" group.
@rem     3 : "-\" group.

@rem ####################
@rem Batch.
@rem ####################

set "DebugPrint=false"

@rem ....................
@rem Batch main.
@rem ....................
set rv=11
if "!DebugPrint!"=="true" call :L_BAT_Output_Args %*
call :Lc_JS %*

@rem ....................
@rem Exit.
@rem ....................
@rem echo.
@rem pause
@rem echo Press any key to exit.
@rem pause>nul
exit /b !rv!
goto :eof


@rem ....................
@rem Output Args.
@rem ....................
:L_BAT_Output_Args
@rem echo BAT %0 %* ....................
set /a y=0
for %%z in (
  %*
) do (
  set /a y=!y!+1
  echo BAT %%!y!=%%~z.
)
set /a rv=0
goto :eof


@rem ....................
@rem Call JScript.
@rem ....................
:Lc_JS
if "!DebugPrint!"=="true" echo BAT %0 %* ....................j
set "jsargs=%*"
if "!jsargs!"=="" (
  cscript.exe //nologo //e:JScript "%~f0"
) else (
  cscript.exe //nologo //e:JScript "%~f0" !jsargs!
)
if "!DebugPrint!"=="true" call :L_echoErrorLevel
goto :eof


@rem ....................
@rem Echo ErrorLevel.
@rem ....................
:L_echoErrorLevel
@rem echo BAT L_echoErrorLevel ....................
echo BAT %0 errorlevel=!errorlevel!
@rem echo.
goto :eof


@end


// ####################
// JScript.
// ####################


var DebugPrint = false;

var fso = new ActiveXObject("Scripting.FileSystemObject");


// ....................
// Output Args.
// ....................
function Output_Args(jsargs) {
//  WScript.Echo("JS Output_Args ....................");
  WScript.Echo("JS [" + jsargs.length + "]" + jsargs + ".");
  for (var idx = 0; idx < jsargs.length; ++idx) {
    WScript.Echo("JS Args[" + idx + "]=" + jsargs[idx] + ".");
  }
  return 0;
}


// ....................
// Unknown arg.
// ....................
function UnknownArg(jsargs) {
  WScript.Echo("JS UnknownArg ....................");
  Output_Args(jsargs);
  return 1;
}


// ....................
// arrowsTest : Test the message arrow of PlantUML sequence diagram.
// ....................
function arrowsTest(jsargs) {
  if (DebugPrint == true) {
    WScript.Echo("JS arrowsTest ....................");
    Output_Args(jsargs);
  }

  // message arrow shape pattern.
  var arrowGroups = [
    [],
    [ // arrowGroup 1.
      [ // arrowType
        "->",
        "<-",
        "<->",
      ],
      [
        "->>",
        "<<-",
        "<<->>",
      ],
    ],
    [ // arrowGroup 2.
      [
        "-/",
        "/-",
        "/-/",
      ],
      [
        "-//",
        "//-",
        "//-//",
      ],
    ],
    [ // arrowGroup 3.
      [
        "-\\",
        "\\-",
        "\\-\\",
      ],
      [
        "-\\\\",
        "\\\\-",
        "\\\\-\\\\",
      ],
    ],
  ];

  // message arrow symbol pattern.
  var symbols = [
    ["",  "" ],
    ["o", "" ],
    ["",  "o"],
    ["o", "o"],
    ["x", "" ],
    ["",  "x"],
    ["x", "x"],
    ["o", "x"],
    ["x", "o"],
  ];

  // Classes at both ends of the arrow.
  var classes = {
    ""  : ["Bob",   "Alice"  ],
    "o" : ["Bob_o", "Alice_o"],
    "x" : ["Bob_x", "Alice_x"]
  };


//   Start definition of sequence diagram.
  WScript.Echo("@startuml");

  WScript.Echo("participant Bob_x");
  WScript.Echo("participant Bob_o");
  WScript.Echo("participant Bob");
  WScript.Echo("participant Alice");
  WScript.Echo("participant Alice_o");
  WScript.Echo("participant Alice_x");
  WScript.Echo("");

  WScript.Echo("note over Bob_x, Alice_x");
  WScript.Echo("  There are no arrows starting with x in the sequence diagram.");
  WScript.Echo("  PlantUML will follow the instructions.");
  WScript.Echo("end note");
  WScript.Echo("");

//   for (var arrowGroupNumber in arrowGroups) {
  var arrowGroupNumber = jsargs[0];
    for (var arrowTypeIdx in arrowGroups[arrowGroupNumber]) {
      WScript.Echo("== " + arrowGroups[arrowGroupNumber][arrowTypeIdx][0].replace(/\\/g, "\\\\") + " ==");
      for (var symbolIdx in symbols) {
        for (var arrowShapeIdx in arrowGroups[arrowGroupNumber][arrowTypeIdx]) {
          var arrowShape = ""
              + symbols[symbolIdx][0]
              + arrowGroups[arrowGroupNumber][arrowTypeIdx][arrowShapeIdx]
              + symbols[symbolIdx][1]
              ;

          var msgCmd = sprintf("%-9s %-9s %-9s",
              classes[symbols[symbolIdx][0]][0],
              arrowShape,
              classes[symbols[symbolIdx][1]][1]);
          var msgTxt = msgCmd.replace(/ +/g, " ");

          WScript.Echo(sprintf("%s : %d-%d-%d : %s",
              msgCmd,
              (parseInt(arrowGroupNumber) - 1) * 2 + 1 + parseInt(arrowTypeIdx),
              symbolIdx, arrowShapeIdx, msgTxt));
        }
      }
//     }
        WScript.Echo("|||");
        WScript.Echo("");
  }

  WScript.Echo("note over Bob_x, Alice_x");
  WScript.Echo("Drawn by PlantUML version:");
  WScript.Echo(getPlantUmlVersion());
  WScript.Echo("end note");
  WScript.Echo("");

//   Finish defining the sequence diagram.
  WScript.Echo("@enduml");

  return 0;
}


// 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
function getPlantUmlVersion() {
  var shell = new ActiveXObject("WScript.Shell");
  // コマンドを実行
  var oe = shell.Exec("java -jar plantuml.jar -v");
  var r = oe.StdErr.ReadAll();
  return r;
}


// https://qiita.com/akinomyoga/items/ccd58731743aa37e0538
// agh.sprintf.js
/* ----------------------------------------------------------------------------

 Author: K. Murase (akinomyoga)

 Changes

 * 2015-05-29 KM created git repository
 * 2014-12-25 KM 様々な言語での実装を確認
 * 2013-09-05 KM added descriptions
 * 2013-09-01 KM first version
 * 2013-09-01 KM created

 ------------------------------------------------------------------------------

 License: The MIT License (MIT)

 Copyright (c) 2013-2015 K. Murase (akinomyoga)

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.

 ----------------------------------------------------------------------------*/

/**
 *  @section sprintf.format 書式指定
 *    書式は以下の形式で指定する。
 *    '%' \<pos\>? \<flag\> \<width\> \<precision\>? \<type\>? \<conv\>
 *
 *    位置指定子   \<pos\>       は引数の番号を指定する。
 *    フラグ       \<flag\>      は出力の見た目を細かく指定する。
 *    幅           \<width\>     は出力時の最小文字数を指定する。
 *    精度         \<precision\> は内容をどれだけ詳しく出力するかを指定する。
 *    サイズ指定子 \<type\>      は引数のサイズ・型を指定する。
 *    変換指定子   \<conv\>      は出力する形式を指定する。
 *
 *  @subsection sprintf.format.pos 位置指定子 (POSIX)
 *    位置指定子は以下の形式を持つ。
 *    \<pos\> := /\d+\$/
 *    整数で引数の番号を指定する。書式指定文字列の次に指定した引数の番号が 1 である。
 *
 *  @subsection sprintf.format.flag フラグ
 *    フラグは以下の形式を持つ。
 *    \<flag\> := ( /[-+ 0#']/ | /\=./ ) +
 *
 *    '-'  (標準)    左寄せを意味する。既定では右寄せである。
 *    '+'  (標準)    非負の数値に正号を付ける事を意味する。
 *    '#'  (標準)    整数の場合、リテラルの基数を示す接頭辞を付ける。
 *                   但し、値が 0 の時は接頭辞を付けない。
 *                   conv = o, x, X のそれぞれに対して "0", "0x", "0X" が接頭辞となる。
 *
 *                   浮動小数点数 conv = f, F, e, E, g, G, a, A の場合は、
 *                   整数 (precision = 0) に対しても小数点を付ける (例 "123.") 事を意味する。
 *                   conv = g, G については小数末尾の 0 の連続を省略せずに全て出力する。
 *    ' '  (標準)    非負の数値の前に空白を付ける事を意味する。
 *                   これは出力幅が width で指定した幅を超えても必ず出力される空白である。
 *    '0'  (標準)    左側の余白を埋めるのに 0 を用いる。但し、空白と異なり 0 は符号や基数接頭辞の右側に追加される。
 *    "'"  (SUSv2)   conv = d, i, f, F, g, G の整数部で桁区切 (3桁毎の ",") を出力する事を意味する。
 *                   但し、flag 0 で指定される zero padding の部分には区切は入れない。
 *
 *    参考: 野良仕様で以下の様なものもあるが、ここでは実装しない。
 *    '=?' (strfmon) 余白に使う文字の指定
 *    ','  (Python)  桁区切。→ "'" (SUSv2) に同じ
 *                   (+ Java, Python-3.1)
 *    '<'  (Python)  左寄せ。'?<' として余白文字を指定できる。
 *                   → '-' (標準) に同じ
 *    '>'  (Python)  右寄せ。'?>' として余白文字を指定できる。
 *                   → 既定 (標準)
 *    '^'  (Python)  中央揃え。'?^' として余白文字を指定できる。
 *    '='  (Python)  整数型において、符号の後に padding を挿入する
 *                   →これは %.3d 等とする事に等価である。
 *    '-'  (Python)  負号のみ表示 → 既定 (標準)
 *    "'?" (PHP)     余白文字の指定。
 *    '('  (Java)    負の数を "()" で括る。
 *
 *  @subsection sprintf.format.width 幅指定子
 *    幅指定子は以下の形式を持つ。
 *    \<width\> := /\d+/ | '*' | '*' /\d+/ '$'
 *
 *    /\d+/         (標準)  最小幅を整数で指定する。
 *    '*'           (標準)  次の引数を読み取って最小幅とする。
 *    '*' /\d+/ '$' (POSIX) 指定した番号の引数を最小幅とする。
 *
 *  @subsection sprintf.format.precision 精度指定子
 *    精度指定子は以下の形式を持つ。
 *    \<precision\> := /\d+/ | '*' | '*' /\d+/ '$'
 *
 *    /\d+/         (標準)  精度を整数で指定する。
 *    '*'           (標準)  次の引数を読み取って精度とする。
 *    '*' /\d+/ '$' (POSIX) 指定した番号の引数を精度とする。
 *
 *    整数の場合は精度で指定した桁だけ必ず整数を出力する。例えば、精度 4 の場合は "0001" など。
 *    精度を指定した時はフラグで指定した '0' は無視される。
 *
 *    浮動小数点数 conv = f, F, e, E, a, A の場合は小数点以下の桁数を指定する。
 *    浮動小数点数 conv = g, G の場合は有効桁数を指定する。
 *    conv = f, F, e, E, g, G に対しては既定値は 6 である。
 *    conv = a, A については倍精度浮動小数点数の16進桁数である 13 が既定値である。
 *
 *    文字列の場合は最大出力文字数を指定する。この文字数に収まらない部分は出力されずに無視される。
 *
 *  @subsection sprintf.format.type サイズ指定子
 *    サイズ指定子は以下の何れかである。
 *
 *          + --------- 整数 ---------- + ------- 浮動小数点数 ------- + -------- 文字 ---------- +
 *          | 本来      (規格)  実装 註 | 本来        (規格)   実装 註 | 本来    (規格)   実装 註 |
 *    ----- + ------------------------- + ---------------------------- + ------------------------ +
 *    既定  | int       (標準) double#1 | 既定        (標準) double    | 既定    (標準) unicode   |
 *    'hh'  | char      (C99)    8bit   | float       (agh)   float#4  | char    (agh)    ascii   |
 *    'h'   | short     (標準)  16bit   | float       (agh)   float#4  | char    (MSVC)   ascii   |
 *    'l'   | long      (標準)  32bit   | double      (C99)  double    | wint_t  (C99)  unicode#6 |
 *    'll'  | long long (C99)   32bit   | long double (agh)  double#5  | --      --          --   |
 *    't'   | ptrdiff_t (C99)   32bit#2 | --          --         --    | --      --          --   |
 *    'z'   | size_t    (C99)   32bit#2 | --          --         --    | --      --          --   |
 *    'I'   | ptrdiff_t (MSVC)  32bit#2 | --          --         --    | --      --          --   |
 *          | size_t                    | --          --         --    | --      --          --   |
 *    'I32' | 32bit     (MSVC)  32bit   | --          --         --    | --      --          --   |
 *    'q'   | 64bit     (BSD)   64bit#3 | --          --         --    | --      --          --   |
 *    'I64' | 64bit     (MSVC)  64bit#3 | --          --         --    | --      --          --   |
 *    'j'   | intmax_t  (C99)  double#1 | --          --         --    | --      --          --   |
 *    'L'   | --        --         --   | long double (標準) double#5  | --      --          --   |
 *    'w'   | --        --         --   | long double (agh)  double#5  | wchar_t (MSVC) unicode   |
 *    ----- + ------------------------- + ---------------------------- + ------------------------ +
 *
 *    #1 JavaScript の数値は内部的には double なので、
 *       サイズ指定子を省略した場合はこの double で表現される整数として変換を行う。
 *    #2 JavaScript で 64bit 整数は厳密に取り扱う事が出来ないので、32bit を native な整数とする。
 *    #3 JavaScript では 64bit 整数は厳密に取り扱う事が出来ない。
 *       取り敢えず 64bit 整数として出力はするものの、巨大な整数では下の方の桁が正確ではない。
 *
 *    #4 規格にないが独自拡張で、h/hh が指定された時は float の精度に落としてから出力する。
 *       (C 言語では float の可変長引数は double に変換されるからそもそも float で指定できない)。
 *    #5 規格上は long double だが JavaScript では long double は取り扱えないので、
 *       double と同じ取扱とする。
 *
 *    #6 POSIX を見ると %lc の引数は wchar_t[2] { wint_t(), null } と書かれている気がする? [要確認]
 *
 *    参考: 以下の様な野良サイズ指定子もある。
 *    'n'  (Ocaml)    native int
 *
 *  @subsection sprintf.format.conv 変換指定子
 *    引数の型及び出力の形式を指定する。以下の何れかの値を取る。
 *
 *    'd', 'i' (標準) 10進符号付き整数
 *    'o'      (標準)  8進符号無し整数
 *    'u'      (標準) 10進符号無し整数
 *    'x', 'X' (標準) 16進符号無し整数     (lower/upper case, 0xa/0XA など)
 *    'f', 'F' (標準) 浮動小数点数         (lower/upper case, inf/INF など)
 *    'e', 'E' (標準) 浮動小数点数指数表記 (lower/upper case, 1e+5/1E+5 など)
 *    'g', 'G' (標準) 浮動小数点数短い表記 (lower/upper case, 1e+5/1E+5 など)
 *    'a', 'A' (C99)  浮動小数点数16進表現 (lower/upper case, 1p+5/1P+5 など)
 *    'c'      (標準) 文字
 *         'C' (XSI)  文字   (本来 wchar_t 用だがこの実装では c と区別しない)
 *    's'      (標準) 文字列
 *         'S' (XSI)  文字列 (本来 wchar_t 用だがこの実装では s と区別しない)
 *    'p'      (標準) ポインタ値。この実装では upper hexadecimal number で出力。
 *    'n'      (標準) 今迄の出力文字数を value[0] に格納
 *    '%'      (標準) "%" を出力
 *
 *    参考: 野良仕様で以下の様なものもあるが、ここでは実装しない。
 *    'b'      (Ruby)   2進符号付き整数。(+ Python, Perl, PHP, D, Haskell)
 *                      (Go) では浮動小数点数に対して decimalless scientific notation with 2進指数
 *    'B'      (Ruby)   2進符号付き整数。(+ Python, Perl)
 *    'n'      (Python) 数値。ロカールに従った出力を行う(桁区切など)。
 *    '%'      (Python) 百分率。数値を百倍して解釈し 'f' 変換指定子で出力する。
 *    'D'      (Perl)   'ld' に同じ。
 *    'U'      (Perl)   'lu' に同じ。
 *    'O'      (Perl)   'lo' に同じ。
 *    'U'      (Go)     'U+%04d' に同じ。Unicode code point の為。
 *    't'      (Go)     true/false
 *    'b', 'B' (Java)   true/false (+ OCaml)
 *    'h', 'H' (Java)   null/'%x'
 *
 *    'q'      (Bash)   文字/文字列をリテラル (quoted string) として出力。 (+ Go Lua)
 *                      Go では文字(整数)は '' で、文字列は "" で囲む。Lua では '' で囲む。
 *    'C'      (OCaml)  文字リテラル '' として出力
 *    'S'      (OCaml)  文字列リテラル "" として出力
 *    'T'      (Go)     typename
 *    'v'      (Go)     default format (+ Haskell)
 *    'p'      (Ruby)   Object#inspect の結果を載せる。
 *
 *    'n'      (Java)   改行
 *    'a', 't' (OCaml)  ? (二つ引数を取って、引数2を引数1に対し出力?)
 *    ','      (OCaml)  何も出力しない
 *    '@'      (OCaml)  '@' を出力。
 *    '!'      (OCaml)  出力先を flush する。
 *
 *  @subsection sprintf.format.ref References
 *    Wikipedia en    <a href="https://en.wikipedia.org/wiki/Printf_format_string">printf format string - Wikipedia</a>
 *    POSIX printf(1) <a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html">printf</a>
 *    POSIX printf(1) <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap05.html#tag_05">File Format Notation</a>
 *    POSIX printf(3) <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html">fprintf</a>
 *    MSC   位置指定子 <a href="http://msdn.microsoft.com/ja-jp/library/bt7tawza(v=vs.90).aspx">printf_p の位置指定パラメータ</a>
 *    MSC   サイズ指定子 <a href="http://msdn.microsoft.com/ja-jp/library/vstudio/tcxf1dw6.aspx">サイズ指定</a>
 *
 *    Python   [[6.1. string ? 一般的な文字列操作 ? Python 3.4.2 ドキュメント>http://docs.python.jp/3/library/string.html#format-specification-mini-language]]
 *    PHP      [[PHP: sprintf - Manual>http://php.net/manual/ja/function.sprintf.php]]
 *    Perl     [[sprintf - perldoc.perl.org>http://perldoc.perl.org/functions/sprintf.html]]
 *    D言語    [[std.format - D Programming Language - Digital Mars>http://dlang.org/phobos/std_format.html#format-string]]
 *    Lua      [[Lua 5.1 Reference Manual>http://www.lua.org/manual/5.1/manual.html#pdf-string.format]]
 *    Haskell  [[Text.Printf>http://hackage.haskell.org/package/base-4.7.0.2/docs/Text-Printf.html]]
 *    Go       [[fmt - The Go Programming Language>http://golang.org/pkg/fmt/]]
 *    Java     [[Formatter (Java Platform SE 7 )>http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax]]
 *    R (wrapper for C printf) [[sprintf {base} | inside-R | A Community Site for R>http://www.inside-r.org/r-doc/base/sprintf]]
 *    OCaml    [[Printf>http://caml.inria.fr/pub/docs/manual-ocaml/libref/Printf.html]]
 */

/*
 * その他の書式指定の文法について
 * - terminfo の setaf 等で使われている文法について
 *   %? %t %e %; 条件分岐
 *   %| %! %- %< 演算子
 *   %{ ... } リテラル
 * - date コマンド
 * - strfmod
 * - zsh PS1
 * - GNU screen
 */

// 実装:
// * 解析は正規表現を使えば良い。
// * 出力結果の構成
//   <左余白> <符号> <ゼロ> <中身> <右余白>
//   計算の順番としては、<符号>+<中身> のペアを決定してから、<ゼロ> または <余白> を付加すれば良い。

(function(__exports) {
  // 本来 this にグローバルオブジェクトが入るはず。
  // もし空だった場合はこのスクリプトを呼び出したときの this を入れる。
  var __global = this || __exports || {};
  if (typeof __global.agh !== 'undefined')
    __exports = __global.agh;
  else if (typeof __global.module !== 'undefined' && typeof __global.module.exports != 'undefined')
    __exports = __global.module.exports;
  else if (__exports == null)
    __exports = __global.agh = {};

  function repeatString(s, len) {
    if (len <= 0) return "";
    var ret = "";
    do if (len & 1) ret += s; while ((len >>= 1) >= 1 && (s += s));
    return ret;
  }

  //---------------------------------------------------------------------------
  // サイズ指定子達

  var INT32_MOD = 0x100000000;
  var INT32_MIN = -0x80000000;
  var INT32_MAX = +0x7FFFFFFF;
  var INT64_MOD = INT32_MOD * INT32_MOD;
  var INT64_MIN = -INT64_MOD / 2.0;
  var INT64_MAX = -INT64_MIN - 1;

  function roundTowardZero(value) {
    return value < 0 ? Math.ceil(value) : Math.floor(value);
  }

  function getIntegerValue(value, type) {
    // 整数は内部的には double で表現されている。
    // ビット演算は 32bit 符号付整数として実行される。
    value = roundTowardZero(value);
    switch (type) {
    case 'hh': // C99 char (8bit signed)
      value &= 0xFF;
      return value >= 0x80 ? value - 0x100 : value;
    case 'h': // short (16bit signed)
      value &= 0xFFFF;
      return value >= 0x8000 ? value - 0x10000 : value;
    case 'l':   // C89  long (32bit signed) (ビット演算を使うと変になる)
    case 'z':   // C99  size_t
    case 't':   // C99  ptrdiff_t
    case 'I32': // MSVC __int32
    case 'I':   // MSVC ptrdiff_t/size_t
      value %= INT32_MOD;
      if (value < INT32_MIN)
        value += INT32_MOD;
      else if (value > INT32_MAX)
        value -= INT32_MOD;
      return value;
    case 'll':  // C99 long long (64bit signed)
    case 'I64': // MSVC __int32
    case 'q':   // BSD  quad word
    case 'L':   // agh exntesion
      value %= INT64_MOD;
      if (value < INT64_MIN)
        value += INT64_MOD;
      else if (value > INT64_MAX)
        value -= INT64_MOD;
      return value;
    case 'j': default: // 変換無し (double の整数)
      return value;
    }
  }

  function getUnsignedValue(value, type) {
    // 整数は内部的には double で表現されている。
    // ビット演算は 32bit 符号付整数として実行される。
    value = roundTowardZero(value);
    switch (type) {
    case 'hh': // 8bit unsigned
      value &= 0xFF;
      return value;
    case 'h': // 16bit unsigned
      value &= 0xFFFF;
      return value;
    case 'l':   // C89  long (32bit unsigned) (ビット演算を使うと変になる)
    case 'z':   // C99  size_t
    case 't':   // C99  ptrdiff_t
    case 'I32': // MSVC __int32
    case 'I':   // MSVC ptrdiff_t/size_t
      value %= INT32_MOD;
      return value < 0 ? value + INT32_MOD : value;
    case 'll':  // C99 long long (64bit unsigned)
    case 'I64': // MSVC __int32
    case 'q':   // BSD  quad word
    case 'L':   // agh exntesion
      value %= INT64_MOD;
      return value < 0 ? value + INT64_MOD : value;
    case 'j': default: // double の整数の 2 の補数??
      if (value < 0) {
        // 例 -0x80 ~ -0x41 → 7 ~ 6+epsilon → nbits = 8, mod = 0x100
        var nbits = value < INT32_MIN ? 1 + Math.ceil(Math.LOG2E * Math.log(-value)) : 32;
        var mod = Math.pow(2, nbits);
        value += mod;
      }
      return value;
    }
  }

  function getFloatValue(value, type) {
    if (type === 'h' || type === 'hh') {
      var sgn = value < 0 ? -1 : 1;
      var exp = Math.floor(Math.LOG2E * Math.log(sgn * value));
      var scale = Math.pow(2, exp - 23); // float (exp = 0) は小数点以下2進23桁まで有効
      value = (0 | value / scale) * scale;
    }

    return value;
  }

  function getCharValue(value, type) {
    value |= 0;
    if (type === 'h' || type === 'hh') {
      value &= 0xFF;
    }
    return value;
  }

  //---------------------------------------------------------------------------
  // 変換指定子達

  /**
   * @section \<conv\>
   *   引数の型及び出力の形式を指定します。
   * - 'd', 'i' 10進符号付き整数
   * - 'o'       8進符号無し整数
   * - 'u'      10進符号無し整数
   * - 'x', 'X' 16進符号無し整数
   */

  var groupIntegerRegs = [
    /(...)(?!$)/g,
    /(^.|...)(?!$)/g,
    /(^..|...)(?!$)/g
  ];
  function groupInteger(text, flag) {
    if (text.length < 4 || !/\'/.test(flag))
      return text;
    else
      return text.replace(groupIntegerRegs[text.length % 3], "$1,");
  }

  var xdigits = "0123456789abcdef";
  function convertInteger(value, flag, precision, base) {
    var out = '';
    do {
      out = xdigits.charAt(value % base) + out;
      value = Math.floor(value / base);
    } while (value > 0);

    if (precision != null)
      out = repeatString('0', precision - out.length) + out;

    return out;
  }
  function convertDecimal(value, flag, precision, type) {
    return groupInteger(convertInteger(value, flag, precision, 10), flag);
  }
  function convertOctal(value, flag, precision, type) {
    return convertInteger(value, flag, precision, 8);
  }
  function convertLowerHex(value, flag, precision, type) {
    return convertInteger(value, flag, precision, 16);
  }
  function convertUpperHex(value, flag, precision, type) {
    return convertInteger(value, flag, precision, 16).toUpperCase();
  }

  /**
   * - 'f', 'F' 浮動小数点数         (lower/upper case, inf/INF など)
   * - 'e', 'E' 浮動小数点数指数表記 (lower/upper case, 1e+5/1E+5 など)
   * - 'g', 'G' 浮動小数点数短い表記 (lower/upper case, 1e+5/1E+5 など)
   * - 'a', 'A' 浮動小数点数16進表現 (lower/upper case, 1p+5/1P+5 など)
   */

  var logTable = [];
  logTable[ 2] = Math.LOG2E;
  logTable[10] = Math.LOG10E;
  logTable[16] = Math.LOG2E / 4;
  function frexp(value, base) {
    if (value === 0) return [0, 0];

    var exp = 1 + Math.floor(logTable[base] * Math.log(value));
    value = value * Math.pow(base, -exp);

    // 際どいずれが起きるので補正
    if (value * base < 1) {
      value *= base;
      exp--;
    } else if (value >= 1) {
      value /= base;
      exp++;
    }

    return [value, exp];
  }

  var regCarryReach = []; // 末尾の 9 の並び, 繰上到達距離測定用
  regCarryReach[10] = /9*$/;
  regCarryReach[16] = /f*$/;
  function generateFloatingSequence(value, precision, base) {
    // value [0, 1) の数値
    var seq = '';
    while (--precision > 0)
      seq += xdigits.charAt(0 | (value = value * base % base));

    // 最後の数字は四捨五入
    // (0-10 の整数になるので繰り上がり処理が必要)
    var last = Math.round(value * base % base);
    if (last == base) {
      var cd = regCarryReach[base].exec(seq)[0].length;
      if (cd < seq.length) {
        // 繰り上がり
        var iinc = seq.length - cd - 1;
        seq = seq.slice(0, iinc) + xdigits.charAt(1 + (0 | seq.charAt(iinc))) + repeatString('0', cd + 1);
      } else {
        // 全て 9 の時 → exp更新, seq = 1000...
        seq = '1' + repeatString('0', cd + 1);
      }
    } else {
      seq += xdigits.charAt(last);
    }
    return seq;
  }

  function omitTrailingZero(text, flag) {
    return text.replace(/(\.[\da-f]*?)0+$/, function($0, $1) {
      if ($1 && $1.length > 1)
        return $1;
      else
        return /#/.test(flag) ? '.' : '';
    });
  }
  function omitTrailingZeroE(text, flag) {
    return text.replace(/(\.\d*?)0+e/, function($0, $1) {
      if ($1 && $1.length > 1)
        return $1 + 'e';
      else
        return /#/.test(flag) ? '.e' : 'e';
    });
  }

  function convertScientific(value, flag, precision, type) { // conv = e E
    if (isNaN(value))
      return 'nan';
    else if (!isFinite(value))
      return 'inf';

    if (precision == null) precision = 6;

    var buff = frexp(value, 10);
    var fr = buff[0], exp = buff[1] - 1;
    var man = generateFloatingSequence(fr, 1 + precision, 10);
    if (man.length > precision + 1) {
      // 99..99 から 100..00 に繰り上がった時
      man = man.slice(0, -1);
      exp++;
    }

    if (precision > 0 || /#/.test(flag))
      man = man.slice(0, 1) + '.' + man.slice(1);

    if (exp < 0)
      exp = 'e-' + (1000 - exp).toString().slice(1);
    else
      exp = 'e+' + (1000 + exp).toString().slice(1);
    return man + exp;
  }
  function convertScientificHex(value, flag, precision, type) { // conv = a A
    if (isNaN(value))
      return 'nan';
    else if (!isFinite(value))
      return 'inf';

    if (precision == null)
      precision = type === 'h' || type === 'hh' ? 6 : 13;

    var buff = frexp(value, 2);
    var fr = buff[0], exp = buff[1] - 1;
    var man = generateFloatingSequence((1 / 8) * fr, precision + 1, 16);
    if (man.length > precision + 1) {
      man = man.slice(0, -1);
      exp++;
    }

    if (man.length > 1 || /#/.test(flag))
      man = man.slice(0, 1) + '.' + man.slice(1);

    man = omitTrailingZero(man, flag);

    if (exp < 0)
      exp = 'p-' + (1000 - exp).toString().slice(1);
    else
      exp = 'p+' + (1000 + exp).toString().slice(1);
    return man + exp;
  }
  function convertFloating(value, flag, precision, type) { // conv = f F
    if (isNaN(value))
      return 'nan';
    else if (!isFinite(value))
      return 'inf';

    if (precision == null) precision = 6;

    if (value >= 1.0) {
      var buff = frexp(value, 10);
      var fr = buff[0], exp = buff[1];
    } else {
      var fr = value / 10, exp = 1;
    }

    var man = generateFloatingSequence(fr, exp + precision, 10);
    if (precision > 0 || /#/.test(flag)) {
      var point = man.length - precision;
      man = groupInteger(man.slice(0, point), flag) + '.' + man.slice(point);
    } else
      man = groupInteger(man, flag);

    return man;
  }
  function convertCompact(value, flag, precision, type) { // conv = g G
    if (isNaN(value))
      return 'nan';
    else if (!isFinite(value))
      return 'inf';

    if (precision == null)
      precision = 6;
    else if (precision < 1)
      precision = 1;

    if (value < 1e-4 || Math.pow(10, precision) <= value + 0.5) {
      // scientific
      var result = convertScientific(value, flag, precision - 1, type);
      if (/#/.test(flag))
        return result;
      else
        return omitTrailingZeroE(result, flag);
    } else {
      // floating point
      var buff = frexp(value, 10);
      var fr = buff[0], exp = buff[1];

      if (precision < 1) precision = 1;
      var man = generateFloatingSequence(fr, precision, 10);
      var point = man.length - (precision - exp); // 小数点挿入位置。末端からの位置が繰り上がり不変。
      // assert(exp <= precision);
      // assert(man.length == precision || man.length == precision + 1)
      // assert(point <= man.length);
      if (point > 0) {
        if (point < man.length || /#/.test(flag))
          man = groupInteger(man.slice(0, point), flag) + '.' + man.slice(point, precision);
      } else {
        man = '0.' + repeatString('0', -point) + man.slice(0, precision);
      }

      if (/#/.test(flag))
        return man;
      else
        return omitTrailingZero(man, flag);
    }
  }

  function convertCompactU      (value, flag, precision, type) { return convertCompact      (value, flag, precision, type).toUpperCase(); }
  function convertFloatingU     (value, flag, precision, type) { return convertFloating     (value, flag, precision, type).toUpperCase(); }
  function convertScientificU   (value, flag, precision, type) { return convertScientific   (value, flag, precision, type).toUpperCase(); }
  function convertScientificHexU(value, flag, precision, type) { return convertScientificHex(value, flag, precision, type).toUpperCase(); }

  /**
   * - 'c', 'C' 文字
   * - 's', 'S' 文字列
   * - 'n' 今迄の出力文字数を value[0] に格納
   * - '%' % を出力
   */

  function convertChar(value, flag, precision, type) {
    return String.fromCharCode(value);
  }
  function convertString(value, flag, precision, type) {
    if (value == null)
      value = value === undefined ? '(undefined)' : '(null)';
    else
      value = value.toString();

    if (precision != null)
      value = value.slice(0, precision);

    return value;
  }
  function convertOutputLength(value, flag, precision, type, outputLength) { // conv = n
    value[0] = getIntegerValue(outputLength, type);
    return '';
  }
  function convertEscaped(value, flag, precision, type) { return '%'; }

  //---------------------------------------------------------------------------

  function prefixOctal(flag)      { return /#/.test(flag) ? '0'  : ''; }
  function prefixLHex(flag)       { return /#/.test(flag) ? '0x' : ''; }
  function prefixUHex(flag)       { return /#/.test(flag) ? '0X' : ''; }
  function prefixFloatLHex(flag)  { return '0x'; }
  function prefixFloatUHex(flag)  { return '0X'; }
  function prefixPointerHex(flag) { return '0x'; }

  var conversions = {
    d: {getv: getIntegerValue , integral: true , signed: true , prefix: null            , conv: convertDecimal       },
    i: {getv: getIntegerValue , integral: true , signed: true , prefix: null            , conv: convertDecimal       },
    u: {getv: getUnsignedValue, integral: true , signed: false, prefix: null            , conv: convertDecimal       },
    o: {getv: getUnsignedValue, integral: true , signed: false, prefix: prefixOctal     , conv: convertOctal         },
    x: {getv: getUnsignedValue, integral: true , signed: false, prefix: prefixLHex      , conv: convertLowerHex      },
    X: {getv: getUnsignedValue, integral: true , signed: false, prefix: prefixUHex      , conv: convertUpperHex      },
    e: {getv: getFloatValue   , integral: false, signed: true , prefix: null            , conv: convertScientific    },
    E: {getv: getFloatValue   , integral: false, signed: true , prefix: null            , conv: convertScientificU   },
    f: {getv: getFloatValue   , integral: false, signed: true , prefix: null            , conv: convertFloating      },
    F: {getv: getFloatValue   , integral: false, signed: true , prefix: null            , conv: convertFloatingU     },
    g: {getv: getFloatValue   , integral: false, signed: true , prefix: null            , conv: convertCompact       },
    G: {getv: getFloatValue   , integral: false, signed: true , prefix: null            , conv: convertCompactU      },
    a: {getv: getFloatValue   , integral: false, signed: true , prefix: prefixFloatLHex , conv: convertScientificHex },
    A: {getv: getFloatValue   , integral: false, signed: true , prefix: prefixFloatUHex , conv: convertScientificHexU},
    c: {getv: getCharValue    , integral: false, signed: false, prefix: null            , conv: convertChar          },
    C: {getv: getCharValue    , integral: false, signed: false, prefix: null            , conv: convertChar          },
    s: {getv: null            , integral: false, signed: false, prefix: null            , conv: convertString        },
    S: {getv: null            , integral: false, signed: false, prefix: null            , conv: convertString        },
    p: {getv: getUnsignedValue, integral: false, signed: false, prefix: prefixPointerHex, conv: convertUpperHex      },
    n: {getv: null            , integral: false, signed: false, prefix: null            , conv: convertOutputLength  },
    '%': {noValue: true       , integral: false, signed: false, prefix: null            , conv: convertEscaped       }
  };

  function printf_impl(fmt) {
    // ※arguments の fmt を除いた部分の番号は 1 から始まり、
    //   位置指定子も 1 から始まるので、位置番号はそのまま arguments の添字に指定して良い。

    var args = arguments;
    var aindex = 1;
    var lastIndex = 0;
    var outputLength = 0;
    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) {
      outputLength += index - lastIndex;
      lastIndex = index + $0.length;

      if ((conv = conversions[conv]) == null) {
        var ret = '(sprintf:error:' + $0 + ')';
        outputLength += ret.length;
        return ret;
      }

      pos =
        (pos == null || pos === "") ? null :
        pos === '*' ? 0 | args[aindex++] :
        0 | pos;

      width =
        (width == null || width === "") ? 0 :
        width === '*' ? 0 | args[aindex++]:
        width.charAt(0) === '*' ? args[0 | width.slice(1, -1)] :
        0 | width;

      precision =
        (precision == null || precision === "") ? null:
        precision === '.*' ? 0 | args[aindex++]:
        precision.charAt(1) === '*' ? args[0 | precision.slice(2, -1)] :
        0 | precision.slice(1);

      var value = conv.noValue ? null: pos === null ? args[aindex++] : args[pos];
      if (conv.getv) value = conv.getv(value, type);

      var prefix = '';
      if (conv.signed) {
        if (value < 0) {
          prefix = '-';
          value = -value;
        } else if (/\+/.test(flag))
          prefix = '+';
        else if (/ /.test(flag))
          prefix = ' ';
      }
      if (conv.prefix && value != 0)
        prefix += conv.prefix(flag);

      var body = conv.conv(value, flag, precision, type, outputLength);

      var lpad = '', zero = '', rpad = '';
      width -= prefix.length + body.length;
      if (width >= 1) {
        if (/-/.test(flag)) {
          // POSIX に従うと - の方が優先
          rpad = repeatString(' ', width);
        } else if (/0/.test(flag) && (!conv.integral || precision == null)) {
          zero = repeatString('0', width);
        } else
          lpad = repeatString(' ', width);
      }

      var ret = lpad + prefix + zero + body + rpad;
      outputLength += ret.length;
      return ret;
    });
    outputLength += fmt.length - lastIndex;

    return [outputLength, output];
  }

  __exports.sprintf = function sprintf() {
    var result = printf_impl.apply(this, arguments);
    return result[1];
  };

  __exports.vsprintf = function vsprintf(fmt, args) {
    var result = printf_impl.apply(this, [fmt].concat(args));
    return result[1];
  };

  var stdout = null;
  if (__global.agh && __global.printh)
    stdout = function(text) { printh(agh.Text.Escape(text, 'html')); };
  else if (__global.process && __global.process.stdout)
    stdout = function(text) { process.stdout.write(text); };
  else if (__global.console && __global.console.log)
    stdout = function(text) { console.log(text); };
  else
    stdout = function(text) { document.write(text); };

  __exports.printf = function printf() {
    var result = printf_impl.apply(this, arguments);
    stdout(result[1]);
    return result[0];
  };

  if (__global.agh && __global.agh.scripts)
    __global.agh.scripts.register("agh.sprintf.js");

})(this);

// test
//
// printf("%2$d行目のコマンド %1$sは不正です", "hoge", 20);
// printf("%d(1234) %o(2322) %x(4d2)\n", 1234, 1234, 1234);
// printf("%s(abc) %c(x)\n", "abc", 'x'.charCodeAt(0));
// printf("%*d(   10)", 5, 10);
// printf("%.*s(3)", 3, "abcdef");
// printf("%2d( 3) %02d(03)", 3, 3);
// printf("%1$d:%2$.*3$d:%4$.*3$d(15:035:045)\n", 15, 35, 3, 45);
//
// printf("%%d: [%+10d][%+ 10d][% +10d][%d]", 10, 10, 10, 1e10);
// printf("%%u: [%u][%u][%+u][% u][%-u][%+10u][%-10u]", -1, 10, 10, 10, 10, 10, 10);
// printf("%%x,%%u: %x %o", -1, -1);
// 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);
// printf("%%A: %A %.3A %#.3A", 1e10, 1e10, 1e10);
// printf("%%A: %A %A %A %A", 4096, 2048, 1024, 512);
//
// printf("%%e: %#.3e %#.3e %#.3e", 1e1000, 1e100, 1e10);
// printf("%%e: %#.3e %#.6e %#.10e %#.20e\n", 1.234, 1.234, 1.234, 1.234);
// printf("%%e: %#.1e %#.5e %#.10e %#.100e", 9.999, 9.999, 9.999, 9.999);
// printf("%%f: %f %#g %#f %#.g %f %'f", 1, 1, 1, 1, 1e100, 1e100);
// printf("%%g: %.15g %.15g %#.15g", 1, 1.2, 1.2);
// printf("%%g: %g %.g %#g %#.g", 15, 15, 15, 15);
// printf("%%g: %g %g %g %g %g", 1e-1, 1e-3, 1e-4, 1e-5, 9e-5, 9e-4, 1e10);
// printf("%%#g: %#g %#g %#g %#2g %#6g", 0.1, 1e-5, 1e-4, 1e-4, 1e-4);
// printf("%%#.g: %#.2g %#.2g", 1e-4, 1e-5);
// 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)
//
// printf("%%c: [%c][%c][%c]\n", 1e100, 65, 8);
// printf("%05s %05s\n", 123, "aaa");
// printf("%%p: %p", 512);
// printf("pi: [%1$a][%1$g][%1$'20.9g][%1$020.9g][%1$'020.9g][%2$'020.9g]", Math.PI, Math.PI * 1e3);


// --------------------
// JScript main.
// --------------------
var rv = 0;
var jsargs = new Array();
for (var idx = 0; idx < WScript.Arguments.length; ++idx) {
  jsargs[idx] = WScript.Arguments(idx);
}
var ary = new Array();
ary = jsargs.slice(0, jsargs.length);
if (0 == 1) {
  rv = rv + 1;
} else if (WScript.Arguments.length == 1) {
  rv = rv + arrowsTest(ary);
} else {
  rv = rv + UnknownArg(ary);
}

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

2016年5月24日火曜日

touch.js.bat

@if(0)==(0) echo off
@rem http://computer-technology.hateblo.jp/entry/20131025/p1
setlocal
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
@rem setlocal DISABLEDELAYEDEXPANSION

@rem 指定された日時をファイルの更新日時として設定します。
@rem touch.js.bat "YYYY/MM/DD hh:mm:ss" filepath

cscript.exe //nologo //e:JScript "%~f0" %*

@rem echo.
@rem pause
@rem echo 終了するには何かキーを押してください . . .
@rem pause>nul
@rem exit /b !errorlevel!
goto :eof


@end


// http://d.hatena.ne.jp/aba3/20110612/1307866375
var fso = new ActiveXObject("Scripting.FileSystemObject");
var filepath = WScript.Arguments(1);
WScript.CreateObject("Shell.Application")
    .NameSpace(fso.GetParentFolderName(filepath))
    .ParseName(fso.GetFilename(filepath))
    .ModifyDate = WScript.Arguments(0);
WScript.quit(0);

2016年5月18日水曜日

Lsdfr.ps1.bat

@echo off
setlocal
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
@rem setlocal DISABLEDELAYEDEXPANSION

@rem 説明:
@rem Directory file list.

@rem Usage:
@rem "Lsdfr.ps1.bat" dirpath csvpath
@rem echo errorlevel=%errorlevel%


@rem ####################
@rem Batch.
@rem ####################

@rem ....................
@rem Batch main.
@rem ....................
set rv=11
if "%~1"=="" (                                              call :L_call_BAT_NoArgs
) else if "%~1"=="BAT_Output_Args" (                        call :L_BAT_Output_Args %*
) else if "%~1"=="PS1_Output_PowerShellScriptLinesRange" (  call :L_call_PS1 %*
) else (                                                    call :L_call_BAT_OtherArgs %*
)

@rem ....................
@rem Exit.
@rem ....................
@rem echo.
@rem pause
@rem echo 終了するには何かキーを押してください . . .
@rem pause>nul
exit /b !rv!
goto :eof


@rem ....................
@rem No args.
@rem ....................
:L_call_BAT_NoArgs
@rem echo BAT %0 %* ....................
call :L_call_PS1
set /a rv=!errorlevel!+9
goto :eof


@rem ....................
@rem Output Args.
@rem ....................
:L_BAT_Output_Args
set /a y=0
for %%z in (
  %*
) do (
  set /a y=!y!+1
  echo BAT %%!y!=%%~z.
)
set /a rv=!errorlevel!+1
goto :eof


@rem ....................
@rem Other args.
@rem ....................
:L_call_BAT_OtherArgs
call :L_call_PS1 %*
set /a rv=!errorlevel!+0
goto :eof


@rem ....................
@rem Echo ErrorLevel.
@rem ....................
:L_echoErrorLevel
@rem echo BAT L_echoErrorLevel ....................
echo BAT %0 R errorlevel=!errorlevel!
@rem echo.
goto :eof


@rem ....................
@rem Get PowerShellScriptLinesRange.
@rem ....................
:L_getPowerShellScriptLinesRange
for /f "usebackq tokens=1,2 delims=, " %%y in (
  `call "%~f0" "PS1_Output_PowerShellScriptLinesRange" "%~f0"`
) do (
  set /a ps1Sta1=%%y+0 2>nul
  set /a ps1End1=%%z+0 2>nul
  if "!ps1Sta1!,!ps1End1!"=="%%y,%%z" (
    set "ps1Sta=%%y"
    set "ps1End=%%z"
  )
)
goto :eof


@rem ....................
@rem Call PowerShell script.
@rem ....................
:L_call_PS1
@rem http://qiita.com/cd01/items/82829ba0ec0f59e1b04d
@rem http://scripting.cocolog-nifty.com/blog/2007/07/powershellps1_bd41.html
set "ps1args=%*"
set "ps1line=$ps1sb = (\"\");"
set "ps1line=!ps1line!$ps1obj = (Get-Content \"%~f0\");"
if "!ps1Sta!,!ps1End!"=="," (
  if "%~1"=="PS1_Output_PowerShellScriptLinesRange" (
    set "ps1line=!ps1line!$ps1Sta = ($ps1obj | Select-String (\"^goto \:eof$\") | Select-Object -Last 1).LineNumber + 1;"
    set "ps1line=!ps1line!$ps1End = ($ps1obj | Select-String (\"^@\" + \"end$\") | Select-Object -First 1).LineNumber - 1;"
    set "ps1line=!ps1line!if ($ps1End -eq -1) {$ps1End = $ps1obj.Length};"
  ) else (
    call :L_getPowerShellScriptLinesRange
    set "ps1line=!ps1line!$ps1Sta = !ps1Sta!;"
    set "ps1line=!ps1line!$ps1End = !ps1End!;"
  )
) else (
  set "ps1line=!ps1line!$ps1Sta = !ps1Sta!;"
  set "ps1line=!ps1line!$ps1End = !ps1End!;"
)
set "ps1line=!ps1line!$ps1sb += for ($cc = 0; $cc -lt $ps1Sta; ++$cc) {$ps1sb += \"`n\"} <# Dummy blank lines for line number in PowerShell message. #>;"
set "ps1line=!ps1line!$ps1sb += ($ps1obj | Select-Object -First $ps1End | Select-Object -Skip $ps1Sta) -Join \"`n\";"
set "ps1line=!ps1line!$ps1sb = [scriptblock]::create($ps1sb);"
set "ps1line=!ps1line!&$ps1sb"
if "!ps1args!"=="" (
  powershell -NoProfile -ExecutionPolicy Unrestricted "!ps1line!"
) else (
  set "ps1args=!ps1args:"='!"
  rem '
  powershell -NoProfile -ExecutionPolicy Unrestricted "!ps1line!" "!ps1args!"
)
@rem call :L_echoErrorLevel
goto :eof


# ####################
# PowerShell script.
# ####################


# ....................
# No args.
# ....................
function global:NoArgs {
  # Write-Host "PS1 NoArgs ...................."
  # Write-Host "PS1 Argc=$($Args.Length)."  
  Write-Host "Usage: Lsdfr.ps1.bat dirpath csvpath"
  return 9
}


# ....................
# Get-Lsdfr.
# ....................
# http://eco.senritu.net/make_filelist_with_powershell/
function global:Get-Lsdfr {
  Param ([string]$dirpath, [string]$csvpath)
  Set-Location $dirpath
  # "PSPath","PSParentPath","PSChildName","PSDrive","PSProvider","PSIsContainer",
  # "BaseName","Mode","Name","Parent","Exists","Root","FullName","Extension",
  # "CreationTime","CreationTimeUtc","LastAccessTime","LastAccessTimeUtc","LastWriteTime","LastWriteTimeUtc","Attributes"
  Get-ChildItem -Recurse | Select-Object Mode,CreationTime,CreationTimeUtc,LastAccessTime,FullName,Extension | Export-Csv -Encoding Default -force -notype $csvpath
  return 0
}


# ....................
# Other args.
# ....................
function global:OtherArgs([string[]]$ps1args) {
#  Write-Host "PS1 OtherArgs ...................."
#  Write-Host "PS1 [$($ps1args.Length)]$($ps1args)."
#  for($idx = 0; $idx -lt $ps1args.Length; ++$idx) {
#    Write-Host "PS1 Args[$($idx)]=$($ps1args[$idx])."
#  }
  Write-Host "Usage: Lsdfr.ps1.bat dirpath csvpath"
  return 1
}


# ....................
# Output PowerShellScriptLinesRange.
# ....................
function global:Output_PowerShellScriptLinesRange([string]$pathPowerShellScript) {
  $ps1Sta = 0
  $ps1End = 0
  if (Test-Path $pathPowerShellScript) {
    $ps1obj = Get-Content $pathPowerShellScript
    $ps1Sta = ($ps1obj | Select-String ("^goto \:eof$") | Select-Object -Last 1).LineNumber + 1
    $ps1End = ($ps1obj | Select-String ("^@" + "end$") | Select-Object -First 1).LineNumber - 1
    if ($ps1End -eq -1) {$ps1End = $ps1obj.Length}
  }
  Write-Host "$ps1Sta,$ps1End"
  return 7
}


# --------------------
# PowerShell script main.
# --------------------
$rv = 0
if ($Args.Length -eq 0) {
  $rv = $rv + (NoArgs)
} else {
  if (0 -eq 1) {
    $rv = $rv + 1
  } elseif (($Args.Length -ge 2) -and ($Args[0].Equals("PS1_Output_PowerShellScriptLinesRange"))) {
    $rv = $rv + (Output_PowerShellScriptLinesRange ($Args[1]))
  } elseif ($Args.Length -ge 2) {
    $rv = $rv + (Get-Lsdfr $Args[0] $Args[1])
  } else {
    $rv = $rv + (OtherArgs ($Args))
  }
}
exit $rv

2016年5月17日火曜日

EventCheck.bat

@if(0)==(0) echo off
@rem http://computer-technology.hateblo.jp/entry/20131025/p1
setlocal
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
@rem setlocal DISABLEDELAYEDEXPANSION

@rem 説明:
@rem Windowsの開始日時と終了日時の一覧を出力します。
@rem
@rem 出力例:
@rem   2016/01/28 09:32:21 Thu - 2016/01/28 20:46:37 Thu
@rem   2016/01/29 09:40:02 Fri - 2016/01/29 18:40:56 Fri
@rem   2016/02/01 09:53:05 Mon - 2016/02/01 19:52:03 Mon
@rem   2016/02/02 09:30:32 Tue -
@rem
@rem 引数
@rem   日数
@rem     過去何日前からの記録をするかの日数を指定します。
@rem     日数は正の整数です。
@rem     既定値は40です。
@rem     不正値チェックはしていません。不正値の場合、異常終了します。
@rem
@rem 戻り値
@rem   0
@rem     常に0です。
@rem
@rem 情報源
@rem   Windowsの開始日時
@rem     Windowsのシステム ログのイベントID=6005(イベント ログ サービスの開始)。
@rem
@rem   Windowsの終了日時
@rem     Windowsのシステム ログのイベントID=6006(イベント ログ サービスの終了)。
@rem
@rem Windowsのシステム ログ内を検索するときの期間の条件
@rem   期間の開始日
@rem   「40日前」は当バッチ コマンドの第1引数で変更できます。
@rem
@rem   期間の終了日
@rem   当バッチ コマンド実行日。
@rem
@rem 当バッチ コマンドの名称
@rem   変更できます。
@rem
@rem 実行方法
@rem   引数を指定しない場合
@rem     EventCheck.bat
@rem
@rem   引数を指定する場合
@rem     EventCheck.bat 10

@rem Usage:
@rem EventCheck.bat


@rem ####################
@rem Batch.
@rem ####################

@rem ....................
@rem Batch main.
@rem ....................
set rv=0
if "%~1"=="" (                                              call :L_call_BAT_NoArgs
) else (                                                    call :L_call_BAT_OtherArgs %*
)

@rem ....................
@rem Exit.
@rem ....................
@rem echo.
@rem pause
echo 終了するには何かキーを押してください . . .
pause>nul
exit /b !rv!
goto :eof


@rem ....................
@rem No args.
@rem ....................
:L_call_BAT_NoArgs
@rem echo BAT %0 %* ....................
call :L_call_JS "JS_EventCheck"
set /a rv=!errorlevel!+0
goto :eof


@rem ....................
@rem Other args.
@rem ....................
:L_call_BAT_OtherArgs
@rem echo BAT %0 %* ....................
call :L_call_JS "JS_EventCheck" %*
set /a rv=!errorlevel!+0
goto :eof


@rem ....................
@rem Echo ErrorLevel.
@rem ....................
:L_echoErrorLevel
@rem echo BAT L_echoErrorLevel ....................
@rem echo BAT %0 R errorlevel=!errorlevel!
@rem echo.
goto :eof


@rem ....................
@rem Call JScript.
@rem ....................
:L_call_JS
@rem echo BAT %0 %* ....................
set "jsargs=%*"
if "!jsargs!"=="" (
  cscript.exe //nologo //e:JScript "%~f0"
) else (
  cscript.exe //nologo //e:JScript "%~f0" !jsargs!
)
call :L_echoErrorLevel
goto :eof


@end


// ####################
// JScript.
// ####################


// ....................
// No args.
// ....................
function NoArgs() {
//  WScript.Echo("JS NoArgs ....................");
  // WScript.Echo("JS Argc=" + WScript.Arguments.length + ".");
  WScript.Echo("There are no arguments.");
  return 1;
}


http://qiita.com/osakanafish/items/c64fe8a34e7221e811d0
/**
 * 日付をフォーマットする
 * @param  {Date}   date     日付
 * @param  {String} [format] フォーマット
 * @return {String}          フォーマット済み日付
 */
var formatDate = function (date, format) {
  var WEEK_DAY_EN = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
  if (!format) format = 'YYYY-MM-DD hh:mm:ss.SSS www';
  format = format.replace(/YYYY/g, date.getFullYear());
  format = format.replace(/MM/g, ('0' + (date.getMonth() + 1)).slice(-2));
  format = format.replace(/DD/g, ('0' + date.getDate()).slice(-2));
  format = format.replace(/hh/g, ('0' + date.getHours()).slice(-2));
  format = format.replace(/mm/g, ('0' + date.getMinutes()).slice(-2));
  format = format.replace(/ss/g, ('0' + date.getSeconds()).slice(-2));
  if (format.match(/S/g)) {
    var milliSeconds = ('00' + date.getMilliseconds()).slice(-3);
    var length = format.match(/S/g).length;
    for (var i = 0; i < length; ++i) format = format.replace(/S/, milliSeconds.substring(i, i + 1));
  }
  format = format.replace(/www/g, (WEEK_DAY_EN[date.getDay()]));
  return format;
};


// http://www.activexperts.com/admin/scripts/wmi/jscript/0406/
function WmiDate_parseWmiDateTimeString(strDtmDate) {
  if (strDtmDate == null) {
    return "null date";
  }
  var strDateTime;
  if (strDtmDate.substr(4, 1) == 0) {
    strDateTime = strDtmDate.substr(5, 1) + "/";
  }  else  {
    strDateTime = strDtmDate.substr(4, 2) + "/";
  }
  if (strDtmDate.substr(6, 1) == 0) {
     strDateTime = strDateTime + strDtmDate.substr(7, 1) + "/";
  }  else  {
    strDateTime = strDateTime + strDtmDate.substr(6, 2) + "/";
  }
  strDateTime = strDateTime +
      strDtmDate.substr(0, 4) + " " +
      strDtmDate.substr(8, 2) + ":" +
      strDtmDate.substr(10, 2) + ":" +
      strDtmDate.substr(12, 2);
  return(strDateTime);
};


// http://qiita.com/search?q=JScript%E3%81%A7WMI&sort=rel
// http://qiita.com/tnakagawa/items/89917ca9fbde1c2f47a9
function WmiDate(date) {
  var datetime = null;
  if (date && date instanceof Date) {
    // 「SWbemDateTime」オブジェクト生成
    datetime = new ActiveXObject("WbemScripting.SWbemDateTime");
    datetime.Year = date.getUTCFullYear();                      // 年
    datetime.Month = date.getUTCMonth() + 1;                    // 月
    datetime.Day = date.getUTCDate();                           // 日
    datetime.Hours = date.getUTCHours();                        // 時
    datetime.Minutes = date.getUTCMinutes();                    // 分
    datetime.Seconds = date.getUTCSeconds();                    // 秒
    datetime.Microseconds = date.getUTCMilliseconds() * 1000;   // ミリ秒
  }
  return datetime;
};


function Date_formatLocal(date) {
  var ret = null;
  var DLM_YMD = "/";
  var DLM_HMS = ":";
  if (date && date instanceof Date) {
    ret = date.getFullYear() + DLM_YMD                          // 年
        + ("0" + (date.getMonth() + 1)).slice(-2) + DLM_YMD     // 月
        + ("0" + date.getDate()).slice(-2) + " "                // 日
        + ("0" + date.getHours()).slice(-2) + DLM_HMS           // 時
        + ("0" + date.getMinutes()).slice(-2) + DLM_HMS         // 分
        + ("0" + date.getSeconds()).slice(-2)                   // 秒
//      + "." + ("00" + date.getMilliseconds()).slice(-3)       // ミリ秒
//      + "000"                                                 // ナノ秒
//      + date.getTimezoneOffset()                              // 時差
        ;
  }
  return ret;
};


// http://qiita.com/tnakagawa/items/ae579f19d74dd86e40c6
function wmiProps(wqlQuery) {
  // 結果
  var result = [];
  try {
    // 「SWbemLocator」オブジェクト取得
    var locator = new ActiveXObject("WbemScripting.SWbemLocator");
    // 「SWbemServices」オブジェクト取得(ローカルコンピュータ、名前空間「root\CIMV2」)
    var services = locator.ConnectServer(null, "root\\CIMV2");
    // クエリ実行、「SWbemObjectSet」オブジェクト取得
    var set = services.ExecQuery(wqlQuery);
    // 「SWbemObjectSet」をJScriptで扱えるように「Enumerator」に変換
    var enumSet = new Enumerator(set);
    // 「SWbemObjectSet」の最後までループ
    while (!enumSet.atEnd()) {
      // 要素「SWbemObject」を取得
      var item = enumSet.item();
      // プロパティ「SWbemPropertySet」取得
      var props = item.Properties_;
      // 「SWbemPropertySet」をJScriptで扱えるように「Enumerator」に変換
      var enumProps = new Enumerator(props);
      // アイテム変数
      var item = {};
      // プロパティ分ループ
      item["RecordNumber"] = "";    // Reserve item[0]
      item["Logfile"] = "";         // Reserve item[1]
      while (!enumProps.atEnd()) {
        var val = null;
        // プロパティ取得
        var prop = enumProps.item();
        //WScript.StdOut.WriteLine(prop);
        // nullチェック
        if (prop.Value != null) {
          // 配列判定
          if (prop.IsArray) {
            // 配列化
            val = new VBArray(prop.Value).toArray();
          } else {
            val = prop.Value;
          }
        }
        // アイテム設定
        item[prop.Name] = val;
        // 次のプロパティへ移動
        enumProps.moveNext();
      }
      // アイテム設定
      result.push(item);
      // 次の要素へ移動
      enumSet.moveNext();
    }
  } catch (e) {
      // エラーの場合
      throw e;
  }
  return result;
};


function wmiPropsPrintAscend(props) {
  var DLM_DT_WK = " ";
  var DLM_DT_DT = " - ";
  // 曜日(英語)
  var WEEK_DAY_EN = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
                  // "YYYY/MM/DD hh:mm:dd" + DLM_DT_WK + "www"
                  // "2016/01/02 03:04:05" + DLM_DT_WK + "Sat"
  var DATE_STR_SPC = "                   " + DLM_DT_WK + "   ";
  var dateStrSta = DATE_STR_SPC;
  var dateStrSto = DATE_STR_SPC;
  var dateStrCrr = DATE_STR_SPC;
  var dateTimeDst = new Date().getTimezoneOffset() * 60 * 1000;   // UTCと現地の時差。
  // キー配列
  var keys = null;
  var line1 = [];     // 1要素は1行
  // プロパティ配列数分ループ
  for (var i = props.length - 1; i >= 0; --i) {
    // 1プロパティを1イベントとして要素取得
    var items = props[i];
    // キー存在チェック
    if (keys == null) {
      // 初期化
      keys = [];
      // 要素のキー取得
      for (key in items) {
        keys.push(key);
      }
    }
    var line2 = [];   // 1要素は1イベント
    // 要素数分ループ
    for (var j = 0; j < keys.length; ++j) {
      // 要素取得
      var item = items[keys[j]];
      // 要素存在チェック
      if (item != null) {
        // 要素配列チェック
        if (item instanceof Array) {
          // 配列の場合、改行で連結
          item = item.join("\r\n");
        } else {
          // 文字列化
          item = "" + item;
        }
        // ダブルクォーテーションフラグ偽
        var isQuote = false;
        // 要素にダブルクォーテーションの存在チェック
        if (item.indexOf("\"") >= 0) {
          // ダブルクォーテーションを置き換え
          item = item.replace(/\"/g, "\"\"");
          // ダブルクォーテーションフラグ真
          isQuote = true;
        } else if (item.indexOf(",") >= 0
            || item.indexOf("\r") >= 0
            || item.indexOf("\n") >= 0) {
          // 要素に、「,」「CR」「LF」のいずれかがあるので
          // ダブルクォーテーションフラグ真
          isQuote = true;
        }
        // ダブルクォーテーションフラグ判定
        if (isQuote) {
          // 両端をダブルクォーテーションで囲む
          item = "\"" + item + "\"";
        }
      }
      // 要素設定
      line2.push(item);
    }
    // Windowsの1回分の開始日時と終了日時を1文字列として配列line1へ格納する。
    // Windowsをシャットダウンせずに電源断して再起動した場合、開始日時のイベントが連続することを考慮する。
    // WMIで取得したイベントの日時文字列を現地日時のDate型に変換する。
    var eventDate = new Date(
      Date.parse(WmiDate_parseWmiDateTimeString(line2[3])) - dateTimeDst
    );
    // イベントの現地日時のDate型を文字列に変換する。
    dateStrCrr = Date_formatLocal(eventDate) + DLM_DT_WK + WEEK_DAY_EN[eventDate.getDay()];
    // 1行分のデータを設定。
    if (6005 == line2[2]) {     // 開始日時
      if (dateStrSta != DATE_STR_SPC) {
        line1.push(dateStrSta + DLM_DT_DT + dateStrSto);
      }
      dateStrSta = dateStrCrr;
      dateStrSto = DATE_STR_SPC;
    }
    if (6006 == line2[2]) {     // 終了日時
      line1.push(dateStrSta + DLM_DT_DT + dateStrCrr);
      dateStrSta = DATE_STR_SPC;
      dateStrSto = DATE_STR_SPC;
    }
  }
  // 現在の稼働分は、開始日時ありで終了日時なしとして取得できているはず。
  if ((dateStrSta != DATE_STR_SPC) || (dateStrSto != DATE_STR_SPC)) {
    // 終了日時なしの場合、最終行の終了日時を現在の日時にする
    if ((true) && (dateStrSto == DATE_STR_SPC)) {
      dateStrSto = formatDate(new Date(), "YYYY/MM/DD hh:mm:ss www");
    }
    line1.push(dateStrSta + DLM_DT_DT + dateStrSto);
  }
  for (j = 0; j < line1.length; ++j) {
    WScript.StdOut.WriteLine(line1[j]);
  }
  return;
};


// ....................
// EventCheck.
// ....................
function EventCheck(args) {
  var DAYS = 40;      // 抽出日数(過去n日)
  if ((args != null) && (args.length >= 1)) {
    DAYS = args;
  }
  var dt = new Date();
  dt.setHours(0);
  dt.setMinutes(0);
  dt.setSeconds(0);
  dt.setDate(dt.getDate() - DAYS);
  // WMIでイベントログを抽出するWQL。
  // WMIは日時をUTCで扱う。ただし、日時の書式は独自で、時差の±は逆。
  // WQLはSQLに似ているがORDER BY句がない。
  // Windowsの開始日時と終了日時であれば、降順と言えると思われる。
  var wqlQuery = [
    "SELECT EventCode,TimeGenerated,TimeWritten",
    "  FROM Win32_NTLogEvent",
    "  WHERE (EventCode = 6005 OR EventCode = 6006)",
    "  AND Logfile = 'System'",
    "  AND TimeGenerated >= '" + WmiDate(dt) + "'",
  ].join(" ");
  var props = wmiProps(wqlQuery);
  // 並べ替えせずに末尾から先頭方向へ参照していく方式で
  // Windowsの開始日時と終了日時を昇順で出力。
  wmiPropsPrintAscend(props);
  return 0;
}


// ....................
// Other args.
// ....................
function OtherArgs(jsargs) {
//  WScript.Echo(" OtherArgs ....................");
//  WScript.Echo("JS [" + jsargs.length + "]" + jsargs + ".");
//  for(var idx = 0; idx < jsargs.length; ++idx) {
//    WScript.Echo("JS Args[" + idx + "]=" + jsargs[idx] + ".");
//  }
  WScript.Echo("Other args.");
  return 1;
}


// --------------------
// JScript main.
// --------------------
var rv = 0;
if (WScript.Arguments.length == 0) {
  rv = rv + NoArgs();
} else {
  var args = new Array();
  for (var idx = 0; idx < WScript.Arguments.length; ++idx) {
    args[idx] = WScript.Arguments(idx);
  }
  var ary = new Array();
  ary = args.slice(0, args.length);
  if (0 == 1) {
    rv = rv + 1;
  } else if ((args.length == 1) && (WScript.Arguments(0) == "JS_EventCheck")) {
    rv = rv + EventCheck();
  } else if ((args.length == 2) && (WScript.Arguments(0) == "JS_EventCheck")) {
    rv = rv + EventCheck(args[1]);
  } else {
    rv = rv + OtherArgs(ary);
  }
}
WScript.quit(rv);