xref: /haiku/src/tests/apps/miniterminal/Arguments.cpp (revision c90684742e7361651849be4116d0e5de3a817194)
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