4 # This file is part of BeRTOS.
6 # Bertos is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
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.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 # As a special exception, you may use this file as part of a free software
21 # library without restriction. Specifically, if other files instantiate
22 # templates or use macros or inline functions from this file, or you compile
23 # this file and link it with other files to produce an executable, this
24 # file does not by itself cause the resulting executable to be covered by
25 # the GNU General Public License. This exception does not however
26 # invalidate any other reasons why the executable file might be covered by
27 # the GNU General Public License.
29 # Copyright 2008 Develer S.r.l. (http://www.develer.com/)
33 # Author: Lorenzo Berni <duplo@develer.com>
41 # Use custom copytree function
47 import DefineException
50 from _wizard_version import WIZARD_VERSION
52 from LoadException import VersionException, ToolchainException
54 def isBertosDir(directory):
55 return os.path.exists(directory + "/VERSION")
57 def bertosVersion(directory):
58 return open(directory + "/VERSION").readline().strip()
60 def setEnabledModules(project_info, enabled_modules):
61 modules = project_info.info("MODULES")
63 for module, information in modules.items():
64 information["enabled"] = module in enabled_modules
65 if information["enabled"]:
66 for dependency in information["depends"]:
67 if not dependency in modules:
68 files[dependency] = files.get(dependency, 0) + 1
69 project_info.setInfo("MODULES", modules)
70 project_info.setInfo("FILES", files)
72 def enabledModules(project_info):
74 for name, module in project_info.info("MODULES").items():
76 enabled_modules.append(name)
77 return enabled_modules
79 def mergeSources(srcdir, new_sources, old_sources):
80 # The current mergeSources function provide only a raw copy of the sources in the
83 # TODO: implement the three way merge algorithm
85 shutil.rmtree(srcdir, True)
86 copytree.copytree(os.path.join(new_sources, "bertos"), srcdir, ignore_list=const.IGNORE_LIST)
88 def projectFileGenerator(project_info):
89 directory = project_info.info("PROJECT_PATH")
92 for module, information in project_info.info("MODULES").items():
93 if information["enabled"]:
94 enabled_modules.append(module)
95 project_data["ENABLED_MODULES"] = enabled_modules
96 # Use the local BeRTOS version instead of the original one
97 # project_data["SOURCES_PATH"] = project_info.info("SOURCES_PATH")
98 project_data["SOURCES_PATH"] = directory
99 project_data["PROJECT_NAME"] = project_info.info("PROJECT_NAME", os.path.basename(directory))
100 project_data["TOOLCHAIN"] = project_info.info("TOOLCHAIN")
101 project_data["CPU_NAME"] = project_info.info("CPU_NAME")
102 project_data["SELECTED_FREQ"] = project_info.info("SELECTED_FREQ")
103 project_data["OUTPUT"] = project_info.info("OUTPUT")
104 project_data["WIZARD_VERSION"] = WIZARD_VERSION
105 return pickle.dumps(project_data)
107 def createBertosProject(project_info, edit=False):
108 directory = project_info.info("PROJECT_PATH")
109 sources_dir = project_info.info("SOURCES_PATH")
110 old_sources_dir = project_info.info("OLD_SOURCES_PATH")
112 if os.path.isdir(directory):
113 shutil.rmtree(directory, True)
114 os.makedirs(directory)
115 # Write the project file
116 f = open(directory + "/project.bertos", "w")
117 f.write(projectFileGenerator(project_info))
120 version_file = open(os.path.join(const.DATA_DIR, "vtemplates/VERSION"), "r").read()
121 open(directory + "/VERSION", "w").write(versionFileGenerator(project_info, version_file))
122 # Destination source dir
123 srcdir = directory + "/bertos"
125 # If not in editing mode it copies all the bertos sources in the /bertos subdirectory of the project
126 shutil.rmtree(srcdir, True)
127 copytree.copytree(sources_dir + "/bertos", srcdir, ignore_list=const.IGNORE_LIST)
128 elif old_sources_dir:
129 # If in editing mode it merges the current bertos sources with the selected ones
130 # TODO: implement the three way merge algotihm
132 mergeSources(srcdir, sources_dir, old_sources_dir)
133 # Destination makefile
134 makefile = directory + "/Makefile"
135 makefile = open(os.path.join(const.DATA_DIR, "mktemplates/Makefile"), 'r').read()
136 makefile = makefileGenerator(project_info, makefile)
137 open(directory + "/Makefile", "w").write(makefile)
138 # Destination project dir
139 # prjdir = directory + "/" + os.path.basename(directory)
140 prjdir = os.path.join(directory, project_info.info("PROJECT_NAME"))
142 shutil.rmtree(prjdir, True)
144 # Destination hw files
145 hwdir = prjdir + "/hw"
147 shutil.rmtree(hwdir, True)
149 # Copy all the hw files
150 for module, information in project_info.info("MODULES").items():
151 for hwfile in information["hw"]:
152 string = open(sources_dir + "/" + hwfile, "r").read()
153 hwfile_path = hwdir + "/" + os.path.basename(hwfile)
154 if not edit or not os.path.exists(hwfile_path):
155 # If not in editing mode it copies all the hw files. If in
156 # editing mode it copies only the files that don't exist yet
157 open(hwdir + "/" + os.path.basename(hwfile), "w").write(string)
158 # Destination configurations files
159 cfgdir = prjdir + "/cfg"
161 shutil.rmtree(cfgdir, True)
163 # Set properly the autoenabled parameters
164 for module, information in project_info.info("MODULES").items():
165 if "configuration" in information and information["configuration"] != "":
166 configurations = project_info.info("CONFIGURATIONS")
167 configuration = configurations[information["configuration"]]
168 for start, parameter in configuration["paramlist"]:
169 if "type" in configuration[parameter]["informations"] and configuration[parameter]["informations"]["type"] == "autoenabled":
170 configuration[parameter]["value"] = "1" if information["enabled"] else "0"
171 project_info.setInfo("CONFIGURATIONS", configurations)
172 # Copy all the configuration files
173 for configuration, information in project_info.info("CONFIGURATIONS").items():
174 string = open(sources_dir + "/" + configuration, "r").read()
175 for start, parameter in information["paramlist"]:
176 infos = information[parameter]
177 value = infos["value"]
178 if "unsigned" in infos["informations"] and infos["informations"]["unsigned"]:
180 if "long" in infos["informations"] and infos["informations"]["long"]:
182 string = sub(string, parameter, value)
183 f = open(cfgdir + "/" + os.path.basename(configuration), "w")
187 # Destination user mk file (only on project creation)
188 makefile = open(os.path.join(const.DATA_DIR, "mktemplates/template.mk"), "r").read()
189 # Deadly performances loss was here :(
190 makefile = userMkGenerator(project_info, makefile)
191 open(prjdir + "/" + os.path.basename(prjdir) + ".mk", "w").write(makefile)
192 # Destination wizard mk file
193 makefile = open(os.path.join(const.DATA_DIR, "mktemplates/template_wiz.mk"), "r").read()
194 makefile = mkGenerator(project_info, makefile)
195 open(prjdir + "/" + os.path.basename(prjdir) + "_wiz.mk", "w").write(makefile)
196 # Destination main.c file
198 main = open(os.path.join(const.DATA_DIR, "srctemplates/main.c"), "r").read()
199 open(prjdir + "/main.c", "w").write(main)
200 # Files for selected plugins
202 for plugin in project_info.info("OUTPUT"):
203 module = loadPlugin(plugin)
204 relevants_files[plugin] = module.createProject(project_info)
205 project_info.setInfo("RELEVANT_FILES", relevants_files)
207 def loadPlugin(plugin):
209 Returns the given plugin module.
211 return getattr(__import__("plugins", {}, {}, [plugin]), plugin)
213 def versionFileGenerator(project_info, version_file):
214 version = bertosVersion(project_info.info("SOURCES_PATH"))
215 return version_file.replace('$version', version)
217 def userMkGenerator(project_info, makefile):
219 mk_data["$pname"] = os.path.basename(project_info.info("PROJECT_PATH"))
220 mk_data["$main"] = os.path.basename(project_info.info("PROJECT_PATH")) + "/main.c"
222 while makefile.find(key) != -1:
223 makefile = makefile.replace(key, mk_data[key])
226 def mkGenerator(project_info, makefile):
228 Generates the mk file for the current project.
231 mk_data["$pname"] = os.path.basename(project_info.info("PROJECT_PATH"))
232 mk_data["$cpuclockfreq"] = project_info.info("SELECTED_FREQ")
233 cpu_mk_parameters = []
234 for key, value in project_info.info("CPU_INFOS").items():
235 if key.startswith(const.MK_PARAM_ID):
236 cpu_mk_parameters.append("%s = %s" %(key.replace("MK", mk_data["$pname"]), value))
237 mk_data["$cpuparameters"] = "\n".join(cpu_mk_parameters)
238 mk_data["$csrc"], mk_data["$pcsrc"], mk_data["$cppasrc"], mk_data["$cxxsrc"], mk_data["$asrc"], mk_data["$constants"] = csrcGenerator(project_info)
239 mk_data["$prefix"] = replaceSeparators(project_info.info("TOOLCHAIN")["path"].split("gcc")[0])
240 mk_data["$suffix"] = replaceSeparators(project_info.info("TOOLCHAIN")["path"].split("gcc")[1])
241 mk_data["$main"] = os.path.basename(project_info.info("PROJECT_PATH")) + "/main.c"
243 while makefile.find(key) != -1:
244 makefile = makefile.replace(key, mk_data[key])
247 def makefileGenerator(project_info, makefile):
249 Generate the Makefile for the current project.
251 # TODO write a general function that works for both the mk file and the Makefile
252 while makefile.find("$pname") != -1:
253 makefile = makefile.replace("$pname", os.path.basename(project_info.info("PROJECT_PATH")))
256 def csrcGenerator(project_info):
257 modules = project_info.info("MODULES")
258 files = project_info.info("FILES")
259 if "harvard" in project_info.info("CPU_INFOS")["CPU_TAGS"]:
263 # file to be included in CSRC variable
265 # file to be included in PCSRC variable
267 # files to be included in CPPASRC variable
269 # files to be included in CXXSRC variable
271 # files to be included in ASRC variable
273 # constants to be included at the beginning of the makefile
275 for module, information in modules.items():
276 module_files = set([])
277 dependency_files = set([])
280 hwdir = os.path.basename(project_info.info("PROJECT_PATH")) + "/hw"
281 if information["enabled"]:
282 if "constants" in information:
283 constants.update(information["constants"])
284 cfiles, sfiles = findModuleFiles(module, project_info)
285 module_files |= set(cfiles)
286 asm_files |= set(sfiles)
287 for file in information["hw"]:
288 if file.endswith(".c"):
289 module_files |= set([hwdir + "/" + os.path.basename(file)])
290 for file_dependency in information["depends"] + tuple(files.keys()):
291 dependencyCFiles, dependencySFiles = findModuleFiles(file_dependency, project_info)
292 dependency_files |= set(dependencyCFiles)
293 asm_files |= set(dependencySFiles)
294 for file in module_files:
295 if not harvard or information.get("harvard", "both") == "both":
297 if harvard and "harvard" in information:
299 for file in dependency_files:
301 for file in project_info.info("CPU_INFOS")["C_SRC"]:
303 for file in project_info.info("CPU_INFOS")["PC_SRC"]:
305 for file in asm_files:
307 for file in project_info.info("CPU_INFOS")["CPPA_SRC"]:
309 for file in project_info.info("CPU_INFOS")["CXX_SRC"]:
311 for file in project_info.info("CPU_INFOS")["ASRC"]:
314 csrc = " \\\n\t".join(csrc) + " \\"
316 pcsrc = " \\\n\t".join(pcsrc) + " \\"
317 cppasrc = set(cppasrc)
318 cppasrc = " \\\n\t".join(cppasrc) + " \\"
320 cxxsrc = " \\\n\t".join(cxxsrc) + " \\"
322 asrc = " \\\n\t".join(asrc) + " \\"
323 constants = "\n".join([os.path.basename(project_info.info("PROJECT_PATH")) + "_" + key + " = " + unicode(value) for key, value in constants.items()])
324 return csrc, pcsrc, cppasrc, cxxsrc, asrc, constants
326 def findModuleFiles(module, project_info):
327 # Find the files related to the selected module
330 # .c files related to the module and the cpu architecture
331 for filename, path in project_info.searchFiles(module + ".c") + \
332 project_info.searchFiles(module + "_" + project_info.info("CPU_INFOS")["TOOLCHAIN"] + ".c"):
333 path = path.replace(project_info.info("SOURCES_PATH") + os.sep, "")
334 path = replaceSeparators(path)
335 cfiles.append(path + "/" + filename)
336 # .s files related to the module and the cpu architecture
337 for filename, path in project_info.searchFiles(module + ".s") + \
338 project_info.searchFiles(module + "_" + project_info.info("CPU_INFOS")["TOOLCHAIN"] + ".s") + \
339 project_info.searchFiles(module + ".S") + \
340 project_info.searchFiles(module + "_" + project_info.info("CPU_INFOS")["TOOLCHAIN"] + ".S"):
341 path = path.replace(project_info.info("SOURCES_PATH") + os.sep, "")
342 path = replaceSeparators(path)
343 sfiles.append(path + "/" + filename)
344 # .c and .s files related to the module and the cpu tags
345 for tag in project_info.info("CPU_INFOS")["CPU_TAGS"]:
346 for filename, path in project_info.searchFiles(module + "_" + tag + ".c"):
347 path = path.replace(project_info.info("SOURCES_PATH") + os.sep, "")
349 path = replaceSeparators(path)
350 cfiles.append(path + "/" + filename)
351 for filename, path in project_info.searchFiles(module + "_" + tag + ".s") + \
352 project_info.searchFiles(module + "_" + tag + ".S"):
353 path = path.replace(project_info.info("SOURCES_PATH") + os.sep, "")
354 path = replaceSeparators(path)
355 sfiles.append(path + "/" + filename)
356 return cfiles, sfiles
358 def replaceSeparators(path):
360 Replace the separators in the given path with unix standard separator.
363 while path.find(os.sep) != -1:
364 path = path.replace(os.sep, "/")
368 path = os.environ["PATH"]
370 path = path.split(";")
372 path = path.split(":")
375 def findToolchains(path_list):
377 for element in path_list:
378 for toolchain in glob.glob(element+ "/" + const.GCC_NAME):
379 toolchains.append(toolchain)
380 return list(set(toolchains))
382 def getToolchainInfo(output):
384 expr = re.compile("Target: .*")
385 target = expr.findall(output)
387 info["target"] = target[0].split("Target: ")[1]
388 expr = re.compile("gcc version [0-9,.]*")
389 version = expr.findall(output)
390 if len(version) == 1:
391 info["version"] = version[0].split("gcc version ")[1]
392 expr = re.compile("gcc version [0-9,.]* \(.*\)")
393 build = expr.findall(output)
395 build = build[0].split("gcc version ")[1]
396 build = build[build.find("(") + 1 : build.find(")")]
397 info["build"] = build
398 expr = re.compile("Configured with: .*")
399 configured = expr.findall(output)
400 if len(configured) == 1:
401 info["configured"] = configured[0].split("Configured with: ")[1]
402 expr = re.compile("Thread model: .*")
403 thread = expr.findall(output)
405 info["thread"] = thread[0].split("Thread model: ")[1]
408 def getToolchainName(toolchain_info):
409 name = "GCC " + toolchain_info["version"] + " - " + toolchain_info["target"].strip()
412 def loadCpuInfos(project_info):
414 for definition in project_info.findDefinitions(const.CPU_DEFINITION):
415 cpuInfos.append(getInfos(definition))
418 def getTagSet(cpu_info):
421 tag_set |= set([cpu["CPU_NAME"]])
422 tag_set |= set(cpu["CPU_TAGS"])
423 tag_set |= set([cpu["TOOLCHAIN"]])
427 def getInfos(definition):
429 D.update(const.CPU_DEF)
430 def include(filename, dict = D, directory=definition[1]):
431 execfile(directory + "/" + filename, {}, D)
432 D["include"] = include
433 include(definition[0], D)
434 D["CPU_NAME"] = definition[0].split(".")[0]
435 D["DEFINITION_PATH"] = definition[1] + "/" + definition[0]
439 def getCommentList(string):
440 comment_list = re.findall(r"/\*{2}\s*([^*]*\*(?:[^/*][^*]*\*+)*)/", string)
441 comment_list = [re.findall(r"^\s*\* *(.*?)$", comment, re.MULTILINE) for comment in comment_list]
444 def loadModuleDefinition(first_comment):
446 module_definition = {}
447 for num, line in enumerate(first_comment):
448 index = line.find("$WIZ$")
452 exec line[index + len("$WIZ$ "):] in {}, module_definition
454 raise ParseError(num, line[index:])
455 elif line.find("\\brief") != -1:
456 module_definition["module_description"] = line[line.find("\\brief") + len("\\brief "):]
458 if "module_name" in module_definition:
459 module_name = module_definition[const.MODULE_DEFINITION["module_name"]]
460 del module_definition[const.MODULE_DEFINITION["module_name"]]
461 module_dict[module_name] = {}
462 if const.MODULE_DEFINITION["module_depends"] in module_definition:
463 depends = module_definition[const.MODULE_DEFINITION["module_depends"]]
464 del module_definition[const.MODULE_DEFINITION["module_depends"]]
465 if type(depends) == str:
467 module_dict[module_name]["depends"] = depends
469 module_dict[module_name]["depends"] = ()
470 if const.MODULE_DEFINITION["module_configuration"] in module_definition:
471 module_dict[module_name]["configuration"] = module_definition[const.MODULE_DEFINITION["module_configuration"]]
472 del module_definition[const.MODULE_DEFINITION["module_configuration"]]
474 module_dict[module_name]["configuration"] = ""
475 if "module_description" in module_definition:
476 module_dict[module_name]["description"] = module_definition["module_description"]
477 del module_definition["module_description"]
478 if const.MODULE_DEFINITION["module_harvard"] in module_definition:
479 harvard = module_definition[const.MODULE_DEFINITION["module_harvard"]]
480 module_dict[module_name]["harvard"] = harvard
481 del module_definition[const.MODULE_DEFINITION["module_harvard"]]
482 if const.MODULE_DEFINITION["module_hw"] in module_definition:
483 hw = module_definition[const.MODULE_DEFINITION["module_hw"]]
484 del module_definition[const.MODULE_DEFINITION["module_hw"]]
487 module_dict[module_name]["hw"] = hw
489 module_dict[module_name]["hw"] = ()
490 if const.MODULE_DEFINITION["module_supports"] in module_definition:
491 supports = module_definition[const.MODULE_DEFINITION["module_supports"]]
492 del module_definition[const.MODULE_DEFINITION["module_supports"]]
493 module_dict[module_name]["supports"] = supports
494 module_dict[module_name]["constants"] = module_definition
495 module_dict[module_name]["enabled"] = False
496 return to_be_parsed, module_dict
498 def isSupported(project, module=None, property_id=None):
499 if not module and property_id:
500 item = project.info("CONFIGURATIONS")[property_id[0]][property_id[1]]["informations"]
502 item = project.info("MODULES")[module]
503 tag_dict = project.info("ALL_CPU_TAGS")
504 if "supports" in item:
505 support_string = item["supports"]
508 exec "supported = " + support_string in tag_dict, supported
510 raise SupportedException(support_string)
511 return supported["supported"]
515 def loadDefineLists(comment_list):
517 for comment in comment_list:
518 for num, line in enumerate(comment):
519 index = line.find("$WIZ$")
522 exec line[index + len("$WIZ$ "):] in {}, define_list
524 raise ParseError(num, line[index:])
525 for key, value in define_list.items():
526 if type(value) == str:
527 define_list[key] = (value,)
530 def getDescriptionInformations(comment):
532 Take the doxygen comment and strip the wizard informations, returning the tuple
533 (comment, wizard_information)
538 for num, line in enumerate(comment):
539 index = line.find("$WIZ$")
542 brief += line[:index].strip()
544 description += " " + line[:index]
546 exec line[index + len("$WIZ$ "):] in {}, information
548 raise ParseError(num, line[index:])
551 brief += line.strip()
553 description += " " + line
554 description = description.strip()
555 return brief.strip(), description.strip(), information
557 def getDefinitionBlocks(text):
559 Take a text and return a list of tuple (description, name-value).
562 block_tmp = re.finditer(r"/\*{2}\s*([^*]*\*(?:[^/*][^*]*\*+)*)/\s*#define\s+((?:[^/]*?/?)+)\s*?(?:/{2,3}[^<].*?)?$", text, re.MULTILINE)
563 for match in block_tmp:
564 # Only the first element is needed
565 comment = match.group(1)
566 define = match.group(2)
567 start = match.start()
568 block.append(([re.findall(r"^\s*\* *(.*?)$", line, re.MULTILINE)[0] for line in comment.splitlines()], define, start))
569 for match in re.finditer(r"/{3}\s*([^<].*?)\s*#define\s+((?:[^/]*?/?)+)\s*?(?:/{2,3}[^<].*?)?$", text, re.MULTILINE):
570 comment = match.group(1)
571 define = match.group(2)
572 start = match.start()
573 block.append(([comment], define, start))
574 for match in re.finditer(r"#define\s*(.*?)\s*/{3}<\s*(.+?)\s*?(?:/{2,3}[^<].*?)?$", text, re.MULTILINE):
575 comment = match.group(2)
576 define = match.group(1)
577 start = match.start()
578 block.append(([comment], define, start))
581 def formatParamNameValue(text):
583 Take the given string and return a tuple with the name of the parameter in the first position
584 and the value in the second.
586 block = re.findall("\s*([^\s]+)\s*(.+?)\s*$", text, re.MULTILINE)
589 def loadConfigurationInfos(path):
591 Return the module configurations found in the given file as a dict with the
592 parameter name as key and a dict containig the fields above as value:
593 "value": the value of the parameter
594 "description": the description of the parameter
595 "informations": a dict containig optional informations:
596 "type": "int" | "boolean" | "enum"
597 "min": the minimum value for integer parameters
598 "max": the maximum value for integer parameters
599 "long": boolean indicating if the num is a long
600 "unsigned": boolean indicating if the num is an unsigned
601 "value_list": the name of the enum for enum parameters
602 "conditional_deps": the list of conditional dependencies for boolean parameters
604 configuration_infos = {}
605 configuration_infos["paramlist"] = []
606 for comment, define, start in getDefinitionBlocks(open(path, "r").read()):
607 name, value = formatParamNameValue(define)
608 brief, description, informations = getDescriptionInformations(comment)
609 configuration_infos["paramlist"].append((start, name))
610 configuration_infos[name] = {}
611 configuration_infos[name]["value"] = value
612 configuration_infos[name]["informations"] = informations
613 if not "type" in configuration_infos[name]["informations"]:
614 configuration_infos[name]["informations"]["type"] = findParameterType(configuration_infos[name])
615 if ("type" in configuration_infos[name]["informations"] and
616 configuration_infos[name]["informations"]["type"] == "int" and
617 configuration_infos[name]["value"].find("L") != -1):
618 configuration_infos[name]["informations"]["long"] = True
619 configuration_infos[name]["value"] = configuration_infos[name]["value"].replace("L", "")
620 if ("type" in configuration_infos[name]["informations"] and
621 configuration_infos[name]["informations"]["type"] == "int" and
622 configuration_infos[name]["value"].find("U") != -1):
623 configuration_infos[name]["informations"]["unsigned"] = True
624 configuration_infos[name]["value"] = configuration_infos[name]["value"].replace("U", "")
625 if "conditional_deps" in configuration_infos[name]["informations"]:
626 if (type(configuration_infos[name]["informations"]["conditional_deps"]) == str or
627 type(configuration_infos[name]["informations"]["conditional_deps"]) == unicode):
628 configuration_infos[name]["informations"]["conditional_deps"] = (configuration_infos[name]["informations"]["conditional_deps"], )
629 elif type(configuration_infos[name]["informations"]["conditional_deps"]) == tuple:
632 configuration_infos[name]["informations"]["conditional_deps"] = ()
633 configuration_infos[name]["description"] = description
634 configuration_infos[name]["brief"] = brief
635 return configuration_infos
637 def updateConfigurationValues(def_conf, user_conf):
638 for param in def_conf["paramlist"]:
639 if param[1] in user_conf and "value" in user_conf[param[1]]:
640 def_conf[param[1]]["value"] = user_conf[param[1]]["value"]
643 def findParameterType(parameter):
644 if "value_list" in parameter["informations"]:
646 if "min" in parameter["informations"] or "max" in parameter["informations"] or re.match(r"^\d+U?L?$", parameter["value"]) != None:
649 def sub(string, parameter, value):
651 Substitute the given value at the given parameter define in the given string
653 return re.sub(r"(?P<define>#define\s+" + parameter + r"\s+)([^\s]+)", r"\g<define>" + value, string)
655 def isInt(informations):
657 Return True if the value is a simple int.
659 if ("long" not in informatios or not informations["long"]) and ("unsigned" not in informations or informations["unsigned"]):
664 def isLong(informations):
666 Return True if the value is a long.
668 if "long" in informations and informations["long"] and "unsigned" not in informations:
673 def isUnsigned(informations):
675 Return True if the value is an unsigned.
677 if "unsigned" in informations and informations["unsigned"] and "long" not in informations:
682 def isUnsignedLong(informations):
684 Return True if the value is an unsigned long.
686 if "unsigned" in informations and "long" in informations and informations["unsigned"] and informations["long"]:
691 class ParseError(Exception):
692 def __init__(self, line_number, line):
693 Exception.__init__(self)
694 self.line_number = line_number
697 class SupportedException(Exception):
698 def __init__(self, support_string):
699 Exception.__init__(self)
700 self.support_string = support_string