Update of the convert.py script which generates now fully automatically the LibVLC...
[vlc/bindings/jvlc.git] / extras / convert.py
1 #!/usr/bin/python
2 """
3 VLC to jna interface converter.
4
5 Authors: Filippo Carone <filippo@carone.org>
6          Matthias Braeger <mbraeger@cern.ch>
7
8 This program is free software. It comes without any warranty, to
9 the extent permitted by applicable law. You can redistribute it
10 and/or modify it under the terms of the Do What The Fuck You Want
11 To Public License, Version 2, as published by Sam Hocevar. See
12 http://sam.zoy.org/wtfpl/COPYING for more details. 
13
14 """
15
16 import datetime
17 import glob
18 import os
19
20
21 libvlc_search = "/usr/include/vlc/libvlc*.h"
22 libvlc_body_file = "LibVlc.java_body"
23 out_file_name = "../core/src/main/java/org/videolan/jvlc/internal/LibVlc.java"
24
25 parameter_parsing = False
26 prototype_parsing = False
27
28 # Mapping table to convert C types into Java types
29 types_map = [
30         ["...", "String... args"],
31         ["(void)", "()"],
32         ["const char * const *", "String[] "],
33         ["const ", ""],
34         ["const*", "String[]"],
35         ["VLC_PUBLIC_API ", ""],
36         ["char**", "String[] "],
37         ["char **" , "String[] "],
38         ["char*" , "String "],
39         ["char *" , "String "],
40         ["libvlc_audio_output_t *", "LibVlcAudioOutput"],
41         ["libvlc_callback_t", "LibVlcCallback"],
42         ["libvlc_event_manager_t *", "LibVlcEventManager "],
43         ["libvlc_event_type_t", "int"],
44         ["libvlc_exception_t *", "libvlc_exception_t "],
45         ["libvlc_instance_t *", "LibVlcInstance "],
46         ["libvlc_log_t *", "LibVlcLog "],
47         ["libvlc_log_iterator_t *", "LibVlcLogIterator "],
48         ["libvlc_log_message_t *", "libvlc_log_message_t "],
49         ["libvlc_media_discoverer_t *", "LibVlcMediaDiscoverer"],
50         ["libvlc_media_library_t *", "LibVlcMediaLibrary"],
51         ["VLC_FORWARD_DECLARE_OBJECT(libvlc_media_list_t *)", "LibVlcMediaList"],
52         ["libvlc_media_list_t *", "LibVlcMediaList"],
53         ["libvlc_media_list_player_t *", "LibVlcMediaListPlayer"],
54         ["libvlc_media_list_view_t *", "LibVlcMediaListView"],
55         ["libvlc_media_t *", "LibVlcMedia "],
56         ["libvlc_media_player_t *", "LibVlcMediaPlayer "],
57         ["libvlc_meta_t", "Meta"],
58         ["libvlc_state_t", "int"],
59         ["libvlc_time_t", "long"],
60         ["libvlc_track_description_t *", "LibVlcTrackDescription "],
61         ["uint32_t", "long"],
62         ["unsigned int", "int"],
63         ["unsigned", "int"],
64         ["void *", "Pointer "]
65 ]
66
67 # Mapping table to convert the existing description into JavaDoc
68 javadoc_map = [
69         ["\\bug", "@bug"],
70         ["\param", "@param"],
71         ["\\return", "@return"],
72         ["\see", "@see"]
73 ]
74
75
76 #
77 # Converts the header prototype into a Java method
78 #
79 # proto:      The function prototype taken from the C file
80 # parameters: list of parameters taken out of the function description.
81 #             This implies of course that the description is correct and complete
82 #
83 def convert_prototype(proto, parameters):
84         # replace first all c++ types by Java types
85         for k,v in types_map:
86                 proto = proto.replace(k,v)
87
88         res = proto[:proto.find('(')+1] # resulting java method stub
89         tokens = proto[proto.find('(')+1:].strip().split(",")
90         last = tokens.pop().split(")")
91         for i in tokens:
92                 if parameters != None and len(parameters):
93                         param = parameters.pop(0) 
94                         if i.find(param)==-1 and len(i.strip().split(' '))==1:
95                                 res += i + " " + param + ","
96                         else:
97                                 res += i + ","
98                 else:
99                         res += i + ","
100                         
101         if parameters != None and len(parameters):
102                 param = parameters.pop(0)
103                 if last[0].find(param)==-1 and len(last[0].strip().split(' '))==1:
104                         res += last[0] + " " + param + ")" + last[1]
105                 else:
106                         res += last[0] + ")" + last[1]
107         else:
108                 res += last[0] + ")" + last[1]
109
110
111         # Print resulting Java method stub
112         out_file.write("    " + res + '\n\n')
113
114
115 #
116 # Reads in the given file and creates out of it the Java
117 # calls + JavaDoc.
118 #
119 def convert_header_file(file):
120         javadoc = ''
121         parameters = []
122         parameter_parsing = True
123         prototype_line = ''
124         prototype_parsing = True
125         for line in file.readlines():
126                 if line.find("/**")!=-1:
127                         javadoc = ''
128                         parameters = []
129                         parameter_parsing = True
130
131                 if not line.startswith('#') and line.find("VLC_PUBLIC_API")!=-1 and line.find("VLC_PUBLIC_API struct")==-1:
132                         if javadoc.find("\defgroup") == -1:
133                                 out_file.write(javadoc);
134                         prototype_line = ''
135                         prototype_parsing = True
136
137                 if parameter_parsing:
138                         # Create JavaDoc output
139                         javadoc_line = line
140                         for k,v in javadoc_map:
141                                 javadoc_line = javadoc_line.replace(k,v)
142                         javadoc += "    " + javadoc_line
143
144                         # Get parameter names
145                         param_index = line.find("\param ")
146                         if not param_index==-1:
147                                 parameter = line.split()[2]
148                                 parameters.append(parameter)
149                         if line.find("*/")!=-1:
150                                 parameter_parsing = False
151
152                 if prototype_parsing:
153                         prototype_line += line.strip() + ' '
154                         if line.find(");")!=-1:
155                                 prototype_line.strip()
156                                 prototype_parsing = False
157                                 convert_prototype(prototype_line, parameters)
158                                 javadoc = ''
159                                 parameters = None
160                         continue
161
162 #
163 # Parses all libvlc header files and generates out
164 # the public functions the Java method stubs.
165 #
166 def generate_libvlc():
167         fileList = glob.glob(libvlc_search)
168         for fname in fileList:
169                 file = open(fname, 'r')
170                 convert_header_file(file)
171                 out_file.write('\n');   
172
173
174 #
175 # Main Routine
176 #
177 body_file = open(libvlc_body_file, 'r')
178 if os.path.exists(out_file_name):
179         os.rename(out_file_name, out_file_name + "_bak")
180         print "Moved " + out_file_name + " to " + out_file_name + "_bak"
181 out_file = open(out_file_name, 'w')
182
183 for line in body_file.readlines():
184         if line.find("$year")!=-1:
185                 curr_date = datetime.datetime.now()
186                 curr_year = '%d' % curr_date.year
187                 line = line.replace("$year", curr_year)
188         if line.find("$libVLC_stubs")!=-1:
189                 generate_libvlc()
190         else:
191                 out_file.write(line)
192 out_file.close()
193 print "Finished generation of " + out_file_name
194 print "\nBye"