dockapps/washerdryer/wmgeneral/misc.c

230 lines
3.8 KiB
C

/* dock.c- built-in Dock module for WindowMaker
* WindowMaker window manager
*
* Copyright (c) 1997 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h>
#include <string.h>
#include "list.h"
#include "misc.h"
/*
*----------------------------------------------------------------------
* parse_command--
* Divides a command line into a argv/argc pair.
*----------------------------------------------------------------------
*/
#define PRC_ALPHA 0
#define PRC_BLANK 1
#define PRC_ESCAPE 2
#define PRC_DQUOTE 3
#define PRC_EOS 4
#define PRC_SQUOTE 5
typedef struct
{
short nstate;
short output;
}
DFA;
static DFA mtable[9][6] =
{
{
{3, 1},
{0, 0},
{4, 0},
{1, 0},
{8, 0},
{6, 0}},
{
{1, 1},
{1, 1},
{2, 0},
{3, 0},
{5, 0},
{1, 1}},
{
{1, 1},
{1, 1},
{1, 1},
{1, 1},
{5, 0},
{1, 1}},
{
{3, 1},
{5, 0},
{4, 0},
{1, 0},
{5, 0},
{6, 0}},
{
{3, 1},
{3, 1},
{3, 1},
{3, 1},
{5, 0},
{3, 1}},
{
{-1, -1},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0}}, /* final state */
{
{6, 1},
{6, 1},
{7, 0},
{6, 1},
{5, 0},
{3, 0}},
{
{6, 1},
{6, 1},
{6, 1},
{6, 1},
{5, 0},
{6, 1}},
{
{-1, -1},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0}}, /* final state */
};
char * next_token (char *word, char **next)
{
char *ptr;
char *ret, *t;
int state, ctype;
t = ret = malloc (strlen (word) + 1);
ptr = word;
state = 0;
*t = 0;
while (1)
{
if (*ptr == 0)
ctype = PRC_EOS;
else if (*ptr == '\\')
ctype = PRC_ESCAPE;
else if (*ptr == '"')
ctype = PRC_DQUOTE;
else if (*ptr == '\'')
ctype = PRC_SQUOTE;
else if (*ptr == ' ' || *ptr == '\t')
ctype = PRC_BLANK;
else
ctype = PRC_ALPHA;
if (mtable[state][ctype].output)
{
*t = *ptr;
t++;
*t = 0;
}
state = mtable[state][ctype].nstate;
ptr++;
if (mtable[state][0].output < 0)
{
break;
}
}
if (*ret == 0)
t = NULL;
else
t = strdup (ret);
free (ret);
if (ctype == PRC_EOS)
*next = NULL;
else
*next = ptr;
return t;
}
extern void parse_command (char *command, char ***argv, int *argc)
{
LinkedList *list = NULL;
char *token, *line;
int count, i;
line = command;
do
{
token = next_token (line, &line);
if (token)
{
list = list_cons (token, list);
}
}
while (token != NULL && line != NULL);
count = list_length (list);
*argv = malloc (sizeof (char *) * count);
i = count;
while (list != NULL)
{
(*argv)[--i] = list->head;
list_remove_head (&list);
}
*argc = count;
}
extern pid_t execCommand (char *command)
{
pid_t pid;
char **argv;
int argc;
parse_command (command, &argv, &argc);
if (argv == NULL)
{
return 0;
}
if ((pid = fork ()) == 0)
{
char **args;
int i;
args = malloc (sizeof (char *) * (argc + 1));
if (!args)
exit (10);
for (i = 0; i < argc; i++)
{
args[i] = argv[i];
}
args[argc] = NULL;
execvp (argv[0], args);
exit (10);
}
return pid;
}