mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	Add a new meta command ".ifexists" to the CLI language, to execute commands only if a specified file exists. Original patch from cjvdb. Closes #36
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1456 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
		
							parent
							
								
									4d88fcd59d
								
							
						
					
					
						commit
						d949983845
					
				
					 3 changed files with 73 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -31,6 +31,7 @@
 | 
			
		|||
#include <assert.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include <pulse/xmalloc.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -63,9 +64,18 @@ struct command {
 | 
			
		|||
    unsigned args;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define INCLUDE_META ".include"
 | 
			
		||||
#define FAIL_META ".fail"
 | 
			
		||||
#define NOFAIL_META ".nofail"
 | 
			
		||||
#define META_INCLUDE ".include"
 | 
			
		||||
#define META_FAIL ".fail"
 | 
			
		||||
#define META_NOFAIL ".nofail"
 | 
			
		||||
#define META_IFEXISTS ".ifexists"
 | 
			
		||||
#define META_ELSE ".else"
 | 
			
		||||
#define META_ENDIF ".endif"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    IFSTATE_NONE = -1,
 | 
			
		||||
    IFSTATE_FALSE = 0,
 | 
			
		||||
    IFSTATE_TRUE = 1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Prototypes for all available commands */
 | 
			
		||||
static int pa_cli_command_exit(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail);
 | 
			
		||||
| 
						 | 
				
			
			@ -959,7 +969,7 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_G
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, int *fail) {
 | 
			
		||||
int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *buf, int *fail, int *ifstate) {
 | 
			
		||||
    const char *cs;
 | 
			
		||||
 | 
			
		||||
    cs = s+strspn(s, whitespace);
 | 
			
		||||
| 
						 | 
				
			
			@ -967,19 +977,50 @@ int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, int *
 | 
			
		|||
    if (*cs == '#' || !*cs)
 | 
			
		||||
        return 0;
 | 
			
		||||
    else if (*cs == '.') {
 | 
			
		||||
        if (!strcmp(cs, FAIL_META))
 | 
			
		||||
        if (!strcmp(cs, META_ELSE)) {
 | 
			
		||||
            if (!ifstate || *ifstate == IFSTATE_NONE) {
 | 
			
		||||
                pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs);
 | 
			
		||||
                return -1;
 | 
			
		||||
            } else if (*ifstate == IFSTATE_TRUE)
 | 
			
		||||
                *ifstate = IFSTATE_FALSE;
 | 
			
		||||
            else
 | 
			
		||||
                *ifstate = IFSTATE_TRUE;
 | 
			
		||||
            return 0;
 | 
			
		||||
        } else if (!strcmp(cs, META_ENDIF)) {
 | 
			
		||||
            if (!ifstate || *ifstate == IFSTATE_NONE) {
 | 
			
		||||
                pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs);
 | 
			
		||||
                return -1;
 | 
			
		||||
            } else
 | 
			
		||||
                *ifstate = IFSTATE_NONE;
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        if (ifstate && *ifstate == IFSTATE_FALSE)
 | 
			
		||||
            return 0;
 | 
			
		||||
        if (!strcmp(cs, META_FAIL))
 | 
			
		||||
            *fail = 1;
 | 
			
		||||
        else if (!strcmp(cs, NOFAIL_META))
 | 
			
		||||
        else if (!strcmp(cs, META_NOFAIL))
 | 
			
		||||
            *fail = 0;
 | 
			
		||||
        else {
 | 
			
		||||
            size_t l;
 | 
			
		||||
            l = strcspn(cs, whitespace);
 | 
			
		||||
 | 
			
		||||
            if (l == sizeof(INCLUDE_META)-1 && !strncmp(cs, INCLUDE_META, l)) {
 | 
			
		||||
            if (l == sizeof(META_INCLUDE)-1 && !strncmp(cs, META_INCLUDE, l)) {
 | 
			
		||||
                const char *filename = cs+l+strspn(cs+l, whitespace);
 | 
			
		||||
 | 
			
		||||
                if (pa_cli_command_execute_file(c, filename, buf, fail) < 0)
 | 
			
		||||
                    if (*fail) return -1;
 | 
			
		||||
            } else if (l == sizeof(META_IFEXISTS)-1 && !strncmp(cs, META_IFEXISTS, l)) {
 | 
			
		||||
                if (!ifstate) {
 | 
			
		||||
                    pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs);
 | 
			
		||||
                    return -1;
 | 
			
		||||
                } else if (*ifstate != IFSTATE_NONE) {
 | 
			
		||||
                    pa_strbuf_printf(buf, "Nested %s commands not supported\n", cs);
 | 
			
		||||
                    return -1;
 | 
			
		||||
                } else {
 | 
			
		||||
                    const char *filename = cs+l+strspn(cs+l, whitespace);
 | 
			
		||||
 | 
			
		||||
                    *ifstate = access(filename, F_OK) == 0 ? IFSTATE_TRUE : IFSTATE_FALSE;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                pa_strbuf_printf(buf, "Invalid meta command: %s\n", cs);
 | 
			
		||||
                if (*fail) return -1;
 | 
			
		||||
| 
						 | 
				
			
			@ -990,6 +1031,10 @@ int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, int *
 | 
			
		|||
        int unknown = 1;
 | 
			
		||||
        size_t l;
 | 
			
		||||
 | 
			
		||||
        if (ifstate && *ifstate == IFSTATE_FALSE)
 | 
			
		||||
             return 0;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        l = strcspn(cs, whitespace);
 | 
			
		||||
        
 | 
			
		||||
        for (command = commands; command->name; command++)
 | 
			
		||||
| 
						 | 
				
			
			@ -1017,11 +1062,19 @@ int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, int *
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, int *fail) {
 | 
			
		||||
    return pa_cli_command_execute_line_stateful(c, s, buf, fail, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, int *fail) {
 | 
			
		||||
    char line[256];
 | 
			
		||||
    FILE *f = NULL;
 | 
			
		||||
    int ifstate = IFSTATE_NONE;
 | 
			
		||||
    int ret = -1;
 | 
			
		||||
    assert(c && fn && buf);
 | 
			
		||||
    
 | 
			
		||||
    assert(c);
 | 
			
		||||
    assert(fn);
 | 
			
		||||
    assert(buf);
 | 
			
		||||
 | 
			
		||||
    if (!(f = fopen(fn, "r"))) {
 | 
			
		||||
        pa_strbuf_printf(buf, "open('%s') failed: %s\n", fn, pa_cstrerror(errno));
 | 
			
		||||
| 
						 | 
				
			
			@ -1034,7 +1087,7 @@ int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, int
 | 
			
		|||
        char *e = line + strcspn(line, linebreak);
 | 
			
		||||
        *e = 0;
 | 
			
		||||
 | 
			
		||||
        if (pa_cli_command_execute_line(c, line, buf, fail) < 0 && *fail)
 | 
			
		||||
        if (pa_cli_command_execute_line_stateful(c, line, buf, fail, &ifstate) < 0 && *fail)
 | 
			
		||||
            goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1049,14 +1102,18 @@ fail:
 | 
			
		|||
 | 
			
		||||
int pa_cli_command_execute(pa_core *c, const char *s, pa_strbuf *buf, int *fail) {
 | 
			
		||||
    const char *p;
 | 
			
		||||
    assert(c && s && buf && fail);
 | 
			
		||||
    int ifstate = IFSTATE_NONE;
 | 
			
		||||
    
 | 
			
		||||
    assert(c);
 | 
			
		||||
    assert(s);
 | 
			
		||||
    assert(buf);
 | 
			
		||||
 | 
			
		||||
    p = s;
 | 
			
		||||
    while (*p) {
 | 
			
		||||
        size_t l = strcspn(p, linebreak);
 | 
			
		||||
        char *line = pa_xstrndup(p, l);
 | 
			
		||||
 | 
			
		||||
        if (pa_cli_command_execute_line(c, line, buf, fail) < 0&& *fail) {
 | 
			
		||||
        if (pa_cli_command_execute_line_stateful(c, line, buf, fail, &ifstate) < 0 && *fail) {
 | 
			
		||||
            pa_xfree(line);
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,4 +39,7 @@ int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, int
 | 
			
		|||
/* Split the specified string into lines and run pa_cli_command_execute_line() for each. */
 | 
			
		||||
int pa_cli_command_execute(pa_core *c, const char *s, pa_strbuf *buf, int *fail);
 | 
			
		||||
 | 
			
		||||
/* Same as pa_cli_command_execute_line() but also take ifstate var. */
 | 
			
		||||
int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *buf, int *fail, int *ifstate);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -258,7 +258,7 @@ void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa
 | 
			
		|||
    struct timeval tv;
 | 
			
		||||
    assert(pd && pd->ref >= 1 && cb);
 | 
			
		||||
 | 
			
		||||
    r = pa_xmalloc(sizeof(struct reply_info));
 | 
			
		||||
    r = pa_xnew(struct reply_info, 1);
 | 
			
		||||
    r->pdispatch = pd;
 | 
			
		||||
    r->callback = cb;
 | 
			
		||||
    r->userdata = userdata;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue