1/*2 * Copyright © 2016-2018 Sören Tempel3 *4 * This program is free software: you can redistribute it and/or5 * modify it under the terms of the GNU Affero General Public6 * License as published by the Free Software Foundation, either7 * 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 of11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12 * Affero General Public License for more details.13 *14 * You should have received a copy of the GNU Affero General Public15 * License along with this program. If not, see16 * <http://www.gnu.org/licenses/>.17 */1819#include <stdio.h>20#include <stdlib.h>21#include <unistd.h>2223#include <sys/types.h>2425#include "turing.h"26#include "parser.h"27#include "util.h"2829/**30 * Writes the usage string for this program to stderr and terminates31 * the program with EXIT_FAILURE.32 */33static void34usage(char *prog)35{36 fprintf(stderr, "USAGE: %s %s\n", prog,37 "[-r] [-h|-v] FILE [INPUT]");38 exit(EXIT_FAILURE);39}4041/**42 * Writes an input error message to stderr and terminates the program43 * 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 first47 * character is located at position 0 not 1.48 */49static void50inputerr(char *str, size_t pos)51{52 char *marker, *msg;5354 msg = "Input can only consist of alphanumeric "55 "characters.\n\t Besides it can't contain the "56 "special blank character.";5758 marker = mark(pos, str);59 fprintf(stderr, "Input error at position %zu: %s\n %s\n %s\n",60 ++pos, msg, str, marker);6162 exit(EXIT_FAILURE);63}6465/**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 */71int72main(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;8182 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 }9697 if (argc <= 1 || optind >= argc)98 usage(argv[0]);99100 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);104105 tm = newtm();106 if ((ret = parsetm(par, tm)) != PAR_OK) {107 strparerr(par, ret, fp, stderr);108 return EXIT_FAILURE;109 }110 freeparser(par);111112 if (argc <= 2 || ++optind >= argc)113 return EXIT_SUCCESS;114115 in = argv[optind];116 if (!verifyinput(in, &pos))117 inputerr(in, pos);118 writetape(tm, in);119120 ext = (runtm(tm)) ? EXIT_FAILURE : EXIT_SUCCESS;121 if (rtape)122 printtape(tm);123124 return ext;125}