1/* 2 * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. 3 * Distributed under the terms of the MIT License. 4 */ 5 6#include <stdio.h> 7#include <stdlib.h> 8#include <string.h> 9 10#include "Arguments.h" 11 12extern const char *__progname; 13 14// usage 15static const char *kUsage = 16 "%s <options> [ <program> ... ]\n" 17 "Starts a terminal with a shell running in it. If <program> is given\n" 18 "and is an absolute or relative path to an executable, it is run instead\n" 19 "of the shell. The command line arguments for the program just follow the\n" 20 "path of the program.\n" 21 "\n" 22 "Options:\n" 23 " -h, --help - print this info text\n" 24 " -l <x> <y> - open the terminal window at location (<x>, <y>)\n" 25 " -s <width> <height> - open the terminal window with width <width> and\n" 26 " height <height>)\n" 27 " -t <title> - set the terminal window title to <title>\n"; 28 29// application name 30const char *kAppName = __progname; 31 32static void 33print_usage(bool error) 34{ 35 fprintf(error ? stderr : stdout, kUsage, kAppName); 36} 37 38static void 39print_usage_and_exit(bool error) 40{ 41 print_usage(error); 42 exit(error ? 0 : 1); 43} 44 45Arguments::Arguments() 46 : fBounds(50, 50, 630, 435), 47 fStandardShell(true), 48 fShellArgumentCount(0), 49 fShellArguments(NULL), 50 fTitle("MiniTerminal") 51{ 52 const char *argv[] = { "/bin/sh", "--login" }; 53 54 _SetShellArguments(2, argv); 55} 56 57 58Arguments::~Arguments() 59{ 60 _SetShellArguments(0, NULL); 61} 62 63 64void 65Arguments::Parse(int argc, const char *const *argv) 66{ 67 int argi = 1; 68 while (argi < argc) { 69 const char *arg = argv[argi++]; 70 71 if (*arg == '-') { 72 if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) { 73 print_usage_and_exit(false); 74 75 } else if (strcmp(arg, "-l") == 0) { 76 // location 77 float x, y; 78 if (argi + 1 >= argc 79 || sscanf(argv[argi++], "%f", &x) != 1 80 || sscanf(argv[argi++], "%f", &y) != 1) { 81 print_usage_and_exit(true); 82 } 83 84 fBounds.OffsetTo(x, y); 85 86 } else if (strcmp(arg, "-s") == 0) { 87 // size 88 float width, height; 89 if (argi + 1 >= argc 90 || sscanf(argv[argi++], "%f", &width) != 1 91 || sscanf(argv[argi++], "%f", &height) != 1) { 92 print_usage_and_exit(true); 93 } 94 95 fBounds.right = fBounds.left + width; 96 fBounds.bottom = fBounds.top + height; 97 98 } else if (strcmp(arg, "-t") == 0) { 99 // title 100 if (argi >= argc) 101 print_usage_and_exit(true); 102 103 fTitle = argv[argi++]; 104 105 } else { 106 // illegal option 107 fprintf(stderr, "Unrecognized option \"%s\"\n", arg); 108 print_usage_and_exit(true); 109 } 110 111 } else { 112 // no option, so the remainder is the shell program with arguments 113 _SetShellArguments(argc - argi + 1, argv + argi - 1); 114 argi = argc; 115 fStandardShell = false; 116 } 117 } 118} 119 120 121void 122Arguments::GetShellArguments(int &argc, const char *const *&argv) const 123{ 124 argc = fShellArgumentCount; 125 argv = fShellArguments; 126} 127 128 129void 130Arguments::_SetShellArguments(int argc, const char *const *argv) 131{ 132 // delete old arguments 133 delete[] fShellArguments; 134 fShellArguments = NULL; 135 fShellArgumentCount = 0; 136 137 // copy new ones 138 if (argc > 0 && argv) { 139 fShellArguments = new const char*[argc + 1]; 140 for (int i = 0; i < argc; i++) 141 fShellArguments[i] = argv[i]; 142 143 fShellArguments[argc] = NULL; 144 fShellArgumentCount = argc; 145 } 146} 147 148