1 /*****************************************************************************/
2 /*									     */
3 /*				  WILDARGS.CC				     */
4 /*									     */
5 /* (C) 1996	Ullrich von Bassewitz					     */
6 /*		Wacholderweg 14						     */
7 /*		D-70597 Stuttgart					     */
8 /* EMail:	uz@ibb.schwaben.com					     */
9 /*									     */
10 /*****************************************************************************/
11 
12 
13 
14 // $Id$
15 //
16 // $Log$
17 //
18 //
19 
20 
21 
22 // This is a special module for DOS and OS/2. It is used to expand the
23 // argument vector if any of the arguments has wildcards in it.
24 
25 
26 
27 #include <stdio.h>
28 
29 #include "chartype.h"
30 #include "filecoll.h"
31 #include "filepath.h"
32 #include "wildargs.h"
33 
34 
35 
36 /*****************************************************************************/
37 /*			Explicit template instantiation			     */
38 /*****************************************************************************/
39 
40 
41 
42 #ifdef EXPLICIT_TEMPLATES
43 template class Collection<String>;
44 #endif
45 
46 
47 
48 /*****************************************************************************/
49 /*				     Code				     */
50 /*****************************************************************************/
51 
52 
53 
ExpandWildArg(const String & Arg,Collection<String> & NewArgs)54 static void ExpandWildArg (const String& Arg, Collection<String>& NewArgs)
55 // Search for all files that match Arg and insert the names into NewArgs
56 {
57     // Separate path and filename
58     String Dir, Name;
59     FSplit (Arg, Dir, Name);
60 
61     // Read the files into a filename collection
62     FileInfoColl Files;
63     Files.ReadFiles (Dir, Name, 0xFFFF, 0x0000);
64 
65     // Now transfer the filenames. Beware: If the name does not expand to
66     // anything insert just the name of the file.
67     int Count = Files.GetCount ();
68     if (Count == 0) {
69 
70 	// Insert the original name
71 	NewArgs.Insert (new String (Arg));
72 
73     } else {
74 
75 	// Transfer all files
76 	for (int I = 0; I < Count; I++) {
77 
78 	    NewArgs.Insert (new String (Files [I]->Name));
79 
80 	}
81     }
82 }
83 
84 
85 
ExpandArgs(int & ArgCount,_PPCHAR & ArgVec)86 void ExpandArgs (int& ArgCount, _PPCHAR& ArgVec)
87 // Expand the argument list
88 {
89     // Initialize ...
90     char** OldArgs = ArgVec;
91     Collection<String> NewArgs (20, 20, 1);
92 
93     // Copy the first argument without looking at it, since this is the
94     // name of the executable under DOS and OS/2
95     NewArgs.Insert (new String (*OldArgs++));
96 
97     // Loop over all arguments, remember if we did an expand
98     int DidExpand = 0;
99     while (*OldArgs != NULL) {
100 
101 	// Get the argument into a string
102 	String Arg = *OldArgs;
103 
104 	// Here is a special convention: If an argument is preceeded by a
105 	// '@', it holds the name of a text file with one argument per
106 	// line. This is used to circumvent the 128 bytes command line
107 	// restriction of dos.
108 	FILE* F;
109 	if (Arg [0] == '@' && (F = fopen (&(*OldArgs) [1], "rt")) != NULL) {
110 
111 	    // We could open the file, read the lines
112 	    char Buf [512];
113 	    while (fgets (Buf, sizeof (Buf), F) != NULL) {
114 
115 		// Assign the line to the argument string
116 		Arg = Buf;
117 
118 		// Remove leading and trailing white space
119 		Arg.Remove (WhiteSpace, rmLeading | rmTrailing);
120 
121 		// Check if we have to expand the string
122 		if (Arg [0] != '-' && FHasWildcards (Arg)) {
123 
124 		    // Expand the argument
125 		    ExpandWildArg (Arg, NewArgs);
126 
127 		} else {
128 
129 		    // No wildcards, no switch: store a copy
130 		    NewArgs.Insert (new String (Arg));
131 
132 		}
133 
134 		// We expanded the file
135 		DidExpand = 1;
136 	    }
137 
138 	    // Close the response file
139 	    (void) fclose (F);
140 
141 	} else if (Arg [0] != '-' && FHasWildcards (Arg)) {
142 
143 	    // Expand the argument
144 	    ExpandWildArg (Arg, NewArgs);
145 	    DidExpand = 1;
146 
147 	} else {
148 
149 	    // No wildcards, no switch: store a copy
150 	    NewArgs.Insert (new String (Arg));
151 
152 	}
153 
154 	// Next argument
155 	OldArgs++;
156    }
157 
158     // If we did not expand anything, we are done now, else copy the new
159     // arguments
160     if (DidExpand) {
161 
162 	// Create a new char* argument vector. Don't forget the trailing NULL
163 	ArgVec = new char* [NewArgs.GetCount () + 1];
164 
165 	// Transfer the strings
166 	ArgCount = 0;
167 	for (ArgCount = 0; ArgCount < NewArgs.GetCount (); ArgCount++) {
168 
169 	    // Get the string argument
170 	    String* Arg = NewArgs [ArgCount];
171 
172 	    // Create a copy on the heap
173 	    ArgVec [ArgCount] = new char [Arg->Len () + 1];
174 	    memcpy (ArgVec [ArgCount], Arg->GetStr (), Arg->Len () + 1);
175 
176 	}
177 
178 	// Add the trailing NULL
179 	ArgVec [ArgCount] = NULL;
180     }
181 }
182 
183