chiark / gitweb /
Initial revision
[ssr] / StraySrc / Utilities / c / cmdr
1 /*
2  * cmdr.c
3  *
4  * Perform expansions on the command line arguments
5  *
6  * © 1998 Straylight/Edgeware
7  */
8
9 /*----- Licensing note ----------------------------------------------------*
10  *
11  * This file is part of Straylight's core utilities (coreutils).
12  *
13  * Coreutils is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2, or (at your option)
16  * any later version.
17  *
18  * Coreutils is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with coreutils.  If not, write to the Free Software Foundation,
25  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26  */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "swis.h"
35 #include "swiv.h"
36
37 #include "alloc.h"
38 #include "cmdr.h"
39 #include "gf.h"
40 #include "glob.h"
41
42 /*----- Type definitions --------------------------------------------------*/
43
44 typedef struct cmdr_ctx {
45   char **av;                            /* Pointer to @argv@ array */
46   size_t sz;                            /* Size currently allocated */
47   size_t i;                             /* Next available @argv@ index */
48 } cmdr_ctx;
49
50 /*----- Main code ---------------------------------------------------------*/
51
52 /* --- @cmdr_add@ --- *
53  *
54  * Arguments:   @const char *p@ = pointer to an expanded item
55  *              @void *ctx@ = pointer to my context
56  *
57  * Returns:     ---
58  *
59  * Use:         Adds a globbed filename to the output buffer.
60  */
61
62 static void cmdr_add(const char *p, void *ctx)
63 {
64   cmdr_ctx *cx = ctx;
65
66   if (cx->i == cx->sz) {
67     cx->sz += 1024;
68     cx->av = xrealloc(cx->av, cx->sz * sizeof(cx->av[0]));
69   }
70   cx->av[cx->i++] = xstrdup(p);
71 }
72
73 /* --- @cmdreplace@ --- *
74  *
75  * Arguments:   @int *argc@ = pointer to argument count
76  *              @char ***argv@ = address of pointer to arg list
77  *
78  * Returns:     ---
79  *
80  * Use:         Mangles the argument list until it's nice.
81  */
82
83 void cmdreplace(int *argc, char ***argv)
84 {
85   cmdr_ctx cx;
86   char **iav = *argv;
87   int iac = 0;
88
89   /* --- Initialise the context --- */
90
91   cx.sz = 256;
92   cx.av = xmalloc(cx.sz * sizeof(cx.av[0]));
93   cx.i = 0;
94
95   /* --- Copy over @argv[0]@ because it's special --- */
96
97   cx.av[cx.i++] = iav[iac++];
98
99   /* --- Copy over everything else --- */
100
101   while (iav[iac]) {
102     if (glob(iav[iac], cmdr_add, &cx) == 0) {
103       if (cx.i == cx.sz) {
104         cx.sz += 1024;
105         cx.av = xrealloc(cx.av, cx.sz * sizeof(cx.av[0]));
106       }
107       cx.av[cx.i++] = iav[iac];
108     }
109     iac++;
110   }
111
112   /* --- Copy over the terminator --- */
113
114   if (cx.i == cx.sz) {
115     cx.sz += 1024;
116     cx.av = xrealloc(cx.av, cx.sz * sizeof(cx.av[0]));
117   }
118   cx.av[cx.i] = 0;
119
120   /* --- Return appropriate values to the caller --- */
121
122   *argc = cx.i;
123   *argv = cx.av;
124 }
125
126 /*----- That's all, folks -------------------------------------------------*/