Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
options.py
Go to the documentation of this file.
1 #!/usr/bin/python
2 # :noTabs=true:
3 
4 # (c) Copyright Rosetta Commons Member Institutions.
5 # (c) This file is part of the Rosetta software suite and is made available under license.
6 # (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 # (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 # (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 ## @file basic/options/options.py
11 ## @brief Program options generation script that is run to generate the options
12 ## @author Sergey Lyskov (Sergey.Lyskov@jhu.edu)
13 
14 # Script for generating option.gen.cc.hh, keys/OptionKeys.hh.gen.hh, keys/OptionKeys.cc.gen.hh files
15 # Use 'python options.py -Wiki' to generate a Wiki table
16 
17 import sys
18 
19 import options_class, options_rosetta
20 import os.path, os
21 #from difflib import Differ
22 
23 Options = options_rosetta.Options
24 james_debug = 1
25 
26 class KeepSameFile(object):
27  def __init__(self,fname,opts):
28  self.fname = fname
29  self.opts = opts
30  self.body = ""
31  def write(self,s):
32  self.body += s
33  def close(self):
34  ischanged = False
35  try :
36  existing_file = open(self.fname)
37  try:
38  if existing_file.read() != self.body:
39  ischanged = True
40  finally:
41  existing_file.close()
42  except IOError :
43  ischanged = True
44  if ischanged:
45  print "file",self.fname,"being updated"
46  out = open(self.fname,self.opts)
47  try:
48  out.write(self.body)
49  finally:
50  out.close()
51  return 1
52  return 0
53 
54 
55 def main(args):
56  num_changed_files = 0
57  if len(args) <= 1: # no option give - just generating C++ files.
58 
59  # code below is for if we ever want to split options into separate groups
60  # to speed up compilation times. totally untested!
61  if james_debug:
62 
63  header1 = '// -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-\n' + '// vi: set ts=2 noet:\n' + '//\n' + '// (c) Copyright Rosetta Commons Member Institutions.\n' + '// (c) This file is part of the Rosetta software suite and is made available under license.\n' + '// (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.\n' + '// (c) For more information, see http://www.rosettacommons.org. Questions about this can be\n' + '// (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.\n\n'
64  header3 = '\n/// @brief basic::options::OptionKeys collection\n' + '/// @author Stuart G. Mentzer (Stuart_Mentzer@objexx.com)\n' + '/// @author James M. Thompson (tex@u.washington.edu)\n' + '\n'
65  header5 = '\n// Unit headers\n#include <basic/options/keys/OptionKeys.hh>\n\n' + 'namespace basic {\n' + 'namespace options {\n' + 'namespace OptionKeys {\n' + '\n'
66  footer = '\n} // namespace OptionKeys\n' + '} // namespace options\n' + '} // namespace basic\n\n#endif\n'
67  header_gen_hh = '#ifndef OPTION_CC_GEN_HH\n' +\
68  '#define OPTION_CC_GEN_HH\n'+\
69  '#include <basic/options/option.hh>\n' + \
70  '#include <basic/options/option.cc.include.gen.hh>\n' + \
71  '#include <utility/options/OptionCollection.hh>\n'
72 
73  footer_gen_hh_pre = '\ninline void add_all_rosetta_options( utility::options::OptionCollection &option ) {\n'
74  footer_gen_hh_post = '}\n#endif\n'
75 
76 
77  #def callback(arg, directory, files):
78  # for file in files:
79  # print os.path.join(directory, file), repr(arg)
80  #os.path.walk(".", callback, "secret")
81 
82  output = {}
83  output[ 'option.cc.gen.hh' ] = []
84  output[ 'keys/OptionKeys.gen.hh' ] = {}
85  output[ 'keys/OptionKeys.cc.gen' ] = []
86 
87  # Why is this here? It seems to be unused.
88  ##if not os.path.isdir('def'):
89  # os.mkdir( 'def' )
90 
91 
92  for opt in Options:
93  ns = str( opt.get_namespace(0) )
94 
95  # create new lists if necessary
96  if not output[ 'keys/OptionKeys.gen.hh' ].has_key( ns ):
97  output[ 'keys/OptionKeys.gen.hh' ][ ns ] = []
98 
99  output[ 'option.cc.gen.hh' ].append( opt.getOptionCC() )
100  output[ 'keys/OptionKeys.gen.hh' ][ ns ].append( opt.getOptionKeysHH() )
101  output[ 'keys/OptionKeys.cc.gen' ].append( opt.getOptionKeysCC() )
102 
103 
104  gen_hh_files = []
105  gen_cc_files = []
106  for file_prefix in output.keys():
107  (dirname,filename) = os.path.split( file_prefix )
108  if file_prefix == 'option.cc.gen.hh':
109  outfile = file_prefix
110  #print outfile
111  f = KeepSameFile(outfile, 'wb')
112  f.write( header_gen_hh )
113 
114  split_len = len( output[ file_prefix ] ) // 16 + 1 # for now we generate 16 functions instead of 1
115  groups = [ output[ file_prefix ][i: i+split_len] for i in range(0, len(output[ file_prefix ]), split_len) ]
116  for i,g in enumerate(groups):
117  lines = 'inline void add_rosetta_options_%s( utility::options::OptionCollection &option ) {' % i
118  lines += "".join(g) + '\n}\n'
119  f.write( lines )
120  #lines = output[ file_prefix ]
121  f.write( footer_gen_hh_pre )
122  for i,g in enumerate(groups):
123  f.write( '\tadd_rosetta_options_%s( option );\n' %i )
124  f.write( footer_gen_hh_post )
125  num_changed_files += f.close()
126  elif file_prefix == 'keys/OptionKeys.cc.gen':
127  split_len = len( output[ file_prefix ] ) // 16 + 1 # for now we split .cc just in 16 files
128  groups = [ output[ file_prefix ][i: i+split_len] for i in range(0, len(output[ file_prefix ]), split_len) ]
129  for i,g in enumerate(groups):
130  outfile = file_prefix + '%s.hh' % i
131  #print outfile
132  f = KeepSameFile(outfile, 'wb')
133  f.write( "".join(g) )
134  num_changed_files += f.close()
135  else:
136  for ns in output[ file_prefix ].keys():
137  new_filename = ".".join( [ns, filename] )
138  outfile = os.path.join( dirname, new_filename )
139  header2 = '/// @file basic/options/' + outfile
140  full_fn = 'basic/options/keys/' + ns + '_OptionKeys_gen_HH'
141  inc_path = full_fn.replace('/','_')
142  inc_symb = 'INCLUDED_' + inc_path
143  header4 = '#ifndef ' + inc_symb + '\n#define ' + inc_symb + '\n'
144  gen_hh_files.append( new_filename )
145  header = [ header1, header2, header3, header4, header5 ]
146  output[ file_prefix ][ ns ].append( footer )
147  output[ file_prefix ][ ns ] = header + output[ file_prefix ][ ns ]
148  lines = "".join( output[ file_prefix ][ ns ] )
149  #print outfile
150  f = KeepSameFile(outfile, 'wb')
151  f.write( "".join(lines) )
152  num_changed_files += f.close()
153 
154  f = KeepSameFile('option.cc.include.gen.hh', 'wb')
155  for include_file in gen_hh_files:
156  f.write( '#include <basic/options/keys/' + include_file + '>\n' )
157  num_changed_files += f.close()
158 
159  else:
160  options_class.writeToFile(Options, 'option.cc.gen.hh', options_class.Option.getOptionCC)
161  options_class.writeToFile(Options, 'keys/OptionKeys.gen.hh', options_class.Option.getOptionKeysHH)
162  options_class.writeToFile(Options, 'keys/OptionKeys.cc.gen.hh', options_class.Option.getOptionKeysCC)
163 
164  # Generating Doxygen docs
165  #print "Generating Doxygen docs...",
166  f = KeepSameFile("./options.dox", 'wb')
167  f.write( options_class.getDoxygenPage(Options) )
168  num_changed_files += f.close()
169  #print " Done!"
170  #print "Generating Markdown docs...",
171  f = KeepSameFile("./full-options-list.md", 'wb')
172  f.write( options_class.getMarkdownPage(Options) )
173  num_changed_files += f.close()
174  #print " Done!"
175  print "Number of option files updated:",num_changed_files
176  print "Total %s options." % len(Options)
177 
178  elif args[1] == '-Wiki':
179  print options_class.printWikiTable(Options)
180 
181 
182 if __name__ == "__main__": main(sys.argv)
def main
Definition: options.py:55
Fstring::size_type len(Fstring const &s)
Length.
Definition: Fstring.hh:2207
bool open(utility::io::izstream &db_stream, std::string const &db_file, bool warn)
Open a database file on a provided stream.
Definition: open.cc:55