#! /usr/bin/env python """ This script extracts macros functions from the OpenCV headers and attempts to generate standard C function prototypes. Type information is missing in the macros, so SWIG cannot generate C code for them unless we provide this. """ import sys, re ARG_MAP = { "mat":"CvMat*", "type":"int", "flags":"int", "img":"CvArr *", "image":"IplImage *", "mat1":"CvMat*", "mat2":"CvMat*", "seq":"CvSeq*", "elem_ptr":"void *", "elem":"CvPoint", "elem_type":"ignore", "elemtype":"ignore", "elem_size":"int", "edge":"CvGraphEdge *", "vertex":"CvGraphVtx *", "contour":"CvSeq *", "vtx":"CvGraphVtx *", "reader":"CvSeqReader", "writer":"CvSeqWriter", "hist":"CvHistogram *", "ptr":"void *", "arr":"CvArr *", "header":"CvMat *", "src":"CvArr *", "src1":"CvArr *", "src2":"CvArr *", "src3":"CvArr *", "dst":"CvArr *", "pt1":"CvPoint", "pt2":"CvPoint", "_pt":"CvPoint", "index":"int", "idx":"int", "set":"CvSet *", "n":"int", "a":"int", "b":"int", "t":"int", "value":"double", "row":"int", "col":"int", "cn":"int", "new_cn":"int", "pix_size":"int", "depth":"int", "node":"CvSparseNode *", "storage":"CvMemStorage *", "new_dims": "int", "new_sizes": "int *", "A":"CvArr *", "B":"CvArr *", "C":"CvArr *", "real_scalar":"double", "graph":"CvGraph *", "r":"double", "g":"double", # "b":"double", "line_iterator":"CvLineIterator", "deltas":"double *", "step":"int", "haar":"void *", # "contour":"const void*", # handled as a special case in cvshadow "range":"CvSize", "nch":"int", "method":"int", "factor":"double" } RET_MAP = { "cvContourPerimeter":"double", "CV_RGB":"CvScalar", "CV_NEXT_GRAPH_EDGE":"CvGraphEdge *", "CV_IMIN":"int", "CV_IMAX":"int", "CV_IABS":"int", "CV_MAT_CN":"int", "CV_MAT_DEPTH":"int", "CV_NEXT_LINE_POINT":"void", } # special cases MACROS = { #"CV_MAKETYPE":"", # SWIG 1.3.29 doesn't like this one for some indeterminant reason "CV_TURN_ON_IPL_COMPATIBILITY":"", "CV_MAT_ELEM_PTR_FAST":"void * CV_MAT_ELEM_PTR_FAST(CvMat mat,int row,int col,int pix_size);", "CV_MAT_ELEM_PTR":"void * CV_MAT_ELEM_PTR(CvMat mat,int row,int col);", "CV_NODE_VAL":"void * CV_NODE_VAL(CvSparseMat* mat,CvSparseNode * node);", "CV_NODE_IDX":"int * CV_NODE_IDX(CvSparseMat* mat,CvSparseNode * node);", "CV_READ_CHAIN_POINT":"void CV_READ_CHAIN_POINT(CvPoint _pt, CvChainPtReader reader);", "CV_SUBDIV2D_NEXT_EDGE":"CvQuadEdge2D* CV_SUBDIV2D_NEXT_EDGE(CvSubdiv2DEdge edge);", "cvFree":"void cvFree(void ** ptr);", } print """ /*////////////////////////////////////////////////////////////////////////////////////////////////// // This file is automatically generated from the extract_macros.py script found in the 'utils' // subdirectory of the OpenCV distribution. If the generated function prototypes are missing or // incorrect, it is likely that a name->type mapping will have to be added to the script /////////////////////////////////////////////////////////////////////////////////////////////////M*/ """ print "// This file was generated from the following header files: " print "// %s" % "\n// ".join(sys.argv[1:]) def determine_return_type(name, arguments): if RET_MAP.has_key( name ): return RET_MAP[name] if name.find("_IS_")>=0 or \ name.find("_HAS_")>=0 or \ name.find("_KIND")>=0 or \ name.find("_ARE_")>=0 or \ name.find("_SIZE")>=0 or \ name.find("Idx")>=0 or \ name.find("Count")>=0 or \ (name.find("TYPE")>=0 and not name.find("TYPES")>=0): return "int" if re.match( r"CV_(?:8|16|32|64)(?:U|S|F)C", name ): return "int" if len(arguments) is 1 and arguments[0].startswith("double"): return "double" if name.find("_PTR")>=0: return "void *" if name.endswith("POINT"): return "CvPoint" return "void" for m in MACROS: print MACROS[m] for fn in sys.argv[1:]: f = open( fn, "r" ) in_define = False fstr="" macro_name="" for l in f.xreadlines(): m = re.match( r"^#define\s+((?:CV_|IPL_|cv)\w+)\s*\(([_, a-zA-Z0-9]*)\)\s*(.*)", l ) if m and not m.group(1).endswith("FIELDS") and not MACROS.has_key(m.group(1)): macro_name = m.group(1) args = m.group(2).strip().split(",") # assign return type ret=determine_return_type( macro_name, args ) # assign type to each argument no_args = len(args) is 0 typed_args = [] ignore = False for arg in args: arg = arg.strip() if len(arg) is 0: no_args = True break if ARG_MAP.has_key( arg ): if ARG_MAP[arg] is "ignore": ignore=True break typed_args.append( "%s %s"%( ARG_MAP[arg], arg ) ) else: sys.stderr.write( "\"%s\":\"?\", in macro '%s'\n" % (arg, macro_name) ) typed_args = [] break if not ignore and (no_args or len(typed_args)>0): decl = "%s %s(%s);" % (ret, macro_name, ",".join( typed_args) ) MACROS[ macro_name ] = decl print decl f.close()