Typo in comment pointed out by dionoea
[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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23 #*****************************************************************************/
24
25 use strict;
26
27 my $srcdir = $ENV{'top_srcdir'};
28
29 #
30 # Reads to-be exported APIs
31 #
32 my %new_APIs;
33
34 while (<STDIN>)
35 {
36         if (/VLC_EXPORT\(\s*(\w.*\S)\s*,\s*(\w*)\s*,\s*\(\s*(\w.*\S)\s*\)\s*\)[^)]*$/)
37         {
38                 $new_APIs{$2} = [ ( $1, $3 ) ];
39         } 
40 }
41
42 #
43 # Write header's header
44 #
45 open my $new_sym, '> vlc_symbols.h.new' or die "$!";
46 print { $new_sym }
47         "/*\n".
48         " * This file is automatically generated. DO NOT EDIT!\n".
49         " * You can force an update with \"make stamp-api\".\n".
50         " */\n".
51         "\n".
52         "#ifndef __VLC_SYMBOLS_H\n".
53         "# define __VLC_SYMBOLS_H\n".
54         "\n".
55         "# ifdef HAVE_SHARED_LIBVLC\n".
56         "/*\n".
57         " * In an ideal world, plugins would include all the headers they need.\n".
58         " * But of course, many, if not all, of them don't, so we have to make sure\n".
59         " * the whole libvlc API is defined here in any case when included from a\n".
60         " * plugin.\n".
61         " */\n".
62         "#  ifdef __PLUGIN__\n".
63         "#   ifdef __cplusplus\n".
64         "extern \"C\" {\n".
65         "#   endif\n";
66
67 foreach (keys %new_APIs)
68 {
69         print { $new_sym }
70                 $new_APIs{$_}[0]." $_ (".$new_APIs{$_}[1].");\n";
71 }
72
73 print { $new_sym }
74         "#   ifdef __cplusplus\n".
75         "}\n".
76         "#   endif\n".
77         "#  endif /* __PLUGIN__ */\n".
78         "# else /* HAVE_LIBVLC_SHARED */\n".
79         "/*\n".
80         " * This is the big VLC API structure for plugins :\n".
81         " * Changing its layout breaks plugin's binary compatibility,\n".
82         " * so DO NOT DO THAT.\n".
83         " * In case of conflict with SVN, add your uncommited APIs\n".
84         " * at the *end* of the structure so they don't mess the other's\n".
85         " * offset in the structure.\n".
86         " */\n".
87         "struct module_symbols_t\n".
88         "{\n";
89
90 my $changes = 0;
91
92 #
93 # Compares new APIs with currently exported APIs
94 #
95 my @API;
96 my @deprecated_API;
97 my $parse = 0;
98
99 open my $oldfd, "< $srcdir/include/vlc_symbols.h";
100
101 while (<$oldfd>)
102 {
103         if (/^struct module_symbols_t/)
104         {
105                 $parse = 1;
106         }
107         elsif ($parse == 0)
108         {
109         }
110         elsif (/^    void \*(\w*)_deprecated;$/)
111         {
112                 if (defined $new_APIs{$1})
113                 {
114                         print "[info] $1 was RESTORED!\n";
115                         print { $new_sym }
116                                 "    ".$new_APIs{$1}[0]." (*$1_inner) (".$new_APIs{$1}[1].");\n";
117                         delete $new_APIs{$1};
118                         push (@API, $1);
119                         $changes++;
120                 }
121                 else
122                 {
123                         print { $new_sym } $_;
124                         push (@deprecated_API, $1);
125                 }
126         }
127         elsif (/^\s*(\w.*\S)\s*\(\*\s*(\w*)_inner\)\s*\(\s*(\w.*\S)\s*\)\s*;\s*$/)
128         {
129                 if (!defined $new_APIs{$2})
130                 {
131                         print "[warn] $2 was REMOVED!\n";
132                         print { $new_sym } "    void *$2_deprecated;\n";
133                         push (@deprecated_API, $2);
134                         $changes++;
135                 }
136                 elsif (($new_APIs{$2}[0] ne $1)
137                     || ($new_APIs{$2}[1] ne $3))
138                 {
139                         print
140                                 "[warn] $2 was CHANGED!\n".
141                                 "       Old argument(s) : \"$3\"\n".
142                                 "       New argument(s) : \"".$new_APIs{$2}[1]."\"\n".
143                                 "       Old return type : \"$1\"\n".
144                                 "       New return type : \"".$new_APIs{$2}[0]."\"\n";
145
146                         print { $new_sym }
147                                 "    ".$new_APIs{$2}[0]." (*$2_inner) (".$new_APIs{$2}[1].");\n";
148                         delete $new_APIs{$2};
149                         push (@API, $2);
150                         $changes++;
151                 }
152                 else
153                 {
154                         print { $new_sym } "    $1 (*$2_inner) ($3);\n";
155                         push (@API, $2);
156                         delete $new_APIs{$2};
157                 }
158         }
159 }
160 close $oldfd;
161
162 #
163 # Adds brand-new APIs
164 #
165 foreach (keys %new_APIs)
166 {
167         print "[info] $_ was ADDED!\n";
168         print { $new_sym }
169                 "    ".$new_APIs{$_}[0]." (*${_}_inner) (".$new_APIs{$_}[1].");\n";
170         push (@API, $_);
171         $changes++;
172 }
173
174 #
175 # Writes #defines
176 #
177 print { $new_sym }
178         "};\n".
179         "#  if defined (__PLUGIN__)\n";
180
181 foreach (@API)
182 {
183         print { $new_sym } "#  define $_ (p_symbols)->${_}_inner\n";
184 }
185
186 print { $new_sym }
187         "#  elif defined (HAVE_DYNAMIC_PLUGINS) && !defined (__BUILTIN__)\n".
188         "/******************************************************************\n".
189         " * STORE_SYMBOLS: store VLC APIs into p_symbols for plugin access.\n".
190         " ******************************************************************/\n".
191         "#   define STORE_SYMBOLS( p_symbols ) \\\n";
192
193 foreach (@API)
194 {
195         print { $new_sym } "    ((p_symbols)->${_}_inner) = $_; \\\n";
196 }
197 foreach (@deprecated_API)
198 {
199         print { $new_sym } "    (p_symbols)->${_}_deprecated = NULL; \\\n";
200 }
201
202 print { $new_sym }
203         "\n".
204         "#  endif /* __PLUGIN__ */\n".
205         "# endif /* HAVE_SHARED_LIBVLC */\n".
206         "#endif /* __VLC_SYMBOLS_H */\n";
207 close $new_sym;
208
209 #
210 # Replace headers if needed
211 #
212 if ($changes != 0)
213 {
214         rename 'vlc_symbols.h.new', "$srcdir/include/vlc_symbols.h";
215         print "$changes API(s) changed.\n";
216 }
217 else
218 {
219         unlink 'vlc_symbols.h.new';
220 }