0
|
1
|
|
2 /* Digital Mars DMDScript source code.
|
|
3 * Copyright (c) 2000-2002 by Chromium Communications
|
|
4 * D version Copyright (c) 2004-2005 by Digital Mars
|
|
5 * All Rights Reserved
|
|
6 * written by Walter Bright
|
|
7 * www.digitalmars.com
|
|
8 * Use at your own risk. There is no warranty, express or implied.
|
|
9 * License for redistribution is by the GNU General Public License in gpl.txt.
|
|
10 *
|
|
11 * A binary, non-exclusive license for commercial use can be
|
|
12 * purchased from www.digitalmars.com/dscript/buy.html.
|
|
13 *
|
|
14 * DMDScript is implemented in the D Programming Language,
|
|
15 * www.digitalmars.com/d/
|
|
16 *
|
|
17 * For a C++ implementation of DMDScript, including COM support,
|
|
18 * see www.digitalmars.com/dscript/cppscript.html.
|
|
19 */
|
|
20
|
|
21
|
3
|
22 module dmdscript_tango.test.testscript;
|
0
|
23
|
|
24 import std.path;
|
|
25 import std.file;
|
|
26 import std.stdio;
|
|
27 import std.c.stdlib;
|
|
28 import std.gc;
|
|
29
|
3
|
30 import dmdscript_tango.script;
|
|
31 import dmdscript_tango.program;
|
|
32 import dmdscript_tango.textgen.errmsgs;
|
0
|
33
|
|
34 enum
|
|
35 {
|
|
36 EXITCODE_INIT_ERROR = 1,
|
|
37 EXITCODE_INVALID_ARGS = 2,
|
|
38 EXITCODE_RUNTIME_ERROR = 3,
|
|
39 }
|
|
40
|
|
41 version (Windows)
|
|
42 {
|
|
43 pragma(lib, "dmdscript");
|
|
44 }
|
|
45
|
|
46
|
|
47
|
|
48 /**************************************************
|
|
49 Usage:
|
|
50
|
|
51 ds
|
|
52 will run test.ds
|
|
53
|
|
54 ds foo
|
|
55 will run foo.ds
|
|
56
|
|
57 ds foo.js
|
|
58 will run foo.js
|
|
59
|
|
60 ds foo1 foo2 foo.bar
|
|
61 will run foo1.ds, foo2.ds, foo.bar
|
|
62
|
|
63 The -iinc flag will prefix the source files with the contents of file inc.
|
|
64 There can be multiple -i's. The include list is reset to empty any time
|
|
65 a new -i is encountered that is not preceded by a -i.
|
|
66
|
|
67 ds -iinc foo
|
|
68 will prefix foo.ds with inc
|
|
69
|
|
70 ds -iinc1 -iinc2 foo bar
|
|
71 will prefix foo.ds with inc1+inc2, and will prefix bar.ds
|
|
72 with inc1+inc2
|
|
73
|
|
74 ds -iinc1 -iinc2 foo -iinc3 bar
|
|
75 will prefix foo.ds with inc1+inc2, and will prefix bar.ds
|
|
76 with inc3
|
|
77
|
|
78 ds -iinc1 -iinc2 foo -i bar
|
|
79 will prefix foo.ds with inc1+inc2, and will prefix bar.ds
|
|
80 with nothing
|
|
81
|
|
82 */
|
|
83
|
|
84 int main(char[][] args)
|
|
85 {
|
|
86 uint errors = 0;
|
|
87 char[][] includes;
|
|
88 SrcFile[] srcfiles;
|
|
89 int result;
|
|
90 bool verbose;
|
|
91 ErrInfo errinfo;
|
|
92
|
|
93 fwritefln(stderr, dmdscript.script.banner());
|
|
94
|
|
95 for (size_t i = 1; i < args.length; i++)
|
|
96 { char[] p = args[i];
|
|
97
|
|
98 if (p[0] == '-')
|
|
99 {
|
|
100 switch (p[1])
|
|
101 {
|
|
102 case 'i':
|
|
103 if (p[2])
|
|
104 includes ~= p[2 .. length];
|
|
105 break;
|
|
106
|
|
107 case 'v':
|
|
108 verbose = 1;
|
|
109 break;
|
|
110
|
|
111 default:
|
|
112 writefln(errmsgtbl[ERR_BAD_SWITCH],p);
|
|
113 errors++;
|
|
114 break;
|
|
115 }
|
|
116 }
|
|
117 else
|
|
118 {
|
|
119 srcfiles ~= new SrcFile(p, includes);
|
|
120 includes = null;
|
|
121 }
|
|
122 }
|
|
123 if (errors)
|
|
124 return EXITCODE_INVALID_ARGS;
|
|
125
|
|
126 if (srcfiles.length == 0)
|
|
127 {
|
|
128 srcfiles ~= new SrcFile("test", null);
|
|
129 }
|
|
130
|
|
131 fwritefln(stderr, "%d source files", srcfiles.length);
|
|
132
|
|
133 // Read files, parse them, execute them
|
|
134 foreach (SrcFile m; srcfiles)
|
|
135 {
|
|
136 if (verbose)
|
|
137 writefln("read %s:", m.srcfile);
|
|
138 m.read();
|
|
139 if (verbose)
|
|
140 writefln("compile %s:", m.srcfile);
|
|
141 m.compile();
|
|
142 if (verbose)
|
|
143 writefln("execute %s:", m.srcfile);
|
|
144 m.execute();
|
|
145 }
|
|
146
|
|
147 return EXIT_SUCCESS;
|
|
148 }
|
|
149
|
|
150
|
|
151 class SrcFile
|
|
152 {
|
|
153 char[] srcfile;
|
|
154 char[][] includes;
|
|
155
|
|
156 Program program;
|
|
157 char[] buffer;
|
|
158
|
|
159 this(char[] srcfilename, char[][] includes)
|
|
160 {
|
|
161 /* DMDScript source files default to a '.ds' extension
|
|
162 */
|
|
163
|
|
164 srcfile = std.path.defaultExt(srcfilename, "ds");
|
|
165 this.includes = includes;
|
|
166 }
|
|
167
|
|
168 void read()
|
|
169 {
|
|
170 /* Read the source file, prepend the include files,
|
|
171 * and put it all in buffer[]. Allocate an extra byte
|
|
172 * to buffer[] and terminate it with a 0x1A.
|
|
173 * (If the 0x1A isn't at the end, the lexer will put
|
|
174 * one there, forcing an extra copy to be made of the
|
|
175 * source text.)
|
|
176 */
|
|
177
|
|
178 //writef("read file '%s'\n",srcfile);
|
|
179
|
|
180 // Read the includes[] files
|
|
181 size_t i;
|
|
182 void[] buf;
|
|
183 ulong len;
|
|
184
|
|
185 len = std.file.getSize(srcfile);
|
|
186 foreach (char[] filename; includes)
|
|
187 {
|
|
188 len += std.file.getSize(filename);
|
|
189 }
|
|
190 len++; // leave room for sentinal
|
|
191
|
|
192 assert(len < uint.max);
|
|
193
|
|
194 // Prefix the includes[] files
|
|
195
|
|
196 int sz = cast(int)len;
|
|
197 buffer = new tchar[sz];
|
|
198
|
|
199 foreach (char[] filename; includes)
|
|
200 {
|
|
201 buf = std.file.read(filename);
|
|
202 buffer[i .. i + buf.length] = cast(char[])buf[];
|
|
203 i += buf.length;
|
|
204 }
|
|
205
|
|
206 buf = std.file.read(srcfile);
|
|
207 buffer[i .. i + buf.length] = cast(char[])buf[];
|
|
208 i += buf.length;
|
|
209
|
|
210 buffer[i] = 0x1A; // ending sentinal
|
|
211 i++;
|
|
212 assert(i == len);
|
|
213 }
|
|
214
|
|
215 void compile()
|
|
216 {
|
|
217 /* Create a DMDScript program, and compile our text buffer.
|
|
218 */
|
|
219
|
|
220 program = new Program();
|
|
221 program.compile(srcfile, buffer, null);
|
|
222 }
|
|
223
|
|
224 void execute()
|
|
225 {
|
|
226 /* Execute the resulting program.
|
|
227 */
|
|
228
|
|
229 program.execute(null);
|
|
230 }
|
|
231 }
|