00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 import getopt, sys
00020 import time
00021 import re
00022 import os
00023 import yaml
00024 import copy
00025
00026 default_profile="""
00027 rtcProfile:
00028 version: "1.0"
00029 id: # RTC:SampleVendor.SampleCategory.SampleComponent:1.0.0
00030 basicInfo:
00031 name: ""
00032 description: ""
00033 version: 1.0.0
00034 vendor: SampleVendor
00035 category: ""
00036 componentType: STATIC
00037 activityType: PERIODIC
00038 componentKind: DataFlowComponent
00039 maxInstances: 1
00040 abstract: ""
00041 executionRate: 1000.0
00042 executionType: PeriodicExecutionContext
00043 creationDate:
00044 day: ""
00045 hour: ""
00046 minute: ""
00047 month: ""
00048 second: ""
00049 year: ""
00050 updateDate:
00051 day: 17
00052 hour: 14
00053 minute: 0
00054 month: 4
00055 second: 0
00056 year: 2008
00057 "rtcDoc::doc":
00058 algorithm: ""
00059 creator: ""
00060 description: ""
00061 inout: ""
00062 license: ""
00063 reference: ""
00064 "rtcExt::versionUpLog":
00065 - "2008/04/18 14:00:00:Ver1.0"
00066 - "2008/04/18 17:00:00:Ver1.1"
00067 language:
00068 java:
00069 library:
00070 - library1
00071 actions:
00072 onAborting:
00073 "rtcDoc::doc":
00074 description: on_aborting description
00075 postCondition: on_aborting Post_condition
00076 preCondition: on_aborting Pre_condition
00077 implemented: true
00078 onActivated:
00079 "rtcDoc::doc":
00080 description: on_activated description
00081 postCondition: on_activated Post_condition
00082 preCondition: on_activated Pre_condition
00083 implemented: true
00084 onDeactivated:
00085 "rtcDoc::doc":
00086 description: on_deactivated description
00087 postCondition: on_deactivated Post_condition
00088 preCondition: on_deactivated Pre_condition
00089 onError:
00090 "rtcDoc::doc":
00091 description: on_error description
00092 postCondition: on_error Post_condition
00093 preCondition: on_error Pre_condition
00094 onExecute:
00095 "rtcDoc::doc":
00096 description: on_execute description
00097 postCondition: on_execute Post_condition
00098 preCondition: on_execute Pre_condition
00099 onFinalize:
00100 "rtcDoc::doc":
00101 description: on_finalize description
00102 postCondition: on_finalize Post_condition
00103 preCondition: on_finalize Pre_condition
00104 onInitialize:
00105 "rtcDoc::doc":
00106 description: on_initialize description
00107 postCondition: on_initialize Post_condition
00108 preCondition: on_initialize Pre_condition
00109 implemented: true
00110 onRateChanged:
00111 "rtcDoc::doc":
00112 description: on_rate_changed description
00113 postCondition: on_rate_changed Post_condition
00114 preCondition: on_rate_changed Pre_condition
00115 onReset:
00116 "rtcDoc::doc":
00117 description: on_reset description
00118 postCondition: on_reset Post_condition
00119 preCondition: on_reset Pre_condition
00120 onShutdown:
00121 "rtcDoc::doc":
00122 description: on_shutdown description
00123 postCondition: on_shutdown Post_condition
00124 preCondition: on_shutdown Pre_condition
00125 implemented: true
00126 onStartup:
00127 "rtcDoc::doc":
00128 description: on_startup description
00129 postCondition: on_startup Post_condition
00130 preCondition: on_startup Pre_condition
00131 onStateUpdate:
00132 "rtcDoc::doc":
00133 description: on_state_update description
00134 postCondition: on_state_update Post_condition
00135 preCondition: on_state_update Pre_condition
00136 dataPorts:
00137 -
00138 name: inport1
00139 portType: DataInPort
00140 type: "RTC::TimedLong"
00141 interfaceType: CorbaPort
00142 dataflowType: "Push,Pull"
00143 subscriprionType: "Periodic,New,Flush"
00144 idlFile: DataPort1.idl
00145 "rtcDoc::doc":
00146 type: In1Type
00147 description: In1Description
00148 number: In1Number
00149 occerrence: In1Occerrence
00150 operation: In1Operation
00151 semantics: In1Semantics
00152 unit: In1Unit
00153 "rtcExt::position": LEFT
00154 "rtcExt::varname": In1Var
00155 servicePorts:
00156 -
00157 name: SrvPort1
00158 "rtcDoc::doc":
00159 description: ServicePort1 description
00160 ifdescription: ServicePort1 I/F description
00161 "rtcExt::position": LEFT
00162 serviceInterface:
00163 -
00164 direction: Provided
00165 "rtcDoc::doc":
00166 description: if1 Description
00167 docArgument: if1 Argument
00168 docException: if1 Exception
00169 docPostCondition: if1 PostCond
00170 docPreCondition: if1 PreCond
00171 docReturn: if1 Return
00172 idlFile: IF1Idlfile.idl
00173 instanceName: IF1Instance
00174 name: S1IF1
00175 path: IF1SearchPath
00176 type: IF1Type
00177 varname: IF1VarName
00178 configurationSet:
00179 configuration:
00180 -
00181 name: config1
00182 type: int
00183 varname: var1
00184 defaultValue: ""
00185 "rtcDoc::doc":
00186 constraint: config_constraint1
00187 dataname: dataname1
00188 defaultValue: default1
00189 description: config_Desc1
00190 range: config_range1
00191 unit: config_unit1
00192 parameters:
00193 -
00194 defaultValue: param_def1
00195 name: param1
00196 -
00197 defaultValue: param_def2
00198 name: param2
00199
00200 """
00201
00202
00203 class Struct:
00204 def __init__(self):
00205 return
00206
00207 libdir_path = os.popen("rtm-config --libdir", "r").read().split("\n")
00208 if libdir_path[0] != '':
00209 pyhelper_path = libdir_path[0] + "/py_helper"
00210 sys.path.append(pyhelper_path)
00211 else:
00212 pyhelper_path = os.environ['OPENHRP_SDK_ROOT'] + "/utils/rtc-template"
00213 sys.path.append(pyhelper_path)
00214
00215
00216 opt_args_fmt = ["help",
00217 "module-name=",
00218 "module-type=",
00219 "module-desc=",
00220 "module-version=",
00221 "module-vendor=",
00222 "module-category=",
00223 "module-comp-type=",
00224 "module-act-type=",
00225 "module-max-inst=",
00226 "module-lang=",
00227 "config=",
00228 "inport=",
00229 "outport=",
00230 "service=",
00231 "service-idl=",
00232 "consumer=",
00233 "consumer-idl=",
00234 "idl-include=",
00235 "backend="]
00236
00237
00238 def usage_short():
00239 """
00240 Help message
00241 """
00242 print """
00243 Usage: rtc-template [OPTIONS]
00244
00245 Options:
00246
00247 [-h] Print short help.
00248 [--help] Print details help.
00249 [--backend[=backend] or -b] Specify template code generator.
00250 [--module-name[=name]] Your module name.
00251 [--module-desc[=description]] Module description.
00252 [--module-version[=version]] Module version.
00253 [--module-vendor[=vendor]] Module vendor.
00254 [--module-category[=category]] Module category.
00255 [--module-comp-type[=component_type]] Component type.
00256 [--module-act-type[=activity_type]] Component's activity type.
00257 [--module-max-inst[=max_instance]] Number of maximum instance.
00258 [--module-lang[=language]] Language.
00259 [--config[=ParamName:Type:Default]] Configuration variable.
00260 [--inport[=PortName:Type]] InPort's name and type.
00261 [--outport[=PortName:Type]] OutPort's name and type
00262 [--service[=PortName:Name:Type]] Service Provider Port
00263 [--service-idl[=IDL_file]] IDL file name for service
00264 [--consumer[=PortName:Name:Type]] Service Consumer Port
00265 [--consumer-idl[=IDL_file]] IDL file name for consumer
00266 [--idl-include=[path]] Search path for IDL compile
00267
00268 """
00269 def usage_long():
00270 """
00271 Help message
00272 """
00273 print """
00274 --output[=output_file]:
00275 Specify base name of output file. If 'XXX' is specified,
00276 C++ source codes XXX.cpp, XXX.h, XXXComp.cpp Makefile.XXX is generated.
00277
00278 --module-name[=name]:
00279 Your component's base name. This string is used as module's
00280 name and component's base name. A generated new component
00281 class name is also names as this RTC_MODULE_NAME.
00282 Only alphabetical and numerical characters are acceptable.
00283
00284 --module-desc[=description]:
00285 Short description. If space characters are included, string should be
00286 quoted.
00287
00288 --module-version[=version]:
00289 Your module version. ex. 1.0.0
00290
00291 --module-vendor[=vendor]:
00292 Vendor's name of this component.
00293
00294 --module-category[=category]:
00295 This component module's category. ex. Manipulator MobileRobot, etc...
00296
00297 --module-comp-type[=component_type]:
00298 Specify component type.
00299 'STATIC', 'UNIQUE', 'COMMUTATIVE' are acceptable.
00300
00301 --module-act-type[=activity_type]:
00302 Specify component activity's type.
00303 'PERIODIC', 'SPORADIC', 'EVENT_DRIVEN' ace acceptable.
00304
00305 --module-max-inst[=max_instance]:
00306 Specify maximum number of component instance.
00307
00308 --config=[ParamName:Type:Default]:
00309 Specify configuration value. The 'ParamName' is used as the
00310 configuration value identifier. This character string is also used as
00311 variable name in the source code. The 'Type' is type of configuration
00312 value. The type that can be converted to character string is allowed.
00313 In C++ language, the type should have operators '<<' and '>>' that
00314 are defined as
00315 'istream& operator<<(Type)'
00316 and
00317 'ostream& operator>>(Type)'.
00318
00319 --inport=[PortName:Type]:
00320 Specify InPort's name and type. 'PortName' is used as this InPort's
00321 name. This string is also used as variable name in soruce code.
00322 'Type' is InPort's variable type. The acceptable types are,
00323 Timed[ Short | Long | UShort | ULong | Float | Double | Char | Boolean
00324 | Octet | String ] and its sequence types.
00325
00326 --outport=[PortName:Type]:
00327 Specify OutPort's name and type. 'PortName' is used as this OutPort's
00328 name. This string is also used as variable name in soruce code.
00329 'Type' is OutPort's variable type. The acceptable types are,
00330 Timed[ Short | Long | UShort | ULong | Float | Double | Char | Boolean
00331 | Octet | String ] and its sequence types.
00332
00333 --service=[PortName:Name:Type]:
00334 Specify service name, type and port name.
00335 PortName: The name of Port to which the interface belongs.
00336 This name is used as CorbaPort's name.
00337 Name: The name of the service interface. This name is used as
00338 the name of the interface, instance name and variable name.
00339 Type: The type of the serivce interface.
00340 This name is used as type name of the service.
00341
00342 --service-idl=[IDL filename]:
00343 Specify IDL file of service interface.
00344 For simplicity, please define one interface in one IDL file, although
00345 this IDL file can include two or more interface definition,
00346
00347 --consumer=[PortName:Name:Type]:
00348 Specify consumer name, type and port name.
00349 PortName: The name of Port to which the consumer belongs.
00350 This name is used as CorbaPort's name.
00351 Name: The name of the consumer. This name is used as
00352 the name of the consumer, instance name and variable name.
00353 Type: The serivce interface type that is required by the consumer.
00354 This name is used as type name of the consumer.
00355
00356 --consumer-idl=[IDL filename]:
00357 Specify IDL file of service consumer.
00358 For simplicity, please define one interface in one IDL file, although
00359 this IDL file can include two or more interface definition,
00360
00361
00362 Example:
00363 rtc-template -bcxx \\
00364 --module-name=Sample --module-desc='Sample component' \\
00365 --module-version=0.1 --module-vendor=AIST --module-category=Generic \\
00366 --module-comp-type=DataFlowComponent --module-act-type=SPORADIC \\
00367 --module-max-inst=10 \\
00368 --config=int_param0:int:0 --config=int_param1:int:1 \\
00369 --config=double_param0:double:3.14 --config=double_param1:double:9.99 \\
00370 --config="str_param0:std::string:hoge" \\
00371 --config="str_param1:std::string:foo" \\
00372 --inport=Ref:TimedFloat --inport=Sens:TimedFloat \\
00373 --outport=Ctrl:TimedDouble --outport=Monitor:TimedShort \\
00374 --service=MySvcPort:myservice0:MyService \\
00375 --consumer=YourSvcPort:yourservice0:YourService \\
00376 --service-idl=MyService.idl --consumer-idl=YourService.idl
00377
00378 """
00379 return
00380
00381 def usage():
00382 usage_short()
00383 usage_long()
00384 return
00385
00386
00387 def CreateBasicInfo(opts):
00388 """
00389 MakeModuleProfile
00390
00391 Create ModuleProfile list from command options
00392 """
00393 mapping = {
00394 'name': 'name',
00395 'desc': 'description',
00396 'version': 'version',
00397 'vendor': 'vendor',
00398 'category': 'category',
00399 'comp-type': 'componentType',
00400 'act-type': 'activityType',
00401 'type': 'componentKind',
00402 'max-inst': 'maxInstances'
00403 }
00404
00405 prof = {
00406 "name": "",
00407 "description": "",
00408 "version": "1.0.0",
00409 "vendor": "",
00410 "category": "",
00411 "componentType": "STATIC",
00412 "activityType": "PERIODIC",
00413 "componentKind": "DataFlowComponent",
00414 "maxInstances": "1",
00415 "abstract": "",
00416 "executionRate": "1000.0",
00417 "executionType": "PeriodicExecutionContext",
00418 "creationDate":
00419 {
00420 "day": "",
00421 "hour": "",
00422 "minute": "",
00423 "month": "",
00424 "second": "",
00425 "year": ""
00426 },
00427 "updateDate":
00428 {
00429 "year": "",
00430 "month": "",
00431 "day": "",
00432 "hour": "",
00433 "minute": "",
00434 "second": "",
00435 },
00436 "rtcDoc::doc":
00437 {
00438 "algorithm": "",
00439 "creator": "",
00440 "description": "",
00441 "inout": "",
00442 "license": "",
00443 "reference": ""
00444 },
00445 "rtcExt::versionUpLog": []
00446 }
00447
00448
00449 for opt, arg in opts:
00450 if opt.find("--module-") == 0:
00451 var = opt.replace("--module-","")
00452 if prof.has_key(mapping[var]):
00453 prof[mapping[var]] = arg
00454
00455 cDate = time.localtime()
00456 i = 0
00457 cDateKey = ['year', 'month', 'day', 'hour', 'minute', 'second']
00458 for key in cDateKey:
00459 prof["creationDate"][key] = cDate[i]
00460 i += 1
00461
00462 empty = []
00463 for key in prof.keys():
00464 if prof[key] == "":
00465 empty.append(key)
00466
00467 return prof
00468
00469 def CreateActions(opts):
00470 actnames = [
00471 "onInitialize",
00472 "onFinalize",
00473 "onActivated",
00474 "onDeactivated",
00475 "onAborting",
00476 "onError",
00477 "onReset",
00478 "onExecute",
00479 "onStateUpdate",
00480 "onShutdown",
00481 "onStartup",
00482 "onRateChanged",
00483 ]
00484
00485 actions = {}
00486 for a in actnames:
00487 actions[a] = {
00488 "rtcDoc::doc": {
00489 "description": a + " description",
00490 "postCondition": a + " Post_condition",
00491 "preCondition": a + " Pre_condition"
00492 },
00493 "implemented": True
00494 }
00495 return actions
00496
00497 def CreateConfigurationSet(opts):
00498 """
00499 MakeConfigurationParameters
00500
00501 Create Configuration list from command options
00502 """
00503 prof_list = []
00504 prof = {
00505 "name": "",
00506 "type": "",
00507 "varname": "",
00508 "defaultValue": "",
00509 "rtcDoc::doc":
00510 {
00511 "type": "type",
00512 "constraint": "constraint",
00513 "dataname": "dataname",
00514 "defaultValue": "default",
00515 "description": "description",
00516 "range": "range",
00517 "unit": "unit"
00518 }
00519 }
00520 for opt, arg in opts:
00521 if opt == ("--config"):
00522 try:
00523
00524 arg = re.sub("::", "@@", arg)
00525 name, type, default = arg.split(":")
00526 name = re.sub("@@", "::", name)
00527 type = re.sub("@@", "::", type)
00528 default = re.sub("@@", "::", default)
00529 except:
00530 sys.stderr.write("Invalid option: " \
00531 + opt \
00532 + "=" \
00533 + arg)
00534 tmp = copy.deepcopy(prof)
00535 tmp["name"] = name
00536 tmp["varname"] = name
00537 tmp["l_name"] = name.lower()
00538 tmp["u_name"] = name.upper()
00539 tmp["type"] = type
00540 tmp["defaultValue"] = default
00541 tmp["rtcDoc::doc"]["defaultValue"] = default
00542 prof_list.append(tmp)
00543 return {'configuration': prof_list}
00544
00545
00546 def CreateDataPorts(opts):
00547 """
00548 MakePortProfile
00549
00550 Create PortProfile list from command options
00551 """
00552 prof_list = []
00553 prof = {
00554 "name": "",
00555 "portType": "",
00556 "type": "",
00557 "interfaceType": "CorbaPort",
00558 "dataflowType": "Push,Pull",
00559 "subscriptionType": "Periodic,New,Flush",
00560 "idlFile": "",
00561 "rtcDoc::doc":
00562 {
00563 "type": "",
00564 "description": "",
00565 "number": "",
00566 "occerrence": "",
00567 "operation": "",
00568 "semantics": "",
00569 "unit": ""
00570 },
00571 "rtcExt::position": "",
00572 "rtcExt::varname": ""
00573 }
00574 cnt = 0
00575 portType = {"--inport": "DataInPort", "--outport": "DataOutPort"}
00576 position = {"--inport": "LEFT", "--outport": "RIGHT"}
00577 for opt, arg in opts:
00578 if opt == "--inport" or opt == "--outport":
00579 try:
00580 arg = re.sub("::", "@@", arg)
00581 name, type = arg.split(":")
00582 name = re.sub("@@", "::", name)
00583 type = re.sub("@@", "::", type)
00584 except:
00585 sys.stderr.write("Invalid option: " \
00586 + opt \
00587 + "=" \
00588 + arg)
00589 tmp = copy.deepcopy(prof)
00590 tmp["name"] = name
00591 tmp["portType"] = portType[opt]
00592 tmp["type"] = type
00593 tmp["num"] = cnt
00594 tmp["rtcDoc::doc"]["type"] = type
00595 tmp["rtcDoc::doc"]["number"] = cnt
00596 tmp["rtcExt::varname"] = name
00597 tmp["rtcExt::position"] = position[opt]
00598 prof_list.append(tmp)
00599 cnt += 1
00600 return prof_list
00601
00602
00603 def CreateServicePorts(opts):
00604 """
00605 MakePortInterface
00606
00607 Create Port interface profile list from command options
00608 """
00609 prof_list = []
00610
00611 prof = {
00612 "name": "",
00613 "rtcDoc::doc":
00614 {
00615 "description": "",
00616 "ifdescription": "",
00617 },
00618 "rtcExt::position": "LEFT",
00619 "serviceInterface": []
00620 }
00621 ifprof = {
00622 "name": "",
00623 "type": "",
00624 "direction": "",
00625 "varname": "",
00626 "instanceName": "",
00627 "idlFile": "",
00628 "path": "",
00629 "rtcDoc::doc":
00630 {
00631 "description": "",
00632 "docArgument": "",
00633 "docException": "",
00634 "docPostCondition": "",
00635 "docPreCondition": "",
00636 "docReturn": ""
00637 }
00638 }
00639
00640 def findport(prof_list, port_name):
00641 for p in prof_list:
00642 if p["name"] == port_name:
00643 return p
00644 return None
00645 def lr(port):
00646 cnt = {"Provided": 0, "Required": 0}
00647 for ifprof in port["serviceInterface"]:
00648 cnt[ifprof["direction"]] += 1
00649 if cnt["Provided"] < cnt["Required"]:
00650 return "LEFT"
00651 else:
00652 return "RIGHT"
00653 cnt = 0
00654 ifType = {"--service": "Provided", "--consumer": "Required"}
00655 for opt, arg in opts:
00656 if opt == "--service" or opt == "--consumer":
00657 try:
00658 arg = re.sub("::", "@@", arg)
00659 portname, name, type = arg.split(":")
00660 portname = re.sub("@@", "::", portname)
00661 name = re.sub("@@", "::", name)
00662 type = re.sub("@@", "::", type)
00663 except:
00664 sys.stderr.write("Invalid option: " \
00665 + opt \
00666 + "=" \
00667 + arg)
00668 port = findport(prof_list, portname)
00669 if port == None:
00670 port = copy.deepcopy(prof)
00671 port["name"] = portname
00672 prof_list.append(port)
00673
00674 tmp = copy.deepcopy(ifprof)
00675 tmp["name"] = name
00676 tmp["type"] = type
00677 tmp["direction"] = ifType[opt]
00678 tmp["varname"] = name
00679 tmp["instanceName"] = name
00680 idlfname = FindIdlFile(opts, type)
00681 if idlfname == None:
00682 print "Error:"
00683 print "IDL file not found for a interface: ", type
00684 sys.exit(1)
00685 tmp["idlFile"] = idlfname
00686 port["serviceInterface"].append(tmp)
00687 port["rtcExt::position"] = lr(port)
00688 cnt += 1
00689 return prof_list
00690
00691
00692 def FindIdlFile(opts, ifname):
00693 _re_text = "interface\s+" + ifname
00694 for opt, arg in opts:
00695 if opt == "--service-idl" or opt == "--consumer-idl":
00696 fname = arg
00697 fd = open(fname, "r")
00698 if fd == None:
00699 print "IDL file not found: ", arg
00700 sys.exit(1)
00701 t = fd.read()
00702 if None != re.compile(_re_text).search(t):
00703 fd.close()
00704 return fname
00705 fd.close()
00706 return None
00707
00708 def PickupIDLFiles(dict):
00709 svcidls = {}
00710 cnsidls = {}
00711 for svc in dict["servicePorts"]:
00712 for sif in svc["serviceInterface"]:
00713 if sif["direction"] == "Provided":
00714 svcidls[sif["idlFile"]] = ""
00715 elif sif["direction"] == "Required":
00716 if not svcidls.has_key(sif["idlFile"]):
00717 cnsidls[sif["idlFile"]] = ""
00718 dict["service_idl"] = []
00719 dict["consumer_idl"] = []
00720 for f in svcidls.keys():
00721 idl = {}
00722 idl["idl_fname"] = f
00723 idl["idl_basename"] = f.split(".")[0]
00724 dict["service_idl"].append(idl)
00725 for f in cnsidls.keys():
00726 idl = {}
00727 idl["idl_fname"] = f
00728 idl["idl_basename"] = f.split(".")[0]
00729 dict["consumer_idl"].append(idl)
00730 return
00731
00732 def CreateId(dict):
00733 dict["id"] = "RTC:" + \
00734 dict["basicInfo"]["vendor"] + "." + \
00735 dict["basicInfo"]["category"] + "." + \
00736 dict["basicInfo"]["name"] + ":" + \
00737 dict["basicInfo"]["version"]
00738
00739 def find_opt(opts, value, default):
00740 for opt, arg in opts:
00741 if opt.find(value) == 0:
00742 return arg
00743
00744 return default
00745
00746
00747 def find_opt_list(opts, value, default):
00748 list = []
00749 if len(default) > 0:
00750 list += default
00751 for opt, arg in opts:
00752 if opt == ("--" + value):
00753 list.append(arg)
00754 return list
00755
00756
00757 class Backend:
00758 def __init__(self, mod_name, mod):
00759 self.mod = mod
00760 self.obj = getattr(mod, mod_name)
00761 self.mod_name = mod_name
00762
00763
00764 class BackendLoader:
00765 def __init__(self):
00766 self.backends = {}
00767 self.opts = []
00768 self.available()
00769 return
00770
00771
00772 def available(self):
00773 path_list = [pyhelper_path, "."]
00774 for path in path_list:
00775 for f in os.listdir(path):
00776 if re.compile("_gen.py$").search(f):
00777 mod_name = f.replace(".py", "")
00778 opt_name = f.replace("_gen.py", "")
00779 mod = __import__(mod_name, globals(), locals(), [])
00780 try:
00781 mod.usage()
00782 be = Backend(mod_name, mod)
00783 self.backends[opt_name] = be
00784 except:
00785 pass
00786
00787 return self.backends
00788
00789
00790 def check_args(self, args):
00791 for opt in args:
00792 if opt.find('-b') == 0:
00793 backend_name = opt.replace("-b", "")
00794 if self.backends.has_key(backend_name):
00795 self.opts.append(backend_name)
00796 else:
00797 print "No such backend: ", backend_name
00798 sys.exit(-1)
00799 elif opt.find('--backend=') == 0:
00800 backend_name = opt.replace("--backend=", "")
00801 if self.backends.has_key(backend_name):
00802 self.opts.append(backend_name)
00803 else:
00804 print "No such backend: ", backend_name
00805 sys.exit(-1)
00806 return self.opts
00807
00808
00809 def get_opt_fmts(self):
00810 fmts = []
00811 for be in self.opts:
00812 fmts += self.backends[be].mod.get_opt_fmt()
00813 return fmts
00814
00815
00816 def usage_available(self):
00817 print "The following backends are available."
00818 space = 10
00819 for key in self.backends:
00820 desc = self.backends[key].mod.description()
00821 print " -b" + key + ("." * (space - len(key))) + desc
00822 print """
00823 Backend [xxx] specific help can be available by the following options.
00824 -bxxx --help|-h or --backend=xxx --help|-h
00825 """
00826 return
00827
00828
00829 def usage(self):
00830 for be in self.opts:
00831 print self.backends[be].mod.usage()
00832 print ""
00833 return
00834
00835 def usage_short(self):
00836 for be in self.opts:
00837 print self.backends[be].mod.usage_short()
00838 print ""
00839 return
00840
00841
00842 def generate_code(self, data, opts):
00843 for be in self.opts:
00844 self.backends[be].obj(data, opts).print_all()
00845 return
00846
00847
00848 def fmtd_args(width, args):
00849 arg_fmt = [""]
00850 w = 0
00851 line = 0
00852 for a in args:
00853 w += len(a) + 1
00854 if w > width:
00855 w = len(a) + 1
00856 line += 1
00857 arg_fmt.append("")
00858 arg_fmt[line] += a + " "
00859 return arg_fmt
00860
00861
00862
00863 def main():
00864 global opt_args_fmt
00865
00866 backends = BackendLoader()
00867 backends.check_args(sys.argv[1:])
00868 opt_args_fmt += backends.get_opt_fmts()
00869
00870 try:
00871 opts, args = getopt.getopt(sys.argv[1:], "b:ho:v", opt_args_fmt)
00872 except getopt.GetoptError:
00873 print "Error: Invalid option.", getopt.GetoptError
00874 usage_short()
00875 backends.usage_available()
00876 sys.exit(-1)
00877
00878 if not opts:
00879 usage_short()
00880 backends.usage_available()
00881 sys.exit(-1)
00882
00883 output = None
00884 verbose = False
00885 output_cxx = False
00886 output_python = False
00887
00888 for o, a in opts:
00889 if o == "-v":
00890 verbose = True
00891 if o in ("-h"):
00892 usage_short()
00893 backends.usage_available()
00894 backends.usage_short()
00895 sys.exit(0)
00896 if o in ("--help"):
00897 usage()
00898 backends.usage_available()
00899 backends.usage()
00900 sys.exit(0)
00901 if o in ("-o", "--output"):
00902 output = a
00903
00904
00905 prefix = os.popen("rtm-config --prefix", "r").read().split("\n")
00906 idl_inc = []
00907 if prefix[0] != '':
00908 idl_inc.append(prefix[0] + "/include/rtm/idl")
00909 idl_inc.append(prefix[0] + "/include/rtm")
00910 idl_inc.append(".")
00911
00912
00913 data = {'basicInfo': CreateBasicInfo(opts),
00914 'actions': CreateActions(opts),
00915 'configurationSet': CreateConfigurationSet(opts),
00916 'dataPorts': CreateDataPorts(opts),
00917 'servicePorts': CreateServicePorts(opts),
00918 'args': sys.argv,
00919 'fmtd_args': fmtd_args(70, sys.argv),
00920 'idl_include': idl_inc
00921 }
00922 CreateId(data)
00923 PickupIDLFiles(data)
00924
00925 if not data.has_key('fname'):
00926 data['fname'] = data['basicInfo']['name']
00927 backends.generate_code(data, opts)
00928
00929 import README_gen
00930 readme = README_gen.README_gen(data)
00931 readme.print_all()
00932 import profile_gen
00933 profile = profile_gen.profile_gen(data)
00934 profile.print_all()
00935 return
00936
00937
00938 if __name__ == "__main__":
00939 main()