Update to 2.0.0 tree from current Fremantle build
[opencv] / utils / extract_macros.py
1 #! /usr/bin/env python
2 """
3 This script extracts macros functions from the OpenCV headers and attempts to generate
4 standard C function prototypes.  Type information is missing in the macros, so SWIG 
5 cannot generate C code for them unless we provide this.  
6 """
7
8 import sys, re
9
10 ARG_MAP = { 
11     "mat":"CvMat*",   
12     "type":"int", 
13     "flags":"int",
14     "img":"CvArr *", 
15     "image":"IplImage *", 
16     "mat1":"CvMat*", 
17     "mat2":"CvMat*",
18     "seq":"CvSeq*",
19     "elem_ptr":"void *",
20     "elem":"CvPoint",
21     "elem_type":"ignore",
22     "elemtype":"ignore",
23     "elem_size":"int",
24     "edge":"CvGraphEdge *",
25     "vertex":"CvGraphVtx *",
26     "contour":"CvSeq *",
27     "vtx":"CvGraphVtx *",
28     "reader":"CvSeqReader",
29     "writer":"CvSeqWriter",
30     "hist":"CvHistogram *",
31     "ptr":"void *",
32     "arr":"CvArr *",
33     "header":"CvMat *",
34     "src":"CvArr *",
35     "src1":"CvArr *",
36     "src2":"CvArr *",
37     "src3":"CvArr *",
38     "dst":"CvArr *",
39     "pt1":"CvPoint",
40     "pt2":"CvPoint",
41     "_pt":"CvPoint",
42     "index":"int",
43     "idx":"int",
44     "set":"CvSet *",
45     "n":"int",
46     "a":"int",
47     "b":"int",
48     "t":"int",
49     "value":"double",
50     "row":"int",
51     "col":"int",
52     "cn":"int",
53     "new_cn":"int",
54     "pix_size":"int",
55     "depth":"int",
56     "node":"CvSparseNode *",
57     "storage":"CvMemStorage *",
58     "new_dims": "int",
59     "new_sizes": "int *",
60     "A":"CvArr *",
61     "B":"CvArr *",
62     "C":"CvArr *",
63     "real_scalar":"double",
64     "graph":"CvGraph *",
65     "r":"double",
66     "g":"double",
67 #    "b":"double",
68     "line_iterator":"CvLineIterator",
69     "deltas":"double *",
70     "step":"int",
71     "haar":"void *",
72 #    "contour":"const void*",  # handled as a special case in cvshadow
73     "range":"CvSize", 
74     "nch":"int",
75     "method":"int",
76     "factor":"double"
77 }
78 RET_MAP = {
79     "cvContourPerimeter":"double",
80     "CV_RGB":"CvScalar",
81     "CV_NEXT_GRAPH_EDGE":"CvGraphEdge *",
82     "CV_IMIN":"int",
83     "CV_IMAX":"int",
84     "CV_IABS":"int",
85     "CV_MAT_CN":"int",
86     "CV_MAT_DEPTH":"int",
87     "CV_NEXT_LINE_POINT":"void",
88 }
89
90 # special cases
91 MACROS = {
92     #"CV_MAKETYPE":"",  # SWIG 1.3.29 doesn't like this one for some indeterminant reason
93     "CV_TURN_ON_IPL_COMPATIBILITY":"",
94     "CV_MAT_ELEM_PTR_FAST":"void * CV_MAT_ELEM_PTR_FAST(CvMat mat,int row,int col,int pix_size);",
95     "CV_MAT_ELEM_PTR":"void * CV_MAT_ELEM_PTR(CvMat mat,int row,int col);",
96     "CV_NODE_VAL":"void * CV_NODE_VAL(CvSparseMat* mat,CvSparseNode * node);",
97     "CV_NODE_IDX":"int * CV_NODE_IDX(CvSparseMat* mat,CvSparseNode * node);",
98     "CV_READ_CHAIN_POINT":"void CV_READ_CHAIN_POINT(CvPoint _pt, CvChainPtReader reader);",
99     "CV_SUBDIV2D_NEXT_EDGE":"CvQuadEdge2D* CV_SUBDIV2D_NEXT_EDGE(CvSubdiv2DEdge edge);",
100     "cvFree":"void cvFree(void ** ptr);",
101     
102
103 }
104
105 print """
106 /*//////////////////////////////////////////////////////////////////////////////////////////////////
107 // This file is automatically generated from the extract_macros.py script found in the 'utils'
108 // subdirectory of the OpenCV distribution.  If the generated function prototypes are missing or 
109 // incorrect, it is likely that a name->type mapping will have to be added to the script 
110 /////////////////////////////////////////////////////////////////////////////////////////////////M*/
111 """
112
113 print "// This file was generated from the following header files: "
114 print "// %s" % "\n// ".join(sys.argv[1:])
115
116
117 def determine_return_type(name, arguments):
118     if RET_MAP.has_key( name ):
119         return RET_MAP[name]
120     if name.find("_IS_")>=0 or \
121        name.find("_HAS_")>=0 or \
122        name.find("_KIND")>=0 or \
123        name.find("_ARE_")>=0 or \
124        name.find("_SIZE")>=0 or \
125        name.find("Idx")>=0 or \
126        name.find("Count")>=0 or \
127        (name.find("TYPE")>=0 and not name.find("TYPES")>=0):
128         return "int"
129     if re.match( r"CV_(?:8|16|32|64)(?:U|S|F)C", name ):
130         return "int"
131     if len(arguments) is 1 and arguments[0].startswith("double"):
132         return "double"
133     if name.find("_PTR")>=0:
134         return "void *"
135     if name.endswith("POINT"):
136         return "CvPoint"
137     return "void"
138
139 for m in MACROS:
140     print MACROS[m]
141
142 for fn in sys.argv[1:]:
143     f = open( fn, "r" )
144     in_define = False
145     fstr=""
146     macro_name=""
147     for l in f.xreadlines():
148         m = re.match( r"^#define\s+((?:CV_|IPL_|cv)\w+)\s*\(([_, a-zA-Z0-9]*)\)\s*(.*)", l )
149
150         if m and not m.group(1).endswith("FIELDS") and not MACROS.has_key(m.group(1)):
151             macro_name = m.group(1)
152             args = m.group(2).strip().split(",")
153             
154             # assign return type
155             ret=determine_return_type( macro_name, args )
156
157             # assign type to each argument
158             no_args = len(args) is 0
159             typed_args = []
160             ignore = False
161             for arg in args:
162                 arg = arg.strip()
163                 if len(arg) is 0:
164                     no_args = True
165                     break
166                 if ARG_MAP.has_key( arg ):
167                     if ARG_MAP[arg] is "ignore":
168                         ignore=True
169                         break
170                     typed_args.append( "%s %s"%( ARG_MAP[arg], arg ) )
171                 else:
172                     sys.stderr.write( "\"%s\":\"?\", in macro '%s'\n" % (arg, macro_name) )
173                     typed_args = []
174                     break
175             if not ignore and (no_args or len(typed_args)>0):
176                 decl = "%s %s(%s);" % (ret, macro_name, ",".join( typed_args) )
177                 MACROS[ macro_name ] = decl
178                 print decl
179
180     f.close()