Skip to content

Commit

Permalink
add stdin support
Browse files Browse the repository at this point in the history
  • Loading branch information
TabulateJarl8 committed Jul 14, 2021
1 parent f5f921d commit 90c3f3f
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 8 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,17 @@ ti842py can be installed via PyPI or by cloning the repository. To install it wi

Feel free to use the programs found at [https://github.com/TabulateJarl8/tiprograms](https://github.com/TabulateJarl8/tiprograms) to test this project out.

## CLI Usage

ti842py can be used in 3 different ways. The first way is just running it from the command line. For example, if you wanted to convert the program in `tiprogram.txt` to `tiprogram.py`, you can this command: `ti842py tiprogram.txt -o tiprogram.py`. If no value is specified for `-o`, the converted program will be written to `stdout`. The `-n` flag can be added to force the transpiler to not decompile the input file, and the `-d` flag can be added to force the transpiler to attempt and decompile the input file. If the `--run` or `-r` argument is supplied, the resulting python file will be run after it is done transpiling

```
usage: ti842py [-h] [-o OUTFILE] [-n] [-d] [--no-fix-multiplication] [-r] [-V] infile
usage: ti842py [-h] [-o OUTFILE] [-n] [-d] [--no-fix-multiplication] [--no-fix-floating-point] [--turbo-draw] [-r] [-V] [infile]
TI-BASIC to Python 3 Transpiler
positional arguments:
infile Input file.
infile Input file (filename or stdin).
optional arguments:
-h, --help show this help message and exit
Expand All @@ -88,6 +90,19 @@ optional arguments:
-V, --version show program's version number and exit
```

### Advanced terminal usage

You can use ti842py by piping files to it's stdin. This can be done via pipes or redirects, and the files can be either 8Xp or plain text files, just like normal. Here's some examples:

```sh
$ cat BAR.8Xp | ti842py --run
$ ti842py -o bar.py < BAR.8Xp
$ cat CLOCK.bas | ti842py -nr
$ ti842py --no-fix-floating-point --run < CLOCK.bas
```

## Programmatic Usage

ti842py can also be imported and used in a program. Here is an example program to convert `tiprogram.txt` to `tiprogram.py`:

```py
Expand Down
2 changes: 1 addition & 1 deletion ti842py/__version__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
__title__ = "ti842py"
__description__ = "TI-BASIC to Python 3 Transpiler"
__url__ = "https://github.com/TabulateJarl8/ti842py"
__version__ = "0.7.9"
__version__ = "0.8.0"
__author__ = "Tabulate"
__author_email__ = "[email protected]"
__license__ = "GPLv3"
Expand Down
46 changes: 41 additions & 5 deletions ti842py/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import tempfile
import sys
import subprocess
import io
import pty

try:
from .tiParser import TIBasicParser
Expand All @@ -29,6 +31,16 @@ def isUTF8(file):

def transpile(infile, outfile="stdout", decompileFile=True, forceDecompile=False, multiplication=True, floating_point=True, turbo_draw=False, run=False):

# detect stdin
if not os.path.exists(infile.name):
# Don't auto close since we are shadowing infile
temp_stdin = tempfile.NamedTemporaryFile()
temp_stdin.write(infile.buffer.read())
temp_stdin.seek(0)
infile = temp_stdin.name
else:
infile = infile.name

decode = not isUTF8(infile) and decompileFile is True

if decode is True or forceDecompile is True:
Expand All @@ -47,6 +59,10 @@ def transpile(infile, outfile="stdout", decompileFile=True, forceDecompile=False

pythonCode = TIBasicParser(file_lines, multiplication, floating_point, turbo_draw).toPython()

# Close temp_stdin if used
if 'temp_stdin' in vars() or 'temp_stdin' in globals():
temp_stdin.close()

# Write to outfile
if outfile == "stdout":
if run is False:
Expand All @@ -56,7 +72,16 @@ def transpile(infile, outfile="stdout", decompileFile=True, forceDecompile=False
for line in pythonCode:
f.write(line.encode() + b"\n")
f.seek(0)
proc = subprocess.Popen([sys.executable, f.name])

# test if something was piped to stdin
if 'temp_stdin' in vars() or 'temp_stdin' in globals():
# Create new tty to handle ioctl errors in termios
master_fd, slave_fd = pty.openpty()
proc = subprocess.Popen([sys.executable, f.name], stdin=slave_fd)
else:
# Nothing was piped to stdin
proc = subprocess.Popen([sys.executable, f.name])

try:
proc.wait()
except (Exception, KeyboardInterrupt):
Expand All @@ -71,11 +96,13 @@ def transpile(infile, outfile="stdout", decompileFile=True, forceDecompile=False

def main():
parser = argparse.ArgumentParser(description='TI-BASIC to Python 3 Transpiler')
parser.add_argument(
infile_argument = parser.add_argument(
'infile',
metavar='infile',
nargs=1,
help="Input file."
nargs='?',
type=argparse.FileType('r'),
default=(None if sys.stdin.isatty() else sys.stdin),
help="Input file (filename or stdin)."
)
parser.add_argument(
'-o',
Expand Down Expand Up @@ -136,7 +163,16 @@ def main():
)

args = parser.parse_args()
transpile(args.infile[0], args.outfile, args.n, args.d, args.multiplication, args.floating_point, args.turbo_draw, args.run)

if hasattr(args.infile, '__getitem__'):
infile = args.infile[0]
else:
infile = args.infile

if infile is None:
raise argparse.ArgumentError(infile_argument, 'the infile argument is required')

transpile(infile, args.outfile, args.n, args.d, args.multiplication, args.floating_point, args.turbo_draw, args.run)


if __name__ == "__main__":
Expand Down

0 comments on commit 90c3f3f

Please sign in to comment.