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

📄 gencode.c

📁 这是关于RFC3261实现sip的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * The code generator module for SIP. * * Copyright (c) 2006 * 	Riverbank Computing Limited <info@riverbankcomputing.co.uk> *  * This file is part of SIP. *  * This copy of SIP is licensed for use under the terms of the SIP License * Agreement.  See the file LICENSE for more details. *  * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */#include <stdio.h>#include <time.h>#include <errno.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include "sip.h"/* Control what generateSingleArg() actually generates. */typedef enum {	Call,	Declaration,	Definition} funcArgType;/* An entry in the sorted array of methods. */typedef struct {	memberDef	*md;		/* The method. */	int		is_static;	/* Set if all overloads are static. */} sortedMethTab;/* An API definition. */typedef struct _apiDef {	char		*name;		/* The function name. */	signatureDef	*sd;		/* The function signature. */	struct _apiDef	*next;		/* The next in the list. */} apiDef;static int currentLineNr;		/* Current output line number. */static char *currentFileName;		/* Current output file name. */static int previousLineNr;		/* Previous output line number. */static char *previousFileName;		/* Previous output file name. */static int exceptions;			/* Set if exceptions are enabled. */static int tracing;			/* Set if tracing is enabled. */static int generating_c;		/* Set if generating C. */static int release_gil;			/* Set if always releasing the GIL. */static char *prcode_last = NULL;	/* The last prcode format string. */static void generateDocumentation(sipSpec *,char *);static void generateAPI(sipSpec *,char *);static void generateBuildFile(sipSpec *,char *,char *,int);static void generateInternalAPIHeader(sipSpec *,char *,stringList *);static void generateCpp(sipSpec *,char *,char *,int *);static void generateIfaceCpp(sipSpec *,ifaceFileDef *,char *,char *,FILE *);static void generateMappedTypeCpp(mappedTypeDef *,FILE *);static void generateImportedMappedTypeHeader(mappedTypeDef *mtd,sipSpec *pt,					     FILE *fp);static void generateMappedTypeHeader(mappedTypeDef *,int,FILE *);static void generateClassCpp(classDef *cd, sipSpec *pt, FILE *fp);static void generateImportedClassHeader(classDef *cd,sipSpec *pt,FILE *fp);static void generateClassTableEntries(sipSpec *pt, nodeDef *nd, FILE *fp);static void generateClassHeader(classDef *,int,sipSpec *,FILE *);static void generateClassFunctions(sipSpec *,classDef *,FILE *);static void generateShadowCode(sipSpec *,classDef *,FILE *);static void generateFunction(sipSpec *,memberDef *,overDef *,classDef *,			     classDef *,FILE *);static void generateFunctionBody(sipSpec *,overDef *,classDef *,classDef *,				 int deref,FILE *);static void generateTypeDefinition(sipSpec *pt, classDef *cd, FILE *fp);static void generateTypeInit(sipSpec *,classDef *,FILE *);static void generateCppCodeBlock(codeBlock *,FILE *);static void generateUsedIncludes(ifaceFileList *, int, FILE *);static void generateIfaceHeader(sipSpec *,ifaceFileDef *,char *);static void generateShadowClassDeclaration(sipSpec *,classDef *,FILE *);static void generateResultType(argDef *,FILE *);static int hasConvertToCode(argDef *ad);static void deleteTemps(signatureDef *sd, FILE *fp);static void gc_ellipsis(signatureDef *sd, FILE *fp);static void generateArgs(signatureDef *,funcArgType,FILE *);static void generateVariable(argDef *,int,FILE *);static void generateNamedValueType(argDef *,char *,FILE *);static void generateSingleArg(argDef *,int,funcArgType,FILE *);static void generateBaseType(argDef *,FILE *);static void generateNamedBaseType(argDef *,char *,FILE *);static void generateExpression(valueDef *,FILE *);static void generateTupleBuilder(signatureDef *,FILE *);static void generateEmitters(sipSpec *pt, classDef *cd, FILE *fp);static void generateEmitter(sipSpec *,classDef *,visibleList *,FILE *);static void generateVirtualHandler(sipSpec *,virtHandlerDef *,FILE *);static void generateVirtHandlerErrorReturn(argDef *res,FILE *fp);static void generateVirtualCatcher(sipSpec *,classDef *,int,virtOverDef *,				   FILE *);static void generateUnambiguousClass(classDef *cd,classDef *scope,FILE *fp);static void generateProtectedEnums(sipSpec *,classDef *,FILE *);static void generateProtectedDeclarations(classDef *,FILE *);static void generateProtectedDefinitions(classDef *,FILE *);static void generateProtectedCallArgs(overDef *od, FILE *fp);static void generateConstructorCall(classDef *,ctorDef *,int,FILE *);static void generateHandleResult(overDef *,int,char *,FILE *);static void generateOrdinaryFunction(sipSpec *,classDef *,memberDef *,FILE *);static void generateSimpleFunctionCall(fcallDef *,FILE *);static void generateFunctionCall(classDef *cd,classDef *ocd,overDef *od,				 int deref, FILE *fp);static void generateCppFunctionCall(classDef *cd,classDef *ocd,overDef *od,				    FILE *fp);static void generateSlotArg(signatureDef *sd, int argnr, FILE *fp);static void generateBinarySlotCall(overDef *od, char *op, int deref, FILE *fp);static void generateNumberSlotCall(overDef *od, char *op, FILE *fp);static void generateVariableHandler(varDef *,FILE *);static int generateObjToCppConversion(argDef *,FILE *);static void generateVarClassConversion(varDef *,FILE *);static void generateVarMember(varDef *vd, FILE *fp);static int generateVoidPointers(sipSpec *,classDef *,FILE *);static int generateChars(sipSpec *,classDef *,FILE *);static int generateStrings(sipSpec *,classDef *,FILE *);static sortedMethTab *createFunctionTable(classDef *,int *);static sortedMethTab *createMethodTable(classDef *,int *);static int generateMethodTable(classDef *,FILE *);static void generateEnumMacros(sipSpec *pt, classDef *cd, FILE *fp);static int generateEnumMemberTable(sipSpec *,classDef *,FILE *);static int generateInts(sipSpec *,classDef *,FILE *);static int generateLongs(sipSpec *,classDef *,FILE *);static int generateUnsignedLongs(sipSpec *,classDef *,FILE *);static int generateLongLongs(sipSpec *,classDef *,FILE *);static int generateUnsignedLongLongs(sipSpec *,classDef *,FILE *);static int generateVariableType(sipSpec *pt, classDef *cd, argType atype, const char *eng, const char *s1, const char *s2, FILE *fp);static int generateDoubles(sipSpec *,classDef *,FILE *);static int generateEnums(sipSpec *,classDef *,FILE *);static int generateClasses(sipSpec *,classDef *,FILE *);static void generateEnumsInline(sipSpec *,FILE *);static void generateClassesInline(sipSpec *,FILE *);static void generateAccessFunctions(sipSpec *,classDef *,FILE *);static void generateConvertToDefinitions(mappedTypeDef *,classDef *,FILE *);static void generateEncodedClass(sipSpec *,classDef *,int,FILE *);static int generateArgParser(sipSpec *, signatureDef *, classDef *, ctorDef *,			     overDef *, int, FILE *);static void generateTry(throwArgs *,FILE *);static void generateCatch(throwArgs *ta, signatureDef *sd, FILE *fp);static void generateThrowSpecifier(throwArgs *,FILE *);static void generateSlot(sipSpec *pt, classDef *cd, enumDef *ed, memberDef *md, FILE *fp);static void generateCastZero(argDef *ad,FILE *fp);static void generateCallDefaultCtor(ctorDef *ct,FILE *fp);static void addUniqueAPI(apiDef **,char *,signatureDef *);static int countVirtuals(classDef *);static int skipOverload(overDef *,memberDef *,classDef *,classDef *,int);static int compareMethTab(const void *,const void *);static int compareEnumMembers(const void *,const void *);static char *getSubFormatChar(char,argDef *);static char *createIfaceFileName(char *,ifaceFileDef *,char *);static FILE *createFile(sipSpec *,char *,char *);static void closeFile(FILE *);static void prcode(FILE *,char *,...);static void prScopedName(FILE *,scopedNameDef *,char *);static void prScopedPythonName(FILE *fp, classDef *scope, char *pyname);static void prTypeName(FILE *,argDef *,int);static void prScopedClassName(FILE *,classDef *,char *);static int isZeroArgSlot(memberDef *md);static int isMultiArgSlot(memberDef *md);static int isIntArgSlot(memberDef *md);static int isInplaceNumberSlot(memberDef *md);static int isInplaceSequenceSlot(memberDef *md);static int needErrorFlag(codeBlock *cb);static int needNewInstance(argDef *ad);static int needDealloc(classDef *cd);static char getBuildResultFormat(argDef *ad);static const char *getParseResultFormat(argDef *ad, int isres, int xfervh);static void generateParseResultExtraArgs(argDef *ad, int isres, FILE *fp);static char *makePartName(char *codeDir,char *mname,int part,char *srcSuffix);static void normaliseArgs(signatureDef *);static void restoreArgs(signatureDef *);static const char *slotName(slotType st);static void ints_intro(classDef *cd, FILE *fp);static const char *argName(const char *name, codeBlock *cb);static int usedInCode(codeBlock *code, const char *str);static void generateDefaultValue(argDef *ad, int argnr, FILE *fp);static void generateClassFromVoid(classDef *cd, const char *cname,		const char *vname, FILE *fp);static void generateMappedTypeFromVoid(mappedTypeDef *mtd, const char *cname,		const char *vname, FILE *fp);/* * Generate the code from a specification. */void generateCode(sipSpec *pt,char *codeDir,char *buildfile,char *docFile,		  char *apiFile,char *srcSuffix,int except,int trace,		  int releaseGIL,int parts,stringList *xsl){	exceptions = except;	tracing = trace;	release_gil = releaseGIL;	generating_c = pt -> genc;	if (srcSuffix == NULL)		srcSuffix = (generating_c ? ".c" : ".cpp");	/* Generate the documentation. */	if (docFile != NULL)		generateDocumentation(pt,docFile);	/* Generate the code. */	if (codeDir != NULL)	{		generateCpp(pt,codeDir,srcSuffix,&parts);		generateInternalAPIHeader(pt,codeDir,xsl);	}	/* Generate the build file. */	if (buildfile != NULL)		generateBuildFile(pt,buildfile,srcSuffix,parts);	/* Generate the API file. */	if (apiFile != NULL)		generateAPI(pt,apiFile);}/* * Generate the Scintilla API file. */static void generateAPI(sipSpec *pt,char *apiFile){	apiDef *head, *ad;	overDef *od;	classDef *cd;	FILE *fp;	/* Create the list of unique names/signatures. */	head = NULL;	for (od = pt -> overs; od != NULL; od = od -> next)		addUniqueAPI(&head,od -> cppname,&od -> pysig);	for (cd = pt -> classes; cd != NULL; cd = cd -> next)	{		ctorDef *ct;		if (cd -> iff -> module != pt -> module)			continue;		for (ct = cd -> ctors; ct != NULL; ct = ct -> next)		{			if (isPrivateCtor(ct))				continue;			addUniqueAPI(&head,classBaseName(cd),&ct -> pysig);		}		for (od = cd -> overs; od != NULL; od = od -> next)		{			if (isPrivate(od))				continue;			addUniqueAPI(&head,od -> cppname,&od -> pysig);		}	}	/* Generate the file. */	fp = createFile(pt,apiFile,NULL);	for (ad = head; ad != NULL; ad = ad -> next)	{		fprintf(fp,"%s(",ad -> name);		generateArgs(ad -> sd,Declaration,fp);		fprintf(fp,")\n");	}	closeFile(fp);}/* * Add an API function to a list if it isn't already there. */static void addUniqueAPI(apiDef **headp,char *name,signatureDef *sd){	apiDef *ad;	for (ad = *headp; ad != NULL; ad = ad -> next)	{		if (strcmp(ad -> name,name) != 0)			continue;		if (sameSignature(ad -> sd,sd,TRUE))			break;	}	if (ad == NULL)	{		ad = sipMalloc(sizeof (apiDef));		ad -> name = name;		ad -> sd = sd;		ad -> next = *headp;		*headp = ad;	}}/* * Generate the documentation. */static void generateDocumentation(sipSpec *pt,char *docFile){	FILE *fp;	codeBlock *cb;	fp = createFile(pt,docFile,NULL);	for (cb = pt -> docs; cb != NULL; cb = cb -> next)		fputs(cb -> frag,fp);	closeFile(fp);}/* * Generate the build file. */static void generateBuildFile(sipSpec *pt,char *buildFile,char *srcSuffix,			      int parts){	char *mname = pt -> module -> name;	ifaceFileDef *iff;	FILE *fp;	fp = createFile(pt,buildFile,NULL);	prcode(fp,"target = %s\nsources = ",mname);	if (parts)	{		int p;		for (p = 0; p < parts; ++p)		{			if (p > 0)				prcode(fp," ");			prcode(fp,"sip%spart%d%s",mname,p,srcSuffix);		}	}	else	{		prcode(fp,"sip%scmodule%s",mname,srcSuffix);		for (iff = pt -> ifacefiles; iff != NULL; iff = iff -> next)		{			if (iff -> module != pt -> module)				continue;			if (iff -> type == exception_iface)				continue;			prcode(fp," sip%s%F%s",mname,iff -> fqcname,srcSuffix);		}	}	prcode(fp,"\nheaders = sipAPI%s.h",mname);	for (iff = pt -> ifacefiles; iff != NULL; iff = iff -> next)	{		char *imname;		imname = (iff -> module == pt -> module ? mname : iff -> module -> name);		prcode(fp," sip%s%F.h",imname,iff -> fqcname);	}	prcode(fp,"\n");	closeFile(fp);}/* * Generate an expression in C++. */static void generateExpression(valueDef *vd,FILE *fp){	while (vd != NULL)	{		if (vd -> vunop != '\0')			prcode(fp,"%c",vd -> vunop);		switch (vd -> vtype)		{		case qchar_value:			prcode(fp,"'%c'",vd -> u.vqchar);			break;		case string_value:			prcode(fp,"\"%s\"",vd -> u.vstr);			break;		case numeric_value:			prcode(fp,"%l",vd -> u.vnum);			break;		case real_value:			prcode(fp,"%g",vd -> u.vreal);			break;		case scoped_value:			prcode(fp,"%S",vd -> u.vscp);			break;		case fcall_value:			generateSimpleFunctionCall(vd -> u.fcd,fp);			break;		} 		if (vd -> vbinop != '\0')			prcode(fp," %c ",vd -> vbinop); 		vd = vd -> next;	}}/* * Generate the C++ internal module API header file. */static void generateInternalAPIHeader(sipSpec *pt,char *codeDir,stringList *xsl){	char *hfile, *mname = pt -> module -> name;	int noIntro;	FILE *fp;	nameDef *nd;	moduleDef *mod;	moduleListDef *mld;	hfile = concat(codeDir,"/sipAPI",mname,".h",NULL);	fp = createFile(pt,hfile,"Internal module API header file.");	/* Include files. */	prcode(fp,"\n""#ifndef _%sAPI_H\n""#define	_%sAPI_H\n""\n""\n""#include <sip.h>\n"		,mname		,mname);	/* Define the enabled features. */	noIntro = TRUE;	for (mod = pt -> modules; mod != NULL; mod = mod -> next)	{		qualDef *qd;		for (qd = mod -> qualifiers; qd != NULL; qd = qd -> next)			if (qd -> qtype == feature_qualifier && !excludedFeature(xsl,qd))			{				if (noIntro)				{					prcode(fp,"\n""\n""/* These are the features that are enabled. */\n"						);					noIntro = FALSE;				}				prcode(fp,"#define	SIP_FEATURE_%s\n"					,qd -> name);			}	}	generateCppCodeBlock(pt -> hdrcode,fp);	/* Shortcuts that hide the messy detail of the APIs. */	noIntro = TRUE;	for (nd = pt -> namecache; nd != NULL; nd = nd -> next)	{		if (!isClassName(nd))			continue;		if (noIntro)		{			prcode(fp,"\n""\n""/*\n"" * Convenient names to refer to the names of classes defined in this module.\n"" * These are part of the public API.\n"" */\n""\n"				);			noIntro = FALSE;		}		prcode(fp,"#define	sipName_%s	%N\n"			,nd -> text,nd);	}	prcode(fp,"\n""\n""/* Convenient names to call the SIP API. */\n""#define	sipConvertFromSliceObject(o,len,start,stop,step,slen)	PySlice_GetIndicesEx((PySliceObject *)(o),(len),(start),(stop),(step),(slen))\n""#define	sipIsSubClassInstance(o,wt)	PyObject_TypeCheck((o),(PyTypeObject *)(wt))\n""\n""#define	sipMapStringToClass		sipAPI_%s -> api_map_string_to_class\n""#define	sipMapIntToClass		sipAPI_%s -> api_map_int_to_class\n""#define	sipMalloc			sipAPI_%s -> api_malloc\n""#define	sipFree				sipAPI_%s -> api_free\n""#define	sipBuildResult			sipAPI_%s -> api_build_result\n""#define	sipCallMethod			sipAPI_%s -> api_call_method\n""#define	sipParseResult			sipAPI_%s -> api_parse_result\n""#define	sipParseArgs			sipAPI_%s -> api_parse_args\n""#define	sipParsePair			sipAPI_%s -> api_parse_pair\n""#define	sipCommonCtor			sipAPI_%s -> api_common_ctor\n""#define	sipCommonDtor			sipAPI_%s -> api_common_dtor\n""#define	sipConvertFromSequenceIndex	sipAPI_%s -> api_convert_from_sequence_index\n""#define	sipConvertFromVoidPtr		sipAPI_%s -> api_convert_from_void_ptr\n""#define	sipConvertToCpp			sipAPI_%s -> api_convert_to_cpp\n""#define	sipConvertToVoidPtr		sipAPI_%s -> api_convert_to_void_ptr\n""#define	sipNoFunction			sipAPI_%s -> api_no_function\n""#define	sipNoMethod			sipAPI_%s -> api_no_method\n""#define	sipAbstractMethod		sipAPI_%s -> api_abstract_method\n""#define	sipBadClass			sipAPI_%s -> api_bad_class\n""#define	sipBadSetType			sipAPI_%s -> api_bad_set_type\n""#define	sipBadCatcherResult		sipAPI_%s -> api_bad_catcher_result\n""#define	sipBadOperatorArg		sipAPI_%s -> api_bad_operator_arg\n""#define	sipTrace			sipAPI_%s -> api_trace\n""#define	sipTransfer			sipAPI_%s -> api_transfer\n""#define	sipTransferBack			sipAPI_%s -> api_transfer_back\n""#define	sipTransferTo			sipAPI_%s -> api_transfer_to\n""#define	sipWrapper_Check		sipAPI_%s -> api_wrapper_check\n""#define	sipGetWrapper			sipAPI_%s -> api_get_wrapper\n""#define	sipGetCppPtr			sipAPI_%s -> api_get_cpp_ptr\n""#define	sipGetComplexCppPtr		sipAPI_%s -> api_get_complex_cpp_ptr\n""#define	sipIsPyMethod			sipAPI_%s -> api_is_py_method\n""#define	sipCallHook			sipAPI_%s -> api_call_hook\n""#define	sipStartThread			sipAPI_%s -> api_start_thread\n""#define	sipEndThread			sipAPI_%s -> api_end_thread\n""#define	sipEmitSignal			sipAPI_%s -> api_emit_signal\n""#define	sipConnectRx			sipAPI_%s -> api_connect_rx\n""#define	sipDisconnectRx			sipAPI_%s -> api_disconnect_rx\n""#define	sipGetSender			sipAPI_%s -> api_get_sender\n""#define	sipRaiseUnknownException	sipAPI_%s -> api_raise_unknown_exception\n""#define	sipRaiseClassException		sipAPI_%s -> api_raise_class_exception\n""#define	sipRaiseSubClassException	sipAPI_%s -> api_raise_sub_class_exception\n""#define	sipBadLengthForSlice		sipAPI_%s -> api_bad_length_for_slice\n""#define	sipClassName			sipAPI_%s -> api_class_name\n""#define	sipAddClassInstance		sipAPI_%s -> api_add_class_instance\n""#define	sipAddMappedTypeInstance	sipAPI_%s -> api_add_mapped_type_instance\n""#define	sipAddEnumInstance		sipAPI_%s -> api_add_enum_instance\n""#define	sipConvertFromNamedEnum		sipAPI_%s -> api_convert_from_named_enum\n""#define	sipGetAddress			sipAPI_%s -> api_get_address\n""#define	sipFreeConnection		sipAPI_%s -> api_free_connection\n""#define	sipEmitToSlot			sipAPI_%s -> api_emit_to_slot\n""#define	sipSameConnection		sipAPI_%s -> api_same_connection\n""#define	sipPySlotExtend			sipAPI_%s -> api_pyslot_extend\n""#define	sipConvertRx			sipAPI_%s -> api_convert_rx\n""#define	sipAddDelayedDtor		sipAPI_%s -> api_add_delayed_dtor\n""#define	sipCanConvertToInstance		sipAPI_%s -> api_can_convert_to_instance\n""#define	sipCanConvertToMappedType	sipAPI_%s -> api_can_convert_to_mapped_type\n""#define	sipConvertToInstance		sipAPI_%s -> api_convert_to_instance\n""#define	sipConvertToMappedType		sipAPI_%s -> api_convert_to_mapped_type\n""#define	sipForceConvertToInstance	sipAPI_%s -> api_force_convert_to_instance\n""#define	sipForceConvertToMappedType	sipAPI_%s -> api_force_convert_to_mapped_type\n""#define	sipReleaseInstance		sipAPI_%s -> api_release_instance\n""#define	sipReleaseMappedType		sipAPI_%s -> api_release_mapped_type\n"

⌨️ 快捷键说明

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