--- /dev/null
+#!/usr/bin/perl
+# Check symbols exported by a library
+# (c) 2013 Martin Mares <mj@ucw.cz>
+
+use common::sense;
+
+my $lib = $ARGV[0] or die "Usage: $0 <library>\n";
+open my $f, '-|', 'nm', $lib or die;
+while (<$f>) {
+ chomp;
+ next if /^\s/;
+ my ($addr, $type, $sym) = split /\s+/;
+ if ($sym =~ m{^ucw_}) {
+ next
+ }
+ if ($type =~ m{[A-Z]}) {
+ print "$sym ($type)\n";
+ }
+}
+close $f or die;
--- /dev/null
+#!/usr/bin/perl
+# Search for symbols which might need renaming
+# (c) 2013 Martin Mares <mj@ucw.cz>
+
+use common::sense;
+
+sub parse {
+ my ($file) = @_;
+ print "# $file\n";
+ open my $f, '<', $file or die;
+ while (<$f>) {
+ chomp;
+ # Find things which look like top-level declarations
+ s{//.*}{};
+ s{/\*.*}{};
+ /^\s/ and next;
+ /^$/ and next;
+ /^#/ and next;
+ /^{/ and next;
+ /}/ and next;
+ /^"/ and next;
+ /^-/ and next; # Magic for ucw/getopt.h
+ /^\w+:/ and next; # Labels in inline functions
+ /^typedef\s/ and next;
+ /^static\s/ and next;
+ /^(struct|union|enum)(\s+\w+)?(;|\s*{)/ and next;
+
+ # print "$_\n";
+
+ # Try to parse the declaration
+ s{\[[^\]]*\]}{}g; # Delete array sizes
+ if (m{^extern [^,]*(\s+\**\w+(,\s+\**\w+)*);}) {
+ my $x = $1;
+ $x =~ s{[,*]}{}g;
+ print join("\n", grep { !/^$/ } split /\s+/, $x), "\n";
+ } elsif (m{( |\*)(\w+)\(}) {
+ print "$2\n";
+ } else {
+ print "??? $_\n";
+ }
+
+ }
+ close $f;
+}
+
+my %blacklist = map { $_ => 1 } qw(
+ ucw/binheap.h
+ ucw/char-map.h
+ ucw/ff-binary.h
+ ucw/gbuf.h
+ ucw/hashtable.h
+ ucw/kmp.h
+ ucw/kmp-search.h
+ ucw/redblack.h
+ ucw/str-match.h
+ ucw/strtonum.h
+ ucw/strtonum-gen.h
+ ucw/trie.h
+ charset/charconv-gen.h
+ charset/chartable.h
+ charset/U-cat.h
+ charset/U-ligatures.h
+ charset/U-lower.h
+ charset/U-unacc.h
+ charset/U-upper.h
+);
+
+for my $f (<ucw/*.h>, <ucw/sorter/common.h>, <charset/*.h>) {
+ next if $blacklist{$f};
+ parse($f);
+}
--- /dev/null
+#!/usr/bin/perl
+# Re-generate symbol renaming defines
+# (c) 2013 Martin Mares <mj@ucw.cz>
+
+use common::sense;
+
+my %renames = ();
+open my $f, '<', 'tools/libucw.api' or die;
+my $current;
+while (<$f>) {
+ chomp;
+ if (/^#\s*(.*)/) {
+ $current = $1;
+ } else {
+ push @{$renames{$current}}, $_;
+ }
+}
+close $f;
+
+for my $g (sort keys %renames) {
+ my @symbols = sort @{$renames{$g}};
+ @symbols or next;
+ print "### $g\n";
+
+ open my $in, '<', $g or die;
+ open my $out, '>', "$g.new" or die;
+ my $mode = 0;
+ my $cmt = 0;
+ while (<$in>) {
+ if (!$mode) {
+ if (m{^/\*$} && !$cmt) {
+ $cmt = 1;
+ } elsif (m{^\s} ||
+ m{^#include\s} ||
+ m{^#define\s+_} ||
+ m{^#ifndef\s+_} ||
+ m{^\s*$}
+ ) {
+ # Waiting for the right spot
+ } elsif (m{^#ifdef CONFIG_UCW_CLEAN_ABI$}) {
+ $mode = 2;
+ next;
+ } else {
+ $mode = 1;
+ print $out "#ifdef CONFIG_UCW_CLEAN_ABI\n";
+ for my $sym (@symbols) {
+ print $out "#define $sym ucw_$sym\n";
+ }
+ print $out "#endif\n\n";
+ }
+ } elsif ($mode == 2) {
+ if (m{^$}) {
+ $mode = 0;
+ }
+ next;
+ }
+ print $out "$_";
+ }
+ $mode or die;
+ close $out;
+ close $in;
+ rename "$g.new", $g or die;
+}