def generateTestCode(classes, buildTags, tags, macroDefs): [testMacros, testResultUtilities]=setResultCode() codeDogParser.AddToObjectFromText(classes[0], classes[1], testResultUtilities , 'Test utility functions') TestSpecFile= progSpec.fetchTagValue([tags, buildTags], 'TestSpec') TestSpecStr = progSpec.stringFromFile(TestSpecFile) + testMacros #print "#################################\n", TestSpecStr [testTagStore, testBuildSpecs, testClasses, newTestClasses] = codeDogParser.parseCodeDogString(TestSpecStr, classes[0], classes[1], macroDefs, "TestDog Specification") # Replace runcode if it isn't there # Here: generate EXEC_TESTS() and RUN_TEST() TestsToRun = progSpec.fetchTagValue([testTagStore], 'TestsToRun') TestList = TestsToRun.split() TestArrayText="" SwitchCaseText="" count=0 for T in TestList: if count>0: TestArrayText+=", " SwitchCaseText+="else " count+=1 TestArrayText += '"'+T+'"' SwitchCaseText += 'if(testName=="'+T+'"){' + T.replace('/', '_') +'()}\n' testBedUtilities = setUtilityCode(TestArrayText, SwitchCaseText) # print "TEST TEXT:", testBedUtilities codeDogParser.AddToObjectFromText(classes[0], classes[1], testBedUtilities, 'Test code' ) return testTagStore
def CreateStructsForStringModels(classes, newClasses, tags): # Define fieldResult struct #~ structsName = 'fetchResult' #~ StructFieldStr = "mode [fetchOK, fetchNotReady, fetchSyntaxError, FetchIO_Error] : FetchResult" #~ progSpec.addObject(classes[0], classes[1], structsName, 'struct', 'SEQ') #~ codeDogParser.AddToObjectFromText(classes[0], classes[1], progSpec.wrapFieldListInObjectDef(structsName, StructFieldStr)) if len(newClasses)==0: return populateBaseRules() global extracterFunctionAccumulator extracterFunctionAccumulator="" global nextParseNameID nextParseNameID=0 numStringStructs=0 for className in newClasses: if className[0] == '!': continue ObjectDef = classes[0][className] if(ObjectDef['stateType'] == 'string'): className=className[1:] cdlog(1, " Writing parse system for "+className) numStringStructs+=1 fields = ObjectDef["fields"] configType= ObjectDef['configType'] classTags = ObjectDef['tags'] if 'StartSymbol' in classTags: writeParserWrapperFunction(classes, className) SeqOrAlt='' if configType=='SEQ': SeqOrAlt='parseSEQ' # seq has {} elif configType=='ALT': SeqOrAlt='parseALT' # alt has [] normedObjectName = className.replace('::', '_') if normedObjectName==className: normedObjectName+='_str' # Write the rules for all the fields, and a parent rule which is either SEQ or ALT, and REP/OPT as needed. cdlog(2, "CODING Parser Rules for {}".format(normedObjectName)) ruleID = writeNonTermParseRule(classes, tags, normedObjectName, fields, SeqOrAlt, '', 3) if SeqOrAlt=='parseSEQ': [memObj, memVersionName]=fetchMemVersion(classes, className) if memObj!=None: Write_Extracter(classes, className, className, 2) else: cdlog(2, "NOTE: Skipping {} because it has no struct version defined.".format(className)) if numStringStructs==0: return ExtracterCode = extracterFunctionAccumulator ############ Add struct parser parserCode=genParserCode() codeDogParser.AddToObjectFromText(classes[0], classes[1], parserCode, 'Parser for '+className) structsName='EParser' progSpec.addObject(classes[0], classes[1], structsName, 'struct', 'SEQ') codeDogParser.AddToObjectFromText(classes[0], classes[1], progSpec.wrapFieldListInObjectDef(structsName, ExtracterCode), 'class '+structsName)
def addOrAmendClasses(self, classes, className, modelRef): self.textFuncBody = ' me string: S <- "{\\n"\n' + ' me string: indent2 <- indent + " "\n' + self.textFuncBody + ' S <- S + indent + "}\\n"\n' Code = ' me string: asProteus(me string:indent <- "") <- {\n' + self.textFuncBody + " return(S)\n }" Code = progSpec.wrapFieldListInObjectDef(className, Code) #print"Code=",Code codeDogParser.AddToObjectFromText(classes[0], classes[1], Code, className + '.asProteus()')
def generateMainFunctionality(classes, tags): # TODO: Some deInitialize items should automatically run during abort(). # TODO: System initCode should happen first in initialize, last in deinitialize. runCode = progSpec.fetchTagValue(tags, 'runCode') Platform = progSpec.fetchTagValue(tags, 'Platform') if Platform != 'Android': mainFuncCode = """ me void: main( ) <- { initialize(String.join(" ", args)) """ + runCode + """ deinitialize() endFunc() } """ if Platform == 'Android': mainFuncCode = """ me void: runDogCode() <- { """ + runCode + """ } """ progSpec.addObject(classes[0], classes[1], 'GLOBAL', 'struct', 'SEQ') codeDogParser.AddToObjectFromText( classes[0], classes[1], progSpec.wrapFieldListInObjectDef('GLOBAL', mainFuncCode), 'Java start-up code')
def apply(classes, tags, keyType, valueType): print("APPLY: in Apply\n") CODE = classString CODE = CODE.replace("<KEY_TYPE>", keyType) CODE = CODE.replace("<VALUE_TYPE>", valueType) codeDogParser.AddToObjectFromText(classes[0], classes[1], CODE, "map<keyType,valueType>") return
def addGLOBALSpecialCode(classes, tags, xlator): filename = makeTagText(tags, 'FileName') specialCode = 'const string: filename <- "' + filename + '"\n' GLOBAL_CODE = """ struct GLOBAL{ %s } """ % (specialCode) codeDogParser.AddToObjectFromText(classes[0], classes[1], GLOBAL_CODE, 'Java special code')
def apply(classes, tags, topClassName): print('APPLY: in Apply\n') global classesToProcess global classesEncoded classesEncoded = {} # Choose an appropriate app style appStyle = 'default' topWhichScreenFieldID = topClassName + '::whichScreen(int)' if (progSpec.doesClassDirectlyImlementThisField( classes[0], topClassName, topWhichScreenFieldID)): # if all data fields are classes appStyle = 'Z_stack' else: appStyle = 'TabbedStack' guiStructName = topClassName + '_GUI' classesEncoded[guiStructName] = 1 classesToProcess = [[topClassName, 'struct', appStyle, guiStructName]] # Amend items to each GUI data class for classToAmend in classesToProcess: [className, widgetType, dialogStyle, newStructName] = classToAmend cdlog( 1, 'BUILDING ' + dialogStyle + ' GUI for ' + widgetType + ' ' + className + ' (' + newStructName + ')') if widgetType == 'struct': BuildGuiForStruct(classes, className, dialogStyle, newStructName) #elif widgetType == 'list': #buildListRowView(classes, className, dialogStyle, newStructName) # Fill createAppArea() primaryGUIName = 'primary_GUI_Mgr' CODE = ''' struct APP{ our ''' + topClassName + ''': primary our ''' + guiStructName + ''': <PRIMARY_GUI> me void: createAppArea(me GUI_Frame: frame) <- { Allocate(primary) Allocate(<PRIMARY_GUI>) their GUI_storyBoard: appStoryBoard <- <PRIMARY_GUI>.initWidget(primary) initializeAppGui() addToContainerAndExpand (frame, appStoryBoard) } }''' CODE = CODE.replace('<PRIMARY_GUI>', primaryGUIName) #print ('==========================================================\n'+CODE) codeDogParser.AddToObjectFromText(classes[0], classes[1], CODE, 'APP') return
def Write_structExtracter(classes, ToStructName, FromStructName, fields, nameForFunc, logLvl): global extracterFunctionAccumulator global parserFunctionAccumulator memObjFields = [] progSpec.populateCallableStructFields(memObjFields, classes, ToStructName) if memObjFields == None: cdErr("struct {} is not defined".format( ToStructName.replace('str', 'mem'))) S = ' me string: tmpStr;\n' advance = False for field in fields: # Extract all the fields in the string version. S += Write_fieldExtracter(classes, ToStructName, field, memObjFields, 'SRec', '', advance, '', ' ', 0, logLvl + 1) advance = True if ToStructName == FromStructName: if progSpec.doesClassContainFunc(classes, ToStructName, 'postParseProcessing'): postParseFuncName = "postParseProcessing_" + ToStructName S += " " + postParseFuncName + "(memStruct, SRec0)\n" newStructtxt = '\n struct ' + ToStructName + '{flag: postParseProcessed}\n' codeDogParser.AddToObjectFromText( classes[0], classes[1], newStructtxt, 'Adding ' + ToStructName + '{flag: postParseProcessed}') pppFunc = "\n void: " + postParseFuncName + "(their " + ToStructName + ": item, our stateRec: SRec) <- {item.postParseProcessing(); item.postParseProcessed<-true}\n" extracterFunctionAccumulator += pppFunc elif progSpec.doesClassContainFunc(classes, ToStructName, 'postParseProcessingEtc'): postParseFuncName = "postParseProcessingEtc_" + ToStructName S += " EP." + postParseFuncName + "(memStruct, SRec0)\n memStruct.postParseProcessed<-true\n" newStructtxt = '\n struct ' + ToStructName + '{flag: postParseProcessed}\n' codeDogParser.AddToObjectFromText( classes[0], classes[1], newStructtxt, 'Adding ' + ToStructName + '{flag: postParseProcessed}') pppFunc = "\n void: " + postParseFuncName + "(their " + ToStructName + ": item, our stateRec: SRec) <- {print(\"Override this function!\")}\n" parserFunctionAccumulator += pppFunc return S
def apply(classes, tags, topClassName): print "APPLY: in Apply\n" global classesToProcess global classesEncoded classesEncoded={} # Choose an appropriate app style appStyle='default' topWhichScreenFieldID = topClassName+'::whichScreen(int)' if (progSpec.doesClassDirectlyImlementThisField(classes[0], topClassName, topWhichScreenFieldID)): # if all data fields are classes appStyle='Z_stack' else: appStyle='TabbedStack' guiStructName = topClassName+'_GUI' classesEncoded[guiStructName]=1 classesToProcess=[[topClassName, 'struct', appStyle, guiStructName]] # Amend items to each GUI data class for classToAmend in classesToProcess: [className, widgetType, dialogStyle, newStructName] = classToAmend cdlog(1, "BUILDING "+dialogStyle+" GUI for "+widgetType+" " + className + ' ('+newStructName+')') if widgetType == 'struct': BuildGuiForStruct(classes, className, dialogStyle, newStructName) elif widgetType == 'list': BuildGuiForList(classes, className, dialogStyle, newStructName) # Fill createAppArea() primaryGUIName = 'primary_GUI_Mgr' primaryMakerFuncName = 'make'+topClassName[0].upper() + topClassName[1:]+'Widget' CODE =''' struct APP{ our <TOPCLASSNAME>: primary our <GUI_STRUCTNAME>: <PRIMARY_GUI> me void: createAppArea(me GUI_Frame: frame) <- { Allocate(primary) Allocate(<PRIMARY_GUI>) their GUI_storyBoard: appStoryBoard <- <PRIMARY_GUI>.<PRIMARY_MAKERFUNCNAME>(primary) initializeAppGui() gui.addToContainerAndExpand (frame, appStoryBoard) } }''' CODE = CODE.replace('<PRIMARY_GUI>', primaryGUIName) CODE = CODE.replace('<TOPCLASSNAME>', topClassName) CODE = CODE.replace('<GUI_STRUCTNAME>', guiStructName) CODE = CODE.replace('<PRIMARY_MAKERFUNCNAME>', primaryMakerFuncName) #print '==========================================================\n'+CODE codeDogParser.AddToObjectFromText(classes[0], classes[1], CODE, 'APP') return
def addGlobalCode(self, classes): if structDrawingWriter.structDrawGlobalsWritten: return else: structDrawingWriter.structDrawGlobalsWritten = True CODE = ''' struct GLOBAL{ const int: fontSize <- 10 me bool: isNull(me string: value) <- { if(value=="0" or value=="''" or value=="Size:0" or value=="NULL" or value=="false"){return(true)} else{return(false)} } } ''' codeDogParser.AddToObjectFromText(classes[0], classes[1], CODE, 'Global functions to draw structs')
def generateMainFunctionality(classes, tags): # TODO: Make initCode, runCode and deInitCode work better and more automated by patterns. # TODO: Some deInitialize items should automatically run during abort(). # TODO: Deinitialize items should happen in reverse order. runCode = progSpec.fetchTagValue(tags, 'runCode') mainFuncCode=""" me void: main() <- { //initialize() """ + runCode + """ //deinitialize() } """ progSpec.addObject(classes[0], classes[1], 'GLOBAL', 'struct', 'SEQ') codeDogParser.AddToObjectFromText(classes[0], classes[1], progSpec.wrapFieldListInObjectDef('GLOBAL', mainFuncCode ), 'Swift start-up code')
def apply(classes, tags, classesToTrack): S = "" if isinstance(classesToTrack, str): classesToTrack = [classesToTrack] for className in classesToTrack: if className in classesTracked: continue else: classesTracked[className] = True C = ''' struct <CLASSNAME> { we uint: symbolCount <- 0 we Map<me uint, me uint>: ptrToUint we string: classTag <- "<CLASSNAME>" we Mutex: chkMySymbol me string: mySymbol() <- { // find or generate symbol their <CLASSNAME>: obj <- self if(obj==NULL){return("NULL")} protect(chkMySymbol){ me uint: objID <- uniqueObjectID(obj) if(! ptrToUint.containsKey(objID)){ symbolCount <+- 1 ptrToUint[objID] <- symbolCount return(classTag + toString(symbolCount)) } else { me uint: item <- ptrToUint.at(objID) me uint: symbol <- item return(classTag + toString(symbol)) } } } // their <CLASSNAME>: classPtrFromSymbol(me string: symbol) <- {} // what about our, my, me, ...? void: clearSymbol(their <CLASSNAME>: obj) <- { protect(chkMySymbol){ me uint: objID <- uniqueObjectID(obj) ptrToUint.erase(objID) } } '''.replace("<CLASSNAME>", className) C += "}\n" S += C + "\n" #print(S) codeDogParser.AddToObjectFromText(classes[0], classes[1], S, 'Pattern: generate symbols')
def getListWidgetMgrCode(classes, listManagerStructName, rowTypeName, fieldName, classOptionsTags): # New listWidgetMgr code generator # Find the model rowWidgetName = rowTypeName + 'Widget' listWidgetStyle = progSpec.fetchTagValue([classOptionsTags], fieldName + '.style.widgetStyle') if listWidgetStyle == None: listWidgetStyle = 'simpleList' modelRef = progSpec.findSpecOf(classes[0], rowWidgetName, 'struct') if modelRef == None: print("modelRef: ", modelRef, rowTypeName) addNewStructToProcess(rowWidgetName, rowTypeName, 'struct', 'rowWidget') filename = './preDynamicTypes/' + listWidgetStyle + '.dog' classSpec = progSpec.stringFromFile(filename) classSpec = classSpec.replace('<ROW_TYPE>', rowTypeName) classSpec = classSpec.replace('<LIST_CLASS_NAME>', listManagerStructName) #print '==========================================================\n'+classSpec codeDogParser.AddToObjectFromText(classes[0], classes[1], classSpec, rowWidgetName)
def writeParserWrapperFunction(classes, className): S=''' struct GLOBAL{ our <CLASSNAME>: Parse_<CLASSNAME>(me string: textIn) <- { me EParser: parser parser.populateGrammar() parser.initParseFromString(parser.<CLASSNAME>_str, textIn) parser.doParse() if (parser.doesParseHaveError()) { print("Parse Error:" + parser.errorMesg + "\\n") } our stateRec: topItem <- parser.resolve(parser.lastTopLevelItem, "") our <CLASSNAME>: result Allocate(result) parser.Extract_<CLASSNAME>_to_<CLASSNAME>(topItem, result) return(result) } } '''.replace('<CLASSNAME>', className) codeDogParser.AddToObjectFromText(classes[0], classes[1], S, 'Parse_'+className+'()')
def apply(classes, globalTags): progSpec.appendToStringTagValue(globalTags, 'initCode', 'thisApp.gui.GUI_Init()') progSpec.appendToStringTagValue(globalTags, 'runCode', 'thisApp.gui.GUI_Run()') progSpec.appendToStringTagValue(globalTags, 'deinitCode', 'thisApp.gui.GUI_Deinit()') progSpec.setFeaturesNeeded(globalTags, ['GUI_ToolKit']) # Provide wrapper commands # Make a class with init, event-loop, deInit (Can be activated from main.) title = progSpec.searchATagStore(globalTags, 'Title')[0] GUI_TK_code = """ struct GUI { const string: title <- "%s" } """ % title codeDogParser.AddToObjectFromText(classes[0], classes[1], GUI_TK_code, 'Pattern: make GUI')
def apply(classes, tags, classesToTrack): S = "" for className in classesToTrack: if className in classesTracked: continue else: classesTracked[className] = True C = ''' struct <CLASSNAME> { we uint: symbolCount me uint[we map int]: ptrToUint /- me <CLASSNAME>[their map]: uintToPtr we string: classTag <- "<CLASSNAME>" we string: mySymbol(their <CLASSNAME>: obj) <- { /- find or generate symbol if(obj==NULL){return("NULL")} me int: objID <- uniqueObjectID(obj) if(! ptrToUint.containsKey(objID)){ symbolCount <- symbolCount+1 ptrToUint[objID] <- symbolCount return(classTag + toString(symbolCount)) } else { me int: item <- ptrToUint.get(objID) me int: symbol <- item return(classTag + toString(symbol)) } } /- their <CLASSNAME>: classPtrFromSymbol(me string: symbol) <- {} /- what about our, my, me, ...? /- void: clearSymbol(me string: symbol) <- {} '''.replace("<CLASSNAME>", className) C += "}\n" S += C + "\n" codeDogParser.AddToObjectFromText(classes[0], classes[1], S, 'Pattern: generate symbols')
def addOrAmendClasses(self, classes, className, modelRef): Code = 'me string: makeString(me string:indent) <- {\n me string: SRet_ <- ""\n' + self.textFuncBody + " return(SRet_)\n }\n" Code = progSpec.wrapFieldListInObjectDef(className, Code) codeDogParser.AddToObjectFromText(classes[0], classes[1], Code, className + '.makeString()')
def apply(classes, tags, proxyStyle, className, funcName, platformTag): print('APPLY: in pattern_WriteCallProxy.apply: ',proxyStyle, '::', className,'\n') newParamFields = '' runParams = '' structRef = findStructRef(classes[0], className) funcSpec = getFieldSpec(funcName, structRef) typeSpec = funcSpec['typeSpec'] fieldOwner = typeSpec['owner'] argList = typeSpec['argList'] fieldType = typeSpec['fieldType'] if className[0] == '%': className = className[1:] callbackName = className+'_'+funcName+'_CB' bundleName = className+'_'+funcName+'_bundle' if proxyStyle == "bundledArgs" and platformTag == "Linux": #print "Linux BundledArgs: ", callbackName, typeSpec if len(argList)>0: count=0 for arg in argList: argName = arg['fieldName'] argTypeSpec = arg['typeSpec'] argOwner = argTypeSpec['owner'] argFieldType = progSpec.getFieldType(argTypeSpec) if not isinstance(argFieldType, str): argFieldType=argFieldType[0] if count > 0: runParams = runParams+', ' newParamFields = newParamFields+ ' ' runParams = runParams+' bundle.'+argName newParamFields = newParamFields + argOwner+' '+ argFieldType+': '+ argName + '\n' count = count + 1 CODE = ''' struct GLOBAL { bool: '''+callbackName+'''(their '''+bundleName+''': bundle) <- { bundle._object.'''+funcName+'''('''+runParams+''') return(false) } } struct '''+bundleName+''' { their '''+className+''': _object '''+newParamFields+''' }\n''' codeDogParser.AddToObjectFromText(classes[0], classes[1], CODE, callbackName) elif proxyStyle == "bundledArgs" and platformTag == "Android": #print "Android BundledArgs: ", callbackName, funcSpec if len(argList)>0: count=0 for arg in argList: argName = arg['fieldName'] argTypeSpec = arg['typeSpec'] argOwner = argTypeSpec['owner'] argFieldType = progSpec.getFieldType(argTypeSpec) if not isinstance(argFieldType, str): argFieldType=argFieldType[0] if count > 0: runParams = runParams+', ' newParamFields = newParamFields+ ' ' runParams=runParams+argName newParamFields = newParamFields + argOwner+' '+ argFieldType+': '+ argName + '\n' count = count + 1 CODE = ''' struct '''+bundleName+''': implements=Runnable{ their '''+className+''': objToCall '''+newParamFields+''' void: run() <- { objToCall.'''+funcName+'''('''+runParams+''') } }\n''' codeDogParser.AddToObjectFromText(classes[0], classes[1], CODE, callbackName) elif proxyStyle == "widgetData" and platformTag == "Linux": #print "Linux widgetData: ", callbackName, funcSpec CODE = ''' struct GLOBAL { void: '''+callbackName+'''(their GtkWidget: wid, their '''+className+''': _obj) <- { _obj.'''+funcName+'''() } }\n''' codeDogParser.AddToObjectFromText(classes[0], classes[1], CODE, callbackName) elif proxyStyle == "widgetData" and platformTag == "Android": pass elif proxyStyle == "widgetEventData" and platformTag == "Linux": #print "Linux widgetEventData: ", callbackName, funcSpec CODE = ''' struct GLOBAL { void: '''+callbackName+'''(their GtkWidget: wid, their GdkEvent: event, their '''+className+''': _obj) <- { _obj.'''+funcName+'''() } }\n''' codeDogParser.AddToObjectFromText(classes[0], classes[1], CODE, callbackName) elif proxyStyle == "widgetEventData" and platformTag == "Android": pass elif platformTag == "IOS": pass else: print("###ERROR: unknown proxyStyle & Platform: ", proxyStyle, platformTag); exit(1)
def BuildGuiForStruct(classes, className, dialogStyle, newStructName): # This makes 4 types of changes to the class: # It adds a widget variable for items in model // newWidgetFields: ' their '+typeName+': '+widgetName # It adds a set Widget from Vars function // widgetFromVarsCode: Func setValue() # It adds a set Vars from Widget function // varsFromWidgetCode: Func getValue() # It add an initialize Widgets function. // widgetInitFuncCode: widgetName+' <- '+makeTypeNameCall+'\n addToContainer(box, '+widgetName+')\n' # dialogStyles: 'Z_stack', 'X_stack', 'Y_stack', 'TabbedStack', 'FlowStack', 'WizardStack', 'Dialog', 'SectionedDialogStack', 'V_viewable' # also, handle non-modal dialogs global classesEncoded global currentClassName global currentModelSpec classesEncoded[className] = 1 currentClassName = className # reset the string vars that accumulate the code global newWidgetFields global widgetInitFuncCode global widgetFromVarsCode global varsFromWidgetCode global clearWidgetCode newWidgetFields = '' widgetInitFuncCode = '' widgetFromVarsCode = '' varsFromWidgetCode = '' clearWidgetCode = '' containerWidget = '' boxFooterCode = '' scrollerCode = '' onLoadedCode = '' tagCode = '' makeBoxFooter = False makeBackBtn = False makeNextBtn = False makeVScroller = False # Find the model modelRef = findModelRef(classes[0], className) currentModelSpec = modelRef classPrimaryGuiItem = progSpec.searchATagStore(modelRef['tags'], 'primaryGuiItem') if classPrimaryGuiItem != None: # This GUI Item is important visually classPrimaryGuiItem = classPrimaryGuiItem[0] classOptionsTags = progSpec.searchATagStore(modelRef['tags'], 'classOptions') guiStyleTag = progSpec.searchATagStore(modelRef['tags'], 'dialogStyle') if guiStyleTag != None: # This GUI Item is important visually guiStyleTag = guiStyleTag[0] if guiStyleTag == 'WizardStack': dialogStyle = 'WizardStack' if guiStyleTag == 'Z_stack': dialogStyle = 'Z_stack' if guiStyleTag == 'WizardChild': dialogStyle = 'WizardChild' makeBoxFooter = True makeBackBtn = True makeNextBtn = True clickNextLabel = "Next" if guiStyleTag == 'WizardChildLast': dialogStyle = 'WizardChild' makeBoxFooter = True makeBackBtn = True makeNextBtn = True clickNextLabel = "Done" if guiStyleTag == 'WizardChildFirst': dialogStyle = 'WizardChild' makeBoxFooter = True makeNextBtn = True clickNextLabel = "Next" classProperties = progSpec.searchATagStore(modelRef['tags'], 'properties') if classProperties != None: for classProperty in classProperties: if classProperty[0] == 'vScroller': makeVScroller = True ### Write code for each field for field in modelRef['fields']: typeSpec = field['typeSpec'] fldCat = progSpec.fieldsTypeCategory(typeSpec) fieldName = field['fieldName'] labelText = deCamelCase(fieldName) fieldType = typeSpec['fieldType'] if fieldName == 'settings': # add settings continue structTypeName = '' if fldCat == 'struct': # Add a new class to be processed structTypeName = typeSpec['fieldType'][0] if (progSpec.doesClassDirectlyImlementThisField( classes, structTypeName, structTypeName + ':managedWidget') or structTypeName.endswith('Widget')): fldCat = 'widget' else: newGUIStyle = 'Dialog' guiStructName = structTypeName + '_' + newGUIStyle + '_GUI' addNewStructToProcess(guiStructName, structTypeName, 'struct', 'Dialog') if fldCat != 'widget' and progSpec.isAContainer( typeSpec): # Add a new list to be processed if not isinstance(fieldType, str): fieldType = fieldType[0] structTypeName = fieldType guiStructName = structTypeName + '_ROW_View' addNewStructToProcess(guiStructName, structTypeName, 'list', 'Dialog') #TODO: make actions for each function if fldCat == 'func': if fieldName[-4:] == '_btn': buttonLabel = deCamelCase(fieldName[:-4]) # Add a button whose click calls this. print('ADDING BUTTON FOR:', fieldName) getButtonHandlingCode(classes, buttonLabel, fieldName) else: # Here is the main case where code to edit this field is written getWidgetHandlingCode(classes, fldCat, fieldName, field, structTypeName, dialogStyle, classPrimaryGuiItem, classOptionsTags, '') onLoadedCode = 'onLoaded()\n' returnCode = ' return(box)' if dialogStyle == 'Z_stack': newWidgetFields += ' their GUI_ZStack: Zbox\n' newWidgetFields += ' me List<me string>: children\n' newWidgetFields += ' me int: activeScreenIdx <-1\n' newWidgetFields += ' void: setActiveChild(me int: N) <- {\n' newWidgetFields += ' if (N >= 0 and N < children.size()){' newWidgetFields += ' me string: childName <- children[N]\n' #newWidgetFields += ' print("^^^setZStackActive: ",N)\n' newWidgetFields += ' setZStackActive(Zbox, childName)\n' newWidgetFields += ' activeScreenIdx <- N\n' newWidgetFields += ' }\n' newWidgetFields += ' }\n' containerWidget = 'Zbox <- makeZStack("' + className + '")\n' onLoadedCode = 'setActiveChild(0)\n' onLoadedCode += ' onLoaded()\n' returnCode = ' return(Zbox)\n' elif dialogStyle == 'TabbedStack': containerWidget = 'their GUI_Frame:box <- makeTabbedWidget("makeTabbedWidget")' elif dialogStyle == 'WizardStack': newWidgetFields += ' our wizardWidget: wiz\n' newWidgetFields += ' their GUI_Frame: box\n' newWidgetFields += ''' void: clickNext() <-{ me int: size <- wiz.children.size() if (wiz.activeScreenIdx == size-1){ _data.wizardFinished(wiz.widgetID) } else if (wiz.activeScreenIdx < size-1){ wiz.activeScreenIdx <- wiz.activeScreenIdx+1 wiz.setActiveChild(wiz.activeScreenIdx) } }\n''' newWidgetFields += ''' void: clickBack() <-{ me int: size <- wiz.children.size() if (wiz.activeScreenIdx > 0){wiz.activeScreenIdx <- wiz.activeScreenIdx-1} wiz.setActiveChild(wiz.activeScreenIdx) }\n''' containerWidget = 'Allocate(wiz)\n' containerWidget += ' box <- wiz.initWidget("' + currentClassName + '")\n' containerWidget += ' wiz._data <- _data\n' containerWidget += ' wiz.parentGuiMgr <- self\n' widgetInitFuncCode += ' wiz.activeScreenIdx <- 0\n' widgetInitFuncCode += ' wiz.setActiveChild(wiz.activeScreenIdx)\n' elif dialogStyle == 'X_stack': newWidgetFields += ' their GUI_XStack:box\n' containerWidget = 'box <- makeXStack("")' elif dialogStyle == 'rowWidget': newWidgetFields += ' their GUI_XStack: box\n' containerWidget = 'box <- makeXStack("")' else: newWidgetFields += ' their GUI_Frame:box\n' containerWidget = 'box <- makeYStack("")' if makeBoxFooter: newWidgetFields += ' their GUI_Frame: boxFooter\n' boxFooterCode += 'boxFooter <- makeXStack("")\n' if makeBackBtn: newWidgetFields += ' their GUI_button: backBtn\n' newWidgetFields += ' void: clickBack() <-{parentGuiMgr.clickBack()}\n' boxFooterCode += ' backBtn <- makeButtonWidget("Back")\n' boxFooterCode += ' GUI.setBtnCallback(backBtn, "clicked", clickBack, this)\n' boxFooterCode += ' addToContainer(boxFooter, backBtn)\n' tagCode += '' if makeNextBtn: newWidgetFields += ' their GUI_button: nextBtn\n' newWidgetFields += ''' void: clickNext() <-{ if(isComplete()){ save() parentGuiMgr.clickNext() } }\n''' newWidgetFields += ''' void: setNextBtnActive(me bool: checkState) <-{ nextBtn.setWidgetActive(checkState) }\n''' newWidgetFields += ''' void: onChanged() <- { getValue() setNextBtnActive(isComplete()) }\n''' boxFooterCode += ' nextBtn <- makeButtonWidget("' + clickNextLabel + '")\n' boxFooterCode += ' nextBtn.setWidgetActive(false)\n' boxFooterCode += ' GUI.setBtnCallback(nextBtn, "clicked", clickNext, this)\n' boxFooterCode += ' addToContainer(boxFooter, nextBtn)\n' tagCode += '' boxFooterCode += ' addToContainer(box, boxFooter)\n' if makeVScroller: scrollerCode = 'their GUI_VerticalScroller: scroller <- makeVerticalScroller()\n' scrollerCode += 'addToContainerAndExpand(scroller, box)\n' returnCode = 'return (scroller)' CODE = ''' struct <CLASSNAME>:inherits=appComponentData{} struct <NEWSTRUCTNAME>:inherits=appComponentGUI '''+tagCode+'''{ '''+newWidgetFields+''' our <CLASSNAME>: _data their GUI_Frame: initWidget(our <CLASSNAME>: Data) <- { _data <- Data _data.guiMgr <- self '''+containerWidget+''' '''+widgetInitFuncCode+''' '''+boxFooterCode+''' '''+scrollerCode+''' '''+onLoadedCode+''' '''+returnCode+''' } void: setValue(our <CLASSNAME>: var) <- { '''+widgetFromVarsCode+''' } void: getValue() <- { '''+varsFromWidgetCode+''' } void: clear() <- { '''+clearWidgetCode+''' } }\n''' # TODO: add <VARSFROMWIDGETCODE> CODE = CODE.replace('<NEWSTRUCTNAME>', newStructName) CODE = CODE.replace('<CLASSNAME>', className) #print ('==========================================================\n'+CODE) codeDogParser.AddToObjectFromText(classes[0], classes[1], CODE, newStructName)
def buildListRowView(classes, className, dialogStyle, newStructName): # This makes 4 types of changes to the class: # It adds a widget variable for items in model // newWidgetFields: ' their '+typeName+': '+widgetName # It adds a set Widget from Vars function // widgetFromVarsCode: Func UpdateWidgetFromVars() # It adds a set Vars from Widget function // varsFromWidgetCode: Func UpdateVarsFromWidget() # It add an initialize Widgets function. // widgetInitFuncCode: widgetName+' <- '+makeTypeNameCall+'\n addToContainer(box, '+widgetName+')\n' # dialogStyles: 'Z_stack', 'X_stack', 'Y_stack', 'TabbedStack', 'FlowStack', 'WizardStack', 'Dialog', 'SectionedDialogStack' # also, handle non-modal dialogs global classesEncoded global currentClassName global currentModelSpec classesEncoded[className] = 1 currentClassName = className # reset the string vars that accumulate the code global newWidgetFields global widgetInitFuncCode global widgetFromVarsCode global varsFromWidgetCode global clearWidgetCode newWidgetFields = '' widgetInitFuncCode = '' widgetFromVarsCode = '' varsFromWidgetCode = '' clearWidgetCode = '' funcTextToUpdateViewWidget = '' funcTextToUpdateEditWidget = '' funcTextToUpdateCrntFromWidget = '' # Find the model modelRef = findModelRef(classes[0], className) currentModelSpec = modelRef rowHeaderCode = '' rowViewCode = '' for field in modelRef['fields']: fieldName = field['fieldName'] typeSpec = field['typeSpec'] fldCat = progSpec.fieldsTypeCategory(typeSpec) fieldType = progSpec.fieldTypeKeyword(field['typeSpec']['fieldType']) [fieldSpec, params] = getFieldSpec(fldCat, field) structTypeName = '' if fldCat == 'struct': # Add a new class to be processed structTypeName = typeSpec['fieldType'][0] newGUIStyle = 'Dialog' guiStructName = structTypeName + '_' + newGUIStyle + '_GUI' addNewStructToProcess(guiStructName, structTypeName, 'struct', 'Dialog') if progSpec.isAContainer(typeSpec): # Add a new list to be processed structTypeName = typeSpec['fieldType'][0] guiStructName = structTypeName + '_ROW_View' addNewStructToProcess(guiStructName, structTypeName, 'list', 'Dialog') else: print("field::", fieldName, fldCat) if (fldCat != 'struct'): rowHeaderCode += ' their GUI_Label: ' + fieldName + '_header <- makeLabelWidget("' + fieldName + '")\n' rowHeaderCode += ' setLabelWidth(' + fieldName + '_header, 15)\n' rowHeaderCode += ' addToContainer(headerBox, ' + fieldName + '_header)\n' if fldCat == 'struct': funcTextToUpdateViewWidget += '' elif fldCat == 'enum' or fldCat == 'mode': funcTextToUpdateViewWidget += '' #funcTextToUpdateEditWidget += '' funcTextToUpdateCrntFromWidget += '' # crntRecord.'+fieldName+' <- dialog.' + widgetName + '.getValue()\n' elif fldCat == 'bool': funcTextToUpdateViewWidget += '' elif fldCat == 'string': #funcTextToUpdateViewWidget += '' #funcTextToUpdateEditWidget += ' dialog.' + widgetName + '.setValue('+structTypeName+'_ListData[N].'+fieldName+')\n' #funcTextToUpdateCrntFromWidget += ' me string: '+widgetName+'Str <- dialog.' + widgetName + '.getValue()\n' #funcTextToUpdateCrntFromWidget += ' crntRecord.'+fieldName+' <- '+widgetName+'Str\n' rowViewCode += ' their GUI_Label: ' + fieldName + '_value <- makeLabelWidget2(Data.' + fieldName + ')\n' rowViewCode += ' setLabelWidth(' + fieldName + '_value, 15)\n' rowViewCode += ' addToContainer(box, ' + fieldName + '_value)\n' rowViewCode += ' showWidget(' + fieldName + '_value)\n' elif fldCat == 'int': funcTextToUpdateViewWidget += '' #funcTextToUpdateEditWidget += ' dialog.' + widgetName + '.setValue('+structTypeName+'_ListData[N].'+fieldName+')\n' #funcTextToUpdateCrntFromWidget += ' me string: '+widgetName+'Str <- string(dialog.' + widgetName + '.getValue())\n' #funcTextToUpdateCrntFromWidget += ' crntRecord.'+fieldName+' <- dataStr\n' rowViewCode += ' their GUI_Label: ' + fieldName + '_value <- makeLabelWidget2(toString(Data.' + fieldName + '))\n' rowViewCode += ' setLabelWidth(' + fieldName + '_value, 15)\n' rowViewCode += ' addToContainer(box, ' + fieldName + '_value)\n' rowViewCode += ' showWidget(' + fieldName + '_value)\n' else: print( 'pattern_MakeGUI.codeListWidgetManagerClassOverride fldCat not specified: ', fldCat) exit(2) CODE = '''struct ''' + newStructName + '''{ their GUI_Frame: box their GUI_Frame: makeHeaderView() <- { their GUI_Frame: headerBox <- makeXStack("") ''' + rowHeaderCode + ''' showWidget(headerBox) return(headerBox) } their GUI_Frame: initWidget(their ''' + className + ''': Data) <- { box <- makeXStack("") ''' + rowViewCode + ''' showWidget(box) return(box) } } ''' #print ('==========================================================\n'+CODE) codeDogParser.AddToObjectFromText(classes[0], classes[1], CODE, newStructName)
def apply(classes, tags, stylerTagName): if not (isinstance(stylerTagName, str)): cdErr("Styler tag name must be a string") stylerTagValue = progSpec.fetchTagValue(tags, stylerTagName) initCode = processStyler(stylerTagValue) code = r""" struct GLOBAL{ our Styler:: styler } struct Styler{ me Map<me string, our cdColor>: userColors me cdColor: frGndColor <- Black me cdColor: bkGndColor <- White me cdColor: highlight1Color <- Black me cdColor: highlight2Color <- Cornflower me cdColor: highlight3Color <- OrangeRed me cdColor: primaryTextColor <- Black me cdColor: data1Color <- Cornflower me cdColor: data2Color <- Turquoise me cdColor: data3Color <- Magenta me cdColor: data4Color <- MediumVioletRed me cdColor: data5Color <- OrangeRed me cdColor: data6Color <- Gold //TODO: Why don't these constructor inits work? our fontSpec:: defaultFont{"Ariel", 10, 0} our fontSpec:: titleFont{"Ariel", 16, 0} our fontSpec:: smallFont{"Ariel", 8, 0} our fontSpec:: verySmallFont{"Ariel", 5, 0} void: setCustomColor(me string: ID, me cdColor: color) <- { our cdColor:: tmpColor <- color userColors.insert(ID, tmpColor) } me cdColor: color(me string: ID, me cdColor: defaultColor) <- { itr Map<me string, our cdColor>: colorItr <- userColors.find(ID) if(colorItr != userColors.end()){return(colorItr.val)} return(defaultColor) } // FONT NAMES me Map<me string, me string>: userFontNames me string: titleFontname me string: normalFontname me string: H1_fontname me string: H2_fontname me string: H3_fontname me string: H4_fontname me string: H5_fontname me string: H6_fontname me string: timesFontname me string: sansSerifFontname me string: comicFontname me string: scriptFontname me string: monoFontname void: setCustomFont(me string: ID, me string: fontName) <- { userFontNames.insert(ID, fontName) } me string: font(me string: ID) <- {return(userFontNames.at(ID))} // FONT SIZES me Map<me string, me int>: userFontSizes me int: verySmallFontSize me int: smallFontSize me int: normalSizeFontSize me int: largeFontSize me int: veryLargeFontSize void: setCustomFontSize(me string: ID, me int: fontSize) <- { userFontSizes.insert(ID, fontSize) } me int: fontSize(me string: ID) <- { return(userFontSizes.at(ID)) } // FONT SIZE MODES me mode[pp, dp, sp]: pixelMode <- pp me int: widgetLabelBoxWidth <- 100 me int: widgetValueBoxWidth <- 100 // OTHER KEY/VALUES me Map<me string, me string>: userStrings void: setCustomString(me string: key, me string: value) <- { userStrings.insert(key, value) } me Map<me string, me int>: userIntegers void: setCustomInteger(me string: key, me string: value) <- { // userIntegers.insert(key, (value)) } me Map<me string, me int>: userDoubles void: setCustomDouble(me string: key, me string: value) <- { // userIntegers.insert(key, (value)) } void: INIT()<-{ <INITCODE> Allocate(defaultFont, "ariel", "14") Allocate(titleFont, "ariel", "20") Allocate(smallFont, "ariel", "10") Allocate(verySmallFont, "ariel", "5") } } """ code = code.replace('<INITCODE>', initCode) #print '==========================================================\n'+code codeDogParser.AddToObjectFromText(classes[0], classes[1], code, 'Pattern: MakeStyler')
def BuildGuiForList(classes, className, dialogStyle, newStructName): # This makes 4 types of changes to the class: # It adds a widget variable for items in model // newWidgetFields: ' their '+typeName+': '+widgetName # It adds a set Widget from Vars function // widgetFromVarsCode: Func UpdateWidgetFromVars() # It adds a set Vars from Widget function // varsFromWidgetCode: Func UpdateVarsFromWidget() # It add an initialize Widgets function. // widgetInitFuncCode: widgetName+' <- '+makeTypeNameCall+'\n addToContainer(box, '+widgetName+')\n' # dialogStyles: 'Z_stack', 'X_stack', 'Y_stack', 'TabbedStack', 'FlowStack', 'WizardStack', 'Dialog', 'SectionedDialogStack' # also, handle non-modal dialogs global classesEncoded global currentClassName global currentModelSpec classesEncoded[className]=1 currentClassName = className # reset the string vars that accumulate the code global newWidgetFields global widgetInitFuncCode global widgetFromVarsCode global varsFromWidgetCode newWidgetFields='' widgetInitFuncCode='' widgetFromVarsCode='' varsFromWidgetCode='' # Find the model modelRef = progSpec.findSpecOf(classes[0], className, 'model') if modelRef==None: cdErr('To build a GUI for a list of "'+className+'" a model is needed but is not found.') currentModelSpec = modelRef rowHeaderCode = '' rowViewCode = '' for field in modelRef['fields']: fieldName = field['fieldName'] typeSpec = field['typeSpec'] fldCat = progSpec.fieldsTypeCategory(typeSpec) fieldType = progSpec.fieldTypeKeyword(field['typeSpec']['fieldType']) [fieldSpec, params] = getFieldSpec(fldCat, field) structTypeName ='' if fldCat=='struct': # Add a new class to be processed structTypeName =typeSpec['fieldType'][0] newGUIStyle = 'Dialog' guiStructName = structTypeName+'_'+newGUIStyle+'_GUI' addNewStructToProcess(guiStructName, structTypeName, 'struct', 'Dialog') if progSpec.isAContainer(typeSpec):# Add a new list to be processed structTypeName = typeSpec['fieldType'][0] guiStructName = structTypeName+'_LIST_View' addNewStructToProcess(guiStructName, structTypeName, 'list', 'Dialog') CODE = '''struct <NEWSTRUCTNAME>{ our <CLASSNAME>[our list]: <CLASSNAME>_ListData our <CLASSNAME>: crntRecord } ''' CODE = CODE.replace('<NEWSTRUCTNAME>', newStructName) CODE = CODE.replace('<CLASSNAME>', className) CODE = CODE.replace('<NEWWIDGETFIELDS>', newWidgetFields) CODE = CODE.replace('<WIDGETFROMVARSCODE>', widgetFromVarsCode) CODE = CODE.replace('<VARSFROMWIDGETCODE>', varsFromWidgetCode) #print '==========================================================\n'+CODE codeDogParser.AddToObjectFromText(classes[0], classes[1], CODE, newStructName)
def apply(classes, tags, stylerTagName): if not (isinstance(stylerTagName, str)): cdErr("Styler tag name must be a string") stylerTagValue = progSpec.fetchTagValue(tags, stylerTagName) initCode = processStyler(stylerTagValue) code = r""" struct GLOBAL{ our Styler:: styler } struct Styler{ our cdColor[map string]: userColors me cdColor: frGndColor <- Black me cdColor: bkGndColor <- White me cdColor: highlight1Color <- Black me cdColor: highlight2Color <- Cornflower me cdColor: highlight3Color <- OrangeRed me cdColor: primaryTextColor <- Black me cdColor: data1Color <- Cornflower me cdColor: data2Color <- Turquoise me cdColor: data3Color <- Magenta me cdColor: data4Color <- MediumVioletRed me cdColor: data5Color <- OrangeRed me cdColor: data6Color <- Gold our fontSpec:: fontDefault{"Ariel", 10, 0} our fontSpec:: fontTitle{"Ariel", 16, 0} our fontSpec:: fontSmall{"Ariel", 8, 0} our fontSpec: fontVerySmall our fontSpec: fontLabelWidgetAndroid our fontSpec: fontEntryWidgetAndroid our fontSpec: fontTitleAndroid our fontSpec: fontTextAndroid void: setCustomColor(me string: ID, me cdColor: color) <- { our cdColor:: tmpColor <- color userColors.insert(ID, tmpColor) } me cdColor: color(me string: ID, me cdColor: defaultColor) <- { our cdColor[itr map string]: colorItr <- userColors.find(ID) if(colorItr == userColors.end()){ return(defaultColor) }else{ return(colorItr.val) } } // FONT NAMES me string[map string]: userFontNames me string: titleFont me string: normalFont me string: H1_font me string: H2_font me string: H3_font me string: H4_font me string: H5_font me string: H6_font me string: timesFont me string: sansSerifFont me string: comicFont me string: scriptFont me string: monoFont void: setCustomFont(me string: ID, me string: fontName) <- { userFontNames.insert(ID, fontName) } me string: font(me string: ID) <- {return(userFontNames.get(ID))} // FONT SIZES me int[map string]: userFontSizes me int: fontSizeVerySmall me int: fontSizeSmall me int: fontSizeNormalSize me int: fontSizeLarge me int: fontSizeVeryLarge void: setCustomFontSize(me string: ID, me int: fontSize) <- { userFontSizes.insert(ID, fontSize) } me int: fontSize(me string: ID) <- { return(userFontSizes.get(ID)) } // FONT SIZE MODES me mode[pp, dp, sp]: pixelMode <- pp me int: widgetLabelBoxWidth <- 100 me int: widgetValueBoxWidth <- 100 void: INIT()<-{ <INITCODE> Allocate(fontDefault, "ariel", "14") Allocate(fontTitle, "ariel", "20") Allocate(fontSmall, "ariel", "10") Allocate(fontVerySmall, "ariel", "5") Allocate(fontLabelWidgetAndroid, "ariel", "25") Allocate(fontEntryWidgetAndroid, "ariel", "25") Allocate(fontTitleAndroid, "ariel", "25") Allocate(fontTextAndroid, "ariel", "20") } } """ code = code.replace('<INITCODE>', initCode) #print '==========================================================\n'+code codeDogParser.AddToObjectFromText(classes[0], classes[1], code, 'Pattern: MakeStyler')
def apply(classes, tags): progSpec.appendToStringTagValue( tags, 'initCode', 'CommandLineManager.processCmdLine(prgArgs, false)') code = r""" struct GLOBAL{ me CmdLineArgsMngr: CommandLineManager } struct optionRecord{ me string: groupID me string: optionID me string: shortName me string: longName me string: helpText } struct CmdLineArgsMngr { me string: cmdLineText our optionRecord[list]: options void: defineOption(me string: groupID, me string: optionID, me string: shortName, me string: longName, me string: helpText) <- { our optionRecord: rec Allocate(rec, groupID, optionID, shortName, longName, helpText) options.pushLast(rec) } me string: getOption(me string: groupID, me string: optionID) <- { me stringScanner: scanner me string: argToReturn <- "" scanner.initialize(cmdLineText) /- Find optionRecord me int: recIdx <- -1 withEach optRec in options{ if(optRec.optionID==optionID){ recIdx <- optRec_key break() } } if(recIdx==-1){return("")} me string: shortName <- options[recIdx].shortName me string: longName <- options[recIdx].longName me int: scanPos <- scanner.pos me int: foundPos <- scanner.skipPast(shortName) me int: startPos <- scanner.skipWS() me int: endPos <- 0 if(foundPos>=0){ endPos <- scanner.skipTo(" -") argToReturn <- cmdLineText.subStr(startPos, endPos-startPos) } else { scanner.pos <- scanPos foundPos <- scanner.skipPast(longName) startPos <- scanner.skipWS() if(foundPos>=0){ endPos <- scanner.skipTo(" -") argToReturn <- cmdLineText.subStr(startPos, endPos-startPos) } } return(argToReturn) } me string: helpText() <- { return("This is the help text") } void: processCmdLine(me string:prgArgs, me bool: exitOnInvalid) <- { cmdLineText <- prgArgs me int: txtSize <- cmdLineText.size() /- TODO: make this handle multiple options of each kind e.g., as with a compiler having multiple link options. /- ALSO: add features from posix's or java's command line style /- me char: ch /- withEach p in RANGE(0 .. txtSize){ /- ch <- cmdLineText[p] /- } } } """ codeDogParser.AddToObjectFromText(classes[0], classes[1], code, 'Pattern: Manage Command-Line')
def addOrAmendClasses(self, classes, className, modelRef): self.setPosFuncTextAcc += '\n y <- y+5' + '\n height <- y-posY' + '\n me int:depX <- posX+width+40\n' countOfRefs = 0 for field in modelRef['fields']: typeSpec = field['typeSpec'] typeName = progSpec.getFieldType(field['typeSpec'])[0] fldCat = progSpec.fieldsTypeCategory(typeSpec) if fldCat == 'func': continue if progSpec.typeIsPointer(typeSpec): # Draw dereferenced POINTER fieldName = field['fieldName'] dispStructTypeName = "display_" + typeName declSymbolStr = ' ' if (countOfRefs == 0): declSymbolStr += 'me string: ' countOfRefs += 1 [ structText, updateFuncText, drawFuncText, setPosFuncText, handleClicksFuncText ] = self.getDashDeclAndUpdateCode('their', '"' + fieldName + '"', 'data.' + fieldName, fieldName, field, 'skipPtr', ' ') self.structTextAcc += structText tempFuncText = updateFuncText updateFuncText = declSymbolStr + 'mySymbol <- data.' + fieldName + '.mySymbol(data.' + fieldName + ')\n' updateFuncText += ( ' if(data.' + fieldName + ' != NULL){\n' + ' ' + fieldName + ' <- asClass(' + dispStructTypeName + ', dependentIsRegistered(mySymbol))\n' ' if(!' + fieldName + '){' '\n Allocate(' + fieldName + ')' + '\n ' + fieldName + '.dashParent <- self' + '\n addDependent(mySymbol, ' + fieldName + ')' + '\n' + tempFuncText + '\n }\n } else {' + fieldName + ' <- NULL}\n') self.updateFuncTextPart2Acc += updateFuncText self.setPosFuncTextAcc += ''' if(<fieldName> != NULL and !<fieldName>Ptr.refHidden){ if(!<fieldName>.posIsSet){ <fieldName>.setPos(depX, extC, extC) extC <- <fieldName>.extY + 40 extX <- max(extX, <fieldName>.extX) extY <- max(extY, <fieldName>.extY) } addRelation("arrow", <fieldName>Ptr, <fieldName>) } '''.replace('<fieldName>', fieldName) self.handleClicksFuncTxtAcc2 += ' if(' + fieldName + ' != NULL and !' + fieldName + 'Ptr.refHidden){\n' + fieldName + '.isHidden<-false\n }\n' Code = ''' struct display_''' + className + ": inherits=dash" + '''{ me bool: isChanged me dataField: header me mode[headerOnly, fullDisplay, noZeros]: displayMode their ''' + className + ''': data ''' + self.structTextAcc + ''' void: update(me string: _label, me string: textValue, their ''' + className + ''': _Data) <- { title <- "''' + className + ''':" + _label isChanged <- !(data === _Data) data <- _Data if(data==NULL){ header.update(100, 180, _label, "NULL", false) return() } header.update(100, 180, _label, textValue, false) if(isChanged){displayMode<-headerOnly} ''' + self.updateFuncTextAcc + ''' ''' + self.updateFuncTextPart2Acc + ''' } void: setPos(me int:x, me int:y, me int: extCursor) <- { posIsSet <- true posX <- x; posY <- y; extC <- extCursor isHidden<-false header.setPos(x,y,extC) y <- y+header.height width <- header.width height <- y-posY extX <- header.extX extY <- max(y, extC) if(displayMode!=headerOnly){ x <- x+10 // Indent fields in a struct ''' + self.setPosFuncTextAcc + ''' width <- width+10 } } me bool: primaryClick(their GUI_ButtonEvent: event) <- { if(isHidden){return(false)} me GUI_Scalar: eventX <- event.x me GUI_Scalar: eventY <- event.y if( header.isTouching(eventX, eventY)){ if(displayMode==headerOnly){displayMode <- noZeros} else if(displayMode==noZeros){displayMode <- fullDisplay} else if(displayMode==fullDisplay){displayMode <- headerOnly} } else { ''' + self.handleClicksFuncTextAcc + ''' } ''' + self.handleClicksFuncTxtAcc2 + ''' return(true) } void: draw(their GUI_ctxt: cr) <- { header.isHidden <- false me cdColor: hedrColor <- styler.frGndColor cr.setColor(hedrColor) header.draw(cr) cr.strokeNow() hedrColor <- styler.frGndColor cr.setColor(hedrColor) if(displayMode!=headerOnly){ ''' + self.drawFuncTextAcc + ''' me cdColor: rectColor <- styler.color(data.mySymbol(data), styler.frGndColor) cr.setColor(rectColor) cr.rectangle(posX, posY, width, height) cr.strokeNow() rectColor <- styler.frGndColor cr.setColor(rectColor) ''' + self.drawFuncTextPart2Acc + ''' } } }\n''' #if className == 'pureInfon': print Code codeDogParser.AddToObjectFromText(classes[0], classes[1], Code, 'display_' + className)
def apply(classes, tags, stylerTagName): if not (isinstance(stylerTagName, basestring)): cdErr("Styler tag name must be a string") stylerTagValue = progSpec.fetchTagValue(tags, stylerTagName) initCode = processStyler(stylerTagValue) code = r""" struct GLOBAL{ our Styler:: styler } struct Styler{ our cdColor[map string]: userColors me cdColor: frGndColor <- White me cdColor: bkGndColor <- Black me cdColor: highlight1Color <- White me cdColor: highlight2Color <- Cornflower me cdColor: highlight3Color <- OrangeRed our fontSpec:: fontDefault <- ("Ariel", 10, 0) our fontSpec:: fontTitle <- ("Ariel", 16, 0) our fontSpec:: fontSmall <- ("Ariel", 8, 0) void: setCustomColor(me string: ID, me cdColor: color) <- { our cdColor:: tmpColor <- color userColors.insert(ID, tmpColor) } me cdColor: color(me string: ID) <- { return(userColors.get(ID)) } /- FONT NAMES me string[map string]: userFontNames me string: titleFont me string: normalFont me string: H1_font me string: H2_font me string: H3_font me string: H4_font me string: H5_font me string: H6_font me string: timesFont me string: sansSerifFont me string: comicFont me string: scriptFont me string: monoFont void: setCustomFont(me string: ID, me string: fontName) <- { userFontNames.insert(ID, fontName) } me string: font(me string: ID) <- {return(userFontNames.get(ID))} /- FONT SIZES me int[map string]: userFontSizes me int: fontSizeVerySmall me int: fontSizeSmall me int: fontSizeNormalSize me int: fontSizeLarge me int: fontSizeVeryLarge void: setCustomFontSize(me string: ID, me int: fontSize) <- { userFontSizes.insert(ID, fontSize) } me int: fontSize(me string: ID) <- { return(userFontSizes.get(ID)) } /- FONT SIZE MODES me mode[pp, dp, sp]: pixelMode <- pp void: INIT()<-{ <INITCODE> Allocate(fontDefault, "ariel", "14") Allocate(fontTitle, "ariel", "20") Allocate(fontSmall, "ariel", "10") } } """ code = code.replace('<INITCODE>', initCode) #print '==========================================================\n'+code codeDogParser.AddToObjectFromText(classes[0], classes[1], code, 'Pattern: MakeStyler')
def BuildGuiForStruct(classes, className, dialogStyle, newStructName): # This makes 4 types of changes to the class: # It adds a widget variable for items in model // newWidgetFields: ' their '+typeName+': '+widgetName # It adds a set Widget from Vars function // widgetFromVarsCode: Func UpdateWidgetFromVars() # It adds a set Vars from Widget function // varsFromWidgetCode: Func UpdateVarsFromWidget() # It add an initialize Widgets function. // widgetInitFuncCode: widgetName+' <- '+makeTypeNameCall+'\n addToContainer(box, '+widgetName+')\n' # dialogStyles: 'Z_stack', 'X_stack', 'Y_stack', 'TabbedStack', 'FlowStack', 'WizardStack', 'Dialog', 'SectionedDialogStack', 'V_viewable' # also, handle non-modal dialogs global classesEncoded global currentClassName global currentModelSpec classesEncoded[className]=1 currentClassName = className # reset the string vars that accumulate the code global newWidgetFields global widgetInitFuncCode global widgetFromVarsCode global varsFromWidgetCode newWidgetFields='' widgetInitFuncCode='' widgetFromVarsCode='' varsFromWidgetCode='' # Find the model modelRef = progSpec.findSpecOf(classes[0], className, 'model') currentModelSpec = modelRef if modelRef==None: cdErr('To build a GUI for class "'+className+'" a model is needed but is not found.') #TODO: write func body for: widgetFromVarsCode(selected item & click edit) & varsFromWidgetCode(ckick OK from editMode) ### Write code for each field for field in modelRef['fields']: typeSpec = field['typeSpec'] fldCat = progSpec.fieldsTypeCategory(typeSpec) fieldName = field['fieldName'] labelText = deCamelCase(fieldName) if fieldName=='settings': # add settings continue structTypeName='' if fldCat=='struct': # Add a new class to be processed structTypeName =typeSpec['fieldType'][0] if (progSpec.doesClassDirectlyImlementThisField(classes, structTypeName, structTypeName+':managedWidget') or structTypeName.endswith('Widget')): fldCat = 'widget' else: newGUIStyle = 'Dialog' guiStructName = structTypeName+'_'+newGUIStyle+'_GUI' addNewStructToProcess(guiStructName, structTypeName, 'struct', 'Dialog') if fldCat != 'widget' and progSpec.isAContainer(typeSpec):# Add a new list to be processed structTypeName = typeSpec['fieldType'][0] guiStructName = structTypeName+'_LIST_View' addNewStructToProcess(guiStructName, structTypeName, 'list', 'Dialog') #TODO: make actions for each function if fldCat=='func': if fieldName[-4:]== '_btn': buttonLabel = deCamelCase(fieldName[:-4]) # Add a button whose click calls this. print "ADDING BUTTON FOR:", fieldName getButtonHandlingCode(classes, buttonLabel, fieldName) else: # Here is the main case where code to edit this field is written getWidgetHandlingCode(classes, fldCat, fieldName, field, structTypeName, dialogStyle, '') # Parse everything initFuncName = 'make'+className[0].upper() + className[1:]+'Widget' if dialogStyle == 'Z_stack': containerWidget='makeStoryBoardWidget("makeStoryBoardWidget")' elif dialogStyle == 'TabbedStack': containerWidget='makeTabbedWidget("makeTabbedWidget")' else: containerWidget='makeFrameWidget()' CODE = ''' struct <CLASSNAME> {} struct <NEWSTRUCTNAME> { <NEWWIDGETFIELDS> our <CLASSNAME>: <CLASSNAME>_data their GUI_Frame: <INITFUNCNAME>(our <CLASSNAME>: Data) <- { <CLASSNAME>_data<-Data their GUI_Frame:box <- <CONTAINERWIDGET> <WIDGETINITFUNCCODE> return(box) } void: setValue(our <CLASSNAME>: var) <- { <WIDGETFROMVARSCODE> } void: getValue() <- { <VARSFROMWIDGETCODE> } }\n''' # TODO: add <VARSFROMWIDGETCODE> CODE = CODE.replace('<NEWSTRUCTNAME>', newStructName) CODE = CODE.replace('<NEWWIDGETFIELDS>', newWidgetFields) CODE = CODE.replace('<CLASSNAME>', className) CODE = CODE.replace('<WIDGETINITFUNCCODE>', widgetInitFuncCode) CODE = CODE.replace('<INITFUNCNAME>', initFuncName) CODE = CODE.replace('<WIDGETFROMVARSCODE>', widgetFromVarsCode) CODE = CODE.replace('<VARSFROMWIDGETCODE>', varsFromWidgetCode) CODE = CODE.replace('<CONTAINERWIDGET>', containerWidget) if newStructName == "EntryPad_Dialog_GUI":print '==========================================================\n'+CODE codeDogParser.AddToObjectFromText(classes[0], classes[1], CODE, newStructName)
def writeParserWrapperFunction(classes, className): S = ''' struct EParser{ me uint64: sourceID our <CLASSNAME>: Parse_<CLASSNAME>(me string: textIn) <- { our <CLASSNAME>: result initParseFromString("<CLASSNAME>", textIn) doParse() if (doesParseHaveError()) { print("Parse Error:" + errorMesg + "\\n") } else { our stateRec: topItem <- topDownResolve(lastTopLevelItem, "") Allocate(result) syntax.Extract_<CLASSNAME>_to_<CLASSNAME>(topItem, result, self) } return(result) } } struct <CLASSNAME>ExtracterThread: inherits=Threads{ their Threaded_<CLASSNAME>ParseAndExtractor: ctrls our stateRec: parseTree our <CLASSNAME>: topItem void: init(their Threaded_<CLASSNAME>ParseAndExtractor: Ctrls, our stateRec: ParseTree, our <CLASSNAME>: TopItem) <- { topItem <- TopItem parseTree <- ParseTree ctrls <- Ctrls ctrls.extractCompleted <- false } void: run() <- { me string: streamID <- ctrls.streamName() log("OPENING EXTRACT_THREAD:" + streamID) ctrls.parser.syntax.Extract_<CLASSNAME>_to_<CLASSNAME>(parseTree, topItem, ctrls.parser) log("Extracted_<CLASSNAME>:"+toString(topItem).subStr(0,120)) log("CLOSING EXTRACT_THREAD:" + streamID) protect(ctrls.chkExtractDone){ ctrls.extractCompleted <- true ctrls.extractDoneLock.notifyOne(); } } } struct <CLASSNAME>ParserThread: inherits=Threads{ their Threaded_<CLASSNAME>ParseAndExtractor: ctrls void: init(their Threaded_<CLASSNAME>ParseAndExtractor: Ctrls) <- { ctrls <- Ctrls ctrls.parseCompleted <- false } void: run() <- { me string: streamID <- ctrls.streamName() log("OPENING PARSE_THREAD:" + streamID) ctrls.parser.doParse() log("parser.lastTopLevelItem:"+ctrls.parser.lastTopLevelItem.mySymbol()) our <CLASSNAME>: crnt_<CLASSNAME> if(ctrls.parser.doesParseHaveError()){ ctrls.handleSyntaxError(ctrls.parser.errorMesg) crnt_<CLASSNAME> <- NULL } log("CLOSING PARSE_THREAD:" + streamID) protect(ctrls.chkParseDone){ ctrls.parseCompleted <- true; ctrls.parseDoneLock.notifyOne(); } } } struct Threaded_<CLASSNAME>ParseAndExtractor{ me string: name their EParser: parser our stateRec: leftParseNode me bool: parseCompleted me bool: extractCompleted me Mutex: chkParseDone me Mutex: chkExtractDone me SyncLock: parseDoneLock me SyncLock: extractDoneLock me <CLASSNAME>ParserThread: parserThread me <CLASSNAME>ExtracterThread: extracterThread void: handleSyntaxError(me string: mesg) <- { // Override as needed. log("Syntax Error:"+mesg) } me string: streamName() <- {return("")} // Override as needed. void: waitForParseCompletion()<-{ me MutexMngr: MtxMgr{chkParseDone} while(!parseCompleted){ parseDoneLock.wait(MtxMgr) } } void: waitForExtractCompletion()<-{ me MutexMngr: MtxMgr{chkExtractDone} while(!extractCompleted){ extractDoneLock.wait(MtxMgr) } } void: waitForThreadsToExit() <- { parserThread.waitForExit() extracterThread.waitForExit() } void: start(their EParser: iParser, their strBuf: streamToParse, our <CLASSNAME>: topItem, me string:Name) <- { name <- Name parser<-iParser me int: startProduction <- parser.syntax.<CLASSNAME>_str parser.errorMesg <- "" parser.setStreamingMode(true) leftParseNode <- parser.initParseFromStream(streamToParse) extracterThread.init(self, leftParseNode, topItem) extracterThread.start(name+"_X") parserThread.init(self) parserThread.start(name+"_P") } } '''.replace('<CLASSNAME>', className) codeDogParser.AddToObjectFromText( classes[0], classes[1], S, 'Parse_' + className + '() and threaded parse support structs')
def codeListWidgetManagerClassOverride(classes, listManagerStructName, structTypeName): funcTextToUpdateViewWidget = '' funcTextToUpdateEditWidget = '' funcTextToUpdateCrntFromWidget = '' funcTextToPushCrntToListView = '' rowHeaderCode = '' rowViewCode = '' # Find the model modelRef = progSpec.findSpecOf(classes[0], structTypeName, 'model') currentModelSpec = modelRef if modelRef==None: cdErr('To build a list GUI for list of "'+structTypeName+'" a model is needed but is not found.') ### Write code for each field for field in modelRef['fields']: typeSpec = field['typeSpec'] fldCat = progSpec.fieldsTypeCategory(typeSpec) fieldName = field['fieldName'] label = deCamelCase(fieldName) CasedFieldName = fieldName[0].upper() + fieldName[1:] widgetName = CasedFieldName + 'Widget' if not progSpec.isAContainer(typeSpec): if(fldCat!='struct'): rowHeaderCode += ' their GUI_Frame: '+fieldName + '_header <- makeLabelWidget("'+fieldName+'")\n' rowHeaderCode += ' setLabelWidth('+fieldName+'_header, 15)\n' rowHeaderCode += ' addToContainer(headerBox, '+fieldName+'_header)\n' if fldCat=='struct': funcTextToUpdateViewWidget += '' funcTextToUpdateEditWidget += ' /- updateWidgetFromVars()\n' funcTextToUpdateCrntFromWidget += ' /- updateVarsFromWidget()\n' elif fldCat=='enum' or fldCat=='mode': funcTextToUpdateViewWidget += '' funcTextToUpdateEditWidget += '' funcTextToUpdateCrntFromWidget += ''# crntRecord.'+fieldName+' <- dialog.' + widgetName + '.getValue()\n' elif fldCat=='bool': funcTextToUpdateViewWidget += '' funcTextToUpdateEditWidget += '' funcTextToUpdateCrntFromWidget += ' crntRecord.'+fieldName+' <- dialog.' + widgetName + '.getValue()\n' elif fldCat=='string': funcTextToUpdateViewWidget += '' funcTextToUpdateEditWidget += ' dialog.' + widgetName + '.setValue('+structTypeName+'_ListData[N].'+fieldName+')\n' funcTextToUpdateCrntFromWidget += ' me string: '+widgetName+'Str <- string(dialog.' + widgetName + '.getValue())\n' funcTextToUpdateCrntFromWidget += ' crntRecord.'+fieldName+' <- '+widgetName+'Str\n' rowViewCode += ' their GUI_Frame: '+fieldName + '_value <- makeLabelWidget(crntRecord.'+fieldName+'.data())\n' rowViewCode += ' setLabelWidth('+fieldName+'_value, 15)\n' rowViewCode += ' addToContainer(rowBox, '+fieldName+'_value)\n' rowViewCode += ' showWidget('+fieldName+'_value)\n' elif fldCat=='int': funcTextToUpdateViewWidget += '' funcTextToUpdateEditWidget += ' dialog.' + widgetName + '.setValue('+structTypeName+'_ListData[N].'+fieldName+')\n' #funcTextToUpdateCrntFromWidget += ' me string: '+widgetName+'Str <- string(dialog.' + widgetName + '.getValue())\n' #funcTextToUpdateCrntFromWidget += ' crntRecord.'+fieldName+' <- dataStr\n' rowViewCode += ' their GUI_Frame: '+fieldName + '_value <- makeLabelWidget(toString(crntRecord.'+fieldName+').data())\n' rowViewCode += ' setLabelWidth('+fieldName+'_value, 15)\n' rowViewCode += ' addToContainer(rowBox, '+fieldName+'_value)\n' rowViewCode += ' showWidget('+fieldName+'_value)\n' else: print"pattern_MakeGUI.codeListWidgetManagerClassOverride fldCat not specified: ", fldCat; exit(2) ############### CODE = 'struct '+listManagerStructName+''': inherits=ListWidgetManager{ our <STRUCTNAME>: crntRecord our <STRUCTNAME>[our list]: <STRUCTNAME>_ListData me <STRUCTNAME>_Dialog_GUI: dialog their GUI_Frame: listViewWidget their GUI_Frame[their list]:rows their GUI_Frame: crntRow /- Override all these for each new list editing widget their GUI_Frame: makeListHeader() <- { their GUI_Frame: box <- makeFrameWidget() their GUI_Frame: headerRow <- makeRowWidget("") their GUI_Frame: headerBox <- makeXStackWidget("") <ROWHEADERCODE> addToContainer(headerRow, headerBox) addToContainer(box, headerRow) return(box) } their GUI_Frame: makeRowView(our <STRUCTNAME>: item) <- { crntRecord <- item their GUI_Frame: rowBox <- makeXStackWidget("") <ROWVIEWCODE> showWidget(rowBox) return(rowBox) } their listWidget: makeListViewWidget() <- { listViewWidget <- makeListWidget("") setListWidgetSelectionMode (listViewWidget, SINGLE) withEach item in <STRUCTNAME>_ListData { their GUI_Frame: row <- makeRowView(item) addToContainer(listViewWidget, row) } return(listViewWidget) } me int: pushCrntToList(me int: N) <- { <STRUCTNAME>_ListData.pushLast(crntRecord); me int: listLength <- getListLength() print("listLength: ", listLength) their GUI_Frame: row <- makeRowView(crntRecord) rows.pushLast(row) addToContainer(listViewWidget, row) return(listLength) } void: deleteNthRow(me int: N) <- { rows.deleteNth(N) } their GUI_Frame: getNthRow(me int: N) <-{ crntRow <- rows[N] } me int: deleteNthItem(me int: N) <- { <STRUCTNAME>_ListData.deleteNth(N) me int: retVal <- getListLength() return(retVal) } void: updateViewableWidget() <- {<funcTextToUpdateViewWidget>} their GUI_item: makeEditableWidget() <- {return(dialog.make<STRUCTNAME>Widget(crntRecord))} void: updateEditableWidget(me int: N) <- {<funcTextToUpdateEditWidget>} void: updateCrntFromEdited(me int: N) <- {<funcTextToUpdateCrntFromWidget>} void: allocateNewCurrentItem() <- {Allocate(crntRecord)} void: copyCrntBackToList(me int: N) <- {<STRUCTNAME>_ListData[N] <- crntRecord} void: copyCrntBackToListView(me int: N) <- { print("copyCrntBackToListView ", N) } void: setCurrentItem(me int: idx) <- {crntRecord <- <STRUCTNAME>_ListData[idx]} void: setValue(our <STRUCTNAME>[our list]: ListData) <- {<STRUCTNAME>_ListData <- ListData} me int: getListLength() <- {return(<STRUCTNAME>_ListData.size())} their GUI_item: initWidget(our <STRUCTNAME>[our list]: Data) <- { <STRUCTNAME>_ListData <- Data Allocate(rows) return(ListEdBox.init_dialog(self)) } } ''' CODE = CODE.replace('<STRUCTNAME>', structTypeName) CODE = CODE.replace('<funcTextToUpdateViewWidget>', funcTextToUpdateViewWidget) CODE = CODE.replace('<funcTextToUpdateEditWidget>', funcTextToUpdateEditWidget) CODE = CODE.replace('<funcTextToUpdateCrntFromWidget>', funcTextToUpdateCrntFromWidget) CODE = CODE.replace('<funcTextToPushCrntToListView>', funcTextToPushCrntToListView) CODE = CODE.replace('<ROWHEADERCODE>', rowHeaderCode) CODE = CODE.replace('<ROWVIEWCODE>', rowViewCode) #print '==========================================================\n'+CODE codeDogParser.AddToObjectFromText(classes[0], classes[1], CODE, listManagerStructName)
def apply(classes, tags): global firstRun if not firstRun: return firstRun = False progSpec.addCodeToInit(tags, 'CommandLineManager.processCmdLine(prgArgs, false)') code = r""" struct GLOBAL{ me CmdLineArgsMngr: CommandLineManager } struct optionRecord{ me string: groupID me string: optionID me string: shortName me string: longName me string: helpText me string: defaultVal // "_REQIRED" = required } struct CmdLineArgsMngr { me string: cmdLineText me List<our optionRecord>: options void: defineOption(me string: groupID, me string: optionID, me string: shortName, me string: longName, me string: helpText, me string: defaultTxt) <- { our optionRecord: rec Allocate(rec, groupID, optionID, shortName, longName, helpText, defaultTxt) options.append(rec) } me string: getOption(me string: groupID, me string: optionID) <- { me stringScanner: scanner me string: argToReturn <- "" scanner.initialize(cmdLineText) if(cmdLineText=="-h" or cmdLineText=="--help"){ print(helpText()) exit(1) } // Find optionRecord me int: recIdx <- -1 withEach optRec in options{ if(optRec.optionID==optionID){ recIdx <- optRec_key break() } } if(recIdx==-1){return("")} me string: shortName <- options[recIdx].shortName me string: longName <- options[recIdx].longName me string: defaultTxt <- options[recIdx].defaultVal me int: scanPos <- scanner.pos me int: foundPos <- scanner.skipPast(shortName) me int: startPos <- scanner.skipWS() me int: endPos <- 0 if(foundPos>=0){ endPos <- scanner.skipTo(" -") argToReturn <- cmdLineText.subStr(startPos, endPos-startPos) } else { scanner.pos <- scanPos foundPos <- scanner.skipPast(longName) startPos <- scanner.skipWS() if(foundPos>=0){ endPos <- scanner.skipTo(" -") argToReturn <- cmdLineText.subStr(startPos, endPos-startPos) } } if(argToReturn==""){ if(defaultTxt=="_REQIRED"){ print("\nOption '", optionID, "' is required.\n") print(helpText()) exit(1) } else { argToReturn <- defaultTxt } } return(argToReturn) } me string: helpText() <- { me string: helpTxt <- "\nOPTIONS:\n" withEach optRec in options{ me string: defaultVal <- "(default: "+optRec.defaultVal+")" if(optRec.defaultVal=="_REQIRED"){defaultVal <- "REQUIRED"} helpTxt <+- " "+optRec.shortName+" \t"+alignLeft(optRec.longName, 12)+" "+alignLeft(optRec.helpText, 25)+" \t"+defaultVal+"\n" } helpTxt <+- " -h \t"+alignLeft("--help", 12)+" "+alignLeft("Print this help text", 25)+"\n" return(helpTxt+"\n") } void: processCmdLine(me string:prgArgs, me bool: exitOnInvalid) <- { cmdLineText <- prgArgs me int: txtSize <- cmdLineText.size() // TODO: make this handle multiple options of each kind e.g., as with a compiler having multiple link options. // ALSO: add features from posix's or java's command line style // me char: ch // withEach p in RANGE(0 .. txtSize){ // ch <- cmdLineText[p] // } } } """ codeDogParser.AddToObjectFromText(classes[0], classes[1], code , 'Pattern: Manage Command-Line')