164 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
	
		
			3.5 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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;
 | 
						|
}
 |