as3compile: added -R option, fixed some namespace bugs
[swftools.git] / src / as3compile.c
1 /* as3compile.c
2    Compiles ActionScript 3.0 (.as) files into .swf files.
3
4    Part of the swftools package.
5
6    Copyright (c) 2008/2009 Matthias Kramm <kramm@quiss.org>
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include "../lib/rfxswf.h"
28 #include "../lib/args.h"
29 #include "../lib/q.h"
30 #include "../lib/os.h"
31
32 static char * filename = 0;
33 static char * outputname = 0;
34 static int override_outputname = 0;
35 static int do_cgi = 0;
36 static double framerate = 25.0;
37 static double width = 400;
38 static double height = 300;
39 static int flashversion = 9;
40 static int verbose = 1;
41 static char local_with_networking = 0;
42 static char local_with_filesystem = 0;
43
44 static struct options_t options[] = {
45 {"h", "help"},
46 {"V", "version"},
47 {"v", "verbose"},
48 {"q", "quiet"},
49 {"C", "cgi"},
50 {"X", "width"},
51 {"Y", "height"},
52 {"r", "rate"},
53 {"l", "library"},
54 {"I", "include"},
55 {"T", "flashversion"},
56 {"R", "recurse"},
57 {"o", "output"},
58 {0,0}
59 };
60
61 int args_callback_option(char*name,char*val)
62 {
63     if(!strcmp(name, "V")) {
64         printf("swfc - part of %s %s\n", PACKAGE, VERSION);
65         exit(0);
66     }
67     else if(!strcmp(name, "o")) {
68         outputname = val;
69         override_outputname = 1;
70         return 1;
71     }
72     else if(!strcmp(name, "r")) {
73         framerate = atof(val);
74         return 1;
75     }
76     else if(!strcmp(name, "v")) {
77         verbose++;
78         return 0;
79     }
80     else if(!strcmp(name, "q")) {
81         verbose--;
82         return 0;
83     }
84     else if(!strcmp(name, "X")) {
85         width = atof(val);
86         return 1;
87     }
88     else if(!strcmp(name, "Y")) {
89         height = atof(val);
90         return 1;
91     }
92     else if(!strcmp(name, "T")) {
93         flashversion = atoi(val);
94         return 1;
95     }
96     else if(!strcmp(name, "C")) {
97         do_cgi = 1;
98         return 0;
99     }
100     else if(!strcmp(name, "l")) {
101         as3_import_file(val);
102         return 1;
103     }
104     else if(!strcmp(name, "I")) {
105         as3_add_include_dir(val);
106         return 1;
107     }
108     else if(!strcmp(name, "R")) {
109         as3_set_option("recurse","1");
110         return 0;
111     }
112     else if (!strcmp(name, "N"))
113     {
114         local_with_networking = 1;
115         return 0;
116     }
117     else if (!strcmp(name, "L"))
118     {
119         local_with_filesystem = 1;
120         return 0;
121     }
122     else {
123         printf("Unknown option: -%s\n", name);
124         exit(1);
125     }
126     return 0;
127 }
128 int args_callback_longoption(char*name,char*val)
129 {
130     return args_long2shortoption(options, name, val);
131 }
132 void args_callback_usage(char *name)
133 {
134     printf("\n");
135     printf("Usage: %s file.as [-o file.swf] \n", name);
136     printf("\n");
137     printf("-h , --help                    Print short help message and exit\n");
138     printf("-V , --version                 Print version info and exit\n");
139     printf("-v , --verbose                 Increase verbosity\n");
140     printf("-q , --quiet                   Decrease verbosity\n");
141     printf("-C , --cgi                     Output to stdout (for use in CGI environments)\n");
142     printf("-X , --width                   Set target SWF width\n");
143     printf("-Y , --height                  Set target SWF width\n");
144     printf("-r , --rate                    Set target SWF framerate\n");
145     printf("-l , --library <file>          Include library file <file>\n");
146     printf("-I , --include <dir>           Add include dir <dir>\n");
147     printf("-T , --flashversion <num>      Set target SWF flash version to <num>.\n");
148     printf("-o , --output <filename>       Set output file to <filename>.\n");
149     printf("\n");
150 }
151 int args_callback_command(char*name,char*val)
152 {
153     if(filename) {
154         fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
155                  filename, name);
156     }
157     filename = name;
158     return 0;
159 }
160
161 void writeSWF(SWF*swf)
162 {
163     int fi = -1;
164     if(do_cgi || !strcmp(filename, "-"))
165         fi = fileno(stdout);
166     else
167         fi = open(outputname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
168     if(fi<0) {
169         fprintf(stderr, "couldn't create output file %s\n", filename);
170         exit(1);
171     }
172     if(do_cgi) {
173         if(swf_WriteCGI(swf)<0) {
174             fprintf(stderr, "WriteCGI failed.\n");
175             exit(1);
176         }
177     } else {
178         if(swf_WriteSWF(fi, swf)<0) {
179             fprintf(stderr, "WriteSWF() failed.\n");
180             exit(1);
181         }
182     }
183 }
184
185 int main (int argc,char ** argv)
186 {
187     char buf[512];
188     char*currentdir = getcwd(buf, 512);
189     if(!currentdir) {
190         as3_warning("Could not determine the current directory");
191     } else {
192         as3_add_include_dir(currentdir);
193     }
194     registry_init();
195
196     int t;
197     processargs(argc, argv);
198     as3_setverbosity(verbose);
199
200     if(!filename) {
201         args_callback_usage(argv[0]);
202         exit(1);
203     }
204     if(!outputname) {
205         outputname = stripFilename(filename, ".swf");
206         //as3_warning("output name not given, writing to %s", outputname);
207     }
208
209     as3_parse_file(filename);
210     void*code = as3_getcode();
211
212     SWF swf;
213     memset(&swf, 0, sizeof(swf));
214     swf.fileVersion = flashversion;
215     swf.frameRate = framerate*0x100;
216     swf.movieSize.xmin = 0;
217     swf.movieSize.ymin = 0;
218     swf.movieSize.xmax = width*20;
219     swf.movieSize.ymax = height*20;
220     TAG*tag = swf.firstTag = swf_InsertTag(0, ST_DOABC);
221     swf_WriteABC(tag, code);
222
223     if(as3_getglobalclass()) {
224         tag = swf_InsertTag(tag, ST_SYMBOLCLASS);
225         swf_SetU16(tag, 1);
226         swf_SetU16(tag, 0);
227         swf_SetString(tag, as3_getglobalclass());
228     } else {
229         as3_warning("no global public MovieClip subclass");
230     }
231     
232     as3_destroy();
233
234     tag = swf_InsertTag(tag, ST_SHOWFRAME);
235     tag = swf_InsertTag(tag, ST_END);
236
237     swf_FreeABC(code);
238     
239     if(local_with_filesystem)
240         swf.fileAttributes &= ~FILEATTRIBUTE_USENETWORK;
241     if(local_with_networking)
242         swf.fileAttributes |= FILEATTRIBUTE_USENETWORK;
243
244     writeSWF(&swf);
245     swf_FreeTags(&swf);
246
247     return 0;
248 }
249