예제 #1
0
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.'
예제 #2
0
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.'
예제 #3
0
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.")