root/util/makeswf_utils.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- makeswf_append_cpparg
- makeswf_set_dopreprocess
- makeswf_set_swfversion
- makeswf_compile_source
- printCompileMessage
- compileError
- makeswf_readfile
- makeswf_preprocess
/****************************************************************************
*
* makeswf - a command line actionscript compiler
*
* Copyright (C) 2003-2009 "Sandro Santilli" <strk@keybit.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
****************************************************************************
*
* Utility functions for 'makeswf'
*
***************************************************************************/
/* This is needed to get vasprintf definition */
#define _GNU_SOURCE 1
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <ming.h>
#include "makeswf.h"
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
// Cheating, but it works (not sure why the above ifdef for getopt isn't)
#ifdef _WIN32
#include <getopt.h>
#endif
#define DEFSWFVERSION 6
#define DEFSWFCOMPRESSION 9
//#define CPP "cpp -P -C -Wall"
/* we don't need comments, do we ? */
#define CPP "cpp -xc++ -P -Wall"
#define MAXERRORMSG 1024
/* prototypes */
static int makeswf_preprocess (const char *file, const char *out);
static char *makeswf_readfile (const char *file);
static void compileError(const char *fmt, ...);
static void printCompileMessage(SWFMsgFunc);
/* data */
static char lastcompilemessage[MAXERRORMSG];
static int swfversion = DEFSWFVERSION;
#define MAXCPPARGS 1024
static char cppargs[MAXCPPARGS];
static int dopreprocess = 1; /* use preprocessor by default */
void
makeswf_append_cpparg(const char* buf)
{
strncat(cppargs, buf, MAXCPPARGS-1);
}
void
makeswf_set_dopreprocess(int value)
{
dopreprocess=value;
}
void
makeswf_set_swfversion(int value)
{
swfversion=value;
}
SWFAction
makeswf_compile_source(const char* filename, const char* ppfile, int debug)
{
SWFAction ac;
char *code;
char ppfile_fallback[PATH_MAX]; /* preprocessed file */
SWFMsgFunc old_error_func;
int length;
if ( dopreprocess )
{
if ( ! ppfile )
{
sprintf(ppfile_fallback, "%s.pp", filename);
ppfile = ppfile_fallback;
}
// TODO: make sure ppfile is writable
printf("Preprocessing %s... ", filename);
fflush(stdout);
if ( ! makeswf_preprocess(filename, ppfile) )
{
return NULL;
}
//unlink(ppfile);
filename = ppfile;
printf("done.\n");
}
if ( ! (code=makeswf_readfile(filename)) )
{
return NULL;
}
old_error_func = Ming_setErrorFunction(compileError);
printf("Compiling `%s'... ", filename);
ac = newSWFAction(code);
SWFAction_setDebug(ac, debug);
if (SWFAction_compile(ac, swfversion, &length))
{
printf("failed:\n");
printCompileMessage(old_error_func);
return NULL;
}
else
{
printf("successfully compiled %i bytes bytecode.\n", length);
}
free(code);
Ming_setErrorFunction(old_error_func);
return ac;
}
/*
* Should translate preprocessed file's line number to
* original file's line number (seems not so easy)
*/
static void
printCompileMessage(SWFMsgFunc func)
{
char *ptr1;
fprintf(stderr, " %s\n", strtok(lastcompilemessage, "\n"));
while ( (ptr1=strtok(NULL, "\n")) )
{
fprintf(stderr, " %s\n", ptr1);
}
func("\n");
}
/*
* This is here to handle line number reporting
* due to preprocessor scrambling of it
*/
static void
compileError(const char *fmt, ...)
{
char *msg;
va_list ap;
size_t msglen;
va_start (ap, fmt);
/*
* This is a GNU extension.
* Dunno how to handle errors here.
*/
if ( ! vasprintf(&msg, fmt, ap) )
{
fprintf(stderr, "vasnprintf allocated 0 bytes\n");
va_end(ap);
return;
}
va_end(ap);
msglen = strlen(msg);
if ( msglen > MAXERRORMSG-1 ) msglen = MAXERRORMSG-1;
memcpy(lastcompilemessage, msg, msglen);
free(msg);
lastcompilemessage[MAXERRORMSG-1] = '\0';
return;
}
static char *
makeswf_readfile (const char *file)
{
FILE *fd;
struct stat buf;
int size;
char *ret;
fd = fopen(file, "r");
if ( ! fd )
{
perror(file);
return NULL;
}
fstat(fileno(fd), &buf);
size = buf.st_size;
ret = (char *) malloc( size+1 );
if ( ! ret )
{
perror("readfile");
return NULL;
}
memset(ret, '\0', size+1);
if(fread(ret, 1, size, fd) != size)
{
fprintf(stderr, "makeswf_readfile: failed\n");
fclose(fd);
return NULL;
}
fclose(fd);
return ret;
}
static int
makeswf_preprocess (const char *file, const char *out)
{
char buf[1024];
int ret;
struct stat statbuf;
if ( -1 == stat(file, &statbuf) )
{
perror(file);
exit(EXIT_FAILURE);
}
sprintf(buf, "%s -D__SWF_VERSION__=%d %s %s > %s", CPP,
swfversion, cppargs, file, out);
/*printf("preprocess[%s]\n", buf);*/
ret = system(buf);
if ( ret )
{
exit(EXIT_FAILURE);
}
return 1;
}
/**************************************************************
*
* $Log: makeswf_utils.c,v $
* Revision 1.13 2009/09/08 22:26:17 strk
* Update copyright notice (and FSF address)
*
* Revision 1.12 2008/10/13 21:57:19 krechert
* fix warning
*
* Revision 1.11 2008/06/26 19:36:12 krechert
* fix linker error and make enabling SWFAction's debug mode generic
*
* Revision 1.10 2007/12/17 17:28:26 strk
* Check existance of input file before attempting to preprocess it
*
* Revision 1.9 2007/11/02 10:18:08 krechert
* fix warnings
*
* Revision 1.8 2007/10/31 16:53:29 krechert
* x
*
* Revision 1.7 2007/10/27 15:12:58 krechert
* pass through real swf version
*
* Revision 1.6 2007/10/27 15:03:14 krechert
* handle compile errors. do not output empty swf files
*
* Revision 1.5 2007/04/30 09:58:32 strk
* Don't include getopt.h if it's not found. Patch by Nils Goroll <nils.goroll@mcs.de>.
*
* Revision 1.4 2007/04/14 16:58:46 strk
* Removed unused CPP define from makeswf.c, fix the *used* one in makeswf_utils.
* Thanks to Bastiaan Jacques for finding this out.
*
* Revision 1.3 2007/03/22 10:59:20 strk
* Updated to use newSWFAction() instead of compileSWFActionCode()
*
* Revision 1.2 2006/07/10 16:11:26 strk
* Changed makeswf_compile_source signature to accept path to preprocessor output file. Changed preprocessed file paths to (<output>.frame#.pp) to reduce probability of filesystem permission problems.
*
* Revision 1.1 2006/07/08 13:47:18 strk
* Split makeswf general functionalities in a separate file, for use by unit testers
*
*
**************************************************************/