Fix oversight in previous error-reporting patch; mustn't pfree path string
[PostgreSQL.git] / src / backend / utils / Gen_fmgrtab.pl
blobb61d53ec18554e31ca714e70d47a7b16aebb2738
1 #! /usr/bin/perl -w
2 #-------------------------------------------------------------------------
4 # Gen_fmgrtab.pl
5 # Perl equivalent of Gen_fmgrtab.sh
7 # Usage: perl Gen_fmgrtab.pl path-to-pg_proc.h
9 # The reason for implementing this functionality twice is that we don't
10 # require people to have perl to build from a tarball, but on the other
11 # hand Windows can't deal with shell scripts.
13 # Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
14 # Portions Copyright (c) 1994, Regents of the University of California
17 # IDENTIFICATION
18 # $PostgreSQL$
20 #-------------------------------------------------------------------------
22 use strict;
23 use warnings;
25 # Collect arguments
26 my $infile = shift;
27 defined($infile) || die "$0: missing required argument: pg_proc.h\n";
29 # Note: see Gen_fmgrtab.sh for detailed commentary on what this is doing
31 # Collect column numbers for pg_proc columns we need
32 my ($proname, $prolang, $proisstrict, $proretset, $pronargs, $prosrc);
34 open(I, $infile) || die "Could not open $infile: $!";
35 while (<I>)
37 if (m/#define Anum_pg_proc_proname\s+(\d+)/) {
38 $proname = $1;
40 if (m/#define Anum_pg_proc_prolang\s+(\d+)/) {
41 $prolang = $1;
43 if (m/#define Anum_pg_proc_proisstrict\s+(\d+)/) {
44 $proisstrict = $1;
46 if (m/#define Anum_pg_proc_proretset\s+(\d+)/) {
47 $proretset = $1;
49 if (m/#define Anum_pg_proc_pronargs\s+(\d+)/) {
50 $pronargs = $1;
52 if (m/#define Anum_pg_proc_prosrc\s+(\d+)/) {
53 $prosrc = $1;
56 close(I);
58 # Collect the raw data
59 my @fmgr = ();
61 open(I, $infile) || die "Could not open $infile: $!";
62 while (<I>)
64 next unless (/^DATA/);
65 s/^[^O]*OID[^=]*=[ \t]*//;
66 s/\(//;
67 s/"[^"]*"/"xxx"/g;
68 my @p = split;
69 next if ($p[$prolang] ne "12");
70 push @fmgr,
72 oid => $p[0],
73 proname => $p[$proname],
74 strict => $p[$proisstrict],
75 retset => $p[$proretset],
76 nargs => $p[$pronargs],
77 prosrc => $p[$prosrc],
80 close(I);
82 # Emit headers for both files
83 open(H, '>', "$$-fmgroids.h") || die "Could not open $$-fmgroids.h: $!";
84 print H
85 qq|/*-------------------------------------------------------------------------
87 * fmgroids.h
88 * Macros that define the OIDs of built-in functions.
90 * These macros can be used to avoid a catalog lookup when a specific
91 * fmgr-callable function needs to be referenced.
93 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
94 * Portions Copyright (c) 1994, Regents of the University of California
96 * NOTES
97 * ******************************
98 * *** DO NOT EDIT THIS FILE! ***
99 * ******************************
101 * It has been GENERATED by $0
102 * from $infile
104 *-------------------------------------------------------------------------
106 #ifndef FMGROIDS_H
107 #define FMGROIDS_H
110 * Constant macros for the OIDs of entries in pg_proc.
112 * NOTE: macros are named after the prosrc value, ie the actual C name
113 * of the implementing function, not the proname which may be overloaded.
114 * For example, we want to be able to assign different macro names to both
115 * char_text() and name_text() even though these both appear with proname
116 * 'text'. If the same C function appears in more than one pg_proc entry,
117 * its equivalent macro will be defined with the lowest OID among those
118 * entries.
122 open(T, '>', "$$-fmgrtab.c") || die "Could not open $$-fmgrtab.c: $!";
123 print T
124 qq|/*-------------------------------------------------------------------------
126 * fmgrtab.c
127 * The function manager's table of internal functions.
129 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
130 * Portions Copyright (c) 1994, Regents of the University of California
132 * NOTES
134 * ******************************
135 * *** DO NOT EDIT THIS FILE! ***
136 * ******************************
138 * It has been GENERATED by $0
139 * from $infile
141 *-------------------------------------------------------------------------
144 #include "postgres.h"
146 #include "utils/fmgrtab.h"
150 # Emit #define's and extern's -- only one per prosrc value
151 my %seenit;
152 foreach my $s (sort {$a->{oid} <=> $b->{oid}} @fmgr)
154 next if $seenit{$s->{prosrc}};
155 $seenit{$s->{prosrc}} = 1;
156 print H "#define F_" . uc $s->{prosrc} . " $s->{oid}\n";
157 print T "extern Datum $s->{prosrc} (PG_FUNCTION_ARGS);\n";
160 # Create the fmgr_builtins table
161 print T "\nconst FmgrBuiltin fmgr_builtins[] = {\n";
162 my %bmap;
163 $bmap{'t'} = 'true';
164 $bmap{'f'} = 'false';
165 foreach my $s (sort {$a->{oid} <=> $b->{oid}} @fmgr)
167 print T
168 " { $s->{oid}, \"$s->{prosrc}\", $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, $s->{prosrc} },\n";
171 # And add the file footers.
172 print H "\n#endif /* FMGROIDS_H */\n";
173 close(H);
175 print T
176 qq| /* dummy entry is easier than getting rid of comma after last real one */
177 /* (not that there has ever been anything wrong with *having* a
178 comma after the last field in an array initializer) */
179 { 0, NULL, 0, false, false, NULL }
182 /* Note fmgr_nbuiltins excludes the dummy entry */
183 const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)) - 1;
186 close(T);
188 # Finally, rename the completed files into place.
189 rename "$$-fmgroids.h", "fmgroids.h"
190 || die "Could not rename $$-fmgroids.h to fmgroids.h: $!";
191 rename "$$-fmgrtab.c", "fmgrtab.c"
192 || die "Could not rename $$-fmgrtab.c to fmgrtab.c: $!";
194 exit 0;