Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenlib/intern/BLI_args.c')
-rw-r--r--source/blender/blenlib/intern/BLI_args.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c
new file mode 100644
index 00000000000..9d67556a599
--- /dev/null
+++ b/source/blender/blenlib/intern/BLI_args.c
@@ -0,0 +1,201 @@
+/**
+ * A general argument parsing module
+ *
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <ctype.h> /* for tolower */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_string.h"
+#include "BLI_args.h"
+#include "BLI_ghash.h"
+
+typedef struct bAKey {
+ char *arg;
+ uintptr_t pass; /* cast easier */
+ int case_str; /* case specific or not */
+} bAKey;
+
+typedef struct bArgument {
+ BA_ArgCallback func;
+ void *data;
+} bArgument;
+
+struct bArgs {
+ GHash *items;
+ int argc;
+ char **argv;
+ int *passes;
+};
+
+unsigned int case_strhash(void *ptr) {
+ char *s= ptr;
+ unsigned int i= 0;
+ unsigned char c;
+
+ while ( (c= tolower(*s++)) )
+ i= i*37 + c;
+
+ return i;
+}
+
+static unsigned int keyhash(void *ptr)
+{
+ bAKey *k = ptr;
+ return case_strhash(k->arg) ^ BLI_ghashutil_inthash((void*)k->pass);
+}
+
+static int keycmp(void *a, void *b)
+{
+ bAKey *ka = a;
+ bAKey *kb = b;
+ if (ka->pass == kb->pass || ka->pass == -1 || kb->pass == -1) { /* -1 is wildcard for pass */
+ if (ka->case_str == 1 || kb->case_str == 1)
+ return BLI_strcasecmp(ka->arg, kb->arg);
+ else
+ return strcmp(ka->arg, kb->arg);
+ } else {
+ return BLI_ghashutil_intcmp((void*)ka->pass, (void*)kb->pass);
+ }
+}
+
+bArgs *BLI_argsInit(int argc, char **argv)
+{
+ bArgs *ba = MEM_callocN(sizeof(bArgs), "bArgs");
+ ba->passes = MEM_callocN(sizeof(int) * argc, "bArgs passes");
+ ba->items = BLI_ghash_new(keyhash, keycmp);
+ ba->argc = argc;
+ ba->argv = argv;
+
+ return ba;
+}
+
+static void freeItem(void *val)
+{
+ MEM_freeN(val);
+}
+
+void BLI_argsFree(struct bArgs *ba)
+{
+ BLI_ghash_free(ba->items, freeItem, freeItem);
+ MEM_freeN(ba->passes);
+ MEM_freeN(ba);
+}
+
+void BLI_argsPrint(struct bArgs *ba)
+{
+ int i;
+ for (i = 0; i < ba->argc; i++) {
+ printf("argv[%d] = %s\n", i, ba->argv[i]);
+ }
+}
+
+char **BLI_argsArgv(struct bArgs *ba)
+{
+ return ba->argv;
+}
+
+void BLI_argsAdd(struct bArgs *ba, char *arg, int pass, BA_ArgCallback cb, void *data)
+{
+ bArgument *a = MEM_callocN(sizeof(bArgument), "bArgument");
+ bAKey *key = MEM_callocN(sizeof(bAKey), "bAKey");
+
+ key->arg = arg;
+ key->pass = pass;
+ key->case_str = 1;
+
+ a->func = cb;
+ a->data = data;
+
+ BLI_ghash_insert(ba->items, key, a);
+}
+
+void BLI_argsAddCase(struct bArgs *ba, char *arg, int pass, BA_ArgCallback cb, void *data)
+{
+ bArgument *a = MEM_callocN(sizeof(bArgument), "bArgument");
+ bAKey *key = MEM_callocN(sizeof(bAKey), "bAKey");
+
+ key->arg = arg;
+ key->pass = pass;
+ key->case_str = 0;
+
+ a->func = cb;
+ a->data = data;
+
+ BLI_ghash_insert(ba->items, key, a);
+}
+
+
+void BLI_argsParse(struct bArgs *ba, int pass, BA_ArgCallback default_cb, void *default_data)
+{
+ bAKey key;
+ int i = 0;
+
+ key.case_str = -1; /* signal what side of the comparison it is */
+ key.pass = pass;
+
+ for( i = 1; i < ba->argc; i++) { /* skip argv[0] */
+ key.arg = ba->argv[i];
+ if (ba->passes[i] == 0) {
+ bArgument *a = BLI_ghash_lookup(ba->items, &key);
+ BA_ArgCallback func = NULL;
+ void *data = NULL;
+
+ if (a) {
+ func = a->func;
+ data = a->data;
+ } else {
+ func = default_cb;
+ data = default_data;
+
+ if (func) {
+ printf("calling default on %s\n", ba->argv[i]);
+ }
+ }
+
+ if (func) {
+ int retval = func(ba->argc - i, ba->argv + i, data);
+
+ if (retval >= 0) {
+ int j;
+
+ /* use extra arguments */
+ for (j = 0; j <= retval; j++) {
+ ba->passes[i + j] = pass;
+ }
+ i += retval;
+ } else if (retval == -1){
+ ba->passes[i] = pass;
+ break;
+ }
+ }
+ }
+ }
+}