⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compile.c

📁 Ming is a library for generating Macromedia Flash files (.swf), written in C, and includes useful ut
💻 C
📖 第 1 页 / 共 2 页
字号:
	bufferWriteS16(out, 1);	bufferWriteU8(out, num);	return 4;}void lower(char *s){	while(*s)	{		*s = tolower(*s);		++s;	}}/* this code will eventually help to pop extra values off the stack and make sure that continue and break address the proper context */static enum ctx *ctx_stack = {0};static int ctx_count = {0}, ctx_len = {0};void addctx(enum ctx val){		if(ctx_count >= ctx_len)		ctx_stack = (enum ctx*) realloc(ctx_stack, (ctx_len += 10) * sizeof(enum ctx));	ctx_stack[ctx_count++] = val;}void delctx(enum ctx val){		if(ctx_count <= 0)  		SWF_error("consistency check in delctx: stack empty!\n");	else if (ctx_stack[--ctx_count] != val)		SWF_error("consistency check in delctx: val %i != %i\n", ctx_stack[ctx_count], val);}int chkctx(enum ctx val){	int n, ret = 0;	switch(val)	{	case CTX_FUNCTION:			for(n = ctx_count ; --n >= 0 ; )				switch(ctx_stack[n])				{	case CTX_SWITCH:					case CTX_FOR_IN:						ret++;						break;					case CTX_FUNCTION:						return ret;					default: ; /* computers are stupid */				}			return -1;		case CTX_BREAK:			for(n = ctx_count ; --n >= 0 ; )				switch(ctx_stack[n])				{	case CTX_SWITCH:						return CTX_SWITCH;					case CTX_LOOP:						return CTX_LOOP;					case CTX_FOR_IN:						return CTX_FOR_IN;					case CTX_FUNCTION:						return -1;					case CTX_BREAK:						return CTX_BREAK;					default: ; /* computers are stupid */				}			return -1;		case CTX_CONTINUE:			for(n = ctx_count ; --n >= 0 ; )				switch(ctx_stack[n])				{	case CTX_LOOP:					case CTX_FOR_IN:						return 0;					case CTX_FUNCTION:						return -1;					default: ; /* computers are stupid */				}		default: return -1;; /* computers are stupid */	}}/* replace MAGIC_CONTINUE_NUMBER and MAGIC_BREAK_NUMBER with jumps to	 head or tail, respectively *//* jump offset is relative to end of jump instruction *//* I can't believe this actually worked */void bufferResolveJumpsFull(Buffer out, byte *break_ptr, byte *continue_ptr){	byte *p = out->buffer;	int l, target;	while(p < out->pos)	{		if(*p & 0x80) /* then it's a multibyte instruction */		{			if(*p == SWFACTION_JUMP)			{	p += 3; /* plus instruction plus two-byte length */	if(*p == MAGIC_CONTINUE_NUMBER_LO &&		 *(p+1) == MAGIC_CONTINUE_NUMBER_HI)	{		target = continue_ptr - (p+2);		*p = target & 0xff;		*(p+1) = (target>>8) & 0xff;	}	else if(*p == MAGIC_BREAK_NUMBER_LO &&		*(p+1) == MAGIC_BREAK_NUMBER_HI)	{		target = break_ptr - (p+2);		*p = target & 0xff;		*(p+1) = (target>>8) & 0xff;	}	p += 2;			}			else			{	++p;	l = *p;	++p;	l += *p<<8;	++p;	p += l;			}		}		else			++p;	}}// handle SWITCH statementvoid bufferResolveSwitch(Buffer buffer, struct switchcases *slp){	struct switchcase *scp;	int n, len;	unsigned char *output;				len = bufferLength(buffer);	for(n = 0, scp = slp->list ; n < slp->count ; n++, scp++)	{	scp->actlen = bufferLength(scp->action);		if((n < slp->count-1))			scp->actlen += 5;		if(scp->cond)		{	scp->condlen = bufferLength(scp->cond) + 8;			bufferWriteOp(buffer, SWFACTION_PUSHDUP);			bufferConcat(buffer, scp->cond);			bufferWriteOp(buffer, SWFACTION_EQUALS2);			bufferWriteOp(buffer, SWFACTION_LOGICALNOT);			bufferWriteOp(buffer, SWFACTION_IF);			bufferWriteS16(buffer, 2);			bufferWriteS16(buffer, scp->actlen);		}		else			scp->condlen = 0;		bufferConcat(buffer, scp->action);		bufferWriteOp(buffer, SWFACTION_JUMP);		bufferWriteS16(buffer, 2);		bufferWriteS16(buffer, scp->isbreak ? MAGIC_BREAK_NUMBER : 0);		if(!scp->cond)		{	slp->count = n+1;			break;		}	}	for(n = 0, scp = slp->list ; n < slp->count ; n++, scp++)	{	len += scp->condlen;		output = buffer->buffer + len;		if((n < slp->count-1) && !scp->isbreak)		{	output[scp->actlen-2] = (scp+1)->condlen & 0xff;			output[scp->actlen-1] = (scp+1)->condlen >> 8;		}		len += scp->actlen;	}}	int lookupProperty(char *string){	lower(string);	if(strcmp(string, "_x") == 0)		return PROPERTY_X;	if(strcmp(string, "_y") == 0)		return PROPERTY_Y;	if(strcmp(string, "_xscale") == 0)	return PROPERTY_XSCALE;	if(strcmp(string, "_yscale") == 0)	return PROPERTY_YSCALE;	if(strcmp(string, "_currentframe") == 0) return PROPERTY_CURRENTFRAME;	if(strcmp(string, "_totalframes") == 0)	return PROPERTY_TOTALFRAMES;	if(strcmp(string, "_alpha") == 0)	return PROPERTY_ALPHA;	if(strcmp(string, "_visible") == 0)	return PROPERTY_VISIBLE;	if(strcmp(string, "_width") == 0)	return PROPERTY_WIDTH;	if(strcmp(string, "_height") == 0)	return PROPERTY_HEIGHT;	if(strcmp(string, "_rotation") == 0)	return PROPERTY_ROTATION;	if(strcmp(string, "_target") == 0)	return PROPERTY_TARGET;	if(strcmp(string, "_framesloaded") == 0)	return PROPERTY_FRAMESLOADED;	if(strcmp(string, "_name") == 0)		return PROPERTY_NAME;	if(strcmp(string, "_droptarget") == 0)	return PROPERTY_DROPTARGET;	if(strcmp(string, "_url") == 0)		return PROPERTY_URL;	if(strcmp(string, "_highquality") == 0)	return PROPERTY_HIGHQUALITY;	if(strcmp(string, "_focusrect") == 0)	return PROPERTY_FOCUSRECT;	if(strcmp(string, "_soundbuftime") == 0)	return PROPERTY_SOUNDBUFTIME;	if(strcmp(string, "_quality")==0)	return PROPERTY_QUALITY;	if(strcmp(string, "_xmouse") == 0)	return PROPERTY_XMOUSE;	if(strcmp(string, "_ymouse") == 0)	return PROPERTY_YMOUSE;	SWF_error("No such property: %s\n", string);	return -1;}int bufferWriteProperty(Buffer out, char *string){	int property = lookupProperty(string);	return bufferWriteFloat(out, property);}// XXX: ???int bufferWriteWTHITProperty(Buffer out){	bufferWriteU8(out, SWFACTION_PUSH);	bufferWriteS16(out, 5);	bufferWriteU8(out, PUSH_FLOAT);	bufferWriteS16(out, 0);	bufferWriteS16(out, 0x4680);	return 8;}/** * @param func_name * 	Function name, NULL for anonymous functions. * * @param num_regs * 	Number of registers. * * @param flags * 	See SWFDefineFunction2Flags enum. */static int bufferWriteDefineFunction2(Buffer out, char *func_name, 		Buffer args, Buffer code, int flags, int num_regs){	Buffer c;	char buf[1024];	int num_args = 0, i;	char *p = (char *) args->buffer;	size_t taglen;		strcpy(buf, "");			// REGISTERPARAM records	c = newBuffer();	// TODO: rewrite this function, all these calls to strncat	//       seem overkill to me	for(i = 0; i < bufferLength(args); i++)	{		if(p[i] == '\0')		{			bufferWriteU8(c, 0);			bufferWriteHardString(c, buf, strlen(buf)+1);				strcpy(buf, "");			num_args++;		}		else		{			strncat(buf, &p[i], 1);		}	}	bufferWriteOp(out, SWFACTION_DEFINEFUNCTION2);	if(func_name == NULL)	{		taglen =			+ 1			/* function name (empty) */			+ 2			/* arg count (short) */			+ 1			/* reg count (byte) */			+ 2			/* flags */			+ bufferLength(c)	/* swf_params */			+ 2 			/* body size */			;#ifdef MING_DEBUG_FUNCTION2		printf("adding anonymouse SWF_DEFINEFUNCTION2 nargs=%d flags=%d"				" arglen=%d codelen=%d taglen=%d\n",				num_args, flags, bufferLength(args),				bufferLength(code), taglen);#endif		bufferWriteS16(out, taglen);		bufferWriteU8(out, 0); /* empty function name */	}	else	{		taglen = 0			+ strlen(func_name)+1	/* function name */			+ 2			/* arg count (short) */			+ 1			/* reg count (byte) */			+ 2			/* flags */			+ bufferLength(c)	/* swf_params */			+ 2 			/* body size */			;#ifdef MING_DEBUG_FUNCTION2		printf("adding named SWF_DEFINEFUNCTION2 name=%s nargs=%d flags=%d"				" regparamlen=%d arglen=%d codelen=%d taglen=%d\n",				func_name, num_args, flags,				bufferLength(c),				bufferLength(args),				bufferLength(code), taglen);#endif		bufferWriteS16(out, taglen);		bufferWriteHardString(out, func_name, strlen(func_name)+1);	 	}	bufferWriteS16(out, num_args); /* number of params */ 	bufferWriteU8(out, num_regs); /* register count */ 	bufferWriteS16(out, flags);    /* flags */ 	//bufferWriteS16(out, 0);    /* flags */ 	bufferConcat(out, c);	bufferWriteS16(out, bufferLength(code)); /* code size */	bufferConcat(out, code);	return taglen;}void destroyASFunction(ASFunction func){	free(func->name);	free(func);}int bufferWriteFunction(Buffer out, ASFunction function, int version){	int tagLen; 		if(version == 2)	{		tagLen = bufferWriteDefineFunction2(out, function->name, 			function->params.buffer, function->code, function->flags, 0);	}	else	{		tagLen = 5; 		tagLen += bufferLength(function->params.buffer);		if(function->name != NULL)			tagLen += strlen(function->name); 			bufferWriteOp(out, SWFACTION_DEFINEFUNCTION);		bufferWriteS16(out, tagLen);		if(function->name == NULL) 			bufferWriteU8(out, 0); /* empty function name */		else			bufferWriteHardString(out, function->name, strlen(function->name) +1 );		bufferWriteS16(out, function->params.count);		bufferConcat(out, function->params.buffer);		bufferWriteS16(out, bufferLength(function->code));		bufferConcat(out, function->code);	}	destroyASFunction(function);	return tagLen;}ASFunction newASFunction(){	ASFunction func;	func = (ASFunction) malloc(sizeof(struct function_s));	func->flags = 0;	func->code = NULL;	func->params.count = 0;	func->params.buffer = NULL;	func->name = NULL;	return func;}void destroyASClass(ASClass clazz){	ASClassMember member;	if(clazz->name)		free(clazz->name);		member = clazz->members;	while(member)	{			ASClassMember _this = member;		member = member->next;		free(_this);	}	free(clazz);}ASFunction ASClass_getConstructor(ASClass clazz){	ASClassMember member;	member = clazz->members;	while(member)	{		ASFunction func;		ASClassMember _this = member;		member = member->next;		if(_this->type != METHOD)			continue;		func = _this->element.function;		if(!func || !func->name)			continue;		if(strcmp(func->name, clazz->name) != 0)			continue;				_this->element.function = NULL;		return func;	}	return newASFunction(); // default empty constructor}static int bufferWriteClassConstructor(Buffer out, ASClass clazz){	int len = 0;	ASFunction func;	/* class constructor */	len += bufferWriteString(out, "_global", strlen("_global") + 1);	len += bufferWriteOp(out, SWFACTION_GETVARIABLE);	len += bufferWriteString(out, clazz->name, strlen(clazz->name) + 1);	func = ASClass_getConstructor(clazz);	if(func->name)	{		free(func->name);		func->name = NULL;	}	len += bufferWriteFunction(out, func, 1);	len += bufferWriteSetRegister(out, 1);	len += bufferWriteOp(out, SWFACTION_SETMEMBER);		len += bufferWriteRegister(out, 1);	len += bufferWriteString(out, "prototype", strlen("prototype") + 1);	len += bufferWriteOp(out, SWFACTION_GETMEMBER);	len += bufferWriteSetRegister(out, 2);		len += bufferWriteOp(out, SWFACTION_POP);	return len;}static int bufferWriteClassMethods(Buffer out, ASClass clazz){	ASClassMember member = clazz->members;	int len = 0;	while(member)	{		ASFunction func;		ASClassMember _this = member;		member = member->next;		if(_this->type != METHOD)			continue;		func = _this->element.function;		if(!func || !func->name)			continue;			if(strcmp(func->name, clazz->name) != 0)		{			SWF_error("only one class constructor allowed\n");		}			len += bufferWriteRegister(out, 2);		len += bufferWriteString(out, func->name, strlen(func->name) + 1);		free(func->name);		func->name = NULL;		len += bufferWriteFunction(out, func, 1);		len += bufferWriteOp(out, SWFACTION_SETMEMBER);		_this->element.function = NULL;	}	return len;}static int bufferWriteClassVariable(Buffer out, ASVariable var){	int len = 0;	if(var->initCode != NULL)	{		len += bufferWriteRegister(out, 2);		len += bufferWriteString(out, var->name, strlen(var->name)+1);		len += bufferConcat(out, var->initCode);		len += bufferWriteOp(out, SWFACTION_SETMEMBER); 	}	free(var->name);	free(var); // aka destroyASVariable	return len;}static int bufferWriteClassMembers(Buffer out, ASClass clazz){	ASClassMember member = clazz->members;	int len = 0;	while(member)	{		ASVariable var;		ASClassMember _this = member;		member = member->next;		if(_this->type != VARIABLE)			continue;		var = _this->element.var;		if(!var)			continue;		bufferWriteClassVariable(out, var);			_this->element.var = NULL;	}	return len;}int bufferWriteClass(Buffer out, ASClass clazz){	int len = 0;	len += bufferWriteClassConstructor(out, clazz);	len += bufferWriteClassMembers(out, clazz);		len += bufferWriteClassMethods(out, clazz);	/* set class properties */	len += bufferWriteInt(out, 1);	len += bufferWriteNull(out);	len += bufferWriteString(out, "_global", strlen("_global") + 1);	len += bufferWriteOp(out, SWFACTION_GETVARIABLE);	len += bufferWriteString(out, clazz->name, strlen(clazz->name) + 1);	len += bufferWriteOp(out, SWFACTION_GETMEMBER);	len += bufferWriteString(out, "prototype", strlen("prototype") + 1);	len += bufferWriteOp(out, SWFACTION_GETMEMBER);			len += bufferWriteInt(out, 3);	len += bufferWriteString(out, "ASSetPropFlags", strlen("ASSetPropFlags") + 1);	len += bufferWriteOp(out, SWFACTION_CALLFUNCTION);	len += bufferWriteOp(out, SWFACTION_POP);	destroyASClass(clazz);	return len;}void ASClassMember_append(ASClassMember m0, ASClassMember end){	ASClassMember mb = m0;	while(mb->next)		mb = mb->next;	mb->next = end;}ASClass newASClass(char *name, ASClassMember members){	ASClass clazz;	clazz = (ASClass) malloc(sizeof(struct class_s));	clazz->name = name;	clazz->members = members;	return clazz;	}ASClassMember newASClassMember_function(ASFunction func){	ASClassMember member = (ASClassMember) malloc(sizeof(struct class_member_s));	member->element.function = func;	member->type = METHOD;	member->next = NULL; 	return member;}ASClassMember newASClassMember_variable(ASVariable var){	ASClassMember member = (ASClassMember) malloc(sizeof(struct class_member_s));	member->element.var = var;	member->type = VARIABLE;	member->next = NULL; 	return member;}ASClassMember newASClassMember_buffer(Buffer buf){	ASClassMember member = (ASClassMember) malloc(sizeof(struct class_member_s));	member->element.buffer = buf;	member->type = BUFF;	member->next = NULL; 	return member;}ASVariable newASVariable(char *name, Buffer buf){	ASVariable var = (ASVariable) malloc(sizeof(struct variable_s));	var->name = name;	var->initCode = buf;	return var;}/* * Local variables: * tab-width: 2 * c-basic-offset: 2 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -