OSDN Git Service

update
[bashlib/bashlib-develop.git] / scriptlib / bashlib.sh
1 #// Content-Type: text/plain; charset=utf-8
2
3 #// bashlib is provided under 3-clause BSD license.
4 #// Copyright (C) 2011 Sofrware Design Gallery "Sage Plaisir 21" All Rights Reserved.
5
6
7  
8 #//*********************************************************************
9 #// <<< [declare_AssociativeArrayClass] >>> 
10 #//*********************************************************************
11 if [ "${BASH_VERSINFO[0]}" -ge "4" ];then
12   declare_AssociativeArrayClass="declare -A"  #// bash ver4
13 else
14   declare_AssociativeArrayClass="declare"  #// bash ver3
15 fi
16
17
18  
19 #//*********************************************************************
20 #// <<< [CallMain_func] >>> 
21 #//*********************************************************************
22 function  CallMain_func()
23 {
24   local  is_not_err_handled=0
25
26   trap 'set +x ; ErrTrap_func' EXIT
27   trap 'set +x ; ErrTrap_func $LINENO ;  break' ERR  #// In function, it is necessary to bash -E option
28   trap 'DebugTrap_func  "$LINENO"  "$BASH_COMMAND"  "${PIPESTATUS[@]}"
29     #// resume ${PIPESTATUS[@]}
30     case "${#g_PipeStatus[@]}" in
31       "2")
32         return ${g_PipeStatus[0]} | true;;
33       "3")
34         return ${g_PipeStatus[0]} | return ${g_PipeStatus[1]} | true;;
35     esac' DEBUG
36   set +e
37
38   GetAbsPath_func  "`basename "${g_Arguments[0]}"`" ; g_Arguments[0]="$g_Ret"
39
40   while TryStart_func; do
41
42     Main_func  ""  "AppKey4293"
43
44     g_DebugTrapFunc=""
45     if [ "$g_ExitStatus" != "0" ];then  is_not_err_handled=1  ;fi
46   TryEnd1_func; done ;TryEnd2_func $?
47   g_DebugTrapFunc=""
48
49   if [ "$g_ExitStatus" != "0" ];then
50     if [ "$g_Err_Desc" == "" ];then
51       ColorText_func  "<ERROR/>"  "Red" "Bold"
52     else
53       ColorText_func  "$g_Err_Desc"  "Red" "Bold"
54     fi
55     echo_e_func  "$g_Ret" >&2
56     echo "Exit Status = $g_ExitStatus"  >&2
57     echo_line_func
58     echo -n "$g_Err_ErrCallStack"  >&2
59     if [ "$g_Err_Desc" == "" ];then
60       echo  "<ERROR/>"  >&2
61     else
62       echo  "$g_Err_Desc"  >&2
63     fi
64     if [ "$is_not_err_handled" == "1" ];then
65       echo  "エラー処理がされていません。ErrClass.clear_method または ErrClass.raiseOverwrite_method を呼び出してください"
66     fi
67     trap ':' EXIT
68     exit  "$g_ExitStatus"
69   fi
70   trap ':' EXIT
71 }
72
73
74  
75 #//*********************************************************************
76 #// <<< [DebugTrap_func] >>> 
77 #//*********************************************************************
78 function  DebugTrap_func()
79 {
80   if [ "$g_DebugTrapFunc" == "" ];then
81     shift  2
82     g_PipeStatus=( "$@" )
83   else
84     $g_DebugTrapFunc  "$@"
85   fi
86 }
87
88
89  
90 #//*********************************************************************
91 #// <<< [EchoOn_func] >>> 
92 #//*********************************************************************
93 function  EchoOn_func()
94 {
95   echo  "${BASH_LINENO[0]}: EchoOn_func at ${FUNCNAME[1]}() in ${BASH_SOURCE[1]}" >&2
96
97   g_DebugTrapFunc="EchoOnTrap_func"
98
99   trap 'DebugTrap_func  "$LINENO"  "$BASH_COMMAND"  "${PIPESTATUS[@]}"
100     #// resume ${PIPESTATUS[@]}
101     case "${#g_PipeStatus[@]}" in
102       "2")
103         return ${g_PipeStatus[0]} | true;;
104       "3")
105         return ${g_PipeStatus[0]} | return ${g_PipeStatus[1]} | true;;
106     esac' DEBUG
107 }
108
109 function  EchoOnTrap_func()
110 {
111   local  LineNo="$1"
112   local  Command="$2"
113   shift  2
114   g_PipeStatus=( "$@" )
115
116   echo "$LineNo: $Command" >&2
117 }
118
119
120  
121 #//*********************************************************************
122 #// <<< [EchoOff_func] >>> 
123 #//*********************************************************************
124 function  EchoOff_func()
125 {
126   g_DebugTrapFunc=""
127 }
128
129
130  
131 #//*********************************************************************
132 #// <<< [echo_line_func] >>> 
133 #//*********************************************************************
134 function  echo_line_func()
135 {
136   echo "-------------------------------------------------------------------------------"
137 }
138
139
140  
141 #//*********************************************************************
142 #// <<< [Pause_func] >>> 
143 #//*********************************************************************
144 function  Pause_func()
145 {
146   local  Param="$1"
147   local  key
148   local  sec
149
150   if [ "$Param" != "" ];then
151     local  arguments
152     $declare_AssociativeArrayClass  option
153
154     GetLongOptions_func  arguments  option  "$@"  #//[out] arguments, option
155     Attr_func  option  "time_out" ; sec="$g_Ret"
156     AssociativeArrayClass.destroy_method  option
157   fi
158
159   if [ "$sec" == "" ];then
160     read -p "続行するには Enter キーを押してください . . ."  key
161   else
162     for (( sec = $sec; sec >=0; sec -- )) ;do
163       echo -e -n "\r"
164       if [ "$sec" == "0" ];then
165         echo  "続行するには Enter キーを押してください . . .  "
166         break
167       fi
168
169       read -p "続行するには Enter キーを押してください . . . $sec " -t 1  key || key="...."
170       if [ "$key" == "" ];then  break  ;fi
171     done ; done_func $?
172   fi
173 }
174
175
176  
177 #//*********************************************************************
178 #// <<< [ColorText_func] >>> 
179 #//*********************************************************************
180 function  ColorText_func()
181 {
182   local  Text="$1"
183   shift  1
184   local  ColorNames=("$@")
185   local  i
186   local  n
187   local  str
188
189   #//=== initialize  g_ColorText_Codes
190   Attr_func  g_ColorText_Codes  "Black"
191   if [ "$g_Ret" == "" ];then
192
193     #//=== set escape sequence
194     SetAttr_func  g_ColorText_Codes  "Black"    30
195     SetAttr_func  g_ColorText_Codes  "Red"      31
196     SetAttr_func  g_ColorText_Codes  "Green"    32
197     SetAttr_func  g_ColorText_Codes  "Yellow"   33
198     SetAttr_func  g_ColorText_Codes  "Blue"     34
199     SetAttr_func  g_ColorText_Codes  "Magenta"  35
200     SetAttr_func  g_ColorText_Codes  "Cyan"     36
201     SetAttr_func  g_ColorText_Codes  "White"    37
202
203     SetAttr_func  g_ColorText_Codes  "BlackBack"    40
204     SetAttr_func  g_ColorText_Codes  "RedBack"      41
205     SetAttr_func  g_ColorText_Codes  "GreenBack"    42
206     SetAttr_func  g_ColorText_Codes  "YellowBack"   43
207     SetAttr_func  g_ColorText_Codes  "BlueBack"     44
208     SetAttr_func  g_ColorText_Codes  "MagentaBack"  45
209     SetAttr_func  g_ColorText_Codes  "CyanBack"     46
210     SetAttr_func  g_ColorText_Codes  "WhiteBack"    47
211
212     SetAttr_func  g_ColorText_Codes  "Bold"  1
213   fi
214
215   str="\e["
216   n=$(( ${#ColorNames[@]} - 1 ))
217   for (( i = 0;  i <= n;  i++ )) ;do
218     Attr_func  g_ColorText_Codes  "${ColorNames[$i]}"
219     if [ "$i" == "$n" ];then
220       str="${str}${g_Ret}m"
221     else
222       str="${str}${g_Ret};"
223     fi
224   done ; done_func $?
225
226   g_Ret="${str}${Text}\e[m"
227 }
228
229 $declare_AssociativeArrayClass  g_ColorText_Codes
230
231
232  
233 #//*********************************************************************
234 #// <<< [echo_e_func] >>>
235 #//*********************************************************************
236 function  echo_e_func()
237 {
238   local  Text="$@"
239   eval echo '$'"'$Text'"
240 }
241
242
243  
244 #//*********************************************************************
245 #// <<< [Input_func] >>> 
246 #//*********************************************************************
247 function  Input_func()
248 {
249   local  Prompt="$1"
250   local  key
251   local  ifs_bk
252
253   if [ "$Prompt" == "" ];then  Prompt=">"  ;fi
254
255   if [ "$g_AutoInput_ArgsNextIndex" -lt "${#g_AutoInput_Args[@]}" ];then
256     key="${g_AutoInput_Args[$g_AutoInput_ArgsNextIndex]}"
257     g_Ret="$key"
258     echo  "$Prompt$key"
259     g_AutoInput_ArgsNextIndex=$(( $g_AutoInput_ArgsNextIndex + 1 ))
260   else
261     ifs_bk="$IFS"
262     IFS="\\"  #// This can input space or tab at the end of string
263     read -p "$Prompt" -r g_Ret
264     IFS="$ifs_bk"
265   fi
266 }
267
268
269  
270 #//*********************************************************************
271 #// <<< [SetAutoInputFromMainArg_func] >>> 
272 #//*********************************************************************
273 g_AutoInput_Args=( )
274 g_AutoInput_ArgsNextIndex=0
275
276 function  SetAutoInputFromMainArg_func()
277 {
278   g_AutoInput_Args=( "${g_Arguments[@]}" )
279   g_AutoInput_ArgsNextIndex=1
280 }
281
282
283  
284 #//*********************************************************************
285 #// <<< [InputPath_func] >>> 
286 #//*********************************************************************
287 function  InputPath_func()
288 {
289   local  Prompt="$1"
290   local  input_path
291   local  base_path
292   local  is_file_exist_opt
293   local  is_folder_exist_opt
294   local  is_not_exist_opt
295   local  len
296   local  ret
297   local  arguments
298   $declare_AssociativeArrayClass  options
299
300   GetLongOptions_func  arguments  options  "$@"  #//[out] arguments, options
301
302   while true; do
303     Input_func  "$Prompt$base_path" ; input_path="$g_Ret"
304
305     if [ "$base_path$input_path" == "" ]; then
306       Attr_func  options  "AllowEnterOnly"
307       if [ "$g_Ret" == "1" ]; then
308         ret=""
309         break
310       fi
311
312     else
313
314       StringClass.right_method  "$input_path"  1
315       if [ "$g_Ret" == "$Tab" ];then
316
317         StringClass.length_method  "$input_path"
318         len=$(( $g_Ret - 1 ))
319         StringClass.substring_method  "$input_path"  0  "$len" ; input_path="$g_Ret"
320         InputPathSelectSub_func  "$input_path"  "$base_path"  base_path  #//[out] base_path
321
322       else
323
324         if [ "$base_path" != "" ];then
325           input_path="$base_path$input_path"
326         fi
327         StringClass.substring_method  "$input_path"  0  1
328         if [ "$g_Ret" == "~" ];then
329           StringClass.replace_method  "$input_path"  "~"  "$HOME" ; input_path="$g_Ret"
330         fi
331         eval "input_path=\"$input_path\""
332         GetAbsPath_func  "$input_path"  "$g_StartInPath" ; input_path="$g_Ret"
333
334         Attr_func  options  "ChkFileExists" ; is_file_exist_opt="$g_Ret"
335         Attr_func  options  "ChkFolderExists" ; is_folder_exist_opt="$g_Ret"
336         Attr_func  options  "ChkNotExists" ; is_not_exist_opt="$g_Ret"
337
338         if [ "$is_not_exist_opt" == "1" ];then
339           Assert_func  '"$is_file_exist_opt" != "1"'
340           Assert_func  '"$is_folder_exist_opt" != "1"'
341         fi
342
343         if [ x"$is_file_exist_opt" == x""  -a \
344              x"$is_folder_exist_opt" == x""  -a \
345              x"$is_not_exist_opt" == x"" ];then
346           ret="$input_path"
347           break
348         fi
349
350         if [ "$is_not_exist_opt" == "1" ];then
351           if [ -f "$input_path" ]; then
352             echo  "すでにファイルが存在しています。" >&2
353           elif [ -d "$input_path" ]; then
354             echo  "すでにフォルダーが存在しています。" >&2
355           else
356             ret="$input_path"
357             break
358           fi
359         else
360           if [ "$is_file_exist_opt" == "1" ];then
361             if [ -f "$input_path" ]; then
362               ret="$input_path"
363               break
364             fi
365           fi
366
367           if [ "$is_folder_exist_opt" == "1" ];then
368             if [ -d "$input_path" ]; then
369               ret="$input_path"
370               break
371             fi
372           fi
373
374           if [ "$is_file_exist_opt" == "1" ];then
375             if [ "$is_folder_exist_opt" == "1" ];then
376               echo  "ファイルまたはフォルダーが見つかりません。" >&2
377             else
378               echo  "ファイルが見つかりません。" >&2
379             fi
380           else
381             echo  "フォルダーが見つかりません。" >&2
382           fi
383         fi
384         echo  "$input_path" >&2
385       fi
386     fi
387   done ; done_func $?
388   AssociativeArrayClass.destroy_method  options
389   g_Ret="$ret"
390 }
391
392 function  InputPathSelectSub_func()
393 {
394   local  PartOfPath="$1"
395   local  BasePath="$2"
396   local  out_SelectedPath="$3"
397   local  folder
398   local  paths
399   local  paths2
400   local  i
401   local  path
402   local  part_of_file
403   local  len
404   local  num
405   local  new_base_path
406
407   if [ "$BasePath" != "" ];then
408     PartOfPath="$BasePath$PartOfPath"
409   fi
410   LeftOfLastStr_func  "$PartOfPath"  "/" ; folder="$g_Ret"
411   if [ x"$folder" == x""  -o  x"$folder" == x"$PartOfPath" ];then
412     folder="."
413   else
414     new_base_path="$folder/"
415   fi
416   StringClass.substring_method  "$folder"  0  1
417   if [ "$g_Ret" == "~" ];then
418     StringClass.replace_method  "$folder"  "~"  "$HOME" ; folder="$g_Ret"
419   fi
420   eval "folder=\"$folder\""
421
422   RightOfLastStr_func  "$PartOfPath"  "/" ; part_of_file="$g_Ret"
423
424   unset paths
425   pushd  "$g_StartInPath" > /dev/null
426   paths=`ls -p1A "$folder"`
427   popd  > /dev/null
428   ArrayClass.fromLines_method  paths  "$paths"  #//[out] paths
429
430   i=0
431   StringClass.length_method  "$part_of_file" ; len="$g_Ret"
432   for path  in "${paths[@]}" ;do
433     StringClass.substring_method  "$path"  0  "$len"
434     if [ "$g_Ret" == "$part_of_file" ];then
435       paths2[$i]="$path"
436       i=$(( $i + 1 ))
437     fi
438   done ; done_func $?
439
440   if [ "$PartOfPath" == "" ];then
441     echo  "$g_StartInPath/"
442   else
443     GetAbsPath_func  "$PartOfPath"  "$g_StartInPath"
444     echo  "$g_Ret"
445   fi
446   for (( i = 0; i < ${#paths2[@]}; i ++ ));do
447     echo -n "$(( $i + 1 )). ${paths2[$i]}   "
448   done ; done_func $?
449   echo -n "88. クリア   99. 戻る"
450
451   while true; do
452     Input_func  "  >" ; num="$g_Ret"
453     if [ "$num" == "88" ];then
454       SetOutput_func  "$out_SelectedPath"  ""
455       break
456     elif [ x"$num" == x"99"  -o  x"$num" == x"" ];then
457       SetOutput_func  "$out_SelectedPath"  "$BasePath"
458       break
459     elif [ "$num" -le "$i"  -a  "$num" -ge "0" ];then
460       if [ "$new_base_path" == "" ];then
461         SetOutput_func  "$out_SelectedPath"  "${paths2[$(( $num - 1 ))]}"
462       else
463         SetOutput_func  "$out_SelectedPath"  "$new_base_path${paths2[$(( $num - 1 ))]}"
464       fi
465       break
466     fi
467   done ; done_func $?
468 }
469
470
471  
472 #//*********************************************************************
473 #// <<< [InputCommand_func] >>> 
474 #//*********************************************************************
475 function  InputCommand_func()
476 {
477   local  self="$1"
478   local  Prompt="$2" ; if [ "$Prompt" == "" ];then  Prompt="番号またはコマンド >"  ;fi
479   local  Opt="$3"
480   local  AppKey="$4"
481
482   local  replaces
483   local  key
484   local  num
485   local  func
486   local  is_prompt
487   local  current_folder=`pwd`
488   local  captions
489   local  caption
490   local  a1
491
492
493   SetAutoInputFromMainArg_func
494   if [ "${#g_Arguments[@]}" == "1" ];then  is_prompt=1  ;else  is_prompt=0  ;fi
495
496   Attr_func  $self  CommandReplace ; replaces="$g_Ret"
497   Attr_func  $self  MenuCaption ; captions="$g_Ret"
498
499   while true; do
500
501     #//=== show menu
502     if [ "$is_prompt" != "0" ];then
503       echo_line_func
504       echo  "$g_StartInPath>"
505       Attr_func  $self  Lead
506       echo  "$g_Ret"
507
508       AssociativeArrayClass.getKeys_method "$replaces" ; a1="$g_Ret"
509       for key  in $a1 ;do
510         IsNumeric_func $key ; if [ "$g_Ret" == "1" ]; then
511           Attr_func  $captions  $key ; caption="$g_Ret"
512           if [ "$caption" == "" ];then
513             Attr_func  $replaces  $key
514             echo  "$key. $g_Ret"
515           else
516             echo  "$key. $caption"
517           fi
518         fi
519       done ; done_func $?
520       echo  "99. 終了"
521
522       while true; do
523         Input_func  "$Prompt" ; num="$g_Ret"
524         if [ "$num" != "" ];then  break  ;fi
525       done ; done_func $?
526       echo_line_func
527     else
528       while true; do
529         Input_func  "$Prompt" ; num="$g_Ret"
530         if [ "$num" != "" ];then  break  ;fi
531       done ; done_func $?
532     fi
533     if [ "$num" == "99" ];then
534       a1=`basename "${g_Arguments[0]}"`
535       echo  "(ヒント)$a1 のパラメーターに、入力する内容を指定できます。"
536       break
537     fi
538
539     #//=== call
540     Attr_func  $replaces  "$num" ; func="$g_Ret"
541     if [ "$func" != "" ];then  num="$func" ; Attr_func  $replaces  $func ; func="$g_Ret"  ;fi
542     if [ "$func" == "" ];then  func="$num"  ;fi
543     echo  " ((( $func )))"
544
545     if [ "$is_prompt" != "0" ];then
546       while TryStart_func; do
547         StringClass.right_method  "$func"  5
548         if [ "$g_Ret" == "_func" ];then
549           $func  "$Opt"  "$AppKey"
550         else
551           echo "$PWD\$ $func"
552           eval $func  #// eval is for reference variables
553         fi
554       TryEnd1_func; done ;TryEnd2_func $?
555       EchoOff_func
556       if [ "$g_ExitStatus" != "0" ];then
557         echo  "Exit Status = $g_ExitStatus"
558         if [ "$g_Err_Desc" == "" ];then
559           ColorText_func  "<ERROR/>"  "Red" "Bold"
560         else
561           ColorText_func  "$g_Err_Desc"  "Red" "Bold"
562         fi
563         echo_e_func  "$g_Ret"  >&2
564         if [ "$g_Err_Desc" == "" ];then
565           echo  "${g_Err_ErrCallStack}<ERROR/>"  >&2
566         else
567           echo  "${g_Err_ErrCallStack}${g_Err_Desc}"  >&2
568         fi
569         if [ "$is_not_err_handled" == "1" ];then
570           echo  "エラー処理がされていません。ErrClass.clear_method または ErrClass.raiseOverwrite_method を呼び出してください"  >&2
571         fi
572       fi
573       ErrClass.clear_method
574     else
575       "$func"  "$Opt"  "$AppKey"
576       break
577     fi
578     cd  "$current_folder"
579   done ; done_func $?
580 }
581
582
583  
584 #//*********************************************************************
585 #// <<< [InputOption_func] >>> 
586 #//*********************************************************************
587 function  InputOption_func()
588 {
589   local  name__
590   local  key__
591   local  left__
592   local  right__
593   local  comments__
594   local  i__
595   local  is_err__
596
597   local  Options__
598   $declare_AssociativeArrayClass  option__
599
600   GetLongOptions_func  Options__  option__  "$@"  #//[out] arguments__, option__
601   Attr_func  option__  comment
602   ArrayClass.fromCSV_method  comments__  "$g_Ret"  #//[out] comments__
603
604   SetAutoInputFromMainArg_func
605
606   while true ;do
607
608     #// finish auto input
609     if [ "$g_AutoInput_ArgsNextIndex" -ge "${#g_AutoInput_Args[@]}"  -a \
610          "$g_AutoInput_ArgsNextIndex" -ge "2"  -a \
611          "$is_err__" != "1"  ];then
612       break
613     fi
614
615     echo  ""
616     echo  "現在のオプション設定:"
617     i__=0
618     for  name__  in  "${Options__[@]}" ;do
619       eval echo  "--$name__="'"\"$'"$name__"'\"  ${comments__[$i__]}"'
620       i__=$(( $i__ + 1 ))
621     done ; done_func $?
622     echo  "Enter または . :設定完了"
623     Input_func  "オプションを入力してください(例:--${Options__[0]}=\"abc\"、--flag)>"
624     key__="$g_Ret"
625     if [ x"$key__" == x""  -o  x"$key__" == x"." ];then  break  ;fi
626
627     if [ "${key__:0:2}" == "--" ];then
628       key__="${key__:2}"
629     elif [ "${key__:0:1}" == "-" ];then
630       key__="${key__:1}"
631     fi
632     LeftOfStr_func  "$key__"  "=" ; left__="$g_Ret"
633     if [ "$key__" == "$left__" ];then
634       right__="1"
635     else
636       RightOfStr_func "$key__"  "=" ; eval right__="$g_Ret"
637     fi
638
639     for  name__  in  "${Options__[@]}" ;do
640       if [ "$name__" == "$left__" ];then
641         SetOutput_func  $name__  "$right__"
642         unset  left__
643         break
644       fi
645     done ; done_func $?
646     if [ "$left__" != "" ];then
647       echo  "オプション $left__ はありません。"
648       is_err__="1"
649     fi
650   done ; done_func $?
651 }
652
653
654  
655 #//*********************************************************************
656 #// <<< [sudo_func] >>> 
657 #//*********************************************************************
658 function  sudo_func()
659 {
660   g_TemporarySudo="sudo"
661   "$@"
662   unset  g_TemporarySudo
663 }
664
665
666  
667 #//*********************************************************************
668 #// <<< [mkdir_for_it_func] >>> 
669 #//*********************************************************************
670 function  mkdir_for_it_func()
671 {
672   local  FilePath="$1"
673   CheckArgCount_func  1 "$@"
674
675   folder_path=${FilePath%/*}  #// parent folder
676   if [ "$folder_path" == "$FilePath" ]; then  return 0  ;fi  #// if not found "/"
677   if [ ! -f "$folder_path" ]; then  mkdir -p  "$folder_path"  ;fi
678 }
679
680
681  
682 #//*********************************************************************
683 #// <<< [readlink_func] >>> 
684 #//*********************************************************************
685 function  readlink_func()
686 {
687   local  LinkPath="$1"
688   CheckArgCount_func  1 "$@"
689
690   if [ "$g_is_readlink_f" == "" ];then
691     while TryStart_func; do
692       g_Ret=`readlink -f "$LinkPath" 2> /dev/null`
693     TryEnd1_func; done ;TryEnd2_func $?
694     if [ "$g_ExitStatus" == "0" ]; then  g_is_readlink_f=1 ; return  ;fi
695     ErrClass.clear_method
696     g_is_readlink_f=0
697   fi
698
699   if [ "$g_is_readlink_f" == "1" ];then
700     g_Ret=`readlink -f "$LinkPath"`
701   else
702     local  folder
703     local  ph_folder
704     local  name
705     local  ph_name
706
707     folder=`dirname "$LinkPath"`
708     if [ "$folder" != "" ];then  pushd  "$folder" > /dev/null ;fi
709     ph_folder=`pwd -P`
710
711     name=`basename  "$LinkPath"`
712     ph_name=`readlink  "$name"` || :
713     if [ "$ph_name" == "" ];then
714       g_Ret="$ph_folder/$name"
715     else
716       g_Ret="$ph_folder/$ph_name"
717     fi
718     if [ "$folder" != "" ];then  popd > /dev/null ;fi
719   fi
720 }
721
722 g_is_readlink_f=""
723
724
725  
726 #//*********************************************************************
727 #// <<< [GetAbsPath_func] >>> 
728 #//*********************************************************************
729 function  GetAbsPath_func()
730 {
731   local  StepPath="$1"
732   local  BasePath="$2"
733   CheckMinArgCount_func  1 "$@"
734   CheckMaxArgCount_func  2 "$@"
735
736   local  abs_path
737   local  str
738
739   LeftOfStr_func "$StepPath" "/" ; str="$g_Ret"  #// if abs path, str=""
740   if [ "$str" == "" ]; then
741     g_Ret="$StepPath"
742   elif [ "$str" == "~" ]; then
743     StringClass.substring_method  "$StepPath"  1
744     g_Ret="$HOME$g_Ret"
745   else
746     if [ "$BasePath" == "" ];then  BasePath="$PWD"  ;fi
747
748     abs_path="$BasePath/$StepPath"
749
750     while true; do   #//  "*/../" -> ""
751       echo  "$abs_path" | grep  "[^/]*/\.\./" > /dev/null  || break
752       abs_path=`echo "$abs_path" | sed -e "s%[^/]*/\.\./%%"`
753     done ; done_func $?
754
755     while true; do   #//  "/*/.." -> ""
756       echo  "$abs_path" | grep  "[^/]*/[^/]*/\.\." > /dev/null  || break
757       abs_path=`echo "$abs_path" | sed -e "s%/[^/]*/\.\.$%%"`
758     done ; done_func $?
759
760     while true; do  #//  "/./" -> "/"
761       echo  "$abs_path" | grep  "/\./" > /dev/null  || break
762       StringClass.replace_method  "$abs_path"  "/./"  "/" ; abs_path="$g_Ret"
763     done ; done_func $?
764
765     while true; do  #//  "/." -> ""
766       StringClass.right_method  "$abs_path"  2
767       if [ "$g_Ret" != "/." ];then  break  ;fi
768       StringClass.replace_method  "$abs_path"  "/./"  "/" ; abs_path="$g_Ret"
769       abs_path=`echo "$abs_path" | sed -e "s%/\.$%%"`
770     done ; done_func $?
771
772     g_Ret="$abs_path"
773   fi
774 }
775
776
777  
778 #//*********************************************************************
779 #// <<< [GetParentAbsPath_func] >>> 
780 #//*********************************************************************
781 function  GetParentAbsPath_func()
782 {
783   local  Path="$1"
784   CheckArgCount_func  1 "$@"
785
786   local  str
787
788   LeftOfStr_func "$Path" "/" ; str="$g_Ret"  #// if abs path, str=""
789   if [ "$str" != "" ]; then
790     GetAbsPath_func "$Path" ; Path="$g_Ret"
791   fi
792
793   if [ x"$Path" == x"/"  -o  x"$Path" == x"" ]; then
794     g_Ret="$Path"
795   else
796     RightOfLastStr_func "$Path" "/"  #// if last char is "/", str=""
797     if [ "$g_Ret" == "" ]; then
798       LeftOfLastStr_func "$Path" "/" ; Path="$g_Ret"
799     fi
800     LeftOfLastStr_func  "$Path"  "/" ; Path="$g_Ret"  #// parent folder
801     if [ "$Path" == "" ];then  Path="/"  ;fi
802     g_Ret="$Path"
803   fi
804 }
805
806
807  
808 #//*********************************************************************
809 #// <<< [SearchParent_func] >>>
810 #//*********************************************************************
811 function  SearchParent_func()
812 {
813   local  path="$1"
814   local  folder
815   local  file
816
817   GetAbsPath_func  "$path"  "$PWD" ; path="$g_Ret"
818   if [ -e "$path" ];then  g_Ret="$path" ; return ;fi
819
820   folder=`dirname  "$path"`
821   file=` basename  "$path"`
822   while true; do
823     folder=`dirname  "$folder"`
824     if [ "$folder" == "/" ];then  break  ;fi
825     if [ -e "$folder/$file" ];then  g_Ret="$folder/$file" ; return ;fi
826   done ; done_func $?
827   if [ -e "/$file" ];then  g_Ret="/$file" ; return ;fi
828   g_Ret=""
829 }
830
831
832  
833 #//*********************************************************************
834 #// <<< [local_func] >>> 
835 #//*********************************************************************
836 function  local_func()
837 {
838   local  arguments
839   $declare_AssociativeArrayClass  option
840   local  args
841   local  locals
842   local  param
843   local  name
844   local  code
845   local  arg_num=0
846   local  out_names=( )
847   local  a1
848   local  a2
849
850   GetLongOptions_func  arguments  option  "$@"  #//[out] arguments, option
851
852   Attr_func  option  "arg"
853   ArrayClass.fromCSV_method  args  "$g_Ret"  #//[out] args
854
855   Attr_func  option  "local"
856   ArrayClass.fromCSV_method  locals  "$g_Ret"  #//[out] locals
857
858   for param  in ${args[@]}  ;do
859     StringClass.substring_method  "$param"  0 5 ; a1="$g_Ret"
860     StringClass.substring_method  "$param"  0 8 ; a2="$g_Ret"
861     if [ "$a1" == "(out)" ];then 
862       StringClass.substring_method  "$param"  5 ; param="$g_Ret"
863       out_names=( "${out_names[@]}" "${arguments[$arg_num]}" )
864     elif [ "$a2" == "(in_out)" ];then
865       StringClass.substring_method  "$param"  8 ; param="$g_Ret"
866       out_names=( "${out_names[@]}" "${arguments[$arg_num]}" )
867     fi
868     arg_num=$(( $arg_num + 1 ))
869     code="$code  local  $param=\""'$'"$arg_num\";"
870   done ; done_func $?
871
872   for param  in "${locals[@]}"  ;do
873     code="$code  local  $param;"
874   done ; done_func $?
875
876   locals=( "${args[@]}"  "${locals[@]}" )
877
878   for name  in ${out_names[@]} ;do
879     for param  in "${locals[@]}" ;do
880       if [ "$name" == "$param" ];then
881         AssociativeArrayClass.destroy_method  option
882         Error_func  "<ERROR msg=\"出力引数がローカル変数名と衝突しています\" name=\"$name\"/>"
883       fi
884     done ; done_func $?
885   done ; done_func $?
886
887   AssociativeArrayClass.destroy_method  option
888   g_Ret="$code"
889 }
890
891
892  
893 #//*********************************************************************
894 #// <<< [GetUsableCommands_func] >>> 
895 #//*********************************************************************
896 function  GetUsableCommands_func()
897 {
898   local  out_FoundCommands="$1"
899   shift  1
900   local  Commands=( "$@" )
901   local  command
902   local  is_found
903   local  founds=( )
904
905   for command  in ${Commands[@]} ;do
906     while TryStart_func; do
907       which $command > /dev/null
908     TryEnd1_func; done ;TryEnd2_func $?
909     if [ "$g_ExitStatus" == "0" ];then  founds=( "${founds[@]}"  "$command " )  ;fi
910     ErrClass.clear_method
911   done ; done_func $?
912   SetOutputAsArray_func  $out_FoundCommands  "${founds[@]}"
913 }
914
915
916  
917 #//*********************************************************************
918 #// <<< [GetUsableApplicationsForMac_func] >>> 
919 #//*********************************************************************
920 function  GetUsableApplicationsForMac_func()
921 {
922   local_func \
923     --arg="  (out)out_FoundCommands "  \
924     --local=" command__, commands__, apps__, app__, path__, file_name__, paths__, i__ " \
925     "$@" ; eval  "$g_Ret"
926     #// --arg="Applications ..."
927   apps__=( )
928   shift  1
929   local  Applications=( "$@" )
930
931   #// list up applications
932   while TryStart_func; do
933     paths__=`ls /Applications/*.app /Applications/Utilities/*.app 2>/dev/null | grep :$`
934   TryEnd1_func; done ;TryEnd2_func $?
935   if [ "$g_ExitStatus" != "0" ]; then
936     unset  $out_FoundCommands
937     unset  $out_FoundCommands  #// 配列をクリアするには2回必要?
938     ErrClass.clear_method
939     return  0
940   fi
941   ArrayClass.fromLines_method  paths__  "$paths__"  #//[out] paths__
942
943   i__=0
944   for path__  in "${paths__[@]}" ;do
945     file_name__=`basename "$path__"`
946     LeftOfLastStr_func  "$file_name__"  ".app:" ; apps__[$i__]="$g_Ret"
947     i__=$(( $i__ + 1 ))
948   done ; done_func $?
949
950   if [ "${#Applications[@]}" == "0" ];then
951     for (( i__ = 0; i__ < ${#apps__[@]}; i__ ++ )) ;do
952       apps__[$i__]="open -a \"$apps__[$i__]\" "
953     done ; done_func $?
954     SetOutputAsArray_func  $out_FoundCommands  "${apps__[@]}"
955     return  0
956   fi
957
958   #// pick up applications
959   i__=0
960   for command__  in "${Applications[@]}" ;do
961     for app__  in "${apps__[@]}" ;do
962       if [ "$command__" == "$app__" ];then
963         commands__[$i__]="open -a \"$app__\" "
964         i__=$(( $i__ + 1 ))
965         break
966       fi
967     done ; done_func $?
968   done ; done_func $?
969   if [ "$i__" == "0" ];then  ArrayClass.clear_method  commands__  ;fi  #// because local sets ${#commands__[@]}=1
970   SetOutputAsArray_func  $out_FoundCommands  "${commands__[@]}"
971 }
972
973
974  
975 #//*********************************************************************
976 #// <<< [IsMac_func] >>> 
977 #//*********************************************************************
978 function  IsMac_func()
979 {
980   SystemClass.getProperty_method  "os.name"
981   StringClass.indexOf_method  "$g_Ret"  "Mac OS X"
982   if [ "$g_Ret" == "-1" ];then
983     g_Ret=0
984   else
985     g_Ret=1
986   fi
987 }
988
989
990  
991 #//*********************************************************************
992 #// <<< [SystemClass.getProperty_method] >>> 
993 #//*********************************************************************
994 function  SystemClass.getProperty_method()
995 {
996   local  PropertyName="$1"
997
998   if [ "$PropertyName" == "os.name" ];then
999     if [ -e "/Applications/App Store.app" ];then
1000       g_Ret="Mac OS X ..."
1001     else
1002       g_Ret="Linux ..."
1003     fi
1004   else
1005     Error_func
1006   fi
1007 }
1008
1009
1010  
1011 #//*********************************************************************
1012 #// <<< [IsInstalled_func] >>>
1013 #//*********************************************************************
1014 function  IsInstalled_func()
1015 {
1016   local  PackageSymbol="$1"
1017
1018   local  status=0
1019   dpkg -l "$PackageSymbol" | grep ^ii\ *"$PackageSymbol" > /dev/null|| status=$?
1020   if [ "$status" == "0" ];then
1021     g_Ret=1
1022   else
1023     g_Ret=0
1024   fi
1025 }
1026
1027
1028  
1029 #//*********************************************************************
1030 #// <<< [AppKeyClass.enableInstall_method] >>>
1031 #//*********************************************************************
1032 function  AppKeyClass.enableInstall_method()
1033 {
1034   local  AppKey="$1"
1035
1036   if [ "$AppKey" != "AppKey4293" ]; then  Error_func  "AppKeyClass.enableInstall_method needs \$2 of Main_func"  ;fi
1037
1038   g_IsEnableInstall3192="1310"
1039 }
1040
1041
1042  
1043 #//*********************************************************************
1044 #// <<< [InstallIfNot_func] >>>
1045 #//*********************************************************************
1046 g_IsEnableInstall3192="0"
1047
1048 function  InstallIfNot_func()
1049 {
1050   local  PackageSymbol="$1"
1051
1052   IsInstalled_func  "$PackageSymbol"
1053   if [ "$g_Ret" == "0" ];then
1054     if [ "$g_IsEnableInstall3192" != "1310" ];then  #// チェックのみ
1055       Error_func  "apt-get が許可されていません。参照:AppKeyClass.enableInstall_method"
1056     else
1057       echo  "apt-get install  \"$PackageSymbol\""
1058       $g_TemporarySudo  apt-get install  "$PackageSymbol" <<HereDocument
1059 y
1060 HereDocument
1061     fi
1062   fi
1063 }
1064
1065
1066  
1067 #//*********************************************************************
1068 #// <<< [Uninstall_func] >>>
1069 #//*********************************************************************
1070 function  Uninstall_func()
1071 {
1072   local  PackageSymbol="$1"
1073
1074   if [ "$g_IsEnableInstall3192" != "1310" ];then  #// チェックのみのときは、IsInstalled_func
1075     Error_func  "apt-get が許可されていません。参照:AppKeyClass.enableInstall_method"
1076   fi
1077
1078   IsInstalled_func  "$PackageSymbol"
1079   if [ "$g_Ret" == "1" ];then
1080     echo  "apt-get remove  \"$PackageSymbol\""
1081     $g_TemporarySudo  apt-get remove  "$PackageSymbol" <<HereDocument
1082 y
1083 HereDocument
1084   fi
1085 }
1086
1087
1088  
1089 #//*********************************************************************
1090 #// <<< [GetLongOptions_func] >>> 
1091 #//*********************************************************************
1092 function  GetLongOptions_func()
1093 {
1094   local  out_Arguments="$1"
1095   local  out_OptAssocArray="$2"
1096   shift  2
1097   local  Args__=("$@")
1098   local  param__
1099   local  name__
1100   local  value__
1101   local  ArgIndex__=0
1102
1103   local  locals="out_Arguments  out_OptAssocArray  Args__  param__  name__  value__  locals"
1104   CheckOutParamIsConflictToLocal_func  "$out_Arguments"      $locals
1105   CheckOutParamIsConflictToLocal_func  "$out_OptAssocArray"  $locals
1106
1107   AssociativeArrayClass.clear_method  $out_OptAssocArray
1108
1109   for param__  in "${Args__[@]}" ;do
1110     StringClass.substring_method  "$param__"  0  2
1111     if [ "$g_Ret" == "--" ];then
1112       LeftOfStr_func  "$param__"  "=" ; name__="$g_Ret"
1113       if [ "$name__" == "$param__" ];then
1114         value__="1"
1115       else
1116         RightOfStr_func  "$param__"  "=" ; value__="$g_Ret"
1117       fi
1118       StringClass.substring_method  "$name__"  2 ; name__="$g_Ret"
1119
1120       SetAttr_func  $out_OptAssocArray  $name__  "$value__"
1121     else
1122       SetArrItem_func  $out_Arguments  $ArgIndex__  "$param__"
1123       ArgIndex__=$(( $ArgIndex__ + 1 ))
1124     fi
1125   done ; done_func $?
1126 }
1127
1128
1129  
1130 #//*********************************************************************
1131 #// <<< [Attr_func] >>> 
1132 #//*********************************************************************
1133 function  Attr_func()
1134 {
1135   local  self="$1"
1136   local  AttrName="$2"
1137   local  tmp
1138   CheckArgCount_func  2 "$@"
1139
1140   eval  tmp="\${${self}[\$AttrName]}"
1141   g_Ret="$tmp"
1142 }
1143
1144
1145  
1146 #//*********************************************************************
1147 #// <<< [SetArrItem_func] >>> 
1148 #//*********************************************************************
1149 function  SetArrItem_func()
1150 {
1151   local  self__="$1"
1152   local  Index__="$2"
1153   local  Value__="$3"
1154   CheckArgCount_func  3 "$@"
1155
1156   eval  "$self__[$Index__]=\"$Value__\""
1157 }
1158
1159
1160  
1161 #//*********************************************************************
1162 #// <<< [SetAttr_func] >>> 
1163 #//*********************************************************************
1164 function  SetAttr_func()
1165 {
1166   SetArrItem_func  "$@"
1167 }
1168
1169
1170  
1171 #//*********************************************************************
1172 #// <<< [SetAttr_as_ArrayName_func] >>> 
1173 #//*********************************************************************
1174 function  SetAttr_as_ArrayName_func()
1175 {
1176   local  self__="$1"
1177   local  AttrName__="$2"
1178   local  i__
1179   local  Params__
1180   CheckOutParamIsConflictToLocal_func  "$self__"  self__  AttrName__  i__  Params__
1181
1182   shift  2
1183   Params__=("$@")
1184
1185   SetAttr_func  $self__  "$AttrName__"  "g_Arrays_$g_ArrayLength"
1186
1187   for (( i__ = 0; i__ < ${#Params__[@]}; i__ ++ ));do
1188     eval  "g_Arrays_$g_ArrayLength"'[$i__]'='${Params__[$i__]}'
1189   done ; done_func $?
1190
1191   g_ArrayLength=$(( $g_ArrayLength + 1 ))
1192 }
1193
1194
1195  
1196 #//*********************************************************************
1197 #// <<< [SetAttr_as_AssociativeArrayName_func] >>> 
1198 #//*********************************************************************
1199 function  SetAttr_as_AssociativeArrayName_func()
1200 {
1201   local  self__="$1"
1202   local  AttrName__="$2"
1203   local  i__
1204   local  Params__
1205   local  key__
1206   local  value__
1207   CheckOutParamIsConflictToLocal_func  "$self__"  self__  AttrName__  i__  Params__  key__  value__
1208
1209   shift  2
1210   Params__=("$@")
1211
1212   SetAttr_func  $self__  "$AttrName__"  "g_AssociativeArrays_$g_AssociativeArrayLength"
1213
1214   for (( i__ = 0; i__ < ${#Params__[@]}; i__ = i__ + 2 ));do
1215     key__=${Params__[$i__]}
1216     value__=${Params__[$i__+1]}
1217
1218     SetAttr_func  g_AssociativeArrays_$g_AssociativeArrayLength  $key__  "$value__"
1219   done ; done_func $?
1220
1221   g_AssociativeArrayLength=$(( $g_AssociativeArrayLength + 1 ))
1222 }
1223
1224
1225  
1226 #//*********************************************************************
1227 #// <<< [AssociativeArrayClass.getLength_method] >>> 
1228 #//*********************************************************************
1229 function  AssociativeArrayClass.getLength_method()
1230 {
1231   local  self="$1"
1232   if [ "$self" == "" ];then  Error_func  "no object name"  ;fi
1233
1234   eval  g_Ret='${#'"$self"'[@]}'
1235 }
1236
1237
1238  
1239 #//*********************************************************************
1240 #// <<< [AssociativeArrayClass.getKeys_method] >>> 
1241 #//*********************************************************************
1242 function  AssociativeArrayClass.getKeys_method()
1243 {
1244   local  self="$1"
1245   if [ "$self" == "" ];then  Error_func  "no object name"  ;fi
1246
1247   eval  g_Ret='${!'"$self"'[@]}'
1248 }
1249
1250
1251  
1252 #//*********************************************************************
1253 #// <<< [AssociativeArrayClass.getItems_method] >>> 
1254 #//*********************************************************************
1255 function  AssociativeArrayClass.getItems_method()
1256 {
1257   local  self="$1"
1258   if [ "$self" == "" ];then  Error_func  "no object name"  ;fi
1259
1260   eval  g_Ret='${'"$self"'[@]}'
1261 }
1262
1263
1264  
1265 #//*********************************************************************
1266 #// <<< [AssociativeArrayClass.clear_method] >>> 
1267 #//*********************************************************************
1268 function  AssociativeArrayClass.clear_method()
1269 {
1270   local  self__="$1"
1271   local  keys__
1272   local  key__
1273   local  locals__="self__ key__ keys__  locals"
1274   CheckOutParamIsConflictToLocal_func  "$self__"   $locals__
1275
1276   eval  keys__='${!'"$self__"'[@]}'
1277   for key__  in "${keys__[@]}" ;do
1278     if [ "$key__" != "" ];then
1279       unset  "$self__[$key__]"
1280     fi
1281   done ; done_func $?
1282 }
1283
1284
1285  
1286 #//*********************************************************************
1287 #// <<< [AssociativeArrayClass.destroy_method] >>> 
1288 #//*********************************************************************
1289 function  AssociativeArrayClass.destroy_method()
1290 {
1291   local  self="$1"
1292
1293   unset  $self
1294   unset  $self
1295 }
1296
1297
1298  
1299 #//*********************************************************************
1300 #// <<< [CopyArray_func] >>> 
1301 #//*********************************************************************
1302 function  CopyArray_func()
1303 {
1304   local  DstArray__="$1"
1305   local  SrcArray__="$2"
1306   local  key__
1307   local  keys__
1308   local  code__
1309   local  value__
1310   local  locals__="DstArray__ SrcArray__ key__ keys__ code__ value__  locals"
1311   CheckOutParamIsConflictToLocal_func  "$DstArray__"   $locals__
1312   CheckOutParamIsConflictToLocal_func  "$SrcArray__"   $locals__
1313
1314   code__="$DstArray__=("
1315   eval  keys__=( '"${!'"$SrcArray__"'[@]}"' )
1316   for key__  in "${keys__[@]}" ;do
1317     eval  value__='${'$SrcArray__'[$key__]}'
1318     code__="$code__ [\"$key__\"]=\"$value__\""
1319   done ; done_func $?
1320   eval  "$code__ )"
1321 }
1322
1323
1324  
1325 #//*********************************************************************
1326 #// <<< [CopyArrayAttr_func] >>> 
1327 #//*********************************************************************
1328 function  CopyArrayAttr_func()
1329 {
1330   local  self__="$1"
1331   local  AttrName__="$2"
1332   local  out_Array="$3"
1333   local  array_name__
1334   local  i__
1335   local  n__
1336   local  locals="self__  AttrName__  out_Array__  array_name__  i__  n__  locals"
1337   CheckOutParamIsConflictToLocal_func  "$self__"     $locals
1338   CheckOutParamIsConflictToLocal_func  "$out_Array"  $locals
1339
1340   Attr_func  $self__  "$AttrName__" ; array_name__="$g_Ret"
1341   unset  $out_Array
1342   unset  $out_Array  #// 配列をクリアするには2回必要?
1343
1344   eval  n__='${#'"$array_name__"'[@]}'
1345
1346   for (( i__ = 0; $i__ < $n__; i__ ++ ));do
1347     eval  "$out_Array"'[$i__]=${'"$array_name__"'[$i__]}'
1348   done ; done_func $?
1349 }
1350
1351
1352  
1353 #//*********************************************************************
1354 #// <<< [SetOutput_func] >>> 
1355 #//*********************************************************************
1356 function  SetOutput_func()
1357 {
1358   local  out_Var="$1"
1359   local  Value__="$2"
1360   CheckArgCount_func  2 "$@"
1361   CheckOutParamIsConflictToLocal_func  "$out_Var"  out_Var  Value__
1362
1363   eval  $out_Var="'$Value__'"
1364 }
1365
1366
1367  
1368 #//*********************************************************************
1369 #// <<< [SetOutputAsArray_func] >>> 
1370 #//*********************************************************************
1371 function  SetOutputAsArray_func()
1372 {
1373   local  out_Var="$1"
1374   CheckMinArgCount_func  1 "$@"
1375   CheckOutParamIsConflictToLocal_func  "$out_Var"  out_Var
1376
1377   shift  1
1378   eval  $out_Var="(" '"$@"' ")"
1379 }
1380
1381
1382  
1383 #//*********************************************************************
1384 #// <<< [AddIfNotExist_func] >>> 
1385 #//*********************************************************************
1386 function  AddIfNotExist_func()
1387 {
1388   local  WholeStr="$1"
1389   local  AddStr="$2"
1390   local  Separator="$3"
1391   CheckArgCount_func  3 "$@"
1392
1393   local  whole_str_plus="$WholeStr$Separator"
1394   local  str
1395
1396   if [ "$AddStr" == "" ];then  echo  "$WholeStr"  ;  return  0  ;fi
1397
1398   LeftOfStr_func  "$whole_str_plus"  "$AddStr$Separator" ; str="$g_Ret"
1399   if [ "$str" == "$whole_str_plus" ];then  #// not found
1400     g_Ret="$AddStr$Separator$WholeStr"
1401   else
1402     g_Ret="$WholeStr"
1403   fi
1404 }
1405
1406
1407  
1408 #//*********************************************************************
1409 #// <<< [IsNumeric_func] >>> 
1410 #//*********************************************************************
1411 function  IsNumeric_func()
1412 {
1413   local  Value="$1"
1414   CheckArgCount_func  1 "$@"
1415   if [ "$Value" == "-1" ];then
1416     g_Ret="1"
1417   else
1418     local  status=0
1419     expr  $Value + 1 > /dev/null  2>&1 || status=$?
1420     if [ "$status" == "0" ];then
1421       g_Ret="1"
1422     else
1423       g_Ret="0"
1424     fi
1425   fi
1426 }
1427
1428
1429  
1430 #//*********************************************************************
1431 #// <<< [StringClass.length_method] >>> 
1432 #//*********************************************************************
1433 function  StringClass.length_method()
1434 {
1435   local  self="$1"
1436   CheckArgCount_func  1 "$@"
1437   g_Ret="${#self}"
1438 }
1439
1440
1441  
1442 #//*********************************************************************
1443 #// <<< [StringClass.substring_method] >>> 
1444 #//*********************************************************************
1445 function  StringClass.substring_method()
1446 {
1447   local  self="$1"
1448   local  StartIndex="$2"
1449   local  EndIndex="$3"
1450   CheckMinArgCount_func  2 "$@"
1451   CheckMaxArgCount_func  3 "$@"
1452
1453   if [ "$EndIndex" == "" ];then
1454     g_Ret="${self:$StartIndex}"
1455   else
1456     g_Ret="${self:$StartIndex:$(( $EndIndex - $StartIndex ))}"
1457   fi
1458 }
1459
1460
1461  
1462 #//*********************************************************************
1463 #// <<< [StringClass.trim_method] >>> 
1464 #//*********************************************************************
1465 function  StringClass.trim_method()
1466 {
1467   local  String="$1"
1468   local  field
1469   local  key
1470   local  index
1471   local  ch
1472
1473   index=0
1474   while true ;do
1475     ch="${String:$index:1}"
1476     if [ "$ch" != " "  ];then
1477       if [ "$ch" != "$Tab" ];then
1478         if [ "$ch" != "$LF" ];then
1479           break
1480         fi
1481       fi
1482     fi
1483     index=$(( $index + 1 ))
1484   done ; done_func $?
1485
1486   String="${String:$index}"
1487
1488   index=$(( ${#String} - 1 ))
1489   while true ;do
1490     ch="${String:$index:1}"
1491     if [ "$ch" != " " ];then
1492       if [ "$ch" != "$Tab" ];then
1493         if [ "$ch" != "$LF" ];then
1494           break
1495         fi
1496       fi
1497     fi
1498     index=$(( $index - 1 ))
1499   done ; done_func $?
1500   index=$(( $index + 1 ))
1501
1502   g_Ret="${String:0:$index}"
1503 }
1504
1505
1506  
1507 #//*********************************************************************
1508 #// <<< [StringClass.right_method] >>> 
1509 #//*********************************************************************
1510 function  StringClass.right_method()
1511 {
1512   local  String="$1"
1513   local  Length="$2"
1514   CheckArgCount_func  2 "$@"
1515
1516   g_Ret="${String:$(( ${#String} - $Length ))}"
1517 }
1518
1519
1520  
1521 #//*********************************************************************
1522 #// <<< [StringClass.cutLastOf_method] >>> 
1523 #//*********************************************************************
1524 function  StringClass.cutLastOf_method()
1525 {
1526   local  String="$1"
1527   local  LastStr="$2"
1528   CheckArgCount_func  2 "$@"
1529
1530   if [ "${String:$(( ${#String} - ${#LastStr} ))}" == "$LastStr" ];then
1531     g_Ret="${String:0:$(( ${#String} - ${#LastStr} ))}"
1532   else
1533     g_Ret="$String"
1534   fi
1535 }
1536
1537
1538  
1539 #//*********************************************************************
1540 #// <<< [LeftOfStr_func] >>> 
1541 #//*********************************************************************
1542 function  LeftOfStr_func()
1543 {
1544   local  String="$1"
1545   local  Key="$2"
1546   CheckArgCount_func  2 "$@"
1547
1548   StringClass.replace_method  "$Key"    '\'  '\\'
1549   StringClass.replace_method  "$g_Ret"  '*'  '\*'
1550
1551   g_Ret="${String%%$g_Ret*}"
1552 }
1553
1554
1555  
1556 #//*********************************************************************
1557 #// <<< [LeftOfLastStr_func] >>> 
1558 #//*********************************************************************
1559 function  LeftOfLastStr_func()
1560 {
1561   local  String="$1"
1562   local  Key="$2"
1563   CheckArgCount_func  2 "$@"
1564
1565   StringClass.replace_method  "$Key"    '\'  '\\'
1566   StringClass.replace_method  "$g_Ret"  '*'  '\*'
1567
1568   g_Ret="${String%$g_Ret*}"
1569 }
1570
1571
1572  
1573 #//*********************************************************************
1574 #// <<< [RightOfStr_func] >>> 
1575 #//*********************************************************************
1576 function  RightOfStr_func()
1577 {
1578   local  String="$1"
1579   local  Key="$2"
1580   CheckArgCount_func  2 "$@"
1581
1582   StringClass.replace_method  "$Key"    '\'  '\\'
1583   StringClass.replace_method  "$g_Ret"  '*'  '\*'
1584
1585   g_Ret="${String#*$g_Ret*}"
1586 }
1587
1588
1589  
1590 #//*********************************************************************
1591 #// <<< [RightOfLastStr_func] >>> 
1592 #//*********************************************************************
1593 function  RightOfLastStr_func()
1594 {
1595   local  String="$1"
1596   local  Key="$2"
1597   CheckArgCount_func  2 "$@"
1598
1599   StringClass.replace_method  "$Key"    '\'  '\\'
1600   StringClass.replace_method  "$g_Ret"  '*'  '\*'
1601
1602   g_Ret="${String##*$g_Ret}"
1603 }
1604
1605
1606  
1607 #//*********************************************************************
1608 #// <<< [StringClass.indexOf_method] >>> 
1609 #//*********************************************************************
1610 function  StringClass.indexOf_method()
1611 {
1612   local  self="$1"
1613   local  Keyword="$2"
1614   local  StartIndex="$3"
1615   CheckMinArgCount_func  2 "$@"
1616   CheckMaxArgCount_func  3 "$@"
1617
1618   if [ "$StartIndex" == "" ];then  StartIndex=0  ;fi
1619   if [ "$StartIndex" -le "0" ];then  #// -le:"<="
1620     part="${self%%$Keyword*}"
1621     if [ "$part" == "$self" ];then
1622       g_Ret=-1
1623     else
1624       g_Ret=$(( ${#part} ))
1625     fi
1626   else
1627     self="${self:$StartIndex}"
1628     part="${self%%$Keyword*}"
1629     if [ "$part" == "$self" ];then
1630       g_Ret=-1
1631     else
1632       g_Ret=$(( ${#part} + $StartIndex ))
1633     fi
1634   fi
1635 }
1636
1637
1638  
1639 #//*********************************************************************
1640 #// <<< [StringClass.lastIndexOf_method] >>> 
1641 #//*********************************************************************
1642 function  StringClass.lastIndexOf_method()
1643 {
1644   local  self="$1"
1645   local  Keyword="$2"
1646   local  StartIndex="$3"
1647   CheckMinArgCount_func  2 "$@"
1648   CheckMaxArgCount_func  3 "$@"
1649
1650   if [ "$StartIndex" == "" ];then  StartIndex=0  ;fi
1651   if [ "$StartIndex" -le "0" ];then  #// -le:"<="
1652     part="${self%$Keyword*}"
1653     if [ "$part" == "$self" ];then
1654       g_Ret=-1
1655     else
1656       g_Ret=$(( ${#part} ))
1657     fi
1658   else
1659     self="${self:0:$(( $StartIndex + ${#Keyword} ))}"
1660     part="${self%$Keyword*}"
1661     if [ "$part" == "$self" ];then
1662       g_Ret=-1
1663     else
1664       g_Ret=${#part}
1665     fi
1666   fi
1667 }
1668
1669
1670  
1671 #//*********************************************************************
1672 #// <<< [StringClass.replace_method] >>> 
1673 #//*********************************************************************
1674 function  StringClass.replace_method()
1675 {
1676   local  String="$1"
1677   local  From="$2"
1678   #// To="$3"
1679
1680   StringEscapeUtilsClass.escapeBashReplace_method  "$From"
1681   g_Ret="${String//$g_Ret/$3}"
1682 }
1683
1684
1685  
1686 #//*********************************************************************
1687 #// <<< [StringClass.toLowerCase_method] >>> 
1688 #//*********************************************************************
1689 function  StringClass.toLowerCase_method()
1690 {
1691   #// for bash 4
1692   #// local  self="$1"
1693   #// echo  "${self,,}"
1694
1695   #// for bash 3
1696   g_Ret=`echo  "$1" | sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
1697 }
1698
1699
1700  
1701 #//*********************************************************************
1702 #// <<< [StringClass.toUpperCase_method] >>> 
1703 #//*********************************************************************
1704 function  StringClass.toUpperCase_method()
1705 {
1706   #// for bash 4
1707   #// local  self="$1"
1708   #// echo  "${self^^}"
1709
1710   #// for bash 3
1711   g_Ret=`echo  "$1" | sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
1712 }
1713
1714
1715  
1716 #//*********************************************************************
1717 #// <<< [StringEscapeUtilsClass.escapeGrep_method] >>> 
1718 #//*********************************************************************
1719 function  StringEscapeUtilsClass.escapeGrep_method()
1720 {
1721   local  Str="$1"
1722     Str="${Str//\\/\\\\}"
1723     Str="${Str//-/\-}"
1724     Str="${Str//./\.}"
1725     Str="${Str//$/\\$}"
1726     Str="${Str//^/\^}"
1727     Str="${Str//{/\{}"
1728     Str="${Str//\}/\}}"
1729     Str="${Str//[/\[}"
1730     Str="${Str//]/\]}"
1731     Str="${Str//\*/\*}"
1732     Str="${Str//+/\+}"
1733   g_Ret="${Str//\?/\?}"
1734 }
1735
1736
1737  
1738 #//*********************************************************************
1739 #// <<< [StringEscapeUtilsClass.escapeSed_method] >>> 
1740 #//*********************************************************************
1741 function  StringEscapeUtilsClass.escapeSed_method()
1742 {
1743   local  Str="$1"
1744     Str="${Str//\\/\\\\}"
1745     Str="${Str//./\.}"
1746     Str="${Str//$/\\$}"
1747     Str="${Str//^/\^}"
1748     Str="${Str//[/\[}"
1749     Str="${Str//]/\]}"
1750     Str="${Str//\*/\*}"
1751     Str="${Str//\?/\?}"
1752   g_Ret="${Str//\//\/}"
1753 }
1754
1755
1756  
1757 #//*********************************************************************
1758 #// <<< [StringEscapeUtilsClass.escapeBashReplace_method] >>> 
1759 #//*********************************************************************
1760 function  StringEscapeUtilsClass.escapeBashReplace_method()
1761 {
1762   local  Str="$1"
1763     Str="${Str//\\/\\\\}"
1764     Str="${Str//\}/\}}"
1765     Str="${Str//\(/\\(}"
1766     Str="${Str//\)/\\)}"
1767     Str="${Str//\*/\\*}"
1768     Str="${Str//\?/\\?}"
1769   g_Ret="${Str//\//\\/}"
1770 }
1771
1772
1773  
1774 #//*********************************************************************
1775 #// <<< [StringEscapeUtilsClass.escapeBashDoubleQuot_method] >>> 
1776 #//*********************************************************************
1777 function  StringEscapeUtilsClass.escapeBashDoubleQuot_method()
1778 {
1779   local  Str="$1"
1780     Str="${Str//\\/\\\\}"
1781     Str="${Str//$/\\$}"
1782   g_Ret="${Str//\//\\/}"
1783 }
1784
1785
1786  
1787 #//*********************************************************************
1788 #// <<< [StringEscapeUtilsClass.escapeBashParam_method] >>> 
1789 #//*********************************************************************
1790 function  StringEscapeUtilsClass.escapeBashParam_method()
1791 {
1792   local  Str="$1"
1793     Str="${Str//\\/\\\\}"
1794     Str="${Str// /\\ }"
1795   g_Ret="${Str//$/\\$}"
1796 }
1797
1798
1799  
1800 #//*********************************************************************
1801 #// <<< [ReplaceTextFile_func] >>> 
1802 #//*********************************************************************
1803 function  ReplaceTextFile_func()
1804 {
1805   local  Path="$1"
1806   local  From="$2"
1807   local  To="$3"
1808   local  Opt="$4"
1809
1810   CheckMinArgCount_func  2 "$@"
1811   CheckMaxArgCount_func  4 "$@"
1812
1813   local  str1
1814   local  str2
1815   local  slash
1816   local  slashes=( "%" "/" )
1817
1818   CheckWritable_func  "$Path"
1819
1820   if [ "$Opt" == "-i" ];then  Opt="i"  ;fi
1821
1822   sed_setIsAbleToNotCaseSensitive_func
1823   if [ "$g_sed_isAbleToNotCaseSensitive" == "0" ];then
1824     StringClass.indexOf_method  "$Opt"  "i"
1825     if [ "$g_Ret" -ge 0 ];then
1826       Error_func  "-i オプションは指定できません。"
1827     fi
1828   fi
1829
1830   for  slash  in  ${slashes[@]};do
1831
1832     LeftOfStr_func  "$From"  "$slash" ; str1="$g_Ret"
1833     LeftOfStr_func  "$To"    "$slash" ; str2="$g_Ret"
1834     if [ x"$str1" == x"$From"  -a  x"$str2" == x"$To" ];then  #// $From and $To do not have $slash.
1835
1836       RightOfStr_func  "$From"  "\n" ; str1="$g_Ret"
1837       RightOfStr_func  "$To"    "\n" ; str2="$g_Ret"
1838       if [ x"$str1" == x"$From"  -a  x"$str2" == x"$To" ];then  #// $str1 and $str2 are single line,
1839         sed -i.bak -e "s$slash$From$slash$To${slash}g$Opt"  "$Path" ;  rm "$Path.bak"
1840       else
1841         RightOfStr_func  "$str1"  "\n" ; str2="$g_Ret"
1842         if [ "$str1" != "$str2" ];then
1843           Error_func  "置き換える前の文字列は3行以上にできません。"
1844         fi
1845
1846         #// for GNU sed
1847         #// sed -i.bak -e '/\n/! {;$q;N;};'"s$slash$From$slash$To${slash}g$Opt;P;D;"  "$Path" ;  rm "$Path.bak"
1848
1849         #// for BSD sed in Mac OS X Snow Leopard
1850         To=`echo "$To" | sed  -e 's/\\\\n/\\\\\\'"$LF"'/g' `
1851         cp  "$Path"  "$Path.bak"  #// mv では、chmod 属性が消えてしまいます
1852         sed -e '/\n/! {;$q;N;};'"s$slash$From$slash$To${slash}g$Opt;P;D;"  "$Path.bak" > $Path
1853         rm  "$Path.bak"
1854       fi
1855       return
1856     fi
1857   done ; done_func $?
1858
1859   Error_func  "ReplaceTextFile_func は、置き換える前後の文字列に / と % の両方を含むことはできません"
1860 }
1861
1862
1863  
1864 #//*********************************************************************
1865 #// <<< [sed_setIsAbleToNotCaseSensitive_func] >>> 
1866 #//*********************************************************************
1867 g_sed_isAbleToNotCaseSensitive=""
1868 function  sed_setIsAbleToNotCaseSensitive_func()
1869 {
1870   if [ "$g_sed_isAbleToNotCaseSensitive" == "" ];then
1871     local  status=0
1872     echo -n "" | sed -e s/a/b/i > /dev/null  2>&1  || status=$?
1873     g_sed_isAbleToNotCaseSensitive=$(( 1 - $status ))
1874   fi
1875 }
1876
1877
1878  
1879 #//*********************************************************************
1880 #// <<< [ReplaceTextFileLineRange_func] >>> 
1881 #//*********************************************************************
1882 function  ReplaceTextFileLineRange_func()
1883 {
1884   local  Path="$1"
1885   local  From="$2"
1886   local  FromEnd="$3"
1887   local  To="$4"
1888   local  Opt="$5"
1889   local  str
1890   local  a1
1891
1892   CheckMinArgCount_func  3 "$@"
1893   CheckMaxArgCount_func  5 "$@"
1894
1895   CheckWritable_func  "$Path"
1896
1897   if [ "$Opt" == "-i" ];then  Opt="i"  ;fi
1898
1899   sed_setIsAbleToNotCaseSensitive_func
1900   if [ "$g_sed_isAbleToNotCaseSensitive" == "0" ];then
1901     StringClass.indexOf_method  "$Opt"  "i"
1902     if [ "$g_Ret" -ge 0 ];then
1903       Error_func  "i オプションは指定できません。"
1904     fi
1905   fi
1906
1907   LeftOfStr_func  "$From"  "%"
1908   if [ "$g_Ret" != "$From" ];then  Error_func  ;fi
1909
1910   LeftOfStr_func  "$FromEnd"  "%"
1911   if [ "$g_Ret" != "$FromEnd" ];then  Error_func  ;fi
1912
1913   Opt=`StringClass.toUpperCase_method  "$Opt"`
1914
1915   if [ "$To" != "" ];then
1916     #// for GNU sed
1917     #// To="c${To//\\n/\\${LF}}"
1918
1919     #// for BSD sed in Mac OS X Snow Leopard
1920     if [ "$To" == "\n" ];then
1921       a1=`echo  $'a\nb\nc' | sed -e '/b/c\'"${LF}" `
1922       if [ "$a1" == "a${LF}${LF}c" ];then
1923         To=""
1924       fi
1925     fi
1926
1927     To="c\\${LF}${To//\\n/\\${LF}}"
1928   else
1929     To="d"
1930   fi
1931
1932   #// for GNU sed
1933   #// if [ "$FromEnd" == "" ];then
1934   #//   sed -i.bak -e '\%'"$From"'%'"$Opt$To"  "$Path" ;  rm "$Path.bak"
1935   #// else
1936   #//   sed -i.bak -e '\%'"$From"'%'"$Opt"',\%'"$FromEnd"'%'"$Opt$To"  "$Path" ;  rm "$Path.bak"
1937   #// fi
1938
1939   #// for BSD sed in Mac OS X Snow Leopard
1940   cp  "$Path"  "$Path.bak"  #// mv では、chmod 属性が消えてしまいます
1941   if [ "$FromEnd" == "" ];then
1942     sed -e '\%'"$From"'%'"$Opt$To"  "$Path.bak" > $Path
1943   else
1944     sed -e '\%'"$From"'%'"$Opt"',\%'"$FromEnd"'%'"$Opt$To"  "$Path.bak" > $Path
1945   fi
1946   rm  "$Path.bak"
1947 }
1948
1949
1950  
1951 #//*********************************************************************
1952 #// <<< [MultiLine_func] >>> 
1953 #//*********************************************************************
1954 function  MultiLine_func()
1955 {
1956   local  LineFeedChar="$1"
1957   shift  1
1958
1959   local  Params=( "$@" )
1960   local  line
1961   local  lfs
1962
1963   g_Ret=""
1964   for line  in "$@" ;do
1965     if [ "$line" == "" ];then
1966       lfs="$lfs$LineFeedChar"
1967     else
1968       g_Ret="$g_Ret$lfs$line"
1969       lfs="$LineFeedChar"
1970     fi
1971   done ; done_func $?
1972 }
1973
1974
1975  
1976 #//*********************************************************************
1977 #// <<< [ArrayClass.getLength_method] >>>
1978 #//*********************************************************************
1979 function  ArrayClass.getLength_method()
1980 {
1981   local  self="$1"
1982
1983   eval  g_Ret='${#'"$self"'[@]}'
1984 }
1985
1986
1987  
1988 #//*********************************************************************
1989 #// <<< [ArrayClass.get_method] >>>
1990 #//*********************************************************************
1991 function  ArrayClass.get_method()
1992 {
1993   local  self="$1"
1994   local  Index="$2"
1995   local  over_index
1996   CheckArgCount_func  2 "$@"
1997
1998   eval  over_index='${#'"$self"'[@]}'
1999   if [ "$Index" -ge "$over_index"  -o  "$Index" -lt "0" ];then
2000     Error_func  "<ERROR msg=\"インデックスが範囲外です\" index=\"$Index\"/>"
2001   fi
2002
2003   eval  g_Ret='"${'"$self"'[$Index]}"'
2004 }
2005
2006
2007  
2008 #//*********************************************************************
2009 #// <<< [ArrayClass.set_method] >>>
2010 #//*********************************************************************
2011 function  ArrayClass.set_method()
2012 {
2013   local  self="$1"
2014   local  Index="$2"
2015   local  Value="$3"
2016   local  over_index
2017   local  num
2018   CheckArgCount_func  3 "$@"
2019
2020   eval  over_index='${#'"$self"'[@]}'
2021   if [ "$Index" -lt "0" ];then
2022     Error_func  "<ERROR msg=\"インデックスが範囲外です\" index=\"$Index\"/>"
2023   fi
2024
2025   for (( num = over_index;  $num < $Index;  num++ )) ;do
2026     eval  "$self"'[$num]=""'
2027   done ; done_func $?
2028
2029   eval  "$self"'[$Index]='"'$Value'"
2030 }
2031
2032
2033  
2034 #//*********************************************************************
2035 #// <<< [ArrayClass.remove_method] >>>
2036 #//*********************************************************************
2037 function  ArrayClass.remove_method()
2038 {
2039   local  self="$1"
2040   local  Index="$2"
2041   local  num
2042   local  over_index
2043   local  last_index
2044   CheckArgCount_func  2 "$@"
2045
2046   eval  over_index='${#'"$self"'[@]}'
2047   if [ "$Index" -ge "$over_index"  -o  "$Index" -lt "0" ];then
2048     Error_func  "<ERROR msg=\"インデックスが範囲外です\" index=\"$Index\"/>"
2049   fi
2050
2051   last_index=$(( $over_index - 1 ))
2052   for (( num = $Index;  $num < $last_index;  num++ )) ;do
2053     eval  "$self"'[$num]="${'"$self"'[$(( $num + 1 ))]}"'
2054   done ; done_func $?
2055
2056   eval  unset "$self"'[$last_index]'
2057 }
2058
2059
2060  
2061 #//*********************************************************************
2062 #// <<< [ArrayClass.clear_method] >>> 
2063 #//*********************************************************************
2064 function  ArrayClass.clear_method()
2065 {
2066   local  self="$1"
2067
2068   unset $self
2069   unset $self  #// 配列をクリアするには2回必要?
2070 }
2071
2072
2073  
2074 #//*********************************************************************
2075 #// <<< [ArrayClass.fromLines_method] >>> 
2076 #//*********************************************************************
2077 function  ArrayClass.fromLines_method()
2078 {
2079   local  out_Array="$1"
2080   local  Lines="$2"
2081   local  line
2082   local  i
2083   local  keys
2084
2085   CheckOutParamIsConflictToLocal_func  $out_Array  out_Array  Lines  line  i  keys
2086
2087   unset  $out_Array
2088   unset  $out_Array  #// 配列をクリアするには2回必要?
2089
2090   i=0
2091   while true; do
2092     line="${Lines%%$LF*}"
2093     if [ "$line" != "" ];then  eval $out_Array[$i]="'$line'"  ;fi
2094     if [ "$line" == "$Lines" ];then  break  ;fi
2095     i=$(( $i + 1 ))
2096     Lines=${Lines:$(( ${#line} + 1 ))}  #// next line
2097   done ; done_func $?
2098 }
2099
2100
2101  
2102 #//*********************************************************************
2103 #// <<< [ArrayClass.fromCSV_method] >>> 
2104 #//*********************************************************************
2105 function  ArrayClass.fromCSV_method()
2106 {
2107   local  out_Array="$1"
2108   local  CSV__="$2"
2109   local  index__=0
2110   local  item__
2111   local  char__
2112   local  next__
2113   CheckArgCount_func  2 "$@"
2114
2115   CheckOutParamIsConflictToLocal_func  "$out_Array" \
2116     CSV__  out_Array  index__  item__  __field  char__  next__
2117
2118   unset  $out_Array
2119   unset  $out_Array  #// 配列をクリアするには2回必要?
2120
2121   while true; do
2122     item__=( $CSV__ )  #// ${item__[0]} does not have space
2123     StringClass.substring_method  ${item__[0]}  0  1 ; char__="$g_Ret"
2124     if [ "$char__" == "\"" ];then
2125       RightOfStr_func  "$CSV__"  "\"" ; CSV__="$g_Ret"
2126       LeftOfStr_func  "$CSV__"  "\"" ; item__="$g_Ret"
2127       RightOfStr_func  "$CSV__"  "\"" ; CSV__="$g_Ret"
2128     elif [ "$char__" == "" ];then
2129       break
2130     else
2131       LeftOfStr_func  "$CSV__"  "," ; item__="$g_Ret"
2132       StringClass.trim_method  "$item__" ; item__="$g_Ret"
2133     fi
2134     RightOfStr_func  "$CSV__"  "," ; next__="$g_Ret"
2135
2136     SetArrItem_func  $out_Array  $index__  "$item__"
2137     index__=$(( $index__ + 1 ))
2138
2139     if [ x"$next__" == x""  -o  x"$next__" == x"$CSV__" ];then  break  ;fi
2140     CSV__="$next__"
2141   done ; done_func $?
2142 }
2143
2144
2145  
2146 #//*********************************************************************
2147 #// <<< [IsSameArrayOutOfOrder_func] >>>
2148 #//*********************************************************************
2149 function  IsSameArrayOutOfOrder_func()
2150 {
2151   local  ArrayACount="$1"
2152   local  ArrayAB=("$@")
2153
2154   local  a_index
2155   local  b_index
2156   local  is_same_arr
2157
2158   IsNumeric_func  "$ArrayACount" ; if [ "$g_Ret" == "0" ];then  Error_func  ;fi
2159
2160   if [ ${#ArrayAB[@]} != $(( $ArrayACount * 2 + 1 )) ];then  g_Ret="0" ; return ;fi
2161
2162   for (( b_index = $ArrayACount + 1;  b_index < ${#ArrayAB[@]};  b_index ++ )) ;do
2163     for (( a_index = 1;  a_index <= $ArrayACount;  a_index ++ )) ;do
2164       if [ "${ArrayAB[$a_index]}" == "${ArrayAB[$b_index]}" ];then
2165         if [ "${is_same_arr[$a_index]}" == "" ];then
2166           is_same_arr[$a_index]=1
2167           break
2168         fi
2169       fi
2170     done ; done_func $?
2171   done ; done_func $?
2172
2173   for (( a_index=1;  a_index <= $ArrayACount;  a_index ++ )) ;do
2174     if [ "${is_same_arr[$a_index]}" == "" ];then
2175       g_Ret="0" ; return
2176     fi
2177   done ; done_func $?
2178   g_Ret="1"
2179 }
2180
2181
2182  
2183 #//*********************************************************************
2184 #// <<< [Extract_func] >>> 
2185 #//*********************************************************************
2186 function  Extract_func()
2187 {
2188   local  PackagePath="$1"
2189   local  DstFolder="$2"
2190   local  Option1="$3"
2191
2192   local  ext1
2193   local  ext2
2194   local  i
2195   local  extract_folder
2196   local  status
2197   local  trans_option_1
2198   local  trans_option_2
2199   local  dst_name
2200   local  arguments
2201   $declare_AssociativeArrayClass  option
2202
2203   echo  "$PackagePath -> $DstFolder  $Option1"
2204
2205   CheckWritable_func  "$DstFolder"
2206   dst_name=`basename "$DstFolder"`
2207
2208   RightOfLastStr_func  "$PackagePath"  "." ; ext2="$g_Ret"
2209   LeftOfLastStr_func   "$PackagePath"  "."
2210   RightOfLastStr_func  "$g_Ret"  "." ; ext1="$g_Ret"
2211
2212   #// --transform option
2213   GetLongOptions_func  arguments  option  "$@"  #//[out] arguments, option
2214   Attr_func  option  "transform_from" ; trans_option_1="$g_Ret"
2215
2216
2217   if [ "$trans_option_1" == "" ];then
2218
2219     #// set one_folder_path
2220     ListUpIn_func  "$PackagePath" > /tmp/_Extract_func.txt  #// tar write error, if pipe was used
2221     one_folder_path=`head -n 1 /tmp/_Extract_func.txt`
2222
2223     StringClass.substring_method  "$one_folder_path"  0  1
2224     if [ "$g_Ret" == "/" ];then
2225       one_folder_path=""
2226     else
2227       StringClass.substring_method  "$one_folder_path"  0  2
2228       if [ "$g_Ret" == "./" ];then
2229         StringClass.indexOf_method  "$one_folder_path"  "/"  2
2230       else
2231         StringClass.indexOf_method  "$one_folder_path"  "/"
2232       fi
2233       if [ "$g_Ret" == "-1" ];then
2234         one_folder_path=""
2235       else
2236         StringClass.substring_method  "$one_folder_path"  0  $g_Ret ; one_folder_path="$g_Ret"
2237       fi
2238     fi
2239
2240
2241     #// set one_folder_path="", if there was two folders
2242     if [ "$one_folder_path" != "" ];then
2243       status=0
2244       cat /tmp/_Extract_func.txt | grep -v "^$one_folder_path/" || status=$?
2245       CheckPipeStatus_func  "${PIPESTATUS[@]}"
2246       if [ "$status" == "0" ];then  #// found out of one_folder_path
2247         one_folder_path=""
2248       fi
2249     fi
2250     rm  /tmp/_Extract_func.txt
2251
2252
2253     #// set trans_option
2254     if [ "$one_folder_path" != "" ];then
2255       if [ "$ext2" == "zip" ];then
2256         trans_option_1="$one_folder_path"
2257       else
2258         GetExtractTransformOptionName_func  "$DstFolder"
2259         if [ "$g_Ret" == "--transform" ];then
2260           trans_option_1="--transform=s%^$one_folder_path%$dst_name%"
2261         else
2262           trans_option_1="-s"
2263           trans_option_2="%^$one_folder_path/%$dst_name/%"
2264         fi
2265       fi
2266     fi
2267
2268
2269     #// set extract_folder
2270     if [ "$one_folder_path" == "" ];then
2271       extract_folder="$DstFolder"
2272     else
2273       GetParentAbsPath_func  "$DstFolder" ; extract_folder="$g_Ret"
2274     fi
2275
2276   else
2277
2278     #// modify trans_option
2279     StringClass.right_method  "$trans_option_1"  1
2280     if [ "$g_Ret" == "/" ];then
2281       StringClass.length_method  "$trans_option_1"
2282       StringClass.substring_method  "$trans_option_1"  0  $(( $g_Ret - 1 ))
2283       trans_option_1="$g_Ret"
2284     fi
2285     dst_name=`basename  "$DstFolder"`
2286
2287     if [ "$ext2" != "zip" ];then
2288       GetExtractTransformOptionName_func  "$DstFolder"
2289       if [ "$g_Ret" == "--transform" ];then
2290         trans_option_1="--transform=s%^$trans_option_1%$dst_name%"
2291       else
2292         trans_option_2="%^$trans_option_1%$dst_name%"
2293         trans_option_1="-s"
2294       fi
2295     fi
2296     extract_folder=`dirname  "$DstFolder"`
2297   fi
2298
2299
2300   #// extract
2301   if [ x"$ext1" != x"tar"  -a  x"$ext2" == x"gz" ];then
2302     ExtractGZ_func  "$PackagePath"  "$extract_folder"
2303   elif [ "$ext2" == "zip" ];then
2304     ExtractZip_func  "$PackagePath"  "$DstFolder"  "$trans_option_1"
2305   else
2306     if [ ! -e "$extract_folder" ];then  mkdir -p  "$extract_folder"  ;fi
2307     if [ "$trans_option_1" == "" ];then
2308       echo  "tar xvf  \"$PackagePath\" -C \"$extract_folder\""
2309       tar xvf  "$PackagePath" -C "$extract_folder"
2310     else
2311       echo  "tar xvf  \"$PackagePath\" -C \"$extract_folder\"  \"$trans_option_1\"  \"$trans_option_2\""
2312       tar xvf  "$PackagePath" -C "$extract_folder"  "$trans_option_1"  "$trans_option_2"
2313     fi
2314   fi
2315
2316   AssociativeArrayClass.destroy_method  option
2317 }
2318
2319
2320 declare  g_ExtractTransformOptionName  #// "-s" or "--transform"
2321
2322 function  GetExtractTransformOptionName_func()
2323 {
2324   if [ "$g_ExtractTransformOptionName" == "" ];then
2325
2326     local  WorkDstFolder="$1"
2327     local  is_pushd
2328     local  status
2329     local  i
2330     local  a1
2331
2332     for (( i = 1; i < 100; i ++ ));do
2333       if [ "$i" == "99" ];then  Error_func  "$WorkDstFolder にフォルダーが作れません"  ;fi
2334       a1="$WorkDstFolder/_extract_trans_test_$i"
2335       if [ ! -e "$a1" ];then
2336         WorkDstFolder="$a1"
2337         break
2338       fi
2339     done ; done_func $?
2340
2341     while TryStart_func; do
2342
2343       mkdir -p  "$WorkDstFolder"
2344       pushd  "$WorkDstFolder" > /dev/null
2345       is_pushd=1
2346
2347       echo  "a" > a.txt
2348       tar cvjf  "a.tar.bz2"  "a.txt" > /dev/null
2349
2350       status=0
2351       tar xvf  "a.tar.bz2"  --transform="s%a.txt%b.txt%" > /dev/null 2>&1 || status=$?
2352
2353       if [ "$status" == "0"  -a  -e "b.txt" ];then
2354         g_ExtractTransformOptionName="--transform"
2355       else
2356         status=0
2357         tar xvf  "a.tar.bz2"  -s "%a.txt%b.txt%" > /dev/null 2>&1 || status=$?
2358
2359         if [ "$status" == "0"  -a  -e "b.txt" ];then
2360           g_ExtractTransformOptionName="-s"
2361         else
2362           Error_func
2363         fi
2364       fi
2365
2366     TryEnd1_func; done ;TryEnd2_func $?
2367       #// Finally
2368       if [ "$is_pushd" == "1" ];then  popd > /dev/null ;fi
2369       rm_func  "$WorkDstFolder"
2370     if [ "$g_ExitStatus" != "0" ]; then  ErrClass.raiseOverwrite_method  ;fi
2371   fi
2372   g_Ret="$g_ExtractTransformOptionName"
2373 }
2374
2375
2376  
2377 #//*********************************************************************
2378 #// <<< [ExtractGZ_func] >>> 
2379 #//*********************************************************************
2380 function  ExtractGZ_func()
2381 {
2382   local  GzPath="$1"
2383   local  ExtractedPath="$2"
2384   CheckArgCount_func  2 "$@"
2385
2386   if [ "$TMPDIR" == "" ]; then  temp_folder="$HOME"  ;else  temp_folder="$TMPDIR"  ;fi
2387
2388   if [ "$GzPath" == "${ExtractedPath}.gz" ]; then
2389     if [ -e "$temp_folder/_ExtractGZ_func.gz" -o -e "$temp_folder/_ExtractGZ_func" ]; then
2390       unset ERROR;${ERROR:?exist _ExtractGZ_func.gz is for temporary}  ;fi
2391
2392     cp -ap  "$GzPath"  "$temp_folder/_ExtractGZ_func.gz"
2393     echo  "gunzip  \"$temp_folder/_ExtractGZ_func.gz\""
2394     gunzip  "$temp_folder/_ExtractGZ_func.gz"
2395     mv  "$temp_folder/_ExtractGZ_func"  "$ExtractedPath"
2396   else
2397     cp -ap  "$GzPath"  "${ExtractedPath}.gz"
2398     rm_func "$ExtractedPath"
2399     echo  "gunzip  \"${ExtractedPath}.gz\""
2400     gunzip  "${ExtractedPath}.gz"
2401   fi
2402 }
2403
2404
2405  
2406 #//*********************************************************************
2407 #// <<< [ExtractZip_func] >>> 
2408 #//*********************************************************************
2409 function  ExtractZip_func()
2410 {
2411   local  PackagePath="$1"
2412   local  DstFolder="$2"
2413   local  TarnsformFrom="$3"
2414   local  dst_name ; dst_name=`basename "$DstFolder"`
2415   local  from_name ; from_name=`basename "$TarnsformFrom"`
2416
2417   if [ "$DstFolder" == "" ];then  DstFolder="$PWD" ;fi
2418
2419   if [ x"$TarnsformFrom" == x"" ];then
2420     mkdir_func  "$DstFolder"
2421     echo  "unzip -o -d  \"$DstFolder\"  \"$PackagePath\""
2422     unzip -o -d "$DstFolder"  "$PackagePath"
2423   elif [ x"$dst_name" == x"$from_name" ];then
2424     GetParentAbsPath_func  "$DstFolder"
2425     DstFolder="$g_Ret"
2426     mkdir_func  "$DstFolder"
2427     echo  "unzip -o -d  \"$DstFolder\"  \"$PackagePath\""
2428     unzip -o -d "$DstFolder"  "$PackagePath"
2429   else
2430     local  tmp_folder
2431     local  link_path
2432     local  num
2433
2434     tmp_folder="$DstFolder/_extracting_"
2435     for (( num = 1;  ;  num ++ )) ;do
2436       if [ "$num" == 1000 ];then  Error_func  ;fi
2437       if [ ! -e "$tmp_folder$num" ];then  break  ;fi
2438     done ; done_func $?
2439     tmp_folder="$tmp_folder$num"
2440     mkdir -p  "$tmp_folder"
2441
2442     link_path="$tmp_folder/$from_name"
2443     StringClass.substring_method  "$DstFolder"  0  1
2444     if [ "$g_Ret" == "/" ];then
2445       ln -s "$DstFolder"  "$link_path"
2446     else
2447       ln -s ".."  "$link_path"
2448     fi
2449
2450     echo  "unzip -o -d  \"$tmp_folder\"  \"$PackagePath\""
2451     unzip -o -d "$tmp_folder"  "$PackagePath"
2452
2453     rm  "$link_path"
2454     rmdir  "$tmp_folder"
2455   fi
2456 }
2457
2458
2459  
2460 #//*********************************************************************
2461 #// <<< [ListUpIn_func] >>> 
2462 #//*********************************************************************
2463 function  ListUpIn_func()
2464 {
2465   local  PackagePath="$1"
2466
2467   local  ext1
2468   local  ext2
2469   local  name
2470
2471   RightOfLastStr_func  "$PackagePath"  "." ; ext2="$g_Ret"
2472   LeftOfLastStr_func   "$PackagePath"  "."
2473   RightOfLastStr_func  "$g_Ret"  "." ; ext1="$g_Ret"
2474
2475   if [ x"$ext1" == x"tar"  -a  x"$ext2" == x"bz2" ];then
2476     bzip2 -dkc "$PackagePath" | tar t
2477   elif [ x"$ext1" == x"tar"  -a  x"$ext2" == x"gz" ];then
2478     tar tfz  "$PackagePath"
2479   elif [ x"$ext1" != x"tar"  -a  x"$ext2" == x"gz" ];then
2480     LeftOfLastStr_func  "$PackagePath"  "." ; name="$g_Ret"
2481     echo  "$name"
2482   elif [ "$ext2" == "zip" ];then
2483     unzip -l "$PackagePath" | sed -e "1,3d" -e '/^ *---/,$d' -e "s/.*:[0-9]* *//"
2484     CheckPipeStatus_func  "${PIPESTATUS[@]}"
2485   else
2486     Error_func  ".$ext.$ext2 形式は、サポートしていません。"
2487   fi
2488 }
2489
2490
2491  
2492 #//*********************************************************************
2493 #// <<< [ExpandWildcard_func] >>>
2494 #//*********************************************************************
2495 function  ExpandWildcard_func()
2496 {
2497   local  out_FolderAbsPath="$2"
2498   local  out_StepPaths="$3"
2499   local  list__
2500   local  last__
2501   local  physical_folder__
2502
2503   CheckMinArgCount_func  3 "$@"
2504
2505   local  locals="out_FolderAbsPath  out_StepPaths  list__  last__  physical_folder__  locals"
2506   CheckOutParamIsConflictToLocal_func  $out_FolderAbsPath  $locals
2507   CheckOutParamIsConflictToLocal_func  $out_StepPaths      $locals
2508
2509   #//=== call ExpandWildcardSub_func
2510   list__=`ExpandWildcardSub_func  "$@" `
2511   ArrayClass.fromLines_method  $out_StepPaths  "$list__"  #//[out] $out_StepPaths
2512
2513   #//=== get physical_folder__
2514   ArrayClass.getLength_method  $out_StepPaths
2515   last__=$(( $g_Ret - 1 ))
2516   ArrayClass.get_method  $out_StepPaths  $last__ ; physical_folder__="$g_Ret"
2517
2518   StringClass.length_method  "$physical_folder__" ; length="$g_Ret"
2519   length=$(( $length + 1 ))
2520
2521   ArrayClass.remove_method  $out_StepPaths  $last__
2522
2523   #//=== get $out_FolderAbsPath
2524   last__=$(( $last__ - 1 ))
2525   ArrayClass.get_method  $out_StepPaths  $last__
2526   SetOutput_func  $out_FolderAbsPath  "$g_Ret"
2527   ArrayClass.remove_method  $out_StepPaths  $last__
2528
2529   #//=== change to step_path
2530   for (( last__ = $last__ - 1 ;  $last__ >= 0 ; last__ -- )) ;do
2531     ArrayClass.get_method  $out_StepPaths  $last__
2532     StringClass.substring_method  "$g_Ret"  $length
2533     if [ "$g_Ret" == "" ];then  g_Ret="."  ;fi
2534     ArrayClass.set_method  $out_StepPaths  $last__  "$g_Ret"
2535   done ; done_func $?
2536 }
2537
2538
2539 function  ExpandWildcardSub_func()
2540 {
2541   local  WildcardPath="$1"
2542   local  arguments
2543   $declare_AssociativeArrayClass  option
2544   local  a1
2545   local  folder
2546   local  physical_folder
2547   local  options
2548   local  file_name
2549   local  all_type
2550
2551   local  locals="WildcardPath  arguments  option  a1  folder  physical_folder  options  file_name  all_type  locals"
2552   CheckOutParamIsConflictToLocal_func  $WildcardPath  $locals
2553
2554   GetLongOptions_func  arguments  option  "$@"  #//[out] arguments, option
2555
2556   unset  $out_StepPaths
2557   unset  $out_StepPaths  #// 配列をクリアするには2回必要?
2558
2559   a1=`dirname  "$WildcardPath"`
2560   if [ "$a1" == "" ];then  a1="."  ;fi
2561   GetAbsPath_func  "$a1" ; folder="$g_Ret"
2562   readlink_func  "$folder" ; physical_folder="$g_Ret"
2563
2564   file_name=`basename  "$WildcardPath"`
2565
2566   Attr_func  option  "SubFolder"
2567   if [ "$g_Ret" == "" ];then
2568     options="${options} -maxdepth 1"
2569   fi
2570
2571   all_type="1"
2572
2573   Attr_func  option  "Folder"
2574   if [ "$g_Ret" == "1" ];then
2575     find  "$physical_folder" $options -name "$file_name" -type d -print
2576     all_type=""
2577   fi
2578
2579   Attr_func  option  "File"
2580   if [ "$g_Ret" == "1" ];then
2581     find  "$physical_folder" $options -name "$file_name" -type f -print
2582     all_type=""
2583   fi
2584
2585   Attr_func  option  "Link"
2586   if [ "$g_Ret" == "1" ];then
2587     find  "$physical_folder" $options -name "$file_name" -type l -print
2588     all_type=""
2589   fi
2590
2591   if [ "$all_type" == "1" ];then
2592     find  "$physical_folder" $options -name "$file_name" -print
2593   fi
2594
2595   AssociativeArrayClass.destroy_method  option
2596   echo  "$folder"
2597   echo  "$physical_folder"
2598 }
2599
2600
2601  
2602 #//*********************************************************************
2603 #// <<< [rm_func] >>> 
2604 #//*********************************************************************
2605 function  rm_func()
2606 {
2607   local  Paths=( "$@" )
2608   local  path
2609
2610   for path  in "${Paths[@]}" ;do
2611     if [ "$path" != "" ];then
2612       CheckWritable_func  "$path"
2613
2614       if [ -d "$path" ]; then
2615         $g_TemporarySudo  chmod -R a+rw  "$path"
2616         $g_TemporarySudo  rm -rf  "$path"
2617       elif [ -f "$path" ]; then
2618         $g_TemporarySudo  chmod a+rw  "$path"
2619         $g_TemporarySudo  rm -f  "$path"
2620       elif [ -e "$path"  -o  -L "$path" ]; then
2621         $g_TemporarySudo  rm -f  "$path"
2622       fi
2623     fi
2624   done ; done_func $?
2625 }
2626
2627
2628  
2629 #//*********************************************************************
2630 #// <<< [mkdir_func] >>> 
2631 #//*********************************************************************
2632 function  mkdir_func()
2633 {
2634   local  Path="$1"
2635   CheckArgCount_func  1 "$@"
2636
2637   CheckWritable_func  "$Path"
2638
2639   if [ ! -d "$Path" ];then
2640     $g_TemporarySudo  mkdir -p "$Path"
2641   fi
2642 }
2643
2644
2645  
2646 #//*********************************************************************
2647 #// <<< [chmod_x_func] >>> 
2648 #//*********************************************************************
2649 function  chmod_x_func()
2650 {
2651   local  FolderPath="$1"
2652   local  SetPaths="$2"
2653   local  UnsetPaths="$3"
2654   local  wildcard
2655   local  wildcards
2656   local  folder
2657   local  step_paths
2658   local  path
2659
2660   ArrayClass.fromCSV_method  wildcards  "$SetPaths"  #//[out] wildcards
2661   for wildcard  in "${wildcards[@]}" ;do
2662     if [ "$wildcard" != "." ];then
2663       ExpandWildcard_func  "$work_folder/$wildcard"  folder  step_paths  --File  --SubFolder  #//[out]folder, step_paths
2664       for path  in "${step_paths[@]}" ;do
2665         echo  "chmod +x  \"$folder/$path\""
2666         chmod +x  "$folder/$path"
2667       done ; done_func $?
2668     fi
2669   done ; done_func $?
2670
2671   ArrayClass.fromCSV_method  wildcards  "$UnsetPaths"  #//[out] wildcards
2672   for wildcard  in "${wildcards[@]}" ;do
2673     if [ "$wildcard" != "." ];then
2674       ExpandWildcard_func  "$work_folder/$wildcard"  folder  step_paths  --File  --SubFolder  #//[out]folder, step_paths
2675       for path  in "${step_paths[@]}" ;do
2676         echo  "chmod -x  \"$folder/$path\""
2677         chmod -x  "$folder/$path"
2678       done ; done_func $?
2679     fi
2680   done ; done_func $?
2681 }
2682
2683
2684  
2685 #//*********************************************************************
2686 #// <<< [MakeSymbolicLink_func] >>> 
2687 #//*********************************************************************
2688 function  MakeSymbolicLink_func()
2689 {
2690   local  LinkSrcPath="$1"
2691   local  Target="$2"
2692   CheckArgCount_func  2 "$@"
2693
2694   CheckWritable_func  "$LinkSrcPath"
2695
2696   if [ -d "$LinkSrcPath" ];then
2697     if [ -L "$LinkSrcPath" ];then
2698       rm  "$LinkSrcPath"
2699       $g_TemporarySudo  ln -s  "$Target"  "$LinkSrcPath"
2700     else
2701       Error_func  "フォルダーが存在します"
2702     fi
2703   else
2704     $g_TemporarySudo  ln -sf  "$Target"  "$LinkSrcPath"
2705   fi
2706 }
2707
2708
2709  
2710 #//*********************************************************************
2711 #// <<< [chown_it_and_parent_func] >>> 
2712 #//*********************************************************************
2713 function  chown_it_and_parent_func()
2714 {
2715   local  Option=""
2716   local  Owner="$1"
2717   if [ "$Owner" == "-R" ];then
2718     Option="$Owner"
2719     shift
2720     Owner="$1"
2721   fi
2722   local  Path="$2"
2723   local  parent
2724
2725   CheckWritable_func  "$Path"
2726
2727   GetParentAbsPath_func  "$Path" ; parent="$g_Ret"
2728
2729   if [ -e "$Path" ];then
2730     $g_TemporarySudo  chown  $Option  "$Owner"  "$Path"
2731   fi
2732
2733   if [ ! -d "$parent" ];then
2734     $g_TemporarySudo  mkdir -p  "$parent"
2735   fi
2736   $g_TemporarySudo  chown  $Option  "$Owner"  "$parent"
2737 }
2738
2739
2740  
2741 #//*********************************************************************
2742 #// <<< [AppKeyClass.newWritable_method] >>> 
2743 #//*********************************************************************
2744 function  AppKeyClass.newWritable_method()
2745 {
2746   local  AppKey="$1"
2747   shift  1
2748   local  Args=( "$@" )
2749   local  index
2750   local  count
2751
2752   if [ "$AppKey" != "AppKey4293" ]; then  Error_func  "AppKeyClass.newWritable_method needs \$2 of Main_func"  ;fi
2753
2754   unset g_WritableFolders8920
2755   unset g_WritableFolders8920  #// 配列をクリアするには2回必要?
2756
2757   count=0
2758   for (( index = 0; index < ${#Args[@]}; index ++ ));do
2759     if [ "${Args[$index]}" != "" ];then
2760       GetAbsPath_func  "${Args[$index]}"
2761       g_WritableFolders8920[$count]="$g_Ret"
2762       count=$(( $count + 1 ))
2763     fi
2764   done ; done_func $?
2765 }
2766
2767
2768  
2769 #//*********************************************************************
2770 #// <<< [CheckWritable_func] >>> 
2771 #//*********************************************************************
2772 function  CheckWritable_func()
2773 {
2774   local  Path="$1"
2775   CheckArgCount_func  1 "$@"
2776
2777   local  is_break=""
2778   local  writable
2779
2780   GetAbsPath_func  "$Path"  "$PWD" ; Path="$g_Ret"
2781
2782   if [ "$g_WritableFolders8920" == "" ]; then \
2783     Error_func  "<ERROR msg=\"Not call AppKeyClass.newWritable_method\" Path=\"$Path\"/>"  ;fi
2784   for  writable  in  ${g_WritableFolders8920[@]};do
2785     if [ "${Path%%$writable*}" == "" ]; then  is_break=1 ; break  ;fi
2786   done ; done_func $?
2787   if [ ! "$is_break" == "1" ]; then
2788     Error_func  "<ERROR msg=\"AppKeyClass.newWritable_method による書き込み許可がされていません。\"" \
2789        "Path=\"$Path\" Writable=\"$g_WritableFolders8920\"/>"
2790   fi
2791 }
2792
2793
2794  
2795 #//*********************************************************************
2796 #// <<< [EchoTestStart_func] >>> 
2797 #//*********************************************************************
2798 function  EchoTestStart_func()
2799 {
2800   local  args=("$@")
2801   if [ "${#args[@]}" == "0" ];then
2802     echo  ""
2803     echo  "((( ${FUNCNAME[1]} )))"
2804   else
2805     echo  ""
2806     echo  "((( $@ )))"
2807   fi
2808 }
2809
2810
2811  
2812 #//*********************************************************************
2813 #// <<< [debugger] >>> 
2814 #//*********************************************************************
2815 function  de()
2816 {
2817   debugger
2818 }
2819
2820 function  debugger()
2821 {
2822   g_DebugTrapFunc="StepRunning_func"
2823
2824   trap 'DebugTrap_func  "$LINENO"  "$BASH_COMMAND"  "${PIPESTATUS[@]}"
2825     #// resume ${PIPESTATUS[@]}
2826     case "${#g_PipeStatus[@]}" in
2827       "2")
2828         return ${g_PipeStatus[0]} | true;;
2829       "3")
2830         return ${g_PipeStatus[0]} | return ${g_PipeStatus[1]} | true;;
2831     esac' DEBUG
2832 }
2833
2834 function  StepRunning_func()
2835 {
2836   local  LineNo__="$1"
2837   local  Command__="$2"
2838   shift  2
2839   g_PipeStatus=( "$@" )
2840
2841   local  key__
2842   local  a1__
2843
2844   if [ "$step_running_guided" == "" ]; then
2845     ErrClass.getCallTree_method  "$LINENO"  2  1
2846     echo  "$g_Ret"  >&2
2847     echo  "--- デバッガ情報 -------------------------"  >&2
2848     echo  "ステップ実行 … Enter キーを押してください"  >&2
2849     echo  "変数の値を表示 … 変数名を入力"              >&2
2850     echo  "------------------------------------------"  >&2
2851   fi
2852
2853   echo  "${FUNCNAME[2]}() ${BASH_SOURCE[2]}:${BASH_LINENO[1]}"  >&2
2854   key__="goto_in_while"
2855   while [ "$key__" != "" ]; do
2856     read -p "$LineNo__: $Command__ " key__  #// break at the line
2857
2858     #// inspect variable's value
2859     if [ "$key__" != "" ]; then
2860
2861       case "$key__" in
2862        "LineNo__" | "Command__" | "key__" | "a1__" )
2863         echo  "変数 $key__ の値の表示はサポートしていません。";;
2864
2865        *)
2866         CheckOutParamIsConflictToLocal_func  key__  
2867
2868         key__=${key__/$/}  #// cut first $, if exists
2869         es  $key__  #// call es function
2870         ;;
2871       esac
2872     fi
2873   done ; done_func $?
2874
2875   step_running_guided=1
2876 }
2877
2878
2879  
2880 #//*********************************************************************
2881 #// <<< [ec] >>> 
2882 #//*********************************************************************
2883 function  ec()
2884 {
2885   local  ExpressionArray__=("$@")
2886   local  Expression__="$@"
2887   local  evaled__
2888
2889   echo  "ec> ${FUNCNAME[1]}() ${BASH_SOURCE[1]}(${BASH_LINENO[0]})"  >&2
2890   if [ "${#ExpressionArray__[@]}" != "0" ];then
2891
2892     CheckEvalParamIsConflictToLocal_func  "$Expression__"  ExpressionArray__  Expression__  evaled__
2893
2894     evaled__=`eval echo "\"""$Expression__""\""`
2895     if [ "$Expression__" == "$evaled__" ];then
2896       echo  "ec> \"$Expression__\""  >&2
2897     else
2898       echo  "ec> \"$Expression__\" == '""$evaled__""'" >&2
2899     fi
2900   fi
2901 }
2902
2903
2904  
2905 #//*********************************************************************
2906 #// <<< [es] >>> 
2907 #//*********************************************************************
2908 function  es()
2909 {
2910   local  Name__="$1"
2911   local  keys__
2912   local  value__
2913   local  index__
2914   local  is__
2915
2916   if [ "$g_ExitStatus" == "0" ];then
2917     CheckArgCount_func  1 "$@"
2918
2919     CheckOutParamIsConflictToLocal_func  "$Name__"  Name__  keys__  value__  index__
2920   fi
2921
2922   eval  keys__=( '"${!'"$Name__"'[@]}"' )
2923
2924   is__=0
2925   if [ x"$keys__" == x""  -o  x"$keys__" == x"0" ];then  is__=1 ;fi
2926
2927   if [ "${#keys__[@]}" -le "1"  -a  "$is__" == "1" ];then
2928     eval  value__='"${'"$Name__"'}"'
2929     StringClass.indexOf_method  "$Name__"  "["
2930     if [ "$g_Ret" -ge "0" ];then
2931       echo -n 'Dump "${'"$Name__"}'" == '  >&2
2932     else
2933       echo -n 'Dump "$'"$Name__"'" == '  >&2
2934     fi
2935     echo  "'""$value__""'"  >&2
2936     if [ "$value__" == "" ];then
2937       echo  "00000000                                                    ||" >&2
2938       echo  "00000000" >&2
2939     else
2940       echo -n "$value__" | hexdump -C  >&2
2941     fi
2942     #// hexdump -C <<< "$value__"  >&2
2943   else
2944     for index__  in "${keys__[@]}" ;do
2945       es $Name__[$index__]
2946     done ; done_func $?
2947   fi
2948 }
2949
2950
2951  
2952 #//*********************************************************************
2953 #// <<< [Error_func] >>> 
2954 #//*********************************************************************
2955 function  Error_func()
2956 {
2957   ErrClass.getErrStr_method  "$@" ; g_Err_Desc="$g_Ret"
2958   return_func  1
2959 }
2960
2961
2962  
2963 #//*********************************************************************
2964 #// <<< [return_func] >>> 
2965 #//*********************************************************************
2966 function  return_func()
2967 {
2968   if [ "$g_Err_LineNo" == "???" ];then  g_Err_LineNo=${BASH_LINENO[0]}  ;fi
2969   return  "$1"
2970 }
2971
2972
2973  
2974 #//*********************************************************************
2975 #// <<< [CheckPipeStatus_func] >>> 
2976 #//*********************************************************************
2977 function  CheckPipeStatus_func()
2978 {
2979   local  pipe_status="$@"
2980   local  state
2981
2982   for state in ${pipe_status[@]};do
2983     if [ "$state" != "0" ]; then
2984       echo  '${PIPESTATUS[@]} = '"${pipe_status[@]}" >&2
2985       g_Err_LineNo=${BASH_LINENO[0]}
2986       return  "$state"
2987     fi
2988   done ; done_func $?
2989 }
2990
2991
2992  
2993 #//*********************************************************************
2994 #// <<< [CheckArgCount_func] >>> 
2995 #//*********************************************************************
2996 function  CheckArgCount_func()
2997 {
2998   local  RequestArgumentCount="$1"
2999   shift  1
3000   local  Arguments=( "$@" )
3001   local  str
3002
3003   if [ "${#Arguments[@]}" -ne "$RequestArgumentCount" ];then
3004     str="パラメーターの数が合っていません。 指定=${#Arguments[@]}, 要求=$RequestArgumentCount,"
3005     str="$str コマンドライン: ${FUNCNAME[1]} ${Arguments[@]}"
3006     Error_func  "$str"
3007   fi
3008 }
3009
3010
3011  
3012 #//*********************************************************************
3013 #// <<< [CheckMinArgCount_func] >>> 
3014 #//*********************************************************************
3015 function  CheckMinArgCount_func()
3016 {
3017   local  RequestArgumentCount="$1"
3018   shift  1
3019   local  Arguments=( "$@" )
3020   if [ "${#Arguments[@]}" -lt "$RequestArgumentCount" ];then
3021     echo  "パラメーターが少なすぎます。 指定=${#Arguments[@]}, 要求=$RequestArgumentCount"  >&2
3022     echo  "コマンドライン: ${FUNCNAME[1]} ${Arguments[@]}"  >&2
3023     Error_func
3024   fi
3025 }
3026
3027
3028  
3029 #//*********************************************************************
3030 #// <<< [CheckMaxArgCount_func] >>> 
3031 #//*********************************************************************
3032 function  CheckMaxArgCount_func()
3033 {
3034   local  RequestArgumentCount="$1"
3035   shift  1
3036   local  Arguments=( "$@" )
3037   if [ "${#Arguments[@]}" -gt "$RequestArgumentCount" ];then
3038     echo  "パラメーターが多すぎます。 指定=${#Arguments[@]}, 要求=$RequestArgumentCount"  >&2
3039     echo  "コマンドライン: ${FUNCNAME[1]} ${Arguments[@]}"  >&2
3040     Error_func
3041   fi
3042 }
3043
3044
3045  
3046 #//*********************************************************************
3047 #// <<< [CheckOutParamIsConflictToLocal_func] >>> 
3048 #//*********************************************************************
3049 function  CheckOutParamIsConflictToLocal_func()
3050 {
3051   local  OutParamName__="$1"
3052   shift  1
3053   local  LocalNames__=( "$@" )
3054   local  name__
3055   local  a1__
3056
3057   if [ "$OutParamName__" == "" ];then  Error_func  "出力変数名が指定されていません"  ;fi
3058
3059   for name__  in "${LocalNames__[@]}" ;do
3060     if [ "$OutParamName__" == "$name__" ];then
3061       a1__="<ERROR msg=\"ローカル変数名が衝突しています\" "
3062       a1__="${a1__}local=\"$name__\"/>"
3063       Error_func  "$a1__"
3064     fi
3065   done ; done_func $?
3066 }
3067
3068
3069  
3070 #//*********************************************************************
3071 #// <<< [CheckEvalParamIsConflictToLocal_func] >>> 
3072 #//*********************************************************************
3073 function  CheckEvalParamIsConflictToLocal_func()
3074 {
3075   local  EvalExpression="$1"
3076   shift  1
3077   local  LocalNames=( "$@" )
3078   local  name
3079   local  s
3080
3081   for name  in "${LocalNames[@]}" ;do
3082     if [ "${EvalExpression%%$name*}" != "$EvalExpression"  ];then
3083       s="<ERROR msg=\"ローカル変数名が衝突している可能性があります\" "
3084       s="${s}local=\"$name\"/>"
3085       Error_func  "$s"
3086     fi
3087   done ; done_func $?
3088 }
3089
3090
3091  
3092 #//*********************************************************************
3093 #// <<< [Assert_func] >>> 
3094 #//*********************************************************************
3095 function  Assert_func()
3096 {
3097   local  Expression__="$*"
3098   local  is_pass__
3099   local  message__
3100   local  result__
3101
3102   eval  ' if [ '"$Expression__"' ]; then  is_pass__=1  ;else  is_pass__=0 ;fi '
3103
3104   if [ "$is_pass__" == "0" ];then  result__="`eval  echo "$Expression__"`"  ;fi
3105
3106   if false; then  #// ture, if debug
3107     echo  "<Assert_func"  >&2
3108     echo  "Expression__='$Expression__'"  >&2
3109     echo  "result__='$result__'"  >&2
3110     echo  "is_pass__='$is_pass__'/>"  >&2
3111   fi
3112
3113   if [ "$is_pass__" == "0" ];then
3114     message__=`echo -n "<ERROR msg=\"Assert failed\"><Expression><![CDATA[${LF}$Expression__${LF}]]></Expression>"`
3115     if [ "$Expression__" != "$result__" ];then
3116       message__="$message__"`echo -n "<Result><![CDATA[${LF}$result__${LF}]]></Result>"`
3117     fi
3118     message__="$message__</ERROR>"
3119     Error_func  "$message__"
3120   fi
3121 }
3122
3123
3124  
3125 #//*********************************************************************
3126 #// <<< [TryStart_func] >>> 
3127 #// <<< [TryEnd1_func] >>> 
3128 #// <<< [TryEnd2_func] >>> 
3129 #//*********************************************************************
3130 function  TryStart_func()
3131 {
3132   true
3133   g_Err_NestLevel=$(( $g_Err_NestLevel + 1 ))
3134 }
3135
3136 function  TryEnd1_func()
3137 {
3138   break
3139 }
3140
3141 function  TryEnd2_func()
3142 {
3143   CheckArgCount_func  1  "$@"
3144   if [ "$g_ExitStatus" == "0" ];then
3145     g_ExitStatus=$1
3146   fi
3147   g_Err_NestLevel=$(( $g_Err_NestLevel - 1 ))
3148   g_Err_Desc1st="$g_Err_Desc"
3149 }
3150
3151
3152  
3153 #//*********************************************************************
3154 #// <<< [ErrTrap_func] >>> 
3155 #//*********************************************************************
3156
3157 g_ExitStatus=0
3158 g_Ret=""
3159 g_Ret2=""
3160 g_Ret3=""
3161 g_Err_IsDone=0
3162 g_Err_IsOverwrite=0
3163 g_Err_NestLevel=0
3164 g_Err_ErrID=0
3165 g_Err_Desc=""
3166 g_Err_Desc1st=""
3167 g_Err_LineNo="???"
3168 g_PipeStatus=""
3169 g_DebugTrapFunc=""
3170
3171 function  ErrTrap_func()
3172 {
3173   local  a1
3174
3175   if [ "$g_Err_IsDone" == "1" ];then
3176     g_Err_IsDone=0
3177   elif [ "$g_Err_IsOverwrite" == "1" ];then
3178     g_Err_IsOverwrite=0
3179   else
3180
3181     g_Err_ErrID=$(( $g_Err_ErrID + 1 ))
3182
3183     if [ "$g_ExitStatus" == "0" ];then
3184       if [ "$g_Err_LineNo" == "???" ];then  g_Err_LineNo=$1  ;fi
3185       if [ "$g_Err_LineNo" == "???" ]; then
3186         a1="${a1}(ヒント)現在の行番号は、${FUNCNAME[1]} 関数の最初で \"EchoOn_func\" を呼ぶと表示されます。${LF}"
3187       fi
3188       a1="${a1}(開発者向けヒント)ステップ実行したいときは、開始するところから \"debugger\" 関数を呼び出してください。 "
3189       a1="${a1}下記コールツリーの最も下の関数が、\` \` を使って echo 出力を取得しているときは、取得しないようにすると、更にコール先の関数が表示されます。${LF}"
3190       ErrClass.getCallTree_method  "$g_Err_LineNo"  2  1
3191       g_Err_ErrCallStack="$a1$g_Ret$LF"
3192     else
3193       echo  "<ERROR msg=\"エラー処理中に別のエラーが発生しました。\"/>" >&2
3194
3195       ErrClass.getErrStr_method  "$g_Err_Desc"
3196       if [ "$g_Ret" == "" ];then  g_Ret="<ERROR/>"  ;fi
3197       ColorText_func  "$g_Ret"  "Red" "Bold"
3198       echo_e_func  "$g_Ret"
3199
3200       ErrClass.getCallTree_method  "${BASH_LINENO[0]}"  2  1
3201       echo  "$g_Ret"  >&2
3202       g_Err_Desc="$g_Err_Desc1st"
3203     fi
3204   fi
3205 }
3206
3207
3208  
3209 #//*********************************************************************
3210 #// <<< [done_func] >>> 
3211 #//*********************************************************************
3212 function  done_func()
3213 {
3214   CheckArgCount_func  1 "$@"
3215   if [ "$1" != "0" ];then  g_Err_IsDone=1  ;fi
3216   return  "$1"  #// if not 0, throw again
3217 }
3218
3219
3220  
3221 #//*********************************************************************
3222 #// <<< [ErrClass.raiseOverwrite_method] >>> 
3223 #//*********************************************************************
3224 function  ErrClass.raiseOverwrite_method()
3225 {
3226   local  message ; ErrClass.getErrStr_method  "$@" ; message="$g_Ret"
3227   local  exit_status="$g_ExitStatus"
3228
3229   if [ "$message" != "" ];then
3230     g_Err_Desc="$message"
3231   fi
3232
3233   if [ "$exit_status" == "0" ];then
3234     exit_status=1
3235   fi
3236
3237   g_Err_IsOverwrite=1
3238   return  $exit_status
3239 }
3240
3241
3242  
3243 #//*********************************************************************
3244 #// <<< [ErrClass.clear_method] >>> 
3245 #//*********************************************************************
3246 function  ErrClass.clear_method()
3247 {
3248   g_ExitStatus=0
3249   g_Err_Desc=""
3250   g_Err_Desc1st=""
3251   g_Err_LineNo="???"
3252   g_PipeStatus=""
3253 }
3254
3255
3256  
3257 #//*********************************************************************
3258 #// <<< [ErrClass.getErrStr_method] >>> 
3259 #//*********************************************************************
3260 function  ErrClass.getErrStr_method()
3261 {
3262   local  Message="$@"
3263
3264   if [ "$Message" != "" ]; then
3265     if [ "${Message%%<ERROR *}" == "" ]; then
3266       g_Ret="$Message"
3267     else
3268       StringClass.replace_method  "$Message"  "&"  "&amp;"
3269       StringClass.replace_method  "$g_Ret"  "<"  "&lt;"
3270       StringClass.replace_method  "$g_Ret"  "\""  "&quot;"
3271       g_Ret="<ERROR msg=\"$g_Ret\"/>"
3272     fi
3273   else
3274     g_Ret=""
3275   fi
3276 }
3277
3278
3279  
3280 #//*********************************************************************
3281 #// <<< [ErrClass.getCallTree_method] >>> 
3282 #//*********************************************************************
3283 function  ErrClass.getCallTree_method()
3284 {
3285   local  LineNo="$1"
3286   local  TopIndex="$2"
3287   local  IsAbleLastCut="$3"
3288   local  indent=" "
3289   local  s
3290
3291   s="コールツリー:"
3292   i=$(( ${#FUNCNAME[@]} - 1 ))
3293   s="$s${LF}""(global) ${BASH_SOURCE[$i]}:${BASH_LINENO[$i-1]}"
3294   for(( i=${#FUNCNAME[@]} - 2; i > $TopIndex; i-- ));do
3295     s="$s${LF}${indent}${FUNCNAME[$i]}() ${BASH_SOURCE[$i]}:${BASH_LINENO[$i-1]}"
3296     indent="${indent} "
3297   done ; done_func $?
3298
3299   case  "${FUNCNAME[$TopIndex]}"  in
3300     "Error_func" | "DebugTrap_func" ) ;;
3301     *)  IsAbleLastCut=0 ;;
3302   esac
3303   if [ "$IsAbleLastCut" != "1" ];then
3304     if [ "$g_DebugTrapFunc" == "EchoOnTrap_func" ];then
3305       s="$s${LF}${indent}${FUNCNAME[$TopIndex]}() ${BASH_SOURCE[$TopIndex]}:$LineNo ?(->EchoOn_func)"
3306     else
3307       s="$s${LF}${indent}${FUNCNAME[$TopIndex]}() ${BASH_SOURCE[$TopIndex]}:$LineNo"
3308     fi
3309   fi
3310   g_Ret="$s"
3311 }
3312
3313
3314  
3315 #//*********************************************************************
3316 #// <<< [Exit_func] >>> 
3317 #//*********************************************************************
3318 function  Exit_func()
3319 {
3320   g_DebugTrapFunc=""
3321   trap ':' EXIT
3322   exit $ret
3323 }
3324
3325
3326  
3327 #//*********************************************************************
3328 #// <<< [g_ArrayLength] >>> 
3329 #//*********************************************************************
3330 g_ArrayLength=0
3331
3332
3333  
3334 #//*********************************************************************
3335 #// <<< [g_AssociativeArrayMaxLength] >>> 
3336 #//*********************************************************************
3337 if [ "$g_AssociativeArrayMaxLength" == "" ];then  g_AssociativeArrayMaxLength=100  ;fi
3338
3339 g_AssociativeArrayLength=0
3340 for (( i = 0; i < $g_AssociativeArrayMaxLength; i ++ ));do
3341   $declare_AssociativeArrayClass  g_AssociativeArrays_$i
3342 done
3343
3344
3345  
3346 #//*********************************************************************
3347 #// <<< [LF] >>> 
3348 #// <<< [Tab] >>> 
3349 #//*********************************************************************
3350 LF=`echo_e_func "\nx"`; LF="${LF:0:1}"
3351 Tab=`echo_e_func "\t"`
3352
3353
3354