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 12 extern const char *__progname; 13 14 // usage 15 static 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 30 const char *kAppName = __progname; 31 32 static void 33 print_usage(bool error) 34 { 35 fprintf(error ? stderr : stdout, kUsage, kAppName); 36 } 37 38 static void 39 print_usage_and_exit(bool error) 40 { 41 print_usage(error); 42 exit(error ? 0 : 1); 43 } 44 45 Arguments::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 58 Arguments::~Arguments() 59 { 60 _SetShellArguments(0, NULL); 61 } 62 63 64 void 65 Arguments::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 121 void 122 Arguments::GetShellArguments(int &argc, const char *const *&argv) const 123 { 124 argc = fShellArgumentCount; 125 argv = fShellArguments; 126 } 127 128 129 void 130 Arguments::_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