tmsim

A fast turing machine simulator with graphviz export functionality

git clone https://git.8pit.net/tmsim.git

  1/*
  2 * Copyright © 2016-2018 Sören Tempel
  3 *
  4 * This program is free software: you can redistribute it and/or
  5 * modify it under the terms of the GNU Affero General Public
  6 * License as published by the Free Software Foundation, either
  7 * version 3 of the License, or (at your option) any later version.
  8 *
  9 * This program is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12 * Affero General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU Affero General Public
 15 * License along with this program. If not, see
 16 * <http://www.gnu.org/licenses/>.
 17 */
 18
 19#include <stdio.h>
 20#include <stdlib.h>
 21#include <unistd.h>
 22
 23#include <sys/types.h>
 24
 25#include "turing.h"
 26#include "parser.h"
 27#include "util.h"
 28
 29/**
 30 * Writes the usage string for this program to stderr and terminates
 31 * the program with EXIT_FAILURE.
 32 */
 33static void
 34usage(char *prog)
 35{
 36	fprintf(stderr, "USAGE: %s %s\n", prog,
 37		"[-r] [-h|-v] FILE [INPUT]");
 38	exit(EXIT_FAILURE);
 39}
 40
 41/**
 42 * Writes an input error message to stderr and terminates the program
 43 * with EXIT_FAILURE.
 44 *
 45 * @param str The input string which contained an invalid symbol.
 46 * @param pos Position of the first invalid character. The first
 47 * 	character is located at position 0 not 1.
 48 */
 49static void
 50inputerr(char *str, size_t pos)
 51{
 52	char *marker, *msg;
 53	
 54	msg = "Input can only consist of alphanumeric "
 55		"characters.\n\t Besides it can't contain the "
 56		"special blank character.";
 57
 58	marker = mark(pos, str);
 59	fprintf(stderr, "Input error at position %zu: %s\n %s\n %s\n",
 60			++pos, msg, str, marker);
 61
 62	exit(EXIT_FAILURE);
 63}
 64
 65/**
 66 * The main function invoked when the program is started.
 67 *
 68 * @param argc Amount of command line parameters.
 69 * @param argv Command line parameters.
 70 */
 71int
 72main(int argc, char **argv)
 73{
 74	size_t pos;
 75	int opt, ext, rtape;
 76	parerr ret;
 77	dtm *tm;
 78	parser *par;
 79	char *in, *fc, *fp;
 80	ssize_t len;
 81
 82	rtape = 0;
 83	while ((opt = getopt(argc, argv, "rhv")) != -1) {
 84		switch (opt) {
 85		case 'r':
 86			rtape = 1;
 87			break;
 88		case 'v':
 89			fprintf(stderr, "tmsim-"VERSION"\n");
 90			return EXIT_FAILURE;
 91		case 'h':
 92		default:
 93			usage(argv[0]);
 94		}
 95	}
 96
 97	if (argc <= 1 || optind >= argc)
 98		usage(argv[0]);
 99
100	fp = argv[optind];
101	if ((len = readfile(&fc, fp)) == -1)
102		die("couldn't read from input file");
103	par = newparser(fc, (size_t)len);
104
105	tm = newtm();
106	if ((ret = parsetm(par, tm)) != PAR_OK) {
107		strparerr(par, ret, fp, stderr);
108		return EXIT_FAILURE;
109	}
110	freeparser(par);
111
112	if (argc <= 2 || ++optind >= argc)
113		return EXIT_SUCCESS;
114
115	in = argv[optind];
116	if (!verifyinput(in, &pos))
117		inputerr(in, pos);
118	writetape(tm, in);
119
120	ext = (runtm(tm)) ? EXIT_FAILURE : EXIT_SUCCESS;
121	if (rtape)
122		printtape(tm);
123
124	return ext;
125}