Salome HOME
max lenght of lines is now 80
[tools/sat.git] / src / options.py
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 #  Copyright (C) 2010-2013  CEA/DEN
4 #
5 #  This library is free software; you can redistribute it and/or
6 #  modify it under the terms of the GNU Lesser General Public
7 #  License as published by the Free Software Foundation; either
8 #  version 2.1 of the License.
9 #
10 #  This library is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 #  Lesser General Public License for more details.
14 #
15 #  You should have received a copy of the GNU Lesser General Public
16 #  License along with this library; if not, write to the Free Software
17 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 '''The Options class that manages the access to all options passed as 
19    parameters in salomeTools command lines
20 '''
21 import getopt
22 import sys
23 from . import printcolors
24
25 class OptResult(object):
26     '''An instance of this class will be the object manipulated
27        in code of all salomeTools commands
28        The aim of this class is to have an elegant syntax 
29        to manipulate the options. 
30        ex: 
31        print(options.level)
32        5
33     '''
34     def __init__(self):
35         '''Initialization
36         '''
37         self.__dict__ = dict()
38
39     def __getattr__(self, name):
40         '''Overwrite of the __getattr__ function 
41            to customize it for option usage
42         
43         :param name str: The attribute to get the value.
44         :return: the value corresponding to the attribute.
45         :rtype: str,int,list,boolean
46         '''
47         if name in self.__dict__:
48             return self.__dict__[name]
49         else:
50             raise AttributeError(name + _(u" is not a valid option"))
51
52     def __setattr__(self, name, value):
53         '''Overwrite of the __setattr__ function 
54            to customize it for option usage
55         
56         :param name str: The attribute to set.
57         :param value str: The value  corresponding to the attribute.
58         :return: Nothing.
59         :rtype: N\A
60         '''
61         object.__setattr__(self,name,value)
62
63 class Options:
64     '''Class to manage all salomeTools options
65     '''
66     def __init__(self):
67         '''Initialization
68         '''
69         # The options field stocks all options of a command 
70         # in a list that contains dicts
71         self.options = []
72         # The list of available option type
73         self.availableOptions = ["boolean", "string", "int", "float",
74                                   "long", "list", "list2"]
75
76     def add_option(self, shortName, longName,
77                     optionType, destName, helpString=""):
78         '''Method to add an option to a command. It gets all attributes
79            of an option and append it in the options field
80         
81         :param shortName str: The short name of the option
82                               (ex "l" for level option).
83         :param longName str: The long name of the option 
84                              (ex "level" for level option).
85         :param optionType str: The type of the option (ex "int").
86         :param destName str: The name that will be used in the code.
87         :param helpString str: The text to display 
88                                when user ask for help on a command.     
89         :return: Nothing.
90         :rtype: N\A
91         '''
92         option = dict()
93         option['shortName'] = shortName
94         option['longName'] = longName
95
96         if optionType not in self.availableOptions:
97             print("error optionType", optionType, "not available.")
98             sys.exit(-1)
99
100         option['optionType'] = optionType
101         option['destName'] = destName
102         option['helpString'] = helpString
103         option['result'] = None
104         self.options.append(option)
105
106     def print_help(self):
107         '''Method that display all options stored in self.options and there help
108         
109         :return: Nothing.
110         :rtype: N\A
111         '''
112         # Do nothing if there are no options
113         if len(self.options) == 0:
114             return
115
116         # for all options, print its values. 
117         # "shortname" is an optional field of the options 
118         print(printcolors.printcHeader(_("Available options are:")))
119         for option in self.options:
120             if 'shortName' in option and len(option['shortName']) > 0:
121                 print(" -%(shortName)1s, --%(longName)s"
122                       " (%(optionType)s)\n\t%(helpString)s\n" % option)
123             else:
124                 print(" --%(longName)s (%(optionType)s)\n\t%(helpString)s\n"
125                        % option)
126
127     def parse_args(self, argList=None):
128         '''Method that instantiates the class OptResult 
129            that gives access to all options in the code
130         
131         :param argList list: the raw list of arguments that were passed
132         :return: optResult, args : optResult is the option instance 
133                                    to manipulate in the code. args 
134                                    is the full raw list of passed options 
135         :rtype: (class 'common.options.OptResult',list)
136         '''
137         if argList is None:
138             argList = sys.argv[1:]
139         
140         # format shortNameOption and longNameOption 
141         # to make right arguments to getopt.getopt function
142         shortNameOption = ""
143         longNameOption = []
144         for option in self.options:
145             shortNameOption = shortNameOption + option['shortName']
146             if option['shortName'] != "" and option['optionType'] != "boolean":
147                 shortNameOption = shortNameOption + ":"
148
149             if option['longName'] != "":
150                 if option['optionType'] != "boolean":
151                     longNameOption.append(option['longName'] + "=")
152                 else:
153                     longNameOption.append(option['longName'])
154
155         # call to getopt.getopt function to get the option 
156         # passed in the command regarding the available options
157         optlist, args = getopt.getopt(argList, shortNameOption, longNameOption)
158         
159         # instantiate and completing the optResult that will be returned
160         optResult = OptResult()
161         for option in self.options:
162             shortOption = "-" + option['shortName']
163             longOption = "--" + option['longName']
164             optionType = option['optionType']
165             for opt in optlist:
166                 if opt[0] in [shortOption, longOption]:
167                     if optionType == "string":
168                         option['result'] = opt[1]
169                     elif optionType == "boolean":
170                         option['result'] = True
171                     elif optionType == "int":
172                         option['result'] = int(opt[1])
173                     elif optionType == "float":
174                         option['result'] = float(opt[1])
175                     elif optionType == "long":
176                         option['result'] = long(opt[1])
177                     elif optionType == "list":
178                         if option['result'] is None:
179                             option['result'] = list()
180                         option['result'].append(opt[1])
181                     elif optionType == "list2":
182                         if option['result'] is None:
183                             option['result'] = list()
184                         if opt[1].find(",") == -1:
185                             option['result'].append(opt[1])
186                         else:
187                             elts = filter(lambda l: len(l) > 0, opt[1].split(","))
188                             option['result'].extend(elts)
189
190             optResult.__setattr__(option['destName'], option['result'])
191             # free the option in order to be able to make 
192             # a new free call of options (API case)
193             option['result'] = None
194         return optResult, args
195