OSDN Git Service

GAMESS execution from Ruby script is improved (not quite well yet)
[molby/Molby.git] / Scripts / startup.rb
1 #
2 #  startup.rb
3 #
4 #  Created by Toshi Nagata.
5 #  Copyright 2008 Toshi Nagata. All rights reserved.
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation version 2 of the License.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15
16 include Molby
17 include Math
18
19 Deg2Rad = Math::PI / 180.0
20 Rad2Deg = 180.0 / Math::PI
21
22 $startup_dir = Dir.pwd
23 case RUBY_PLATFORM
24   when /mswin|mingw|cygwin|bccwin/
25     $platform = "win"
26         Encoding.default_external = "shift_jis"
27         $home_directory = ENV['USERPROFILE'].gsub(/\\/, "/")
28   when /darwin/
29     $platform = "mac"
30         Encoding.default_external = "utf-8"
31         $home_directory = ENV['HOME']
32   else
33     $platform = "other"
34         Encoding.default_external = "locale"
35         $home_directory = ENV['HOME']
36 end
37
38 $backtrace = nil
39
40 def backtrace
41   if $backtrace
42     print $backtrace.join("\n")
43   end
44 end
45
46 #  Utility methods
47 module Enumerable
48   def sum(&block)
49     if block
50       self.inject(0) { |sum, v| sum + block.call(v) }
51         else
52           self.inject(0) { |sum, v| sum + v }
53         end
54   end
55   def average(&block)
56     sum(&block) / Float(self.length)
57   end
58 end
59
60 module Math
61   def acos_safe(arg)
62     if arg <= -1.0
63       return PI
64     elsif arg >= 1.0
65       return 0.0
66     else
67       return acos(arg)
68     end
69   end
70
71   def sqrt_safe(arg)
72     arg <= 0.0 ? 0.0 : sqrt(arg)
73   end
74 end
75
76
77 module Kernel
78   def filecopy(src, dst)
79     fpin = File.open(src, "rb")
80     return nil if fpin == nil
81     fpout = File.open(dst, "wb")
82     if fpout == nil
83       fpin.close
84       return nil
85     end
86     a = ""
87     while fpin.read(4096, a)
88       fpout.write(a)
89     end
90     fpin.close
91     fpout.close
92     return true
93   end
94   def mkdir_recursive(path)
95     if FileTest.directory?(path)
96           return 0
97     else
98           dir = File.dirname(path)
99           if !FileTest.exist?(dir)
100             mkdir_recursive(dir)
101           end
102       return Dir.mkdir(path)
103         end
104   end
105   def create_temp_dir(tag, name = nil)
106     #  Create a temporary directory like HomeDirectory/Molby/tag/name.xxxxxx
107         name ||= "temp"
108         base = $home_directory + "/Molby/" + tag
109         mkdir_recursive(base)
110         10000.times { |n|
111           p = sprintf("%s/%s.%05d", base, name, n)
112           if !FileTest.exist?(p)
113             Dir.mkdir(p)
114                 return p
115           end
116         }
117         raise "Cannot create temporary directory in #{base}"
118   end
119   def rm_recursive(path)
120     if FileTest.directory?(path)
121           Dir.foreach(path) { |en|
122             next if en == "." || en == ".."
123                 rm_recursive(path + "/" + en)
124           }
125           Dir.rmdir(path)
126         else
127           File.unlink(path)
128         end
129   end
130   def cleanup_temp_dir(path, option = nil)
131     #  Clean-up temporary directories
132         #  If option is nil, then the directory at path is removed
133         #  If option is a number, then the directories that are in the same parent directory as path
134         #  are removed except for the newest ones
135         if path.index($home_directory + "/Molby/") != 0
136           raise "Bad cleanup_temp_dir call: the path does not begin with $HOME/Molby/ (#{path})"
137         end
138         if !FileTest.directory?(path)
139           raise "Bad cleanup_temp_dir call: the path is not a directory (#{path})"
140         end
141         option = option.to_i
142         if option <= 0
143           rm_recursive(path)
144         else
145           base = File.dirname(path)
146           ent = Dir.entries.sort_by { |en| File.mtime("#{base}/#{en}").to_i * (-1) } - [".", ".."]
147           if $platform == "mac"
148             ent -= [".DS_Store"]
149           end
150           ent[0, option] = []  #  Remove newest #{option} entries
151           #  Mark this directory to be ready to remove (see below)
152           open("#{path}/.done", "w") { |fp| }
153           #  Remove the older directories
154           ent.each { |en|
155             #  Check the existence of ".done" file (otherwise, we may accidentarily remove a directory
156             #  that is still in use in other threads)
157             if File.exist?("#{base}/#{en}/.done")
158               rm_recursive("#{base}/#{en}")
159                 end
160           }
161         end
162   end
163
164   def remove_dir(dir)
165     entries = Dir.entries(dir)
166         entries.each { |en|
167           next if en == "." || en == ".."
168           fname = "#{dir}/#{en}"
169           if File.directory?(fname)
170             remove_dir(fname)
171           else
172             File.unlink(fname)
173           end
174         }
175         Dir.unlink(dir)
176   end
177   
178   def erase_old_logs(tdir, level, keep_number)
179     log_dir = File.dirname(tdir)
180         if level == nil || level == "none"
181           remove_dir(tdir)
182         elsif level == "latest"
183           if keep_number == nil
184             keep_number = 5
185           else
186             keep_number = keep_number.to_i
187           end
188           entries = Dir.entries(log_dir).select { |en| en != "." && en != ".." && File.directory?("#{log_dir}/#{en}") }
189           #  Sort by modification date
190           entries = entries.sort_by { |en| File.mtime("#{log_dir}/#{en}").to_i }
191           (0...entries.count - keep_number).each { |i|
192             remove_dir("#{log_dir}/#{entries[i]}")
193           }
194         end
195   end
196   
197 end
198
199 class IO
200   alias :gets_original :gets
201   def gets(rs = $/)
202     if rs != $/
203           return gets_original(rs)
204         end
205     if @end_of_line
206           s = gets_original(@end_of_line)
207           if s && s.chomp!(@end_of_line)
208             s += $/
209           end
210         else
211           s = ""
212           while c = getc
213             if c == "\r"
214                   #  \r or \r\n
215                   if (c = getc) && c != "\n"
216                     ungetc(c)
217                     @end_of_line = "\r"
218                   else
219                     @end_of_line = "\r\n"
220                   end
221                   break
222                 elsif c == "\n"
223                   #  \n
224                   @end_of_line = "\n"
225                   break
226                 else
227                   s += c
228                 end
229           end
230           if @end_of_line
231             s += $/
232           end
233     end
234         return s
235   end
236 end
237
238 #  Additional method definitions
239 load "transform.rb"
240 load "molecule.rb"
241 load "loadsave.rb"
242 load "formula.rb"
243 load "dialog.rb"
244
245 #  Menu commands
246 load "view.rb"
247 load "uff.rb"
248 load "md.rb"
249 load "mopac6.rb"
250 load "gamess.rb"
251 load "crystal.rb"
252 load "commands.rb"
253
254 GC.start