fix crashes reported by Debian Cylab Mayhem Team
[swftools.git] / src / as3compile.c
blobc5f57c140eb52a228252a7970b9228935fbdd7f3
1 /* as3compile.c
2 Compiles ActionScript 3.0 (.as) files into .swf files.
4 Part of the swftools package.
6 Copyright (c) 2008/2009 Matthias Kramm <kramm@quiss.org>
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.
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.
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 */
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"
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 static char*mainclass = 0;
45 static struct options_t options[] = {
46 {"h", "help"},
47 {"V", "version"},
48 {"v", "verbose"},
49 {"q", "quiet"},
50 {"C", "cgi"},
51 {"R", "resolve"},
52 {"D", "define"},
53 {"X", "width"},
54 {"Y", "height"},
55 {"r", "rate"},
56 {"M", "mainclass"},
57 {"l", "library"},
58 {"I", "include"},
59 {"N", "local-with-network"},
60 {"L", "local-with-filesystem"},
61 {"T", "flashversion"},
62 {"o", "output"},
63 {0,0}
66 int args_callback_option(char*name,char*val)
68 if(!strcmp(name, "V")) {
69 printf("swfc - part of %s %s\n", PACKAGE, VERSION);
70 exit(0);
72 else if(!strcmp(name, "o")) {
73 outputname = val;
74 override_outputname = 1;
75 return 1;
77 else if(!strcmp(name, "r")) {
78 framerate = atof(val);
79 return 1;
81 else if(!strcmp(name, "M")) {
82 mainclass = val;
83 return 1;
85 else if(!strcmp(name, "v")) {
86 verbose++;
87 return 0;
89 else if(!strcmp(name, "q")) {
90 verbose--;
91 return 0;
93 else if(!strcmp(name, "X")) {
94 width = atof(val);
95 return 1;
97 else if(!strcmp(name, "Y")) {
98 height = atof(val);
99 return 1;
101 else if(!strcmp(name, "T")) {
102 flashversion = atoi(val);
103 return 1;
105 else if(!strcmp(name, "C")) {
106 do_cgi = 1;
107 return 0;
109 else if(!strcmp(name, "l")) {
110 as3_import_file(val);
111 return 1;
113 else if(!strcmp(name, "I")) {
114 as3_add_include_dir(val);
115 return 1;
117 else if(!strcmp(name, "R")) {
118 as3_set_option("recurse","1");
119 return 0;
121 else if(!strcmp(name, "D")) {
122 if(!strstr(val, "::")) {
123 fprintf(stderr, "Error: compile definition must contain \"::\"\n");
124 exit(1);
126 as3_set_define(val);
127 return 1;
129 else if (!strcmp(name, "N"))
131 local_with_networking = 1;
132 return 0;
134 else if (!strcmp(name, "L"))
136 local_with_filesystem = 1;
137 return 0;
139 else {
140 printf("Unknown option: -%s\n", name);
141 exit(1);
143 return 0;
145 int args_callback_longoption(char*name,char*val)
147 return args_long2shortoption(options, name, val);
149 void args_callback_usage(char *name)
151 printf("\n");
152 printf("Usage: %s file.as [-o file.swf] \n", name);
153 printf("\n");
154 printf("-h , --help Print short help message and exit\n");
155 printf("-V , --version Print version info and exit\n");
156 printf("-v , --verbose Increase verbosity\n");
157 printf("-q , --quiet Decrease verbosity\n");
158 printf("-C , --cgi Output to stdout (for use in CGI environments)\n");
159 printf("-R , --resolve Try to resolve undefined classes automatically.\n");
160 printf("-D , --define <namespace::variable> Set a compile time variable (for doing conditional compilation)\n");
161 printf("-X , --width Set target SWF width\n");
162 printf("-Y , --height Set target SWF width\n");
163 printf("-r , --rate Set target SWF framerate\n");
164 printf("-M , --mainclass Set the name of the main class (extending flash.display.MovieClip)\n");
165 printf("-l , --library <file> Include library file <file>. <file> can be an .abc or .swf file.\n");
166 printf("-I , --include <dir> Add additional include dir <dir>.\n");
167 printf("-N , --local-with-network Make output file \"local with networking\"\n");
168 printf("-L , --local-with-filesystem Make output file \"local with filesystem\"\n");
169 printf("-T , --flashversion <num> Set target SWF flash version to <num>.\n");
170 printf("-o , --output <filename> Set output file to <filename>.\n");
171 printf("\n");
173 int args_callback_command(char*name,char*val)
175 if(filename) {
176 fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
177 filename, name);
179 filename = name;
180 return 0;
183 void writeSWF(SWF*swf)
185 int fi = -1;
186 if(do_cgi || !strcmp(filename, "-"))
187 fi = fileno(stdout);
188 else
189 fi = open(outputname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
190 if(fi<0) {
191 fprintf(stderr, "couldn't create output file %s\n", filename);
192 exit(1);
194 if(do_cgi) {
195 if(swf_WriteCGI(swf)<0) {
196 fprintf(stderr, "WriteCGI failed.\n");
197 exit(1);
199 } else {
200 if(swf_WriteSWF(fi, swf)<0) {
201 fprintf(stderr, "WriteSWF() failed.\n");
202 exit(1);
207 int main (int argc,char ** argv)
209 char buf[512];
210 char*currentdir = getcwd(buf, 512);
211 if(!currentdir) {
212 as3_warning("Could not determine the current directory");
213 } else {
214 as3_add_include_dir(currentdir);
217 int t;
218 processargs(argc, argv);
219 as3_setverbosity(verbose);
221 if(!filename) {
222 args_callback_usage(argv[0]);
223 exit(1);
225 if(!outputname) {
226 outputname = stripFilename(filename, ".swf");
227 //as3_warning("output name not given, writing to %s", outputname);
230 if(!strcmp(filename, ".")) {
231 as3_parse_directory(".");
232 } else {
233 as3_parse_file(filename);
236 void*code = as3_getcode();
238 SWF swf;
239 memset(&swf, 0, sizeof(swf));
240 swf.fileVersion = flashversion;
241 swf.frameRate = framerate*0x100;
242 swf.movieSize.xmin = 0;
243 swf.movieSize.ymin = 0;
244 swf.movieSize.xmax = width*20;
245 swf.movieSize.ymax = height*20;
246 TAG*tag = swf.firstTag = swf_InsertTag(0, ST_DOABC);
247 swf_WriteABC(tag, code);
249 if(!mainclass)
250 mainclass = as3_getglobalclass();
251 if(mainclass) {
252 tag = swf_InsertTag(tag, ST_SYMBOLCLASS);
253 swf_SetU16(tag, 1);
254 swf_SetU16(tag, 0);
255 swf_SetString(tag, mainclass);
256 } else {
257 as3_warning("no global public MovieClip subclass");
260 as3_destroy();
262 tag = swf_InsertTag(tag, ST_SHOWFRAME);
263 tag = swf_InsertTag(tag, ST_END);
265 swf_FreeABC(code);
267 if(local_with_filesystem)
268 swf.fileAttributes &= ~FILEATTRIBUTE_USENETWORK;
269 if(local_with_networking)
270 swf.fileAttributes |= FILEATTRIBUTE_USENETWORK;
272 writeSWF(&swf);
273 swf_FreeTags(&swf);
275 return 0;