Wiki

Ticket #12: cmdLnArgsAll.2.patch

File cmdLnArgsAll.2.patch, 28.5 KB (added by hopscc, 16 years ago)
  • HowTo/380-WinForms.cobra

     
    11# .compile-only. 
    2 # .args. -c -t:winexe -r:System.Windows.Forms 
     2# .args. -c -t:winexe -ref:System.Windows.Forms 
    33""" 
    44To compile: 
    5 cobra -c -t:winexe -r:System.Windows.Forms 380-WinForms.cobra 
     5cobra -c -t:winexe -ref:System.Windows.Forms 380-WinForms.cobra 
    66 
    77To run: 
    88winforms 
  • Source/Compiler.cobra

     
    393393                assert modules.count 
    394394                _modules.addRange(modules) 
    395395            return modules 
    396  
     396             
     397    # default invocation of runProcess - no explicit exeName and no argList 
    397398    def runProcess as Process 
     399        return .runProcess(nil, nil) 
     400     
     401    def runProcess(exeName as String?, argList as IList<of String>?) as Process      
    398402        """ 
     403        Run a Process passing optional explicit exeName and argList 
    399404        Returns a new Process with startInfo.fileName and p.startInfo.arguments set appropriately 
    400         for the produced executable and the current options. 
     405        for the produced executable and the current options and any provided arglist. 
    401406        """ 
    402         # TODO: support args to the program with a - or -- separator 
    403407        p = Process() 
     408        if exeName 
     409            baseExeFileName = exeName 
     410            fullExeFileName = exeName  
     411        else 
     412            baseExeFileName = .baseExeFileName 
     413            fullExeFileName = .fullExeFileName 
    404414        branch .platform 
    405415            on PlatformEnum.Microsoft 
    406                 p.startInfo.fileName = .baseExeFileName 
     416                p.startInfo.fileName = baseExeFileName 
    407417            on PlatformEnum.Novell 
     418                # fixup fullExeFileName 
     419                if not '.' in fullExeFileName  
     420                    fullExeFileName += '.exe'                    
    408421                p.startInfo.fileName = 'mono' 
    409422                args = '' 
    410423                # mono also needs --debug when running 
    411424                if .options.getDefault('debug', '') not in ['', '-'] 
    412425                    args += '--debug ' 
    413                 args += '"[.fullExeFileName]"' 
     426                args += '"[fullExeFileName]"' 
    414427                p.startInfo.arguments = args 
    415428            else 
    416429                throw FallThroughException(.platform) 
     430                 
     431        if argList 
     432            args = p.startInfo.arguments ? '' 
     433            args += Utils.join(' ', argList) 
     434            p.startInfo.arguments = args 
     435         
    417436        return p 
    418437 
    419438    ## 
     
    670689                print ' |', line 
    671690            return refs 
    672691 
    673         parts = output.replace('-r:', '\0').split(c'\0') 
     692            parts = output.replace('-ref:', '\0').split(c'\0') 
    674693        for part in parts 
    675694            if part.trim <> '', refs.add(part.trim) 
    676695         
  • Source/CommandLine.cobra

     
    201201        }, 
    202202        { 
    203203            'name': 'reference', 
    204             'synonyms': ['r'], 
     204            'synonyms': ['ref'],  
    205205            'isAccumulator': true, 
    206206            'description': 'Add a DLL reference.', 
    207207            'args': 'Some.dll', 
     
    220220#           'args': ':Qualified.Type.Name', 
    221221#       }, 
    222222        { 
    223             'name': 'run', 
    224             'description': 'Runs the Cobra program. This is the default behavior if specify any Cobra source files.', 
     223            'name': 'run',  
     224            'synonyms': ['r'],  
     225            'description': 'Runs the Cobra program after compilation. This is the default behavior if specify any Cobra source files.' +_ 
     226                'Any trailing args are used as filename to execute and args to pass to it.', 
     227            'eg':   '-r echo arg1 arg2 argThree', 
    225228            'type': 'main', 
    226229        }, 
     230 
     231#       # It would be clearer if -run was left without synonym and this activated. 
     232#       # separate the flag behaviour of -run ((compile and) run executable) from 
     233#       # explicitly specifying the run cmdline ( -r exe args...) .....Oh well... 
     234#       {        
     235#           'name': 'exe-args', 
     236#           'synonyms': ['-r'],   
     237#           'description': 'First arg is executable to run,  remaining are to be passed to executable.', 
     238#           'eg':          '-r echo arg1 arg2 argThree', 
     239#           'type': 'exe-args-list', 
     240#       }, 
     241         
     242        {        
     243            'name': 'run-args', 
     244            'synonyms': ['-'],  #'--' 
     245            'description': 'Remaining args are to be passed to executable.', 
     246            'eg':          '-- arg1 arg2 argThree', 
     247            'type': 'args-list', 
     248        }, 
     249             
    227250        { 
    228251            'name': 'sharp-compiler', 
    229252            'description': 'Specify the path to the backend C# compiler.', 
     
    287310 
    288311    var _options = Options() 
    289312    var _pathList as List<of String>? 
     313    var _runArgs  as IList<of String>?  # nil or args set for running exe 
     314    var _exeFileName as String?         # Name specified for exe to run 
    290315    var _htmlWriter as HtmlWriter? 
    291316 
    292317    var _compiler as Compiler? 
     
    382407                .doAbout 
    383408            else if options.boolValue('build-standard-library') 
    384409                .doBuildStandardLibrary 
    385             else if not paths.count 
     410            else if not paths.count and not _exeFileName 
    386411                .doHelp 
    387412            else 
    388413                .doRun(paths) 
    389414        if _htmlWriter 
    390415            _htmlWriter.writeHtml('</body></html>[_htmlWriter.newLine]') 
    391416 
    392     def isOptionSpecRestrictionViolated(optionSpec as Dictionary<of String, Object>) as bool 
    393         """ 
    394         Returns true if the option spec has a 'restriction' key and the check against that restriction is true. 
    395         """ 
    396         if optionSpec.containsKey('restriction') 
    397             branch optionSpec['restriction'] to String 
    398                 on 'mono-only' 
    399                     return not CobraCore.isRunningOnMono 
    400         return false 
    401  
    402417    def parseArgs(args as IList<of String>, options as out Options?, paths as out List<of String>?) 
    403418        """ 
    404419        Parse command line arguments. 
     
    407422        ensure 
    408423            options 
    409424            paths 
    410         body 
     425        body     
    411426            optionPrefix = '-' 
    412             valuePrefix = c':' 
    413427            if not args.count 
    414428                options = Options() 
    415429                options.add('help', true) 
     
    421435            synToName = Dictionary<of String, String>() 
    422436                # ^ maps synonyms to their full names 
    423437            synList = List<of String>() 
    424             for d in _optionSpecs 
    425                 if .isOptionSpecRestrictionViolated(d) 
    426                     continue 
    427                 specDict[d['name'] to String] = d 
    428                 if d.containsKey('synonyms') 
    429                     syns = d['synonyms'] to System.Collections.IList 
    430                     for syn as String in syns 
    431                         assert not specDict.containsKey(syn) 
    432                         specDict[syn] = d 
    433                         synToName[syn] = d['name'] to String 
    434                         synList.add(syn) 
    435                 if not d.containsKey('type') 
    436                     d.add('type', 'string') 
     438            .initSynonyms( specDict, synToName, synList) 
    437439 
    438440            # set up initial valueDict 
    439441            valueDict = Dictionary<of String, Object>() 
    440442            if Utils.isDevMachine 
    441443                valueDict['reveal-internal-exceptions'] = true  # this is a specially computed default, but can still be overridden on the command line 
    442444 
     445            value = 'no-value' to dynamic 
     446            valueStr = 'no-value' 
    443447            fileList = List<of String>() 
    444             value = 'no-value' to dynamic 
    445448            mainOptions = List<of String>() 
    446449            didSpecify = Dictionary<of String, bool>()  # CC: could just be a Set 
     450            argn=0 
    447451            for arg in args 
     452                argn += 1   # next arg after current 
    448453                if arg.trim.length == 0 
    449454                    continue 
    450                 if arg.startsWith(optionPrefix) 
    451                     isOption = true 
    452                     while arg.startsWith(optionPrefix) 
    453                         arg = arg[1:] 
    454                 else 
    455                     isOption = false 
     455                     
     456                isOption = arg.startsWith(optionPrefix) 
    456457                if isOption 
    457                     parts = arg.split(@[valuePrefix], 2) 
    458                     if parts.length == 1 
    459                         name = parts[0] 
    460                         if name.endsWith('+') 
    461                             name = name[:-1] 
    462                             valueStr = 'on' 
    463                         else if name.endsWith('-') 
    464                             name = name[:-1] 
    465                             valueStr = 'off' 
    466                         else 
    467                             valueStr = 'on' 
    468                     else 
    469                         assert parts.length == 2 
    470                         name = parts[0] 
    471                         valueStr = parts[1] 
    472                     assert name.length, parts 
    473                     name = Utils.getSS(synToName to passthrough, name, name) to ! 
    474                     if not specDict.containsKey(name) 
    475                         msg = 'No such option "[name]".' 
    476                         if name.contains('=') 
    477                             msg += ' If you meant to specify an option value, use colon (:) instead of equals (=).' 
    478                         .error(msg) 
     458                    name = .getOptionParts(arg, optionPrefix, synToName, specDict, out valueStr) 
    479459                    spec = specDict[name] 
    480                     if Utils.getSB(spec to passthrough, 'isAccumulator', false) 
    481                         # accumulators are always treated as strings. TODO: assert that 
    482                         if valueDict.containsKey(name) 
    483                             (valueDict[name] to System.Collections.IList).add(valueStr to passthrough) 
    484                         else 
    485                             valueDict[name] = [valueStr] 
    486                             didSpecify[name] = true 
    487                     else 
    488                         cannotProcess = false 
    489                         if name=='debug' 
    490                             # special case 
    491                             if valueStr=='pdbonly' or valueStr=='full' 
    492                                 value = valueStr 
    493                             else 
    494                                 try 
    495                                     value = .boolForString(valueStr) 
    496                                 catch FormatException 
    497                                     cannotProcess = true 
    498                                 success 
    499                                     value = if(value, '+', '-') 
    500                         else 
    501                             if spec['type'] == 'main' 
    502                                 mainOptions.add(name) 
    503                                 value = true 
    504                             else 
    505                                 possible = .interpretValue(valueStr, spec) 
    506                                 if possible is not nil 
    507                                     value = possible 
    508                                 else 
    509                                     cannotProcess = true 
    510                         if cannotProcess 
    511                             .error('Cannot process value "[valueStr]" for option "[name]".') 
    512                         valueDict[name] = value 
    513                         didSpecify[name] = true 
     460 
     461                    if .isAccumulatorOption(spec) 
     462                        .accumulateOptionValue(name, valueStr, valueDict, didSpecify) 
     463                        continue 
     464                         
     465                    cannotProcess = argsDone = false 
     466                    value = .processToValue(name, valueStr, spec, mainOptions, args, argn, out cannotProcess, out argsDone ) 
     467                    if argsDone 
     468                        break   # slurpt up rest of args 
     469                    if cannotProcess 
     470                        .error('Cannot process value "[valueStr]" for option "[name]".') 
     471                    valueDict[name] = value 
     472                    didSpecify[name] = true 
    514473                else # not isOption 
    515                     if File.exists(arg) 
    516                         fileList.add(arg) 
    517                     else if File.exists(arg+'.cobra') 
    518                         fileList.add(arg+'.cobra') 
    519                     else if Directory.exists(arg) 
    520                         fileList.add(arg) 
    521                     else 
    522                         msg = 'Cannot find "[arg]" as a file.' 
    523                         if arg.startsWith('/') 
    524                             msg += ' If you meant to specify an option, use dash (-) instead of slash (/).' 
    525                         .error(msg) 
     474                    if arg.startsWith('/') 
     475                        errHint = ' If you meant to specify an option, use dash (-) instead of slash (/).' 
     476                    .processAsFile(arg, fileList, errHint) 
    526477 
    527             # handle synonyms 
    528             for syn in synList 
    529                 if valueDict.containsKey(syn) 
    530                     valueDict[synToName[syn]] = valueDict[syn] 
    531                     valueDict.remove(syn) 
     478            .handleSynonyms(synList, synToName, valueDict)           
     479            .addInDefaults(valueDict)        
    532480 
    533             # add in defaults 
    534             for d in _optionSpecs 
    535                 defaultName = d['name'] to String 
    536                 if not valueDict.containsKey(defaultName) and d.containsKey('default') 
    537                     defaultValue = .interpretValue(d['default'] to String, d) to ! 
    538                     if .verbosity 
    539                         print 'Setting option "[defaultName]" to default value [defaultValue].' 
    540                     valueDict[defaultName] = defaultValue 
    541  
    542481            # TODO: make the option names case-insensitive 
    543482 
    544483            # check for more than one main option 
    545484            if mainOptions.count > 1 
    546485                .error('Cannot have these main options at the same time: [Utils.join(", ", mainOptions)]') 
    547486 
    548             # unpack certain options into specific class fields 
    549             if valueDict.containsKey('verbosity') 
    550                 _verbosity = valueDict['verbosity'] to int 
    551             if not valueDict.containsKey('timeit') and valueDict.containsKey('testify') 
    552                 valueDict['timeit'] = true 
    553             if valueDict.containsKey('timeit') 
    554                 CobraMain.willTimeIt = valueDict['timeit'] to bool 
    555             if valueDict.containsKey('files') 
    556                 for fileName as String in valueDict['files'] to System.Collections.IList 
    557                     try 
    558                         for line in File.readAllLines(fileName) 
    559                             line = line.trim 
    560                             if line.length==0 or line.startsWith('#') 
    561                                 continue 
    562                             # TODO: dup'ed above 
    563                             arg = line 
    564                             if File.exists(arg) 
    565                                 fileList.add(arg) 
    566                             else if File.exists(arg+'.cobra') 
    567                                 fileList.add(arg+'.cobra') 
    568                             else if Directory.exists(arg) 
    569                                 fileList.add(arg) 
    570                             else 
    571                                 msg = 'Cannot find "[arg]" as a file.' 
    572                                 #if arg.startsWith('/') 
    573                                 #   msg += ' If you meant to specify an option, use dash (-) instead of slash (/).' 
    574                                 .error(msg) 
    575                             # end dup 
    576                     catch IOException 
    577                         .error('Cannot open file "[fileName]".') 
     487            .unpackOptions(valueDict, fileList)  
    578488 
    579489            # set the out parameters 
    580490            options = Options(valueDict) 
     
    583493            paths = fileList 
    584494 
    585495            .computeArgImplications(options to !) 
     496             
     497         
     498    def getOptionParts(arg as String, _ 
     499                optionPrefix as String, _ 
     500                synToName as Dictionary<of String, String>, _ 
     501                specDict as Dictionary<of String, Dictionary<of String, Object>>, _ 
     502                valueStr as out String) as String 
     503        arg = .fixOptionArg(arg, optionPrefix)   
     504        # [name, valueStr] = .splitOption(arg) 
     505        l   = .splitOption(arg)  
     506        name     = l[0] 
     507        valueStr = l[1] 
     508        name = .validateOptionName(name, synToName, specDict) 
     509        return name          
     510         
     511             
     512    def fixOptionArg(arg as String, optionPrefix as String) as String 
     513        """ 
     514        Strip any leading optionPrefix chars and possibly adjust arg 
     515        """ 
     516        while arg.startsWith(optionPrefix) 
     517            arg = arg[1:] 
     518            if not arg.length  # '--' 
     519                arg='run-args' 
     520        return arg 
     521                 
     522    def  splitOption(arg as String) as IList<of String> 
     523        """ 
     524        Split option into name and valueStr returned as a 2 element array 
     525        """ 
     526        valuePrefix = c':' 
     527        parts = arg.split(@[valuePrefix], 2) 
     528        if parts.length == 1 
     529            name = parts[0] 
     530            if name.endsWith('+') 
     531                name = name[:-1] 
     532                valueStr = 'on' 
     533            else if name.endsWith('-') 
     534                name = name[:-1] 
     535                valueStr = 'off' 
     536            else 
     537                valueStr = 'on' 
     538        else 
     539            assert parts.length == 2 
     540            name = parts[0] 
     541            valueStr = parts[1] 
     542        assert parts, name.length  
     543        #assert valueStr.length 
     544        return [name, valueStr]  
     545         
     546    def isOptionSpecRestrictionViolated(optionSpec as Dictionary<of String, Object>) as bool 
     547        """ 
     548        Returns true if the option spec has a 'restriction' key and the check against  
     549        that restriction is true. 
     550        """ 
     551        if optionSpec.containsKey('restriction') 
     552            branch optionSpec['restriction'] to String 
     553                on 'mono-only' 
     554                    return not CobraCore.isRunningOnMono 
     555        return false 
     556             
     557    def initSynonyms(specDict as Dictionary<of String, Dictionary<of String, Object>>, _ 
     558                    synToName as Dictionary<of String, String>, _ 
     559                    synList as List<of String>) 
     560        """ 
     561        Initialise supporting data structures for handling option synonyms 
     562        """ 
     563        for d in _optionSpecs 
     564            if .isOptionSpecRestrictionViolated(d) 
     565                continue 
     566            specDict[d['name'] to String] = d 
     567            if d.containsKey('synonyms') 
     568                syns = d['synonyms'] to System.Collections.IList 
     569                for syn as String in syns 
     570                    assert not specDict.containsKey(syn) 
     571                    specDict[syn] = d 
     572                    synToName[syn] = d['name'] to String 
     573                    synList.add(syn) 
     574            if not d.containsKey('type') 
     575                d.add('type', 'string') 
     576             
     577    def validateOptionName( name as String, _ 
     578            synToName as Dictionary<of String, String>, _ 
     579            specDict as Dictionary<of String, Dictionary<of String, Object>> _ 
     580            ) as String 
     581        """ 
     582        Ensure the given name exists as an option name or synonym mappableto an option name;  
     583        return the canonical name for the option/synonym 
     584        """ 
     585        name = Utils.getSS(synToName to passthrough, name, name) to ! 
     586        if not specDict.containsKey(name) 
     587            msg = 'No such option "[name]".' 
     588            if name.contains('=') 
     589                msg += ' If you meant to specify an option value, use colon (:) instead of equals (=).' 
     590            .error(msg) 
     591        return name      
     592         
     593    def isAccumulatorOption(spec as Dictionary<of String,Object>) as bool 
     594        return  Utils.getSB(spec to passthrough, 'isAccumulator', false) 
     595             
     596    def accumulateOptionValue(name as String, valueStr as String, _ 
     597            valueDict as Dictionary<of String, Object>, _ 
     598            didSpecify as Dictionary<of String, bool>) 
     599        # accumulators are always treated as strings. TODO: assert that 
     600        if valueDict.containsKey(name) 
     601            (valueDict[name] to System.Collections.IList).add(valueStr to passthrough) 
     602        else 
     603            valueDict[name] = [valueStr] 
     604            didSpecify[name] = true 
     605         
     606             
     607    def fixupDebug(valueStr as String, cannotProcess as out bool) as String 
     608        cannotProcess = false 
     609        if valueStr == 'pdbonly' or valueStr == 'full' 
     610            return valueStr 
     611             
     612        value = 'no-value'   
     613        try 
     614            b = .boolForString(valueStr) 
     615        catch FormatException 
     616            cannotProcess = true 
     617        success 
     618            value = if(b, '+', '-') 
     619        return value 
     620     
     621    def processToValue(name as String,  _ 
     622                        valueStr as String, _ 
     623                        spec as Dictionary<of String, Object>,_ 
     624                        mainOptions as List<of String>, _ 
     625                        argList as IList<of String>, _ 
     626                        argn as int, _ 
     627                        cannotProcess as out bool, _ 
     628                        argsDone as out bool ) as dynamic 
     629        value as dynamic = 'no-value' 
     630        argsDone = false 
     631        cannotProcess = false 
     632     
     633        if name == 'debug'      # special case 
     634            return .fixupDebug(valueStr, out cannotProcess ) 
     635         
     636        t  = spec['type'] to String 
     637        branch t 
     638            on 'main' 
     639                mainOptions.add(name) 
     640                value = true 
     641                if name == 'run'  # suck up remainder of args as exeFile and then args for it 
     642                    if argList.count <= argn 
     643                        _exeFileName = nil 
     644                        _runArgs     = nil 
     645                    else 
     646                        _exeFileName = argList[argn] 
     647                        _runArgs     = argList[argn+1:] 
     648                    argsDone = true 
     649            on 'args-list' 
     650                # remainder of args are for execution of exe file 
     651                _runArgs =  argList[argn:] 
     652                argsDone = true 
     653#           on 'exe-args-list' 
     654#               if argList.count <= argn 
     655#                   .error("exe-args option must have at least one arg following") 
     656#               _exeFileName = argList[argn] 
     657#               _runArgs     = argList[argn+1:] 
     658#               argsDone = true 
     659            else 
     660                possible = .interpretValue(valueStr, spec) 
     661                if possible is not nil 
     662                    value = possible 
     663                else 
     664                    cannotProcess = true 
     665        return value 
     666                 
    586667 
     668    def handleSynonyms(synList as List<of String>, _ 
     669                        synToName as Dictionary<of String, String>, _ 
     670                        valueDict as Dictionary<of String, Object>) 
     671        for syn in synList 
     672            if valueDict.containsKey(syn) 
     673                valueDict[synToName[syn]] = valueDict[syn] 
     674                valueDict.remove(syn) 
     675             
     676    def addInDefaults(valueDict as Dictionary<of String, Object>) 
     677        for d in _optionSpecs 
     678            defaultName = d['name'] to String 
     679            if not valueDict.containsKey(defaultName) and d.containsKey('default') 
     680                defaultValue = .interpretValue(d['default'] to String, d) to ! 
     681                if .verbosity 
     682                    print 'Setting option "[defaultName]" to default value [defaultValue].' 
     683                valueDict[defaultName] = defaultValue 
     684         
     685    def unpackOptions(valueDict as Dictionary<of String, Object>, _ 
     686                      fileList as List<of String>)   
     687        """ 
     688        Unpack certain magic options into specific class fields 
     689        """ 
     690        if valueDict.containsKey('verbosity') 
     691            _verbosity = valueDict['verbosity'] to int 
    587692 
     693        if not valueDict.containsKey('timeit') and valueDict.containsKey('testify') 
     694            valueDict['timeit'] = true 
     695        if valueDict.containsKey('timeit') 
     696            CobraMain.willTimeIt = valueDict['timeit'] to bool 
     697             
     698        if valueDict.containsKey('files') 
     699            fileNamesList = valueDict['files'] to System.Collections.IList 
     700            .processFilesFile( fileNamesList, fileList) 
     701 
     702                 
     703    def processFilesFile(fileNamesList as IList, fileList as List<of String>) 
     704        """ 
     705        Treat entries in fileNamesList as names of files containing file 
     706        names to compile, read and validate names and add into fileList 
     707        """ 
     708        for fileName as String in fileNamesList 
     709            try 
     710                for line in File.readAllLines(fileName) 
     711                    line = line.trim 
     712                    if line.length==0 or line.startsWith('#') 
     713                        continue 
     714                    .processAsFile(line, fileList, nil) 
     715            catch IOException 
     716                .error('Cannot open file "[fileName]".') 
     717             
     718    def  processAsFile(arg as String, fileList as List<of String>, _ 
     719                errHint as String?) 
     720        """ 
     721        Validate arg as filename and on success add into fileList 
     722        """ 
     723        if File.exists(arg) 
     724            fileList.add(arg) 
     725        else if File.exists(arg+'.cobra') 
     726            fileList.add(arg+'.cobra') 
     727        else if Directory.exists(arg) 
     728            fileList.add(arg) 
     729        else  
     730            msg = 'Cannot find "[arg]" as a file.' 
     731            if errHint  
     732                msg += errHint 
     733            .error(msg) 
     734 
    588735    def computeArgImplications(options as Options) 
    589736        if options.getDefault('target', '') == 'lib' and not options.isSpecified('compile') 
    590737            options['compile'] = true 
     
    596743            options['include-nil-checks'] = false 
    597744            options['include-tests'] = false 
    598745            options['optimize'] = true 
    599  
     746                 
    600747    def interpretValue(valueStr as String, spec as Dictionary<of String, Object>) as dynamic? 
    601748        value as dynamic? 
    602749        branch spec['type'] to String 
     
    725872            File.delete(c.fullExeFileName) 
    726873 
    727874    def doRun(paths as List<of String>) 
     875        .fixupCompileRunPath(paths) 
    728876        c = .doCompile(paths, false, false, false) 
    729877        if c.errors.count 
    730878            print 'Not running due to errors above.' 
    731879        else 
    732             p = c.runProcess 
     880            p = c.runProcess(_exeFileName, _runArgs) 
    733881            if _verbosity >= 1 
    734882                print 'Running: [p.startInfo.fileName] [p.startInfo.arguments]' 
    735883                print .verboseLineSeparator 
    736884            p.startInfo.useShellExecute = false 
    737885            p.start 
    738886            p.waitForExit  # TODO: is this necessary? 
     887             
     888             
     889    def fixupCompileRunPath(paths as List<of String>) 
     890        """ 
     891        Populate exeFile path if its empty and paths list isnt.  
     892        Populate paths if empty and exeFile path isnt    
     893        """ 
     894        if not _exeFileName   
     895            if paths.count 
     896                file = paths[0] 
     897                if file.endsWith('.cobra') 
     898                    file = file[:-6] 
     899                _exeFileName = file 
     900            else  
     901                .error('No fileName given to compile and run') 
     902        else                        # have exeFileName 
     903            if not paths.count  # but no compile paths 
     904                path0 = _exeFileName to ! 
     905                .processAsFile(path0, paths, nil) 
     906        #trace paths, _exeFileName           
    739907 
    740908    def doHelp 
    741909        # CC: multiline string 
     
    743911        print '' 
    744912        print 'Usage:' 
    745913        print '' 
    746         print '  cobra <options> <filename>' 
     914        print '  cobra <options> <filename(s)>' 
    747915        print '    * run filename' 
    748         print '    * compile if needed' 
     916        print '    * compile files if needed' 
    749917        print '    * .cobra extension is optional' 
    750918        print '' 
    751         print '  cobra <options> <command> <path(s)>' 
     919        print '  cobra <options> <command> <path(s)> ' 
    752920        print '    * commands that operate on path(s) are:' 
    753921        print '      -compile ... Compile only. Also, -c' 
    754         print '      -run ....... Run the program (compile if necessary).' 
     922        print '      -run ....... Run the program (compile if necessary). Also, -r' 
     923        print '                   Any args following are taken as executable file' 
     924        print '                    to compile and run and args to pass to it' 
    755925        print '      -test ...... Run the unit tests of a library.' 
    756926        print '      -document .. Document the program (partial compilation). Also, -doc' 
    757927        print '' 
     
    8411011                        first = false 
    8421012                else 
    8431013                    print '        Example: -[spec["name"]]:[spec["example"]]' 
     1014            if spec.containsKey('eg') #Verbatim example line 
     1015                print '        e.g. [spec["eg"]]' 
    8441016 
    8451017    def doAbout 
    8461018        # CC: multiline string 
  • Tests/720-libraries/100-winforms/100-winforms.cobra

     
    11# .compile-only. 
    2 # .args. -c -t:winexe -r:System.Windows.Forms 
     2# .args. -c -t:winexe -ref:System.Windows.Forms 
    33 
    44use System.Windows.Forms 
    55 
  • Tests/320-misc-two/520-indexer-with-non-standard-name.cobra

     
    1 # .args. -r:System.Xml 
     1# .args. -ref:System.Xml 
    22 
    33# XmlNodeList has an ItemOf property instead of Item. 
    44# This test shows that Cobra is reading the DefaultMemberAttribute of the class. 
  • Tests/700-command-line/700-run-args.cobra

     
     1# Test compile+run execution specifying args to run compiled prog with 
     2class Test 
     3    def main is shared 
     4        p as System.Diagnostics.Process? 
     5        cobraPath = CobraCore.findCobraExe 
     6        assert cobraPath 
     7        if cobraPath 
     8            cmdln = "702-echo -- argA argB argC" 
     9            output = CobraCore.runCobraExe(cobraPath, cmdln, out p) 
     10            #print output 
     11            assert 'Unhandled Exception' not in output 
     12            assert 'argA argB argC' in output 
     13            assert p.exitCode == 0 
     14         
     15            cmdln1 = "702-echo -run-args arg1A arg1B arg1C" 
     16            output = CobraCore.runCobraExe(cobraPath, cmdln1, out p) 
     17            #print output 
     18            assert 'Unhandled Exception' not in output 
     19            assert 'arg1A arg1B arg1C' in output 
     20            assert p.exitCode == 0 
     21             
  • Tests/700-command-line/402-fooprog.cobra

     
    1 # .args. -embed-run-time:no -r:400-foolib.dll 
     1# .args. -embed-run-time:no -ref:400-foolib.dll 
    22 
    33class Program 
    44 
  • Tests/700-command-line/404-fooprog.cobra

     
    1 # .args. -embed-run-time:no -r:400-foolib 
     1# .args. -embed-run-time:no -ref:400-foolib 
    22 
    33# same as other fooprog, but the -r arg does not include the ".dll" extension -- both ways should work 
    44 
  • Tests/700-command-line/410-use-lowernames-dll.cobra

     
    1 # .args. -r:lowernames.dll 
     1# .args. -ref:lowernames.dll 
    22 
    33class Program 
    44 
  • Tests/700-command-line/512-lib-option.cobra

     
    11# .compile-only. 
    2 # .args. -lib:libdir -r:foolib -c 
     2# .args. -lib:libdir -ref:foolib -c 
    33 
    44class Test 
    55 
  • Tests/700-command-line/300-args-reference-gac-lib.cobra

     
    1 # .args. -r:System.Xml 
     1# .args. -ref:System.Xml 
    22 
    33use System.Xml 
    44 
  • Tests/700-command-line/703-exec-args.cobra

     
     1# Test execution specifying cmdln args giving exe and args after compile 
     2class ExecWithArgs 
     3    def main is shared 
     4        p as System.Diagnostics.Process? 
     5        cobraPath = CobraCore.findCobraExe 
     6        assert cobraPath 
     7        if cobraPath 
     8            cmdln = "702-echo -run 702-echo argA argB argC" 
     9            output = CobraCore.runCobraExe(cobraPath, cmdln, out p) 
     10            #print output 
     11            assert 'Unhandled Exception' not in output 
     12            assert 'argA argB argC' in output 
     13            assert p.exitCode == 0 
     14         
     15            cmdln1 = "702-echo -r 110-hello AnyOldArgs AnyOldargs anyAnyOldArgs" 
     16            output = CobraCore.runCobraExe(cobraPath, cmdln1, out p) 
     17            #print output 
     18            assert 'Unhandled Exception' not in output 
     19            assert 'Hello' in output 
     20            assert 'AnyOld' not in output 
     21            assert p.exitCode == 0 
     22             
  • Developer/IntermediateReleaseNotes.text

     
    22 
    33* Added a new built-in doc tool accessible via "cobra -doc ...". The documentation is generated to local HTML files using your declarations, doc strings, contracts, etc. 
    44 
     5* Modified commandline options so -r becomes synonym for -run rather  
     6  than -reference. -reference synonym becoms -ref. 
     7  Support -run-args (--) for specifying args to pass to compiled executable  
     8  Make -run take optional args for executable to run and args to pass to  
     9  executable. (ticket#12)  
     10     
     11 
     12 
    513* Add support for specifying unsigned integers as Hex literals 
    614    e.g. 0x7f  0x7f_8   0x7Fu16  0x7F_u32 
    715