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:
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2005, Ingo Weinhold, [email protected].
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2005, Ingo Weinhold, [email protected].
|
||||||
|
* 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 :
|
Application Terminal :
|
||||||
AppearPrefView.cpp
|
AppearPrefView.cpp
|
||||||
|
Arguments.cpp
|
||||||
CodeConv.cpp
|
CodeConv.cpp
|
||||||
Coding.cpp
|
Coding.cpp
|
||||||
CurPos.cpp
|
CurPos.cpp
|
||||||
|
|||||||
@@ -80,7 +80,7 @@
|
|||||||
#define RDEL 0xFF
|
#define RDEL 0xFF
|
||||||
|
|
||||||
/* default shell command and options. */
|
/* 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
|
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)
|
if (fFd >= 0)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
status_t status = _Spawn(row, col, command, encoding);
|
status_t status = _Spawn(row, col, encoding, argc, argv);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -295,7 +295,7 @@ receive_handshake_message(handshake_t& handshake)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
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);
|
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("TERM", "beterm", true);
|
||||||
setenv("TTY", ttyName, true);
|
setenv("TTY", ttyName, true);
|
||||||
setenv("TTYPE", encoding, 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. */
|
execve(*argv, (char * const *)argv, environ);
|
||||||
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);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exec failed.
|
* Exec failed.
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public:
|
|||||||
Shell();
|
Shell();
|
||||||
virtual ~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();
|
void Close();
|
||||||
|
|
||||||
const char * TTYName() const;
|
const char * TTYName() const;
|
||||||
@@ -48,7 +48,7 @@ private:
|
|||||||
TermParse *fTermParse;
|
TermParse *fTermParse;
|
||||||
bool fAttached;
|
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
|
#endif // _SHELL_H
|
||||||
|
|||||||
+22
-300
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "TermApp.h"
|
#include "TermApp.h"
|
||||||
|
|
||||||
|
#include "Arguments.h"
|
||||||
#include "CodeConv.h"
|
#include "CodeConv.h"
|
||||||
#include "PrefHandler.h"
|
#include "PrefHandler.h"
|
||||||
#include "TermWindow.h"
|
#include "TermWindow.h"
|
||||||
@@ -31,25 +32,6 @@
|
|||||||
static bool sUsageRequested = false;
|
static bool sUsageRequested = false;
|
||||||
static bool sGeometryRequested = 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_ACTIVATE_TERM = 'msat';
|
||||||
const ulong MSG_TERM_IS_MINIMIZE = 'mtim';
|
const ulong MSG_TERM_IS_MINIMIZE = 'mtim';
|
||||||
@@ -59,8 +41,11 @@ TermApp::TermApp()
|
|||||||
: BApplication(TERM_SIGNATURE),
|
: BApplication(TERM_SIGNATURE),
|
||||||
fStartFullscreen(false),
|
fStartFullscreen(false),
|
||||||
fWindowNumber(-1),
|
fWindowNumber(-1),
|
||||||
fTermWindow(NULL)
|
fTermWindow(NULL),
|
||||||
|
fArgs(NULL)
|
||||||
{
|
{
|
||||||
|
fArgs = new Arguments();
|
||||||
|
|
||||||
fWindowTitle = "Terminal";
|
fWindowTitle = "Terminal";
|
||||||
_RegisterTerminal();
|
_RegisterTerminal();
|
||||||
|
|
||||||
@@ -78,6 +63,7 @@ TermApp::TermApp()
|
|||||||
|
|
||||||
TermApp::~TermApp()
|
TermApp::~TermApp()
|
||||||
{
|
{
|
||||||
|
delete fArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -167,73 +153,19 @@ TermApp::MessageReceived(BMessage* msg)
|
|||||||
void
|
void
|
||||||
TermApp::ArgvReceived(int32 argc, char **argv)
|
TermApp::ArgvReceived(int32 argc, char **argv)
|
||||||
{
|
{
|
||||||
int skip_args = 0;
|
fArgs->Parse(argc, argv);
|
||||||
char *value = 0;
|
|
||||||
|
if (fArgs->UsageRequested()) {
|
||||||
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)) {
|
|
||||||
_Usage(argv[0]);
|
_Usage(argv[0]);
|
||||||
sUsageRequested = true;
|
sUsageRequested = true;
|
||||||
PostMessage(B_QUIT_REQUESTED);
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fArgs->Title() != NULL)
|
||||||
|
fWindowTitle = fArgs->Title();
|
||||||
|
|
||||||
// Start fullscreen
|
fStartFullscreen = fArgs->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++];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -277,14 +209,8 @@ TermApp::RefsReceived(BMessage* message)
|
|||||||
status_t
|
status_t
|
||||||
TermApp::_MakeTermWindow(BRect &frame)
|
TermApp::_MakeTermWindow(BRect &frame)
|
||||||
{
|
{
|
||||||
const char *command = NULL;
|
|
||||||
if (fCommandLine.Length() > 0)
|
|
||||||
command = fCommandLine.String();
|
|
||||||
else
|
|
||||||
command = PrefHandler::Default()->getString(PREF_SHELL);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fTermWindow = new TermWindow(frame, fWindowTitle.String(), command);
|
fTermWindow = new TermWindow(frame, fWindowTitle.String(), new Arguments(*fArgs));
|
||||||
} catch (int error) {
|
} catch (int error) {
|
||||||
return (status_t)error;
|
return (status_t)error;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -556,217 +482,13 @@ TermApp::_Usage(char *name)
|
|||||||
"\n"
|
"\n"
|
||||||
"Usage: %s [OPTION] [SHELL]\n", name);
|
"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"
|
" -t, --title set window title\n"
|
||||||
" -geom, --geometry set window geometry\n"
|
" -f, --fullscreen start fullscreen\n"
|
||||||
" An example of geometry is \"80x25+100+100\"\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 <Application.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
|
class Arguments;
|
||||||
class BRect;
|
class BRect;
|
||||||
class BWindow;
|
class BWindow;
|
||||||
class TermApp : public BApplication {
|
class TermApp : public BApplication {
|
||||||
@@ -70,7 +71,7 @@ class TermApp : public BApplication {
|
|||||||
|
|
||||||
BWindow* fTermWindow;
|
BWindow* fTermWindow;
|
||||||
BRect fTermFrame;
|
BRect fTermFrame;
|
||||||
BString fCommandLine;
|
Arguments *fArgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TERM_APP_H
|
#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,
|
: BView(frame, "termview", B_FOLLOW_ALL,
|
||||||
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE| B_PULSE_NEEDED),
|
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE| B_PULSE_NEEDED),
|
||||||
fShell(NULL),
|
fShell(NULL),
|
||||||
@@ -176,11 +176,11 @@ TermView::TermView(BRect frame, const char *command, int32 historySize)
|
|||||||
fQuitting(false),
|
fQuitting(false),
|
||||||
fIMflag(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,
|
: BView(BRect(0, 0, 0, 0), "termview", B_FOLLOW_ALL,
|
||||||
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE| B_PULSE_NEEDED),
|
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE| B_PULSE_NEEDED),
|
||||||
fShell(NULL),
|
fShell(NULL),
|
||||||
@@ -225,7 +225,7 @@ TermView::TermView(int rows, int columns, const char *command, int32 historySize
|
|||||||
fQuitting(false),
|
fQuitting(false),
|
||||||
fIMflag(false)
|
fIMflag(false)
|
||||||
{
|
{
|
||||||
_InitObject(command);
|
_InitObject(argc, argv);
|
||||||
SetTermSize(fTermRows, fTermColumns, true);
|
SetTermSize(fTermRows, fTermColumns, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,16 +282,15 @@ TermView::TermView(BMessage *archive)
|
|||||||
if (archive->FindInt32("rows", (int32 *)&fTermRows) < B_OK)
|
if (archive->FindInt32("rows", (int32 *)&fTermRows) < B_OK)
|
||||||
fTermRows = 25;
|
fTermRows = 25;
|
||||||
|
|
||||||
const char *command = NULL;
|
const char *argv[] = { "/bin/sh", "--login" };
|
||||||
archive->FindString("command", &command);
|
|
||||||
|
|
||||||
// TODO: Retrieve colors, history size, etc. from archive
|
// TODO: Retrieve arguments, colors, history size, etc. from archive
|
||||||
_InitObject(command);
|
_InitObject(2, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TermView::_InitObject(const char *command)
|
TermView::_InitObject(int32 argc, const char **argv)
|
||||||
{
|
{
|
||||||
SetTermFont(be_fixed_font, be_fixed_font);
|
SetTermFont(be_fixed_font, be_fixed_font);
|
||||||
|
|
||||||
@@ -304,7 +303,7 @@ TermView::_InitObject(const char *command)
|
|||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
status_t status = fShell->Open(fTermRows, fTermColumns,
|
status_t status = fShell->Open(fTermRows, fTermColumns,
|
||||||
command, longname2shortname(id2longname(fEncoding)));
|
longname2shortname(id2longname(fEncoding)), argc, argv);
|
||||||
|
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ class Shell;
|
|||||||
class TermBuffer;
|
class TermBuffer;
|
||||||
class TermView : public BView {
|
class TermView : public BView {
|
||||||
public:
|
public:
|
||||||
TermView(BRect frame, const char *command = NULL, int32 historySize = 1000);
|
TermView(BRect frame, int32 argc, const char **argv, int32 historySize = 1000);
|
||||||
TermView(int rows, int columns, const char *command = NULL, int32 historySize = 1000);
|
TermView(int rows, int columns, int32 argc, const char **argv, int32 historySize = 1000);
|
||||||
TermView(BMessage *archive);
|
TermView(BMessage *archive);
|
||||||
~TermView();
|
~TermView();
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ protected:
|
|||||||
const char *property);
|
const char *property);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _InitObject(const char *command);
|
status_t _InitObject(int32 argc, const char **argv);
|
||||||
status_t _InitMouseThread(void);
|
status_t _InitMouseThread(void);
|
||||||
|
|
||||||
status_t _AttachShell(Shell *shell);
|
status_t _AttachShell(Shell *shell);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "TermWindow.h"
|
#include "TermWindow.h"
|
||||||
|
|
||||||
|
#include "Arguments.h"
|
||||||
#include "Coding.h"
|
#include "Coding.h"
|
||||||
#include "ColorWindow.h"
|
#include "ColorWindow.h"
|
||||||
#include "MenuUtil.h"
|
#include "MenuUtil.h"
|
||||||
@@ -55,13 +56,13 @@ const static uint32 kCloseView = 'ClVw';
|
|||||||
|
|
||||||
class CustomTermView : public TermView {
|
class CustomTermView : public TermView {
|
||||||
public:
|
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 NotifyQuit(int32 reason);
|
||||||
virtual void SetTitle(const char *title);
|
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),
|
: BWindow(frame, title, B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE|B_QUIT_ON_WINDOW_CLOSE),
|
||||||
fTabView(NULL),
|
fTabView(NULL),
|
||||||
fMenubar(NULL),
|
fMenubar(NULL),
|
||||||
@@ -82,7 +83,8 @@ TermWindow::TermWindow(BRect frame, const char* title, const char *command)
|
|||||||
fMatchCase(false),
|
fMatchCase(false),
|
||||||
fMatchWord(false)
|
fMatchWord(false)
|
||||||
{
|
{
|
||||||
_InitWindow(command);
|
_InitWindow();
|
||||||
|
_AddTab(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -105,7 +107,7 @@ TermWindow::~TermWindow()
|
|||||||
|
|
||||||
/** Initialize Window object. */
|
/** Initialize Window object. */
|
||||||
void
|
void
|
||||||
TermWindow::_InitWindow(const char *command)
|
TermWindow::_InitWindow()
|
||||||
{
|
{
|
||||||
// make menu bar
|
// make menu bar
|
||||||
_SetupMenu();
|
_SetupMenu();
|
||||||
@@ -115,8 +117,6 @@ TermWindow::_InitWindow(const char *command)
|
|||||||
|
|
||||||
fTabView = new SmartTabView(textFrame, "tab view");
|
fTabView = new SmartTabView(textFrame, "tab view");
|
||||||
AddChild(fTabView);
|
AddChild(fTabView);
|
||||||
|
|
||||||
_AddTab(command);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -561,7 +561,7 @@ TermWindow::_DoPrint()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TermWindow::_AddTab(const char *command)
|
TermWindow::_AddTab(Arguments *args)
|
||||||
{
|
{
|
||||||
// Setup font.
|
// Setup font.
|
||||||
|
|
||||||
@@ -585,9 +585,16 @@ TermWindow::_AddTab(const char *command)
|
|||||||
fullFont.SetSpacing(B_FIXED_SPACING);
|
fullFont.SetSpacing(B_FIXED_SPACING);
|
||||||
|
|
||||||
// Make Terminal text view.
|
// 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),
|
CustomTermView *view = new CustomTermView(PrefHandler::Default()->getInt32(PREF_ROWS),
|
||||||
PrefHandler::Default()->getInt32(PREF_COLS),
|
PrefHandler::Default()->getInt32(PREF_COLS),
|
||||||
command);
|
argc, (const char **)argv);
|
||||||
|
|
||||||
BScrollView *scrollView = new BScrollView("scrollView", view, B_FOLLOW_ALL,
|
BScrollView *scrollView = new BScrollView("scrollView", view, B_FOLLOW_ALL,
|
||||||
B_WILL_DRAW|B_FRAME_EVENTS, false, true);
|
B_WILL_DRAW|B_FRAME_EVENTS, false, true);
|
||||||
@@ -643,9 +650,9 @@ TermWindow::_ActiveTermView()
|
|||||||
|
|
||||||
|
|
||||||
// CustomTermView
|
// 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>
|
#include <Window.h>
|
||||||
|
|
||||||
|
|
||||||
|
class Arguments;
|
||||||
class BMenu;
|
class BMenu;
|
||||||
class BMenuBar;
|
class BMenuBar;
|
||||||
class FindWindow;
|
class FindWindow;
|
||||||
@@ -43,7 +44,7 @@ class TermView;
|
|||||||
class SmartTabView;
|
class SmartTabView;
|
||||||
class TermWindow : public BWindow {
|
class TermWindow : public BWindow {
|
||||||
public:
|
public:
|
||||||
TermWindow(BRect frame, const char* title, const char *command);
|
TermWindow(BRect frame, const char* title, Arguments *args);
|
||||||
virtual ~TermWindow();
|
virtual ~TermWindow();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -55,11 +56,11 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void _SetTermColors(TermView *termView);
|
void _SetTermColors(TermView *termView);
|
||||||
void _InitWindow(const char *command);
|
void _InitWindow();
|
||||||
void _SetupMenu();
|
void _SetupMenu();
|
||||||
status_t _DoPageSetup();
|
status_t _DoPageSetup();
|
||||||
void _DoPrint();
|
void _DoPrint();
|
||||||
void _AddTab(const char *command);
|
void _AddTab(Arguments *args);
|
||||||
void _RemoveTab(int32 index);
|
void _RemoveTab(int32 index);
|
||||||
TermView* _ActiveTermView();
|
TermView* _ActiveTermView();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user