def parseConfigFile(fname, Config=Config, Jobs=Jobs): global DefaultToolList CP = ConfigParser.ConfigParser() CP.readfp(file(fname.rstrip(),'rt')) # First parse global options if CP.has_section('Options'): for opt in CP.options('Options'): # Is it one we expect if Config.has_key(opt): # Yup...override it Config[opt] = CP.get('Options', opt) elif CP.defaults().has_key(opt): pass # Ignore DEFAULTS section keys elif opt in ('fabricationdrawing', 'outlinelayer'): print '*'*73 print '\nThe FabricationDrawing and OutlineLayer configuration options have been' print 'renamed as of GerbMerge version 1.0. Please consult the documentation for' print 'a description of the new options, then modify your configuration file.\n' print '*'*73 sys.exit(1) else: raise RuntimeError, "Unknown option '%s' in [Options] section of configuration file" % opt else: raise RuntimeError, "Missing [Options] section in configuration file" # Ensure we got a tool list if not Config.has_key('toollist'): raise RuntimeError, "INTERNAL ERROR: Missing tool list assignment in [Options] section" # Make integers integers, floats floats for key,val in Config.items(): try: val = int(val) Config[key]=val except: try: val = float(val) Config[key]=val except: pass # Process lists of strings if Config['cutlinelayers']: Config['cutlinelayers'] = parseStringList(Config['cutlinelayers']) if Config['cropmarklayers']: Config['cropmarklayers'] = parseStringList(Config['cropmarklayers']) # setup default x & y spacing, taking into account metric units # if (xspacing == 0): # if (Config['measurementunits'] == 'inch'): # xspacing = 0.125 # else: # xspacing = 3 # if (yspacing == 0): # if (Config['measurementunits'] == 'inch'): # yspacing = 0.125 # else: # yspacing = 3 # Process list of minimum feature dimensions if Config['minimumfeaturesize']: temp = Config['minimumfeaturesize'].split(",") try: for index in range(0, len(temp), 2): MinimumFeatureDimension[ temp[index] ] = float( temp[index + 1] ) except: raise RuntimeError, "Illegal configuration string:" + Config['minimumfeaturesize'] # Process MergeOutputFiles section to set output file names if CP.has_section('MergeOutputFiles'): for opt in CP.options('MergeOutputFiles'): # Each option is a layer name and the output file for this name if opt[0]=='*' or opt in ('boardoutline', 'drills', 'placement', 'toollist'): MergeOutputFiles[opt] = CP.get('MergeOutputFiles', opt) # Now, we go through all jobs and collect Gerber layers # so we can construct the Global Aperture Table. apfiles = [] for jobname in CP.sections(): if jobname=='Options': continue if jobname=='MergeOutputFiles': continue if jobname=='GerbMergeGUI': continue # Ensure all jobs have a board outline if not CP.has_option(jobname, 'boardoutline'): raise RuntimeError, "Job '%s' does not have a board outline specified" % jobname if not CP.has_option(jobname, 'drills'): raise RuntimeError, "Job '%s' does not have a drills layer specified" % jobname for layername in CP.options(jobname): if layername[0]=='*' or layername=='boardoutline': fname = CP.get(jobname, layername) apfiles.append(fname) if layername[0]=='*': LayerList[layername]=1 # Now construct global aperture tables, GAT and GAMT. This step actually # reads in the jobs for aperture data but doesn't store Gerber # data yet. aptable.constructApertureTable(apfiles) del apfiles if 0: keylist = GAMT.keys() keylist.sort() for key in keylist: print '%s' % GAMT[key] sys.exit(0) # Parse the tool list if Config['toollist']: DefaultToolList = parseToolList(Config['toollist']) # Now get jobs. Each job implies layer names, and we # expect consistency in layer names from one job to the # next. Two reserved layer names, however, are # BoardOutline and Drills. Jobs.clear() do_abort = 0 errstr = 'ERROR' if Config['allowmissinglayers']: errstr = 'WARNING' for jobname in CP.sections(): if jobname=='Options': continue if jobname=='MergeOutputFiles': continue if jobname=='GerbMergeGUI': continue print '' # empty line before hand for readability print 'Reading data from', jobname, '...' J = jobs.Job(jobname) # Parse the job settings, like tool list, first, since we are not # guaranteed to have ConfigParser return the layers in the same order that # the user wrote them, and we may get Gerber files before we get a tool # list! Same thing goes for ExcellonDecimals. We need to know what this is # before parsing any Excellon files. for layername in CP.options(jobname): fname = CP.get(jobname, layername) if layername == 'toollist': J.ToolList = parseToolList(fname) elif layername=='excellondecimals': try: J.ExcellonDecimals = int(fname) except: raise RuntimeError, "Excellon decimals '%s' in config file is not a valid integer" % fname elif layername=='repeat': try: J.Repeat = int(fname) except: raise RuntimeError, "Repeat count '%s' in config file is not a valid integer" % fname for layername in CP.options(jobname): fname = CP.get(jobname, layername) if layername=='boardoutline': J.parseGerber(fname, layername, updateExtents=1) elif layername[0]=='*': J.parseGerber(fname, layername, updateExtents=0) elif layername=='drills': J.parseExcellon(fname) # Emit warnings if some layers are missing LL = LayerList.copy() for layername in J.apxlat.keys(): assert LL.has_key(layername) del LL[layername] if LL: if errstr=='ERROR': do_abort=1 print '%s: Job %s is missing the following layers:' % (errstr, jobname) for layername in LL.keys(): print ' %s' % layername # Store the job in the global Jobs dictionary, keyed by job name Jobs[jobname] = J if do_abort: raise RuntimeError, 'Exiting since jobs are missing layers. Set AllowMissingLayers=1\nto override.'
def parseConfigFile(fname, Config=Config, Jobs=Jobs): global DefaultToolList CP = ConfigParser.ConfigParser() CP.readfp(file(fname.rstrip(), 'rt')) # First parse global options if CP.has_section('Options'): for opt in CP.options('Options'): # Is it one we expect if Config.has_key(opt): # Yup...override it Config[opt] = CP.get('Options', opt) elif CP.defaults().has_key(opt): pass # Ignore DEFAULTS section keys elif opt in ('fabricationdrawing', 'outlinelayer'): print '*' * 73 print '\nThe FabricationDrawing and OutlineLayer configuration options have been' print 'renamed as of GerbMerge version 1.0. Please consult the documentation for' print 'a description of the new options, then modify your configuration file.\n' print '*' * 73 sys.exit(1) else: raise RuntimeError, "Unknown option '%s' in [Options] section of configuration file" % opt else: raise RuntimeError, "Missing [Options] section in configuration file" # Ensure we got a tool list if not Config.has_key('toollist'): raise RuntimeError, "INTERNAL ERROR: Missing tool list assignment in [Options] section" # Make integers integers, floats floats for key, val in Config.items(): try: val = int(val) Config[key] = val except: try: val = float(val) Config[key] = val except: pass # Process lists of strings if Config['cutlinelayers']: Config['cutlinelayers'] = parseStringList(Config['cutlinelayers']) if Config['cropmarklayers']: Config['cropmarklayers'] = parseStringList(Config['cropmarklayers']) # setup default x & y spacing, taking into account metric units # if (xspacing == 0): # if (Config['measurementunits'] == 'inch'): # xspacing = 0.125 # else: # xspacing = 3 # if (yspacing == 0): # if (Config['measurementunits'] == 'inch'): # yspacing = 0.125 # else: # yspacing = 3 # Process list of minimum feature dimensions if Config['minimumfeaturesize']: temp = Config['minimumfeaturesize'].split(",") try: for index in range(0, len(temp), 2): MinimumFeatureDimension[temp[index]] = float(temp[index + 1]) except: raise RuntimeError, "Illegal configuration string:" + Config[ 'minimumfeaturesize'] # Process MergeOutputFiles section to set output file names if CP.has_section('MergeOutputFiles'): for opt in CP.options('MergeOutputFiles'): # Each option is a layer name and the output file for this name if opt[0] == '*' or opt in ('boardoutline', 'drills', 'placement', 'toollist'): MergeOutputFiles[opt] = CP.get('MergeOutputFiles', opt) # Now, we go through all jobs and collect Gerber layers # so we can construct the Global Aperture Table. apfiles = [] for jobname in CP.sections(): if jobname == 'Options': continue if jobname == 'MergeOutputFiles': continue if jobname == 'GerbMergeGUI': continue # Ensure all jobs have a board outline if not CP.has_option(jobname, 'boardoutline'): raise RuntimeError, "Job '%s' does not have a board outline specified" % jobname if not CP.has_option(jobname, 'drills'): raise RuntimeError, "Job '%s' does not have a drills layer specified" % jobname for layername in CP.options(jobname): if layername[0] == '*' or layername == 'boardoutline': fname = CP.get(jobname, layername) apfiles.append(fname) if layername[0] == '*': LayerList[layername] = 1 # Now construct global aperture tables, GAT and GAMT. This step actually # reads in the jobs for aperture data but doesn't store Gerber # data yet. aptable.constructApertureTable(apfiles) del apfiles if 0: keylist = GAMT.keys() keylist.sort() for key in keylist: print '%s' % GAMT[key] sys.exit(0) # Parse the tool list if Config['toollist']: DefaultToolList = parseToolList(Config['toollist']) # Now get jobs. Each job implies layer names, and we # expect consistency in layer names from one job to the # next. Two reserved layer names, however, are # BoardOutline and Drills. Jobs.clear() do_abort = 0 errstr = 'ERROR' if Config['allowmissinglayers']: errstr = 'WARNING' for jobname in CP.sections(): if jobname == 'Options': continue if jobname == 'MergeOutputFiles': continue if jobname == 'GerbMergeGUI': continue print '' # empty line before hand for readability print 'Reading data from', jobname, '...' J = jobs.Job(jobname) # Parse the job settings, like tool list, first, since we are not # guaranteed to have ConfigParser return the layers in the same order that # the user wrote them, and we may get Gerber files before we get a tool # list! Same thing goes for ExcellonDecimals. We need to know what this is # before parsing any Excellon files. for layername in CP.options(jobname): fname = CP.get(jobname, layername) if layername == 'toollist': J.ToolList = parseToolList(fname) elif layername == 'excellondecimals': try: J.ExcellonDecimals = int(fname) except: raise RuntimeError, "Excellon decimals '%s' in config file is not a valid integer" % fname elif layername == 'repeat': try: J.Repeat = int(fname) except: raise RuntimeError, "Repeat count '%s' in config file is not a valid integer" % fname for layername in CP.options(jobname): fname = CP.get(jobname, layername) if layername == 'boardoutline': J.parseGerber(fname, layername, updateExtents=1) elif layername[0] == '*': J.parseGerber(fname, layername, updateExtents=0) elif layername == 'drills': J.parseExcellon(fname) # Emit warnings if some layers are missing LL = LayerList.copy() for layername in J.apxlat.keys(): assert LL.has_key(layername) del LL[layername] if LL: if errstr == 'ERROR': do_abort = 1 print '%s: Job %s is missing the following layers:' % (errstr, jobname) for layername in LL.keys(): print ' %s' % layername # Store the job in the global Jobs dictionary, keyed by job name Jobs[jobname] = J if do_abort: raise RuntimeError, 'Exiting since jobs are missing layers. Set AllowMissingLayers=1\nto override.'
def parseConfigFile(configFilePath, Config=Config, Jobs=Jobs): global DefaultToolList CP = configparser.ConfigParser() CP.read(configFilePath) # Store the base directory that all files are referenced from (the one the config file is in). configDir = os.path.dirname(configFilePath) # First parse global options and merge them into the global Config options object. if CP.has_section('Options'): for opt in CP.options('Options'): # Is it one we expect if opt in Config: # Yup...override it Config[opt] = CP.get('Options', opt) elif opt in CP.defaults(): pass # Ignore DEFAULTS section keys elif opt in ('fabricationdrawing', 'outlinelayer'): print('*' * 73) print('\nThe FabricationDrawing and OutlineLayer configuration options have been') print('renamed as of GerbMerge version 1.0. Please consult the documentation for') print('a description of the new options, then modify your configuration file.\n') print('*' * 73) sys.exit(1) else: raise RuntimeError("Unknown option '{:s}' in [Options] section of configuration file".format(opt)) else: raise RuntimeError("Missing [Options] section in configuration file") # Ensure we got a tool list if 'toollist' not in Config: raise RuntimeError("INTERNAL ERROR: Missing tool list assignment in [Options] section") # Make integers integers, floats floats for key, val in Config.items(): try: val = int(val) Config[key] = val except: try: val = float(val) Config[key] = val except: pass # Process lists of strings if Config['cutlinelayers']: Config['cutlinelayers'] = parseStringList(Config['cutlinelayers']) if Config['cropmarklayers']: Config['cropmarklayers'] = parseStringList(Config['cropmarklayers']) if Config['outlinelayers']: Config['outlinelayers'] = parseStringList(Config['outlinelayers']) # Process list of minimum feature dimensions if Config['minimumfeaturesize']: temp = Config['minimumfeaturesize'].split(",") try: for index in range(0, len(temp), 2): MinimumFeatureDimension[temp[index]] = float(temp[index + 1]) except: raise RuntimeError("Illegal configuration string:" + Config['minimumfeaturesize']) # Process MergeOutputFiles section to set output file names if CP.has_section('MergeOutputFiles'): for opt in CP.options('MergeOutputFiles'): # Each option is a layer name and the output file for this name if opt[0] == '*' or opt in ('boardoutline', 'drills', 'placement', 'toollist'): MergeOutputFiles[opt] = CP.get('MergeOutputFiles', opt) # Now, we go through all jobs and collect Gerber layers # so we can construct the Global Aperture Table. apfiles = [] for jobname in CP.sections(): if jobname == 'Options' or jobname == 'MergeOutputFiles' or jobname == 'GerbMergeGUI': continue # Ensure all jobs have a board outline if not CP.has_option(jobname, 'boardoutline'): raise RuntimeError("Job '{:s}' does not have a board outline specified".format(jobname)) if not CP.has_option(jobname, 'drills'): raise RuntimeError("Job '{:s}' does not have a drills layer specified".format(jobname)) for layername in CP.options(jobname): if layername[0] == '*' or layername == 'boardoutline': fname = CP.get(jobname, layername) apfiles.append(fname) if layername[0] == '*': LayerList[layername] = 1 # Now construct global aperture tables, GAT and GAMT. This step actually # reads in the jobs for aperture data but doesn't store Gerber # data yet. aptable.constructApertureTable([os.path.join(configDir, x) for x in apfiles], GAT, GAMT) del apfiles # Parse the tool list if Config['toollist']: DefaultToolList = excellon.parseToolList(Config['toollist']) # Now get jobs. Each job implies layer names, and we # expect consistency in layer names from one job to the # next. Two reserved layer names, however, are # BoardOutline and Drills. Jobs.clear() do_abort = False errstr = 'ERROR' if Config['allowmissinglayers']: errstr = 'WARNING' for jobname in CP.sections(): if jobname == 'Options' or jobname == 'MergeOutputFiles' or jobname == 'GerbMergeGUI': continue print('Reading data from', jobname, '...') J = jobs.Job(jobname) # Parse the job settings, like tool list, first, since we are not # guaranteed to have ConfigParser return the layers in the same order that # the user wrote them, and we may get Gerber files before we get a tool # list! Same thing goes for ExcellonDecimals. We need to know what this is # before parsing any Excellon files. for layername in CP.options(jobname): fname = CP.get(jobname, layername) if layername == 'toollist': fname = os.path.join(configDir, CP.get(jobname, layername)) J.ToolList = excellon.parseToolList(fname) elif layername == 'excellondecimals': try: J.ExcellonDecimals = int(fname) except: raise RuntimeError("Excellon decimals '{:s}' in config file is not a valid integer".format(fname)) elif layername == 'repeat': try: J.Repeat = int(fname) except: raise RuntimeError("Repeat count '{:s}' in config file is not a valid integer".format(fname)) for layername in CP.options(jobname): fname = os.path.join(configDir, CP.get(jobname, layername)) if layername == 'boardoutline': J.parseGerber(fname, layername, updateExtents=1) elif layername[0] == '*': J.parseGerber(fname, layername, updateExtents=0) elif layername == 'drills': J.parseExcellon(fname) # Emit warnings if some layers are missing LL = LayerList.copy() for layername in J.apxlat.keys(): assert layername in LL del LL[layername] if LL: if errstr == 'ERROR': do_abort = True print("{:s}: Job {:s} is missing the following layers:".format(errstr, jobname)) for layername in LL.keys(): print(" {:s}".format(layername)) # Store the job in the global Jobs dictionary, keyed by job name Jobs[jobname] = J if do_abort: raise RuntimeError("Exiting since jobs are missing layers. Set AllowMissingLayers=1\nto override.")