2003-03-02 Roland McGrath <roland@redhat.com>
[kopensolaris-gnu/glibc.git] / scripts / versions.awk
index 49f449c..7e33387 100644 (file)
@@ -1,6 +1,5 @@
-# Combine version map fragments into version files for the generated
-# shared object.
-# (C) Copyright 1998, 1999 Free Software Foundation, Inc.
+# Combine version map fragments into version scripts for our shared objects.
+# Copyright (C) 1998,99,2000,02 Free Software Foundation, Inc.
 # Written by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
 # This script expects the following variables to be defined:
@@ -16,20 +15,21 @@ BEGIN {
       libs[$1] = 1;
       curlib = $1;
       while (getline < defsfile && ! /^}/) {
-       versions[$1] = 1;
-       if (NF > 1) {
-         derived[curlib, $1] = " " $2;
-         for (n = 3; n <= NF; ++n) {
-           derived[curlib, $1] = derived[curlib, $1] ", " $n;
-         }
-       }
+      if ($2 == "=") {
+         renamed[curlib "::" $1] = $3;
+      }
+       else
+         versions[$1] = 1;
       }
     }
   }
   close(defsfile);
 
   tmpfile = buildroot "Versions.tmp";
-  sort = "sort -n > " tmpfile;
+  # Note this sorting presumes only single digits between dots for proper
+  # numeric ordering.  sort -n doesn't do quite the right thing either,
+  # and in some non-GNU sort implementations does not sort at all.
+  sort = "sort > " tmpfile;
 }
 
 # Remove comment lines.
@@ -49,11 +49,14 @@ BEGIN {
 
 # This matches the beginning of a new version for the current library.
 /^  [A-Za-z_]/ {
-  actver = $1;
-  if (!versions[$1]) {
-    printf("version %s not defined\n", $1) > "/dev/stderr";
+  if (renamed[actlib "::" $1])
+    actver = renamed[actlib "::" $1];
+  else if (!versions[$1]) {
+    printf("version %s not defined for %s\n", $1, actlib) > "/dev/stderr";
     exit 1;
   }
+  else
+    actver = $1;
   next;
 }
 
@@ -61,16 +64,25 @@ BEGIN {
 # current library.  This is the only place where we print something to
 # the intermediate file.
 /^   / {
-  printf("%s %s %s\n", actlib, actver, $0) | sort;
+  sortver=actver
+  # Ensure GLIBC_ versions come always first
+  sub(/^GLIBC_/," GLIBC_",sortver)
+  printf("%s %s %s\n", actlib, sortver, $0) | sort;
 }
 
 
-function closeversion(name) {
+function closeversion(name, oldname) {
   if (firstinfile) {
     printf("  local:\n    *;\n") > outfile;
     firstinfile = 0;
   }
-  printf("}%s;\n", derived[oldlib, name]) > outfile;
+  # This version inherits from the last one only if they
+  # have the same nonnumeric prefix, i.e. GLIBC_x.y and GLIBC_x.z
+  # or FOO_x and FOO_y but not GLIBC_x and FOO_y.
+  pfx = oldname;
+  sub(/[0-9.]+/,".+",pfx);
+  if (oldname == "" || name !~ pfx) print "};" > outfile;
+  else printf("} %s;\n", oldname) > outfile;
 }
 
 function close_and_move(name, real_name) {
@@ -84,10 +96,10 @@ END {
   oldlib = "";
   oldver = "";
   printf("version-maps =");
-  while(getline < tmpfile) {
+  while (getline < tmpfile) {
     if ($1 != oldlib) {
       if (oldlib != "") {
-       closeversion(oldver);
+       closeversion(oldver, veryoldver);
        oldver = "";
        close_and_move(outfile, real_outfile);
       }
@@ -95,11 +107,13 @@ END {
       real_outfile = buildroot oldlib ".map";
       outfile = real_outfile "T";
       firstinfile = 1;
+      veryoldver = "";
       printf(" %s.map", oldlib);
     }
     if ($2 != oldver) {
       if (oldver != "") {
-       closeversion(oldver);
+       closeversion(oldver, veryoldver);
+       veryoldver = oldver;
       }
       printf("%s {\n  global:\n", $2) > outfile;
       oldver = $2;
@@ -111,7 +125,7 @@ END {
     printf("\n") > outfile;
   }
   printf("\n");
-  closeversion(oldver);
+  closeversion(oldver, veryoldver);
   close_and_move(outfile, real_outfile);
   system("rm -f " tmpfile);
 }