Maple Native Beta solderpad

maple-native-beta / support / fix_nums.py

3.0 KB · raw

#!/usr/bin/env python

# Fix pin numbering in schematic (.sch) files.  Requires python 2.6 or
# higher.  For usage:
#
# ./fix_nums.py --help

from __future__ import print_function

import optparse
import re

def main(start_num, end_num, action, schematics):
    print('start: {0}. end: {1}. action: {2}. schematics: {3}'.format(
        start_num, end_num, action, ', '.join(schematics)))
    for sch in schematics:
        fixed = act_on_sch(start_num, end_num, action, sch)
        with open(sch, 'w') as sch_out: sch_out.write(''.join(fixed))

def act_on_sch(start_num, end_num, action, sch):
    fixed_lines = []
    with open(sch, 'r') as sch_in:
        maybe_act_on_next = False
        for line in sch_in:
            if maybe_act_on_next and act_on_line_p(line, start_num, end_num):
                fixed_lines.append(act_on_line(line, action))
            else:
                fixed_lines.append(line)

            if consider_next_line_p(line): maybe_act_on_next = True
            else: maybe_act_on_next = False
    return fixed_lines

def consider_next_line_p(line):
    return line.startswith('Text GLabel')

def act_on_line_p(line, start_num, end_num):
    num = None
    if re.match('\d+$', line): num = int(line)
    elif re.match('\d+/', line): num = int(line.split('/')[0])

    return num is not None and (start_num <= num and
                                (end_num is None or num <= end_num))

def act_on_line(line, action):
    line = line.strip()
    if '/' in line: num, rest = line.split('/')
    else: num, rest = line, ''

    num = int(num)
    acted_upon = str({'INC': num + 1, 'DEC': num - 1}[action])

    return '/'.join(filter(None, [acted_upon, rest])) + '\n'

if __name__ == '__main__':
    parser = optparse.OptionParser(usage=('usage: %prog [options] '
                                          'sch1 [sch2...]'))
    parser.add_option('-s', '--start-number', default=0,
                      help='Number to start acting on (default 0)')
    parser.add_option('-e', '--end-number', default=None,
                      help='Number to stop acting on (default infinity)')
    parser.add_option('-a', '--action', default='i',
                      help=('Action to take on numbers (i=increment, '
                            'd=decrement, default=increment)'))
    opts, schematic_files = parser.parse_args()

    def usage(msg, fatal=True):
        if fatal: print ('Error: ', end='')
        print(msg)
        parser.print_help()
        if fatal: sys.exit(1)

    if len(schematic_files) == 0: usage('No schematic files given')
    if opts.action not in ['i', 'd']: usage('Action must be "i" or "d"')

    try: start_num = int(opts.start_number)
    except: usage('Start number must be an integer')

    if opts.end_number is None:
        end_num = None
    else:
        try: end_num = int(opts.end_number)
        except: usage('If specified, end number must be an integer')

    action = {'i': 'INC', 'd': 'DEC'}[opts.action]

    main(start_num, end_num, action, schematic_files)