]> code.delx.au - pulseaudio/commitdiff
Add a new meta command ".ifexists" to the CLI language, to execute commands only...
authorLennart Poettering <lennart@poettering.net>
Sat, 26 May 2007 23:39:33 +0000 (23:39 +0000)
committerLennart Poettering <lennart@poettering.net>
Sat, 26 May 2007 23:39:33 +0000 (23:39 +0000)
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1456 fefdeb5f-60dc-0310-8127-8f9354f1896f

src/pulsecore/cli-command.c
src/pulsecore/cli-command.h
src/pulsecore/pdispatch.c

index e87b257bdbb6660a9b48484d0a6053efa06fa74e..2755c5c9c89d7f050ce1150474e34f67304b8d26 100644 (file)
@@ -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,8 +1031,12 @@ int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, int *
         int unknown = 1;
         size_t l;
 
-        l = strcspn(cs, whitespace);
+        if (ifstate && *ifstate == IFSTATE_FALSE)
+             return 0;
+        
 
+        l = strcspn(cs, whitespace);
+        
         for (command = commands; command->name; command++)
             if (strlen(command->name) == l && !strncmp(cs, command->name, l)) {
                 int ret;
@@ -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;
         }
index 10d50f37927593788ed2fc15013331244072ff24..01bca8be4a976665c512a8e2ca6010916021bda7 100644 (file)
@@ -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
index 758beaff83f0fc91a58858867d32db9d483c0f01..10238acb058bb40a549318b1372fed1f7d31f8be 100644 (file)
@@ -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;