fdccfda1fb5e4560f46f00c45f775fe34275e7f3
[vlc.git] / vlc-api.pl
1 #!/usr/bin/perl
2 #*****************************************************************************
3 #* vlc-api.pl: VLC API maintenance script
4 #*****************************************************************************
5 #* Copyright (C) 2005 the VideoLAN team
6 #* $Id$
7 #*
8 #* Authors: RĂ©mi Denis-Courmont <rem # videolan.org>
9 #*
10 #* This program is free software; you can redistribute it and/or modify
11 #* it under the terms of the GNU General Public License as published by
12 #* the Free Software Foundation; either version 2 of the License, or
13 #* (at your option) any later version.
14 #*
15 #* This program is distributed in the hope that it will be useful,
16 #* but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 #* GNU General Public License for more details.
19 #*
20 #* You should have received a copy of the GNU General Public License
21 #* along with this program; if not, write to the Free Software
22 #* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 #*****************************************************************************/
24
25 use IO::Handle;
26 use strict;
27
28 my $srcdir = $ENV{'top_srcdir'};
29
30 #
31 # Reads to-be exported APIs
32 #
33 my %new_APIs;
34
35 while (<STDIN>)
36 {
37         if (/VLC_EXPORT\(\s*(\w.*\S)\s*,\s*(\w*)\s*,\s*\(\s*(\w.*\S)\s*\)\s*\)[^)]*$/)
38         {
39                 $new_APIs{$2} = [ ( $1, $3 ) ];
40         } 
41 }
42
43 #
44 # Write header's header
45 #
46 my $new_sym=IO::Handle->new();
47 open $new_sym, '> vlc_symbols.h.new' or die "$!";
48 print { $new_sym }
49         "/*\n".
50         " * This file is automatically generated. DO NOT EDIT!\n".
51         " * You can force an update with \"make stamp-api\".\n".
52         " */\n".
53         "\n".
54         "#ifndef __VLC_SYMBOLS_H\n".
55         "# define __VLC_SYMBOLS_H\n".
56         "\n".
57         "# ifdef HAVE_SHARED_LIBVLC\n".
58         "/*\n".
59         " * In an ideal world, plugins would include all the headers they need.\n".
60         " * But of course, many, if not all, of them don't, so we have to make sure\n".
61         " * the whole libvlc API is defined here in any case when included from a\n".
62         " * plugin.\n".
63         " */\n".
64         "#  ifdef __PLUGIN__\n".
65         "#   ifdef __cplusplus\n".
66         "extern \"C\" {\n".
67         "#   endif\n";
68
69 foreach (keys %new_APIs)
70 {
71         print { $new_sym }
72                 $new_APIs{$_}[0]." $_ (".$new_APIs{$_}[1].");\n";
73 }
74
75 print { $new_sym }
76         "#   ifdef __cplusplus\n".
77         "}\n".
78         "#   endif\n".
79         "#  endif /* __PLUGIN__ */\n".
80         "# else /* HAVE_LIBVLC_SHARED */\n".
81         "/*\n".
82         " * This is the big VLC API structure for plugins :\n".
83         " * Changing its layout breaks plugin's binary compatibility,\n".
84         " * so DO NOT DO THAT.\n".
85         " * In case of conflict with SVN, add your uncommited APIs\n".
86         " * at the *end* of the structure so they don't mess the other's\n".
87         " * offset in the structure.\n".
88         " */\n".
89         "struct module_symbols_t\n".
90         "{\n";
91
92 my $changes = 0;
93
94 #
95 # Compares new APIs with currently exported APIs
96 #
97 my @API;
98 my @deprecated_API;
99 my $parse = 0;
100
101 my $oldfd = IO::Handle->new();
102 open $oldfd, "< $srcdir/include/vlc_symbols.h";
103
104 while (<$oldfd>)
105 {
106         if (/^struct module_symbols_t/)
107         {
108                 $parse = 1;
109         }
110         elsif ($parse == 0)
111         {
112         }
113         elsif (/^    void \*(\w*)_deprecated;$/)
114         {
115                 if (defined $new_APIs{$1})
116                 {
117                         print "[info] $1 was RESTORED!\n";
118                         print { $new_sym }
119                                 "    ".$new_APIs{$1}[0]." (*$1_inner) (".$new_APIs{$1}[1].");\n";
120                         delete $new_APIs{$1};
121                         push (@API, $1);
122                         $changes++;
123                 }
124                 else
125                 {
126                         print { $new_sym } $_;
127                         push (@deprecated_API, $1);
128                 }
129         }
130         elsif (/^\s*(\w.*\S)\s*\(\*\s*(\w*)_inner\)\s*\(\s*(\w.*\S)\s*\)\s*;\s*$/)
131         {
132                 if (!defined $new_APIs{$2})
133                 {
134                         print "[warn] $2 was REMOVED!\n";
135                         print { $new_sym } "    void *$2_deprecated;\n";
136                         push (@deprecated_API, $2);
137                         $changes++;
138                 }
139                 elsif (($new_APIs{$2}[0] ne $1)
140                     || ($new_APIs{$2}[1] ne $3))
141                 {
142                         print
143                                 "[warn] $2 was CHANGED!\n".
144                                 "       Old argument(s) : \"$3\"\n".
145                                 "       New argument(s) : \"".$new_APIs{$2}[1]."\"\n".
146                                 "       Old return type : \"$1\"\n".
147                                 "       New return type : \"".$new_APIs{$2}[0]."\"\n";
148
149                         print { $new_sym }
150                                 "    ".$new_APIs{$2}[0]." (*$2_inner) (".$new_APIs{$2}[1].");\n";
151                         delete $new_APIs{$2};
152                         push (@API, $2);
153                         $changes++;
154                 }
155                 else
156                 {
157                         print { $new_sym } "    $1 (*$2_inner) ($3);\n";
158                         push (@API, $2);
159                         delete $new_APIs{$2};
160                 }
161         }
162 }
163 close $oldfd;
164
165 #
166 # Adds brand-new APIs
167 #
168 foreach (keys %new_APIs)
169 {
170         print "[info] $_ was ADDED!\n";
171         print { $new_sym }
172                 "    ".$new_APIs{$_}[0]." (*${_}_inner) (".$new_APIs{$_}[1].");\n";
173         push (@API, $_);
174         $changes++;
175 }
176
177 #
178 # Writes #defines
179 #
180 print { $new_sym }
181         "};\n".
182         "#  if defined (__PLUGIN__)\n";
183
184 foreach (@API)
185 {
186         print { $new_sym } "#  define $_ (p_symbols)->${_}_inner\n";
187 }
188
189 print { $new_sym }
190         "#  elif defined (HAVE_DYNAMIC_PLUGINS) && !defined (__BUILTIN__)\n".
191         "/******************************************************************\n".
192         " * STORE_SYMBOLS: store VLC APIs into p_symbols for plugin access.\n".
193         " ******************************************************************/\n".
194         "#   define STORE_SYMBOLS( p_symbols ) \\\n";
195
196 foreach (@API)
197 {
198         print { $new_sym } "    ((p_symbols)->${_}_inner) = $_; \\\n";
199 }
200 foreach (@deprecated_API)
201 {
202         print { $new_sym } "    (p_symbols)->${_}_deprecated = NULL; \\\n";
203 }
204
205 print { $new_sym }
206         "\n".
207         "#  endif /* __PLUGIN__ */\n".
208         "# endif /* HAVE_SHARED_LIBVLC */\n".
209         "#endif /* __VLC_SYMBOLS_H */\n";
210 close $new_sym;
211
212 #
213 # Replace headers if needed
214 #
215 if ($changes != 0)
216 {
217         rename 'vlc_symbols.h.new', "$srcdir/include/vlc_symbols.h";
218         print "$changes API(s) changed.\n";
219 }
220 else
221 {
222         unlink 'vlc_symbols.h.new';
223 }