summaryrefslogtreecommitdiff
path: root/theos/_setargv.c
diff options
context:
space:
mode:
Diffstat (limited to 'theos/_setargv.c')
-rw-r--r--theos/_setargv.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/theos/_setargv.c b/theos/_setargv.c
new file mode 100644
index 0000000..d76f955
--- /dev/null
+++ b/theos/_setargv.c
@@ -0,0 +1,140 @@
+/*
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 1999-Oct-05 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+*/
+/*
+ * __setargv.c - command argument expander
+ *
+ * Author : Jean-Michel Dubois
+ * Date : 09/26/92
+ *
+ * Function: Expands the command line arguments by replacing any filename
+ * including wilcards by the sorted list of matching files name.
+ * Strings beginning by a dash are considered as options and left
+ * unchanged.
+ *
+ * Syntax : void _setargv(int *argc, char ***argv);
+ *
+ * Returns : new argc. Caller's argc and argv are updated.
+ * If a insufficient memory condition occurs, return 0 and errno
+ * is set to ENOMEM.
+ *
+ * Example :
+ * main(int argc, char **argv)
+ * {
+ * if (_setargv(&argc, &argv)) {
+ * ...
+ */
+#pragma library
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <errno.h>
+#include <scr.h>
+#include <peek.h>
+
+/* Allocate argv array in 16 entries chunks */
+
+static int allocarg(int n, int l, char ***nargv, char *s)
+{
+ if ((n+1) > l) { /* If array full */
+ l += 16; /* increase size and reallocate */
+ if (!(*nargv = (char **) realloc(*nargv,l * sizeof (void *)))) {
+ errno = _errnum = ENOMEM; /* Not enough memory */
+ return 0;
+ }
+ }
+ (*nargv)[n] = strdup(s); /* Save argument */
+ return l; /* Return new maxsize */
+}
+
+/* Comparison function for qsort */
+
+static int sortcmp(char **p, char **q)
+{
+ return stricmp(*p,*q);
+}
+
+/* Main body of the function */
+
+int _setargv(int *argc, char ***argv)
+{
+ register int nargc; /* New arguments counter */
+ char **nargv; /* New arguments pointers */
+ register int i, l, base;
+ char *p, *q, *r;
+ char path[FILENAME_MAX];
+
+ _errnum = 0;
+ nargc = 0; /* Initialise counter, size counter */
+ l = *argc; /* and new argument vector to the */
+ /* current argv array size */
+
+ if ((nargv = (char **) calloc((size_t) *argc, sizeof (void *))) != NULL) {
+ /* For each initial argument */
+ for (i = 0; i < *argc; i++) {
+ q = (*argv)[i];
+ if (q[0] == '-' || ! testwild(q)) {
+ /* if it begins with a dash or doesnt include
+ * wildcard simply add it to the new array
+ */
+ if (! (l = allocarg(nargc, l, &nargv, q)))
+ return 0; /* Not enough memory */
+ nargc++;
+ } else {
+ /* else keep current counter for qsort */
+ base = nargc;
+ /* open directory with argument */
+ diropen(q);
+ while ((r = dirread()) != NULL) {
+ /* reduce path to given one */
+ if ((p = strrchr(q, '/')) != NULL) {
+ strncpy(path, q, p-q+1);
+ path[p-q+1] = '\0';
+ } else
+ path[0] = '\0';
+
+ if ((p = strrchr(r, '/')) != NULL)
+ strcat(path, p+1);
+ else
+ strcat(path, r);
+
+ if (peekscr(&SCR->searchseq[1]) == 255
+ && strchr(q, ':') == NULL) {
+ *strchr(path, ':') = '\0';
+ }
+ /* and add each matching filename. */
+ if (! (l = allocarg(nargc,l,&nargv,path)))
+ return 0;/* Not enough memory */
+ nargc++;
+ }
+ if (nargc == base) {
+ /* if no match found include wild card name */
+ if (! (l = allocarg(nargc, l, &nargv, q)))
+ return 0; /* Not enough memory */
+ nargc++;
+ } else if ((nargc - base) > 1)
+ /* If more than one file name matchs */
+ /* sort arguments. */
+ qsort(&(nargv[base]),(size_t)nargc-base,
+ sizeof(void *),sortcmp);
+ dirclose();
+ }
+ }
+ /* Update caller's parameters */
+ *argc = nargc;
+ *argv = nargv;
+ /* and sign on success */
+ return nargc;
+ }
+
+ /* If it is not possible to allocate initial array, sign on error */
+ _errnum = ENOMEM;
+ return 0;
+}