1998-10-23 22:19:30 -07:00
|
|
|
#!/usr/bin/perl -w
|
|
|
|
|
|
2006-12-09 13:33:38 -08:00
|
|
|
# GIMP - The GNU Image Manipulation Program
|
2003-07-02 17:47:26 -07:00
|
|
|
# Copyright (C) 1998-2003 Manish Singh <yosh@gimp.org>
|
1998-10-23 22:19:30 -07:00
|
|
|
|
2009-01-17 14:28:01 -08:00
|
|
|
# This program is free software: you can redistribute it and/or modify
|
1998-10-23 22:19:30 -07:00
|
|
|
# it under the terms of the GNU General Public License as published by
|
2009-01-17 14:28:01 -08:00
|
|
|
# the Free Software Foundation; either version 3 of the License, or
|
1998-10-23 22:19:30 -07:00
|
|
|
# (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
# You should have received a copy of the GNU General Public License
|
2018-07-11 14:27:07 -07:00
|
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
1998-10-23 22:19:30 -07:00
|
|
|
|
1999-04-03 21:59:08 -08:00
|
|
|
require 5.004;
|
1998-10-23 22:19:30 -07:00
|
|
|
|
|
|
|
|
BEGIN {
|
2011-11-06 08:33:20 -08:00
|
|
|
$srcdir = $ENV{srcdir} || '.';
|
|
|
|
|
$destdir = $ENV{destdir} || '.';
|
|
|
|
|
$builddir = $ENV{builddir} || '.';
|
1998-10-23 22:19:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
use lib $srcdir;
|
|
|
|
|
|
1999-04-22 23:55:37 -07:00
|
|
|
BEGIN {
|
|
|
|
|
# Some important stuff
|
|
|
|
|
require 'pdb.pl';
|
|
|
|
|
require 'enums.pl';
|
|
|
|
|
require 'util.pl';
|
|
|
|
|
|
|
|
|
|
# What to do?
|
|
|
|
|
require 'groups.pl';
|
|
|
|
|
|
1999-04-28 00:03:35 -07:00
|
|
|
if ($ENV{PDBGEN_GROUPS}) {
|
|
|
|
|
@groups = split(/:/, $ENV{PDBGEN_GROUPS});
|
1999-04-22 23:55:37 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-10-23 22:19:30 -07:00
|
|
|
# Stifle "used only once" warnings
|
|
|
|
|
$destdir = $destdir;
|
2011-11-06 08:33:20 -08:00
|
|
|
$builddir = $builddir;
|
1998-10-23 22:19:30 -07:00
|
|
|
%pdb = ();
|
|
|
|
|
|
|
|
|
|
# The actual parser (in a string so we can eval it in another namespace)
|
|
|
|
|
$evalcode = <<'CODE';
|
|
|
|
|
{
|
|
|
|
|
my $file = $main::file;
|
|
|
|
|
my $srcdir = $main::srcdir;
|
1999-04-03 21:59:08 -08:00
|
|
|
|
|
|
|
|
my $copyvars = sub {
|
|
|
|
|
my $dest = shift;
|
|
|
|
|
|
|
|
|
|
foreach (@_) {
|
1999-07-28 16:21:11 -07:00
|
|
|
if (eval "defined scalar $_") {
|
1999-04-03 21:59:08 -08:00
|
|
|
(my $var = $_) =~ s/^(\W)//;
|
1999-07-28 16:21:11 -07:00
|
|
|
for ($1) {
|
1999-04-03 21:59:08 -08:00
|
|
|
/\$/ && do { $$dest->{$var} = $$var ; last; };
|
|
|
|
|
/\@/ && do { $$dest->{$var} = [ @$var ]; last; };
|
|
|
|
|
/\%/ && do { $$dest->{$var} = { %$var }; last; };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
1998-10-23 22:19:30 -07:00
|
|
|
|
|
|
|
|
# Variables to evaluate and insert into the PDB structure
|
2026-02-01 13:33:49 -08:00
|
|
|
my @procvars = qw($name $group $blurb $help $author $copyright $date
|
|
|
|
|
$since $deprecated $deprecated_since
|
|
|
|
|
@inargs @outargs %invoke $canonical_name
|
2022-06-27 04:40:27 -07:00
|
|
|
$lib_private $skip_gi);
|
1998-10-23 22:19:30 -07:00
|
|
|
|
1999-04-03 21:59:08 -08:00
|
|
|
# These are attached to the group structure
|
2010-07-07 02:43:10 -07:00
|
|
|
my @groupvars = qw($desc $doc_title $doc_short_desc $doc_long_desc
|
2022-06-27 04:40:27 -07:00
|
|
|
$lib_private $skip_gi
|
2010-07-07 02:43:10 -07:00
|
|
|
@headers %extra);
|
1999-04-03 21:59:08 -08:00
|
|
|
|
1998-10-23 22:19:30 -07:00
|
|
|
# Hook some variables into the top-level namespace
|
|
|
|
|
*pdb = \%main::pdb;
|
|
|
|
|
*gen = \%main::gen;
|
|
|
|
|
*grp = \%main::grp;
|
|
|
|
|
|
|
|
|
|
# Hide our globals
|
|
|
|
|
my $safeeval = sub { local(%pdb, %gen, %grp); eval $_[0]; die $@ if $@ };
|
|
|
|
|
|
|
|
|
|
# Some standard shortcuts used by all def files
|
|
|
|
|
&$safeeval("do '$main::srcdir/stddefs.pdb'");
|
|
|
|
|
|
|
|
|
|
# Group properties
|
1999-04-03 21:59:08 -08:00
|
|
|
foreach (@groupvars) { eval "undef $_" }
|
1998-10-23 22:19:30 -07:00
|
|
|
|
|
|
|
|
# Load the file in and get the group info
|
2017-12-17 09:41:34 -08:00
|
|
|
&$safeeval("require '$main::srcdir/groups/$file.pdb'");
|
1998-10-23 22:19:30 -07:00
|
|
|
|
|
|
|
|
# Save these for later
|
1999-04-03 21:59:08 -08:00
|
|
|
&$copyvars(\$grp{$file}, @groupvars);
|
1998-10-23 22:19:30 -07:00
|
|
|
|
1999-03-17 15:08:08 -08:00
|
|
|
foreach $proc (@procs) {
|
1998-10-23 22:19:30 -07:00
|
|
|
# Reset all our PDB vars so previous defs don't interfere
|
|
|
|
|
foreach (@procvars) { eval "undef $_" }
|
|
|
|
|
|
|
|
|
|
# Get the info
|
|
|
|
|
&$safeeval("&$proc");
|
|
|
|
|
|
|
|
|
|
# Some derived fields
|
|
|
|
|
$name = $proc;
|
|
|
|
|
$group = $file;
|
|
|
|
|
|
2005-08-05 11:19:09 -07:00
|
|
|
($canonical_name = $name) =~ s/_/-/g;
|
|
|
|
|
|
1998-10-23 22:19:30 -07:00
|
|
|
# Load the info into %pdb, making copies of the data instead of refs
|
|
|
|
|
my $entry = {};
|
1999-04-03 21:59:08 -08:00
|
|
|
&$copyvars(\$entry, @procvars);
|
1998-10-23 22:19:30 -07:00
|
|
|
$pdb{$proc} = $entry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Find out what to do with these entries
|
1999-04-03 21:59:08 -08:00
|
|
|
while (my ($dest, $procs) = each %exports) { push @{$gen{$dest}}, @$procs }
|
1998-10-23 22:19:30 -07:00
|
|
|
}
|
|
|
|
|
CODE
|
|
|
|
|
|
|
|
|
|
# Slurp in the PDB defs
|
|
|
|
|
foreach $file (@groups) {
|
2017-12-17 09:41:34 -08:00
|
|
|
print "Processing $srcdir/groups/$file.pdb...\n";
|
1998-10-23 22:19:30 -07:00
|
|
|
eval "package Gimp::CodeGen::Safe::$file; $evalcode;";
|
|
|
|
|
die $@ if $@;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-13 18:12:26 -07:00
|
|
|
# Squash whitespace into just single spaces between words.
|
|
|
|
|
# Single new lines are considered as normal spaces, but n > 1 newlines are considered (n - 1) newlines.
|
2018-04-18 11:57:03 -07:00
|
|
|
# The slightly complicated suite of regexp is so that \n\s+\n is still considered a double newline.
|
2014-05-29 07:26:16 -07:00
|
|
|
sub trimspace { for (${$_[0]}) { s/(\S)[\ \t\r\f]*\n[\ \t\r\f]*(\S)/$1 $2/g; s/[\ \t\r\f]+/ /gs;
|
|
|
|
|
s/\n(([\ \t\r\f]*\n)+)/$1/g; s/[\ \t\r\f]*\n[\ \t\r\f]/\n/g ; s/^\s+//; s/\s+$//; } }
|
1998-10-23 22:19:30 -07:00
|
|
|
|
|
|
|
|
# Trim spaces and escape quotes C-style
|
|
|
|
|
sub nicetext {
|
|
|
|
|
my $val = shift;
|
1999-12-14 12:01:01 -08:00
|
|
|
if (defined $$val) {
|
|
|
|
|
&trimspace($val);
|
|
|
|
|
$$val =~ s/"/\\"/g;
|
|
|
|
|
}
|
1998-10-23 22:19:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Do the same for all the strings in the args, plus expand constraint text
|
|
|
|
|
sub niceargs {
|
|
|
|
|
my $args = shift;
|
|
|
|
|
foreach $arg (@$args) {
|
|
|
|
|
foreach (keys %$arg) {
|
|
|
|
|
&nicetext(\$arg->{$_});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Trim spaces from all the elements in a list
|
|
|
|
|
sub nicelist {
|
|
|
|
|
my $list = shift;
|
|
|
|
|
foreach (@$list) { &trimspace(\$_) }
|
|
|
|
|
}
|
|
|
|
|
|
app, libgimp, pdb: support triple-backticks unformatted desc sections.
The previous PDB generation was losing pre-formatting inside
triple-backticked blocks. In particular we were losing indentation
(which was already ugly in C, but even syntactically wrong when
displaying Python code samples). And it was also making us add
double-newlines between every code lines, which was annoying.
This updated code now leaves triple-backticked sections as-is.
Unfortunately I was completely unable to do this by modifying the
existing functions, which were modifying the input arg in-place. So I
made them into functions returning the result. But then there is another
part of code (niceargs()) where changing array contents doesn't work
properly, and worse it seems to corrupt the array somehow (because I
have generation breakage in completely-different pieces of the PDB
generation code). I believe there is some passing-by reference/value
concepts in perl which I don't quite get (they use `&`, `\` and other
symbols and even searching for these, I don't quite understand how to
use them the right way) but I've spent already too much time on this. So
since I've got something working now by having duplicate functions, I'll
let someone else from the future, who knows better perl, re-merge these
functions if they know how.
2024-08-27 02:39:31 -07:00
|
|
|
# trimspace2 and nicetext2 are basically copies of the non-2 versions,
|
|
|
|
|
# except that they return the value. I was unable to make the original
|
|
|
|
|
# version (directly modifying the argument) work with the split() call.
|
|
|
|
|
# Inversely, I could not have the niceargs() function use the
|
|
|
|
|
# return-version nicetext2(). Something is wrong and that's very likely
|
|
|
|
|
# my limited knowledge of how perl works. So I just keep both versions
|
|
|
|
|
# around for now, because what I needed anyway was to special-case the
|
|
|
|
|
# triple-backticked (blockquotes) in the 'help' section. Anyone, be my
|
|
|
|
|
# guest to merge these back into one and remove code duplication, if you
|
|
|
|
|
# know how!
|
|
|
|
|
sub trimspace2 {
|
|
|
|
|
my $text = shift;
|
|
|
|
|
my $trimmed = '';
|
|
|
|
|
my $in_triple_ticks = 0;
|
|
|
|
|
|
|
|
|
|
foreach $subtext (split /```/, $text) {
|
|
|
|
|
if ($in_triple_ticks) {
|
|
|
|
|
# Don't touch formatting inside triple-backticked
|
|
|
|
|
# blockquotes.
|
|
|
|
|
$subtext =~ s/\s+$//;
|
|
|
|
|
$subtext = "\n```" . $subtext . "\n```\n";
|
|
|
|
|
$in_triple_ticks = 0;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
# Removing single newlines.
|
|
|
|
|
$subtext =~ s/(\S)[\ \t\r\f]*\n[\ \t\r\f]*(\S)/$1 $2/g;
|
|
|
|
|
# All multi-space are transformed in single space.
|
|
|
|
|
$subtext =~ s/[\ \t\r\f]+/ /gs;
|
|
|
|
|
# Remove one newline per groups of newlines.
|
|
|
|
|
$subtext =~ s/\n(([\ \t\r\f]*\n)+)/$1/g;
|
|
|
|
|
$subtext =~ s/[\ \t\r\f]*\n[\ \t\r\f]/\n/g;
|
|
|
|
|
$in_triple_ticks = 1;
|
|
|
|
|
}
|
|
|
|
|
$trimmed .= $subtext;
|
|
|
|
|
}
|
|
|
|
|
$text = $trimmed;
|
|
|
|
|
|
|
|
|
|
# Remove leading and trailing whitespaces.
|
|
|
|
|
$text =~ s/^\s+//;
|
|
|
|
|
$text =~ s/\s+$//;
|
|
|
|
|
return $text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub nicetext2 {
|
|
|
|
|
my $val = shift;
|
|
|
|
|
if (defined $val) {
|
|
|
|
|
$val = trimspace2($val);
|
|
|
|
|
$val =~ s/"/\\"/g;
|
|
|
|
|
}
|
|
|
|
|
return $val;
|
|
|
|
|
}
|
|
|
|
|
|
1999-03-10 10:56:56 -08:00
|
|
|
# Add args for array lengths
|
|
|
|
|
|
|
|
|
|
sub arrayexpand {
|
|
|
|
|
my $args = shift;
|
|
|
|
|
my $newargs;
|
|
|
|
|
|
|
|
|
|
foreach (@$$args) {
|
2000-01-18 13:39:03 -08:00
|
|
|
if (exists $_->{array}) {
|
1999-03-10 10:56:56 -08:00
|
|
|
my $arg = $_->{array};
|
|
|
|
|
|
|
|
|
|
$arg->{name} = 'num_' . $_->{name} unless exists $arg->{name};
|
|
|
|
|
|
|
|
|
|
# We can't have negative lengths, but let them set a min number
|
|
|
|
|
unless (exists $arg->{type}) {
|
2024-10-24 17:10:57 -07:00
|
|
|
$arg->{type} = '0 <= size';
|
1999-03-10 10:56:56 -08:00
|
|
|
}
|
|
|
|
|
elsif ($arg->{type} !~ /^\s*\d+\s*</) {
|
2010-06-05 10:26:06 -07:00
|
|
|
$arg->{type} = '0 <= ' . $arg->{type};
|
1999-03-10 10:56:56 -08:00
|
|
|
}
|
|
|
|
|
|
1999-12-25 23:54:39 -08:00
|
|
|
$arg->{void_ret} = 1 if exists $_->{void_ret};
|
|
|
|
|
|
1999-03-10 10:56:56 -08:00
|
|
|
$arg->{num} = 1;
|
2024-10-24 16:31:30 -07:00
|
|
|
$arg->{nopdb} = 1;
|
1999-03-10 10:56:56 -08:00
|
|
|
|
|
|
|
|
push @$newargs, $arg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
push @$newargs, $_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$$args = $newargs;
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-05 11:19:09 -07:00
|
|
|
sub canonicalargs {
|
|
|
|
|
my $args = shift;
|
|
|
|
|
foreach $arg (@$args) {
|
|
|
|
|
($arg->{canonical_name} = $arg->{name}) =~ s/_/-/g;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-10-23 22:19:30 -07:00
|
|
|
# Post-process each pdb entry
|
|
|
|
|
while ((undef, $entry) = each %pdb) {
|
app, libgimp, pdb: support triple-backticks unformatted desc sections.
The previous PDB generation was losing pre-formatting inside
triple-backticked blocks. In particular we were losing indentation
(which was already ugly in C, but even syntactically wrong when
displaying Python code samples). And it was also making us add
double-newlines between every code lines, which was annoying.
This updated code now leaves triple-backticked sections as-is.
Unfortunately I was completely unable to do this by modifying the
existing functions, which were modifying the input arg in-place. So I
made them into functions returning the result. But then there is another
part of code (niceargs()) where changing array contents doesn't work
properly, and worse it seems to corrupt the array somehow (because I
have generation breakage in completely-different pieces of the PDB
generation code). I believe there is some passing-by reference/value
concepts in perl which I don't quite get (they use `&`, `\` and other
symbols and even searching for these, I don't quite understand how to
use them the right way) but I've spent already too much time on this. So
since I've got something working now by having duplicate functions, I'll
let someone else from the future, who knows better perl, re-merge these
functions if they know how.
2024-08-27 02:39:31 -07:00
|
|
|
$entry->{blurb} = nicetext2($entry->{blurb});
|
|
|
|
|
$entry->{help} = nicetext2($entry->{help});
|
|
|
|
|
$entry->{author} = nicetext2($entry->{author});
|
|
|
|
|
$entry->{copyright} = nicetext2($entry->{copyright});
|
|
|
|
|
$entry->{date} = nicetext2($entry->{date});
|
1999-03-10 10:56:56 -08:00
|
|
|
|
1999-03-10 15:34:26 -08:00
|
|
|
foreach (qw(in out)) {
|
|
|
|
|
my $args = $_ . 'args';
|
|
|
|
|
if (exists $entry->{$args}) {
|
|
|
|
|
&arrayexpand(\$entry->{$args});
|
|
|
|
|
&niceargs($entry->{$args});
|
2005-08-05 11:19:09 -07:00
|
|
|
&canonicalargs($entry->{$args});
|
1999-03-10 15:34:26 -08:00
|
|
|
}
|
|
|
|
|
}
|
1999-03-10 10:56:56 -08:00
|
|
|
|
1998-10-23 22:19:30 -07:00
|
|
|
&nicelist($entry->{invoke}{headers}) if exists $entry->{invoke}{headers};
|
1999-03-10 10:56:56 -08:00
|
|
|
&nicelist($entry->{globals}) if exists $entry->{globals};
|
|
|
|
|
|
|
|
|
|
$entry->{invoke}{success} = 'TRUE' unless exists $entry->{invoke}{success};
|
1998-10-23 22:19:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Generate code from the modules
|
|
|
|
|
my $didstuff;
|
|
|
|
|
while (@ARGV) {
|
|
|
|
|
my $type = shift @ARGV;
|
1999-03-10 10:56:56 -08:00
|
|
|
|
1998-10-23 22:19:30 -07:00
|
|
|
print "\nProcessing $type...\n";
|
|
|
|
|
|
|
|
|
|
if (exists $gen{$type}) {
|
|
|
|
|
require "$type.pl";
|
|
|
|
|
&{"Gimp::CodeGen::${type}::generate"}($gen{$type});
|
|
|
|
|
print "done.\n";
|
|
|
|
|
$didstuff = 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
print "nothing to do.\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
print "\nNothing done at all.\n" unless $didstuff;
|