diff options
author | Mattias Andrée <maandree@kth.se> | 2021-02-28 00:56:09 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2021-02-28 00:56:09 +0100 |
commit | 32da76d4577b6508aaa2539625b6689f946bc95a (patch) | |
tree | 361390566ee1f1adc64424f1772238f4dba01ad1 /gpp.py | |
parent | remove todo (diff) | |
download | gpp-32da76d4577b6508aaa2539625b6689f946bc95a.tar.gz gpp-32da76d4577b6508aaa2539625b6689f946bc95a.tar.bz2 gpp-32da76d4577b6508aaa2539625b6689f946bc95a.tar.xz |
Finish rewrite to C
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'gpp.py')
-rwxr-xr-x | gpp.py | 230 |
1 files changed, 0 insertions, 230 deletions
@@ -1,230 +0,0 @@ -#!@{SHEBANG} -# -*- coding: utf-8 -*- - -import os -import sys -import shlex -from subprocess import Popen, PIPE - -if sys.version_info.major < 3: - def bytes(string): - r = bytearray(len(string)) - b = buffer(r) - r[:] = string - return r - -if sys.version_info.major < 3: - def bytelist(string): - return [ord(c) for c in string] -else: - bytelist = list - -symbol = '@' -encoding = sys.getdefaultencoding() -iterations = 1 -input_file = '/dev/stdin' -output_file = '/dev/stdout' -unshebang = 0 - -args = sys.argv - -# If the file is executed, the first command line argument will be the first argument in the shebang, -# the second will be the rest of the arguments in the command line as is and the third and final will -# be the executed file. -if len(args) == 3: - if os.path.exists(args[2]) and os.path.isfile(args[2]) and ((os.stat(args[2]).st_mode & 0o111) != 0): - args[1 : 2] = shlex.split(args[1]) - -for i in range(1, len(args)): - arg = args[i] - i += 1 - if arg in ('-s', '--symbol'): symbol = sys.argv[i] - elif arg in ('-e', '--encoding'): encoding = sys.argv[i] - elif arg in ('-n', '--iterations'): iterations = int(sys.argv[i]) - elif arg in ('-u', '--unshebang'): unshebang += 1; continue - elif arg in ('-i', '--input'): input_file = sys.argv[i] - elif arg in ('-o', '--output'): output_file = sys.argv[i] - elif arg in ('-f', '--file'): - input_file = sys.argv[i] - output_file = sys.argv[i] - elif arg in ('-D', '--export'): - export = sys.argv[i] - if '=' not in export: - export += '=1' - export = (export.split('=')[0], '='.join(export.split('=')[1:])) - os.putenv(export[0], export[1]) - else: - continue - i += 1 - -if input_file == '-': input_file = '/dev/stdin' -if output_file == '-': output_file = '/dev/stdout' - -symbol = bytelist(symbol.encode(encoding)) -symlen = len(symbol) - -if iterations < 1: - if input_file != output_file: - data = None - with open(input_file, 'rb') as file: - data = file.read() - with open(output_file, 'wb') as file: - file.write(data) - file.flush() - sys.exit(0) - -def linesplit(bs): - rc = [] - elem = [] - for b in bs: - if b == 10: - rc.append(elem) - elem = [] - else: - elem.append(b) - rc.append(elem) - return rc - -def linejoin(bss): - rc = [] - if len(bss) > 0: - rc += bss[0] - for bs in bss[1:]: - rc.append(10) - rc += bs - return rc - -data = None -with open(input_file, 'rb') as file: - data = file.read() -data = linesplit(bytelist(data)) - -if unshebang == 1: - if (len(data[0]) >= 2) and (data[0][0] == ord('#')) and (data[0][1] == ord('!')): - data[0] = [] - -if unshebang >= 2: - if (len(data[0]) >= 2) and (data[0][0] == ord('#')) and (data[0][1] == ord('!')): - data[0] = data[1] - data[1] = [] - -def pp(line): - rc = [] - symb = False - brackets = 0 - esc = False - dollar = False - quote = [] - n = len(line) - i = 0 - rc.append(ord('\'')) - while i < n: - c = line[i] - i += 1 - if brackets > 0: - if esc: - esc = False - elif len(quote) > 0: - if dollar: - dollar = False - if c == ord('('): - quote.append(ord(')')) - elif c == ord('{'): - quote.append(ord('}')) - elif c == quote[-1]: - quote[:] = quote[:-1] - elif (quote[-1] in (ord(')'), ord('}'))) and (c in (ord('"'), ord('\''), ord('`'))): - quote.append(c) - elif (c == ord('\\')) and (quote[-1] != ord('\'')): - esc = True - elif c == ord('$'): - dollar = True - elif c in (ord('"'), ord('\''), ord('`')): - quote.append(c) - elif c in (ord(')'), ord('}')): - brackets -= 1 - if brackets == 0: - rc.append(c) - rc.append(ord('"')) - rc.append(ord('\'')) - continue - elif c in (ord('('), ord('{')): - brackets += 1 - elif c == ord('\\'): - esc = True - rc.append(c) - elif line[i - 1 : i + symlen - 1] == symbol: - if symb: - rc += symbol - symb = not symb - i += symlen - 1 - elif symb: - symb = False - if c in (ord('('), ord('{')): - brackets += 1 - rc.append(ord('\'')) - rc.append(ord('"')) - rc.append(ord('$')) - else: - rc += symbol - if c == ord('\''): - rc.append(c) - rc.append(ord('\\')) - rc.append(c) - rc.append(c) - elif c == ord('\''): - rc.append(c) - rc.append(ord('\\')) - rc.append(c) - rc.append(c) - else: - rc.append(c) - rc.append(ord('\'')) - return rc - -for _ in range(iterations): - entered = False - bashed = [] - - for lineno in range(len(data)): - line = data[lineno] - if (len(line) > symlen) and (line[:symlen] == symbol) and (line[symlen] in (ord('<'), ord('>'))): - bashed.append(line[symlen + 1:]) - entered = line[symlen] == ord('<') - elif entered: - bashed.append(line) - else: - buf = bytelist(('echo $\'\\e%i\\e\'' % lineno).encode()) - bashed.append(buf + pp(line)) - - bashed = bytes(linejoin(bashed)) - bash = Popen(["bash"], stdin = PIPE, stdout = PIPE, stderr = sys.stderr) - bashed = bash.communicate(bashed)[0] - - if bash.returncode != 0: - sys.exit(bash.returncode) - - bashed = linesplit(bytelist(bashed)) - data = [] - lineno = -1 - - for line in bashed: - no = -1 - if (len(line) > 0) and (line[0] == 0o33): - no = 0 - for i in range(1, len(line)): - if line[i] == 0o33: - line = line[i + 1:] - break - no = no * 10 + (line[i] - ord('0')) - if no > lineno: - while no != lineno + 1: - data.append([]) - lineno += 1 - data.append(line) - lineno += 1 - -data = bytes(linejoin(data)) -with open(output_file, 'wb') as file: - file.write(data) - file.flush() |