Stolen Ingo's Arguments class from Miniterminal and used it in place of
GPL'd code in TermApp (slightly modified, and bugfixed, even :P). TermView now accepts an argument vector instead of a commandline. Same thing for Shell. Temporarily(?) removed some commandline options. This also fixes bug #1396 (tested) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21979 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c9c4a80aaa
commit
bb4632f1ec
123
src/apps/terminal/Arguments.cpp
Normal file
123
src/apps/terminal/Arguments.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Arguments.h"
|
||||
|
||||
|
||||
Arguments::Arguments()
|
||||
: fUsageRequested(false),
|
||||
fBounds(50, 50, 630, 435),
|
||||
fStandardShell(true),
|
||||
fFullScreen(false),
|
||||
fShellArgumentCount(0),
|
||||
fShellArguments(NULL),
|
||||
fTitle(NULL)
|
||||
{
|
||||
const char *argv[] = { "/bin/sh", "--login" };
|
||||
|
||||
_SetShellArguments(2, argv);
|
||||
}
|
||||
|
||||
|
||||
Arguments::~Arguments()
|
||||
{
|
||||
_SetShellArguments(0, NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Arguments::Parse(int argc, const char *const *argv)
|
||||
{
|
||||
int argi = 1;
|
||||
while (argi < argc) {
|
||||
const char *arg = argv[argi++];
|
||||
|
||||
if (*arg == '-') {
|
||||
if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
|
||||
fUsageRequested = true;
|
||||
|
||||
/*} else if (strcmp(arg, "-l") == 0) {
|
||||
// location
|
||||
float x, y;
|
||||
if (argi + 1 >= argc
|
||||
|| sscanf(argv[argi++], "%f", &x) != 1
|
||||
|| sscanf(argv[argi++], "%f", &y) != 1) {
|
||||
print_usage_and_exit(true);
|
||||
}
|
||||
|
||||
fBounds.OffsetTo(x, y);
|
||||
|
||||
} else if (strcmp(arg, "-s") == 0) {
|
||||
// size
|
||||
float width, height;
|
||||
if (argi + 1 >= argc
|
||||
|| sscanf(argv[argi++], "%f", &width) != 1
|
||||
|| sscanf(argv[argi++], "%f", &height) != 1) {
|
||||
print_usage_and_exit(true);
|
||||
}
|
||||
|
||||
fBounds.right = fBounds.left + width;
|
||||
fBounds.bottom = fBounds.top + height;
|
||||
*/
|
||||
} else if (strcmp(arg, "-t") == 0 || strcmp(arg, "--title") == 0) {
|
||||
// title
|
||||
if (argi >= argc)
|
||||
fUsageRequested = true;
|
||||
else
|
||||
fTitle = argv[argi++];
|
||||
|
||||
} else if (strcmp(arg, "-f") == 0 || strcmp(arg, "--fullscreen") == 0) {
|
||||
fFullScreen = true;
|
||||
argi++;
|
||||
} else {
|
||||
// illegal option
|
||||
fprintf(stderr, "Unrecognized option \"%s\"\n", arg);
|
||||
fUsageRequested = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
// no option, so the remainder is the shell program with arguments
|
||||
_SetShellArguments(argc - argi + 1, argv + argi - 1);
|
||||
argi = argc;
|
||||
fStandardShell = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Arguments::GetShellArguments(int &argc, const char *const *&argv) const
|
||||
{
|
||||
argc = fShellArgumentCount;
|
||||
argv = fShellArguments;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Arguments::_SetShellArguments(int argc, const char *const *argv)
|
||||
{
|
||||
// delete old arguments
|
||||
for (int32 i = 0; i < fShellArgumentCount; i++)
|
||||
free((void *)fShellArguments[i]);
|
||||
delete[] fShellArguments;
|
||||
|
||||
fShellArguments = NULL;
|
||||
fShellArgumentCount = 0;
|
||||
|
||||
// copy new ones
|
||||
if (argc > 0 && argv) {
|
||||
fShellArguments = new const char*[argc + 1];
|
||||
for (int i = 0; i < argc; i++)
|
||||
fShellArguments[i] = strdup(argv[i]);
|
||||
|
||||
fShellArguments[argc] = NULL;
|
||||
fShellArgumentCount = argc;
|
||||
}
|
||||
}
|
||||
|
38
src/apps/terminal/Arguments.h
Normal file
38
src/apps/terminal/Arguments.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef ARGUMENTS_H
|
||||
#define ARGUMENTS_H
|
||||
|
||||
#include <Rect.h>
|
||||
|
||||
class Arguments {
|
||||
public:
|
||||
Arguments();
|
||||
~Arguments();
|
||||
|
||||
void Parse(int argc, const char *const *argv);
|
||||
|
||||
BRect Bounds() const { return fBounds; }
|
||||
const char *Title() const { return fTitle; }
|
||||
bool StandardShell() const { return fStandardShell; }
|
||||
bool FullScreen() const { return fFullScreen; }
|
||||
bool UsageRequested() const { return fUsageRequested; }
|
||||
void GetShellArguments(int &argc, const char *const *&argv) const;
|
||||
|
||||
private:
|
||||
void _SetShellArguments(int argc, const char *const *argv);
|
||||
|
||||
bool fUsageRequested;
|
||||
BRect fBounds;
|
||||
bool fStandardShell;
|
||||
bool fFullScreen;
|
||||
int fShellArgumentCount;
|
||||
const char **fShellArguments;
|
||||
const char *fTitle;
|
||||
};
|
||||
|
||||
|
||||
#endif // ARGUMENTS_H
|
@ -6,6 +6,7 @@ UseHeaders [ FDirName $(HAIKU_TOP) src kits tracker ] ;
|
||||
|
||||
Application Terminal :
|
||||
AppearPrefView.cpp
|
||||
Arguments.cpp
|
||||
CodeConv.cpp
|
||||
Coding.cpp
|
||||
CurPos.cpp
|
||||
|
@ -80,7 +80,7 @@
|
||||
#define RDEL 0xFF
|
||||
|
||||
/* default shell command and options. */
|
||||
#define SHELL_COMMAND "/bin/sh -login"
|
||||
const char *kDefaultShellCommand = { "/bin/sh" "-login" };
|
||||
|
||||
|
||||
/*
|
||||
@ -149,12 +149,12 @@ Shell::~Shell()
|
||||
|
||||
|
||||
status_t
|
||||
Shell::Open(int row, int col, const char *command, const char *encoding)
|
||||
Shell::Open(int row, int col, const char *encoding, int argc, const char **argv)
|
||||
{
|
||||
if (fFd >= 0)
|
||||
return B_ERROR;
|
||||
|
||||
status_t status = _Spawn(row, col, command, encoding);
|
||||
status_t status = _Spawn(row, col, encoding, argc, argv);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
@ -295,7 +295,7 @@ receive_handshake_message(handshake_t& handshake)
|
||||
|
||||
|
||||
status_t
|
||||
Shell::_Spawn(int row, int col, const char *command, const char *encoding)
|
||||
Shell::_Spawn(int row, int col, const char *encoding, int argc, const char **argv)
|
||||
{
|
||||
signal(SIGTTOU, SIG_IGN);
|
||||
|
||||
@ -504,54 +504,10 @@ Shell::_Spawn(int row, int col, const char *command, const char *encoding)
|
||||
setenv("TERM", "beterm", true);
|
||||
setenv("TTY", ttyName, true);
|
||||
setenv("TTYPE", encoding, true);
|
||||
setenv("SHELL", *argv, true);
|
||||
|
||||
/*
|
||||
* If don't set command args, exec SHELL_COMMAND.
|
||||
*/
|
||||
if (command == NULL)
|
||||
command = SHELL_COMMAND;
|
||||
|
||||
/*
|
||||
* split up the arguments in the command into an artv-like structure.
|
||||
*/
|
||||
char commandLine[256];
|
||||
memcpy(commandLine, command, 256);
|
||||
char *ptr = commandLine;
|
||||
char *args[16];
|
||||
int i = 0;
|
||||
while (*ptr) {
|
||||
/* Skip white space */
|
||||
while ((*ptr == ' ') || (*ptr == '\t'))
|
||||
*ptr++ = 0;
|
||||
args[i++] = ptr;
|
||||
|
||||
/* Skip over this word to next white space. */
|
||||
while ((*ptr != 0) && (*ptr != ' ') && (*ptr != '\t'))
|
||||
ptr++;
|
||||
}
|
||||
|
||||
args[i] = NULL;
|
||||
|
||||
setenv("SHELL", *args, true);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Print Welcome Message.
|
||||
* (But, Only print message when MuTerminal coding is UTF8.)
|
||||
*/
|
||||
|
||||
time_t now_time_t = time(NULL);
|
||||
struct tm *now_time = localtime (&now_time_t);
|
||||
int now_hour = 0;
|
||||
if (now_time->tm_hour >= 5 && now_time->tm_hour < 11) {
|
||||
now_hour = 0;
|
||||
} else if (now_time->tm_hour >= 11 && now_time->tm_hour <= 18 ) {
|
||||
now_hour = 1;
|
||||
} else {
|
||||
now_hour = 2;
|
||||
}
|
||||
#endif
|
||||
execve(*args, args, environ);
|
||||
execve(*argv, (char * const *)argv, environ);
|
||||
|
||||
/*
|
||||
* Exec failed.
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
Shell();
|
||||
virtual ~Shell();
|
||||
|
||||
status_t Open(int row, int col, const char *command, const char *coding);
|
||||
status_t Open(int row, int col, const char *encoding, int argc, const char **argv);
|
||||
void Close();
|
||||
|
||||
const char * TTYName() const;
|
||||
@ -48,7 +48,7 @@ private:
|
||||
TermParse *fTermParse;
|
||||
bool fAttached;
|
||||
|
||||
status_t _Spawn(int row, int col, const char *command, const char *coding);
|
||||
status_t _Spawn(int row, int col, const char *encoding, int argc, const char **argv);
|
||||
};
|
||||
|
||||
#endif // _SHELL_H
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "TermApp.h"
|
||||
|
||||
#include "Arguments.h"
|
||||
#include "CodeConv.h"
|
||||
#include "PrefHandler.h"
|
||||
#include "TermWindow.h"
|
||||
@ -31,25 +32,6 @@
|
||||
static bool sUsageRequested = false;
|
||||
static bool sGeometryRequested = false;
|
||||
|
||||
struct standard_args {
|
||||
char *name;
|
||||
char *longname;
|
||||
int priority;
|
||||
int nargs;
|
||||
const char *prefname;
|
||||
};
|
||||
|
||||
struct standard_args standard_args[] = {
|
||||
{ "-h", "--help", 90, 0, NULL },
|
||||
{ "-f", "--fullscreen", 30, 0, NULL },
|
||||
{ "-p", "--preference", 80, 1, NULL },
|
||||
{ "-t", "--title", 70, 1, NULL },
|
||||
{ "-geom", "--geometry", 50, 1, NULL },
|
||||
};
|
||||
|
||||
int argmatch(char **, int, char *, char *, int, char **, int *);
|
||||
void sort_args(int, char **);
|
||||
|
||||
|
||||
const ulong MSG_ACTIVATE_TERM = 'msat';
|
||||
const ulong MSG_TERM_IS_MINIMIZE = 'mtim';
|
||||
@ -59,8 +41,11 @@ TermApp::TermApp()
|
||||
: BApplication(TERM_SIGNATURE),
|
||||
fStartFullscreen(false),
|
||||
fWindowNumber(-1),
|
||||
fTermWindow(NULL)
|
||||
fTermWindow(NULL),
|
||||
fArgs(NULL)
|
||||
{
|
||||
fArgs = new Arguments();
|
||||
|
||||
fWindowTitle = "Terminal";
|
||||
_RegisterTerminal();
|
||||
|
||||
@ -78,6 +63,7 @@ TermApp::TermApp()
|
||||
|
||||
TermApp::~TermApp()
|
||||
{
|
||||
delete fArgs;
|
||||
}
|
||||
|
||||
|
||||
@ -167,73 +153,19 @@ TermApp::MessageReceived(BMessage* msg)
|
||||
void
|
||||
TermApp::ArgvReceived(int32 argc, char **argv)
|
||||
{
|
||||
int skip_args = 0;
|
||||
char *value = 0;
|
||||
|
||||
if (argc < 2)
|
||||
return;
|
||||
|
||||
sort_args(argc, argv);
|
||||
argc = 0;
|
||||
while (argv[argc])
|
||||
argc++;
|
||||
|
||||
// Print usage
|
||||
if (argmatch(argv, argc, "-help", "--help", 3, NULL, &skip_args)) {
|
||||
fArgs->Parse(argc, argv);
|
||||
|
||||
if (fArgs->UsageRequested()) {
|
||||
_Usage(argv[0]);
|
||||
sUsageRequested = true;
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fArgs->Title() != NULL)
|
||||
fWindowTitle = fArgs->Title();
|
||||
|
||||
// Start fullscreen
|
||||
if (argmatch(argv, argc, "-f", "--fullscreen", 4, NULL, &skip_args))
|
||||
fStartFullscreen = true;
|
||||
|
||||
// Load preference file
|
||||
if (argmatch(argv, argc, "-p", "--preference", 4, &value, &skip_args))
|
||||
PrefHandler::Default()->Open(value);
|
||||
|
||||
// Set window title
|
||||
if (argmatch(argv ,argc, "-t", "--title", 3, &value, &skip_args))
|
||||
fWindowTitle = value;
|
||||
|
||||
// Set window geometry
|
||||
if (argmatch(argv, argc, "-geom", "--geometry", 4, &value, &skip_args)) {
|
||||
int width, height, xpos, ypos;
|
||||
|
||||
sscanf(value, "%dx%d+%d+%d", &width, &height, &xpos, &ypos);
|
||||
if (width < 0 || height < 0 || xpos < 0 || ypos < 0
|
||||
|| width >= 256 || height >= 256 || xpos >= 2048 || ypos >= 2048) {
|
||||
fprintf(stderr, "%s: invalid geometry format or value.\n", argv[0]);
|
||||
fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
|
||||
sUsageRequested = true;
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
PrefHandler::Default()->setInt32(PREF_COLS, width);
|
||||
PrefHandler::Default()->setInt32(PREF_ROWS, height);
|
||||
|
||||
fTermFrame.Set(xpos, ypos, xpos + 50, ypos + 50);
|
||||
sGeometryRequested = true;
|
||||
}
|
||||
|
||||
skip_args++;
|
||||
|
||||
if (skip_args < argc) {
|
||||
// Check invalid options
|
||||
|
||||
if (*argv[skip_args] == '-') {
|
||||
fprintf(stderr, "%s: invalid option `%s'\n", argv[0], argv[skip_args]);
|
||||
fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
|
||||
sUsageRequested = true;
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
|
||||
fCommandLine += argv[skip_args++];
|
||||
while (skip_args < argc) {
|
||||
fCommandLine += ' ';
|
||||
fCommandLine += argv[skip_args++];
|
||||
}
|
||||
}
|
||||
fStartFullscreen = fArgs->FullScreen();
|
||||
}
|
||||
|
||||
|
||||
@ -277,14 +209,8 @@ TermApp::RefsReceived(BMessage* message)
|
||||
status_t
|
||||
TermApp::_MakeTermWindow(BRect &frame)
|
||||
{
|
||||
const char *command = NULL;
|
||||
if (fCommandLine.Length() > 0)
|
||||
command = fCommandLine.String();
|
||||
else
|
||||
command = PrefHandler::Default()->getString(PREF_SHELL);
|
||||
|
||||
try {
|
||||
fTermWindow = new TermWindow(frame, fWindowTitle.String(), command);
|
||||
fTermWindow = new TermWindow(frame, fWindowTitle.String(), new Arguments(*fArgs));
|
||||
} catch (int error) {
|
||||
return (status_t)error;
|
||||
} catch (...) {
|
||||
@ -556,217 +482,13 @@ TermApp::_Usage(char *name)
|
||||
"\n"
|
||||
"Usage: %s [OPTION] [SHELL]\n", name);
|
||||
|
||||
fprintf(stderr, " -p, --preference load preference file\n"
|
||||
fprintf(stderr,
|
||||
" -h, --help print this help\n"
|
||||
//" -p, --preference load preference file\n"
|
||||
" -t, --title set window title\n"
|
||||
" -geom, --geometry set window geometry\n"
|
||||
" An example of geometry is \"80x25+100+100\"\n");
|
||||
" -f, --fullscreen start fullscreen\n"
|
||||
//" -geom, --geometry set window geometry\n"
|
||||
//" An example of geometry is \"80x25+100+100\"\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// This routine copy from GNU Emacs.
|
||||
// TODO: This might be a GPL licensing issue here. Investigate.
|
||||
int
|
||||
argmatch(char **argv, int argc, char *sstr, char *lstr,
|
||||
int minlen, char **valptr, int *skipptr)
|
||||
{
|
||||
char *p = 0;
|
||||
int arglen;
|
||||
char *arg;
|
||||
|
||||
// Don't access argv[argc]; give up in advance
|
||||
if (argc <= *skipptr + 1)
|
||||
return 0;
|
||||
|
||||
arg = argv[*skipptr+1];
|
||||
if (arg == NULL)
|
||||
return 0;
|
||||
|
||||
if (strcmp(arg, sstr) == 0) {
|
||||
if(valptr != NULL) {
|
||||
*valptr = argv[*skipptr+2];
|
||||
*skipptr += 2;
|
||||
} else
|
||||
*skipptr += 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
arglen =(valptr != NULL &&(p = strchr(arg, '=')) != NULL
|
||||
? p - arg : strlen(arg));
|
||||
|
||||
if(lstr == 0 || arglen < minlen || strncmp(arg, lstr, arglen) != 0)
|
||||
return 0;
|
||||
else
|
||||
if(valptr == NULL)
|
||||
{
|
||||
*skipptr += 1;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
if(p != NULL)
|
||||
{
|
||||
*valptr = p+1;
|
||||
*skipptr += 1;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
if(argv[*skipptr+2] != NULL)
|
||||
{
|
||||
*valptr = argv[*skipptr+2];
|
||||
*skipptr += 2;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// This routine copy from GNU Emacs.
|
||||
// TODO: This might be a GPL licensing issue here. Investigate.
|
||||
void
|
||||
sort_args(int argc, char **argv)
|
||||
{
|
||||
/*
|
||||
For each element of argv,
|
||||
the corresponding element of options is:
|
||||
0 for an option that takes no arguments,
|
||||
1 for an option that takes one argument, etc.
|
||||
-1 for an ordinary non-option argument.
|
||||
*/
|
||||
|
||||
char **newargv =(char **) malloc(sizeof(char *) * argc);
|
||||
|
||||
int *options =(int *) malloc(sizeof(int) * argc);
|
||||
int *priority =(int *) malloc(sizeof(int) * argc);
|
||||
int to = 1;
|
||||
int incoming_used = 1;
|
||||
int from;
|
||||
int i;
|
||||
//int end_of_options = argc;
|
||||
|
||||
// Categorize all the options,
|
||||
// and figure out which argv elts are option arguments
|
||||
for(from = 1; from < argc; from++)
|
||||
{
|
||||
options[from] = -1;
|
||||
priority[from] = 0;
|
||||
if(argv[from][0] == '-')
|
||||
{
|
||||
int match, thislen;
|
||||
char *equals;
|
||||
|
||||
// If we have found "--", don't consider any more arguments as options
|
||||
if(argv[from][1] == '-' && argv[from][2] == 0)
|
||||
{
|
||||
// Leave the "--", and everything following it, at the end.
|
||||
for(; from < argc; from++)
|
||||
{
|
||||
priority[from] = -100;
|
||||
options[from] = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Look for a match with a known old-fashioned option.
|
||||
for(i = 0; i <(int)(sizeof(standard_args) / sizeof(standard_args[0])); i++)
|
||||
if(!strcmp(argv[from], standard_args[i].name))
|
||||
{
|
||||
options[from] = standard_args[i].nargs;
|
||||
priority[from] = standard_args[i].priority;
|
||||
if(from + standard_args[i].nargs >= argc)
|
||||
fprintf(stderr, "Option `%s' requires an argument\n", argv[from]);
|
||||
from += standard_args[i].nargs;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
Look for a match with a known long option.
|
||||
MATCH is -1 if no match so far, -2 if two or more matches so far,
|
||||
>= 0(the table index of the match) if just one match so far.
|
||||
*/
|
||||
if(argv[from][1] == '-')
|
||||
{
|
||||
match = -1;
|
||||
thislen = strlen(argv[from]);
|
||||
equals = strchr(argv[from], '=');
|
||||
if(equals != 0)
|
||||
thislen = equals - argv[from];
|
||||
|
||||
for(i = 0;i <(int )(sizeof(standard_args) / sizeof(standard_args[0])); i++)
|
||||
if(standard_args[i].longname
|
||||
&& !strncmp(argv[from], standard_args[i].longname, thislen))
|
||||
{
|
||||
if(match == -1)
|
||||
match = i;
|
||||
else
|
||||
match = -2;
|
||||
}
|
||||
|
||||
// If we found exactly one match, use that
|
||||
if(match >= 0)
|
||||
{
|
||||
options[from] = standard_args[match].nargs;
|
||||
priority[from] = standard_args[match].priority;
|
||||
|
||||
// If --OPTION=VALUE syntax is used,
|
||||
// this option uses just one argv element
|
||||
if(equals != 0)
|
||||
options[from] = 0;
|
||||
if(from + options[from] >= argc)
|
||||
fprintf(stderr, "Option `%s' requires an argument\n", argv[from]);
|
||||
from += options[from];
|
||||
}
|
||||
}
|
||||
done: ;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the arguments, in order of decreasing priority, to NEW
|
||||
newargv[0] = argv[0];
|
||||
while (incoming_used < argc) {
|
||||
int best = -1;
|
||||
int best_priority = -9999;
|
||||
|
||||
// Find the highest priority remaining option.
|
||||
// If several have equal priority, take the first of them.
|
||||
for (from = 1; from < argc; from++) {
|
||||
if (argv[from] != 0 && priority[from] > best_priority) {
|
||||
best_priority = priority[from];
|
||||
best = from;
|
||||
}
|
||||
|
||||
// Skip option arguments--they are tied to the options.
|
||||
if (options[from] > 0)
|
||||
from += options[from];
|
||||
}
|
||||
|
||||
if (best < 0)
|
||||
abort();
|
||||
|
||||
// Copy the highest priority remaining option, with its args, to NEW.
|
||||
// Unless it is a duplicate of the previous one
|
||||
if (!(options[best] == 0 && ! strcmp(newargv[to - 1], argv[best]))) {
|
||||
newargv[to++] = argv[best];
|
||||
for(i = 0; i < options[best]; i++)
|
||||
newargv[to++] = argv[best + i + 1];
|
||||
}
|
||||
|
||||
incoming_used += 1 +(options[best] > 0 ? options[best] : 0);
|
||||
|
||||
// Clear out this option in ARGV
|
||||
argv[best] = 0;
|
||||
for (i = 0; i < options[best]; i++)
|
||||
argv[best + i + 1] = 0;
|
||||
}
|
||||
|
||||
// If duplicate options were deleted, fill up extra space with null ptrs
|
||||
while (to < argc)
|
||||
newargv[to++] = 0;
|
||||
|
||||
memcpy(argv, newargv, sizeof(char *) * argc);
|
||||
|
||||
free(options);
|
||||
free(newargv);
|
||||
free(priority);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <Application.h>
|
||||
#include <String.h>
|
||||
|
||||
class Arguments;
|
||||
class BRect;
|
||||
class BWindow;
|
||||
class TermApp : public BApplication {
|
||||
@ -70,7 +71,7 @@ class TermApp : public BApplication {
|
||||
|
||||
BWindow* fTermWindow;
|
||||
BRect fTermFrame;
|
||||
BString fCommandLine;
|
||||
Arguments *fArgs;
|
||||
};
|
||||
|
||||
#endif // TERM_APP_H
|
||||
|
@ -131,7 +131,7 @@ const static rgb_color kWhiteColor = { 255, 255, 255, 255 };
|
||||
|
||||
|
||||
|
||||
TermView::TermView(BRect frame, const char *command, int32 historySize)
|
||||
TermView::TermView(BRect frame, int32 argc, const char **argv, int32 historySize)
|
||||
: BView(frame, "termview", B_FOLLOW_ALL,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE| B_PULSE_NEEDED),
|
||||
fShell(NULL),
|
||||
@ -176,11 +176,11 @@ TermView::TermView(BRect frame, const char *command, int32 historySize)
|
||||
fQuitting(false),
|
||||
fIMflag(false)
|
||||
{
|
||||
_InitObject(command);
|
||||
_InitObject(argc, argv);
|
||||
}
|
||||
|
||||
|
||||
TermView::TermView(int rows, int columns, const char *command, int32 historySize)
|
||||
TermView::TermView(int rows, int columns, int32 argc, const char **argv, int32 historySize)
|
||||
: BView(BRect(0, 0, 0, 0), "termview", B_FOLLOW_ALL,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE| B_PULSE_NEEDED),
|
||||
fShell(NULL),
|
||||
@ -225,7 +225,7 @@ TermView::TermView(int rows, int columns, const char *command, int32 historySize
|
||||
fQuitting(false),
|
||||
fIMflag(false)
|
||||
{
|
||||
_InitObject(command);
|
||||
_InitObject(argc, argv);
|
||||
SetTermSize(fTermRows, fTermColumns, true);
|
||||
}
|
||||
|
||||
@ -282,16 +282,15 @@ TermView::TermView(BMessage *archive)
|
||||
if (archive->FindInt32("rows", (int32 *)&fTermRows) < B_OK)
|
||||
fTermRows = 25;
|
||||
|
||||
const char *command = NULL;
|
||||
archive->FindString("command", &command);
|
||||
const char *argv[] = { "/bin/sh", "--login" };
|
||||
|
||||
// TODO: Retrieve colors, history size, etc. from archive
|
||||
_InitObject(command);
|
||||
// TODO: Retrieve arguments, colors, history size, etc. from archive
|
||||
_InitObject(2, argv);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
TermView::_InitObject(const char *command)
|
||||
TermView::_InitObject(int32 argc, const char **argv)
|
||||
{
|
||||
SetTermFont(be_fixed_font, be_fixed_font);
|
||||
|
||||
@ -304,7 +303,7 @@ TermView::_InitObject(const char *command)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t status = fShell->Open(fTermRows, fTermColumns,
|
||||
command, longname2shortname(id2longname(fEncoding)));
|
||||
longname2shortname(id2longname(fEncoding)), argc, argv);
|
||||
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
@ -32,8 +32,8 @@ class Shell;
|
||||
class TermBuffer;
|
||||
class TermView : public BView {
|
||||
public:
|
||||
TermView(BRect frame, const char *command = NULL, int32 historySize = 1000);
|
||||
TermView(int rows, int columns, const char *command = NULL, int32 historySize = 1000);
|
||||
TermView(BRect frame, int32 argc, const char **argv, int32 historySize = 1000);
|
||||
TermView(int rows, int columns, int32 argc, const char **argv, int32 historySize = 1000);
|
||||
TermView(BMessage *archive);
|
||||
~TermView();
|
||||
|
||||
@ -140,7 +140,7 @@ protected:
|
||||
const char *property);
|
||||
|
||||
private:
|
||||
status_t _InitObject(const char *command);
|
||||
status_t _InitObject(int32 argc, const char **argv);
|
||||
status_t _InitMouseThread(void);
|
||||
|
||||
status_t _AttachShell(Shell *shell);
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "TermWindow.h"
|
||||
|
||||
#include "Arguments.h"
|
||||
#include "Coding.h"
|
||||
#include "ColorWindow.h"
|
||||
#include "MenuUtil.h"
|
||||
@ -55,13 +56,13 @@ const static uint32 kCloseView = 'ClVw';
|
||||
|
||||
class CustomTermView : public TermView {
|
||||
public:
|
||||
CustomTermView(int32 rows, int32 columns, const char *command = NULL, int32 historySize = 1000);
|
||||
CustomTermView(int32 rows, int32 columns, int32 argc, const char **argv, int32 historySize = 1000);
|
||||
virtual void NotifyQuit(int32 reason);
|
||||
virtual void SetTitle(const char *title);
|
||||
};
|
||||
|
||||
|
||||
TermWindow::TermWindow(BRect frame, const char* title, const char *command)
|
||||
TermWindow::TermWindow(BRect frame, const char* title, Arguments *args)
|
||||
: BWindow(frame, title, B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE|B_QUIT_ON_WINDOW_CLOSE),
|
||||
fTabView(NULL),
|
||||
fMenubar(NULL),
|
||||
@ -82,7 +83,8 @@ TermWindow::TermWindow(BRect frame, const char* title, const char *command)
|
||||
fMatchCase(false),
|
||||
fMatchWord(false)
|
||||
{
|
||||
_InitWindow(command);
|
||||
_InitWindow();
|
||||
_AddTab(args);
|
||||
}
|
||||
|
||||
|
||||
@ -105,7 +107,7 @@ TermWindow::~TermWindow()
|
||||
|
||||
/** Initialize Window object. */
|
||||
void
|
||||
TermWindow::_InitWindow(const char *command)
|
||||
TermWindow::_InitWindow()
|
||||
{
|
||||
// make menu bar
|
||||
_SetupMenu();
|
||||
@ -115,8 +117,6 @@ TermWindow::_InitWindow(const char *command)
|
||||
|
||||
fTabView = new SmartTabView(textFrame, "tab view");
|
||||
AddChild(fTabView);
|
||||
|
||||
_AddTab(command);
|
||||
}
|
||||
|
||||
|
||||
@ -561,7 +561,7 @@ TermWindow::_DoPrint()
|
||||
|
||||
|
||||
void
|
||||
TermWindow::_AddTab(const char *command)
|
||||
TermWindow::_AddTab(Arguments *args)
|
||||
{
|
||||
// Setup font.
|
||||
|
||||
@ -585,9 +585,16 @@ TermWindow::_AddTab(const char *command)
|
||||
fullFont.SetSpacing(B_FIXED_SPACING);
|
||||
|
||||
// Make Terminal text view.
|
||||
int argc;
|
||||
const char *const *argv = NULL;
|
||||
args->GetShellArguments(argc, argv);
|
||||
|
||||
// Note: I don't pass the Arguments class directly to the termview,
|
||||
// only to avoid adding it as a dependency: in other words, to keep
|
||||
// the TermView class as agnostic as possible about the surrounding world.
|
||||
CustomTermView *view = new CustomTermView(PrefHandler::Default()->getInt32(PREF_ROWS),
|
||||
PrefHandler::Default()->getInt32(PREF_COLS),
|
||||
command);
|
||||
argc, (const char **)argv);
|
||||
|
||||
BScrollView *scrollView = new BScrollView("scrollView", view, B_FOLLOW_ALL,
|
||||
B_WILL_DRAW|B_FRAME_EVENTS, false, true);
|
||||
@ -643,9 +650,9 @@ TermWindow::_ActiveTermView()
|
||||
|
||||
|
||||
// CustomTermView
|
||||
CustomTermView::CustomTermView(int32 rows, int32 columns, const char *command, int32 historySize)
|
||||
CustomTermView::CustomTermView(int32 rows, int32 columns, int32 argc, const char **argv, int32 historySize)
|
||||
:
|
||||
TermView(rows, columns, command, historySize)
|
||||
TermView(rows, columns, argc, argv, historySize)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <Window.h>
|
||||
|
||||
|
||||
class Arguments;
|
||||
class BMenu;
|
||||
class BMenuBar;
|
||||
class FindWindow;
|
||||
@ -43,7 +44,7 @@ class TermView;
|
||||
class SmartTabView;
|
||||
class TermWindow : public BWindow {
|
||||
public:
|
||||
TermWindow(BRect frame, const char* title, const char *command);
|
||||
TermWindow(BRect frame, const char* title, Arguments *args);
|
||||
virtual ~TermWindow();
|
||||
|
||||
protected:
|
||||
@ -55,11 +56,11 @@ protected:
|
||||
|
||||
private:
|
||||
void _SetTermColors(TermView *termView);
|
||||
void _InitWindow(const char *command);
|
||||
void _InitWindow();
|
||||
void _SetupMenu();
|
||||
status_t _DoPageSetup();
|
||||
void _DoPrint();
|
||||
void _AddTab(const char *command);
|
||||
void _AddTab(Arguments *args);
|
||||
void _RemoveTab(int32 index);
|
||||
TermView* _ActiveTermView();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user