This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v3 1/7] manual: Provide one-off standards conversion script.


This is an ephemeral script used to automate conversion of the
@comment-based header and standards annotations to the @standards
macro.

	* manual/convert-stds.pl: New file.  Convert header and
	standards @comments to @standards.
---
 manual/convert-stds.pl | 186 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 186 insertions(+)
 create mode 100755 manual/convert-stds.pl

diff --git a/manual/convert-stds.pl b/manual/convert-stds.pl
new file mode 100755
index 0000000000..d67354a850
--- /dev/null
+++ b/manual/convert-stds.pl
@@ -0,0 +1,186 @@
+#!/usr/bin/perl
+# Copyright (C) 2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Rical Jasan <ricaljasan@pacific.net>, 2017.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+
+# The GNU C Library 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# This is a one-off script, used to convert existing header and
+# standards annotations embedded in @comments to @standards macros.
+# Buffers each input file, making adjustments as necessary, then
+# replaces the file with the reannotated contents.
+
+use strict;
+use warnings;
+
+# Files to convert.
+my @texis = @ARGV;
+
+# Track context.
+my @lines;
+my ($c, $s, $h); # Cur, Std, Hdr indices.
+
+# Regexes.
+my $cmt = qr/\@comment /;
+my $hdr = qr/^${cmt}(([\w\/]+\.h,? ?)+(\(optional\))?|\(none\))$/i;
+my $std = qr/^${cmt}[^\@]+/;
+my $def = qr/^\@def/;
+my $itm = qr/^\@itemx? /;
+my $dix = qr/^\@(def\S+|item)x /;
+my $stm = qr/\@standards/;
+my $stx = qr/^${stm}x\{/;
+
+# Convert.
+for (@texis) {
+    open my $input, '<', $_ or die "open $_: $!";
+    while ($lines[@lines] = <$input>) {
+	($c, $s, $h) = (@lines-1, @lines-2, @lines-3);
+	if ($lines[$c] =~ $def || $lines[$c] =~ $itm)
+	{
+	    # Convert @comments to @standards.
+	    my @standards = &convert($lines[$h], $lines[$s],
+				     $lines[$c] =~ $dix
+				     ? &get_elem($lines[$c]) : undef);
+
+	    # Unannotated, but beware partial @*x chains.
+	    next if ! @standards && $lines[$s] !~ /^${stm}/;
+
+	    # Splice out the @comment(s).
+	    if ($lines[$h] =~ $hdr) {
+		splice @lines, $h, 1; --$s;
+	    }
+	    if ($lines[$s] =~ $std || $lines[$s] =~ $hdr) {
+		splice @lines, $s, 1;
+	    }
+
+	    # Relocate preceding @standards.
+	    my $i = my $j = $#lines-1;
+	    while ($lines[$i] =~ /^${stm}/) {
+		splice @standards, 0, 0, $lines[$i--];
+	    }
+	    splice @lines, $i+1, $j-$i;
+
+	    # Convert @standards in @*x chains.
+	    if ($standards[$#standards] =~ $stx && $standards[0] !~ $stx) {
+		my $e = &get_elem($lines[$#lines-1]);
+		$i = 0;
+		while ($standards[$i] !~ $stx) {
+		    $standards[$i++] =~ s/^(${stm})\{(.*)/$1x{$e, $2/;
+		}
+	    }
+	    # Partial @*x chain w/ only the first annotation.
+	    elsif (@standards == 1 && $lines[$#lines] =~ $dix
+		     && $standards[0] !~ $stx)
+	    {
+		$i = $#lines;
+		--$i while $lines[$i] =~ $dix;
+		my $e = &get_elem($lines[$i]);
+		$standards[0] =~ s/^(${stm})\{(.*)/$1x{$e, $2/;
+	    }
+
+	    # Append the @standards.
+	    push @lines, @standards;
+	}
+    }
+    close $input or die "close $_: $!";
+    splice @lines, -1;
+    open my $output, '>', "$_" or die "open $_: $!";
+    print $output @lines;
+    close $output or die "close $_: $!";
+    @lines=();
+}
+
+# Returns the annotated element from an @def or @item line.
+sub get_elem
+{
+    my @toks = split /\s+/, shift;
+    my $i = 0;
+    for (; $i<@toks; $i++) {
+	last if $toks[$i] =~ /^\(/;
+    }
+    return $toks[$i-1];
+}
+
+# Converts header and standards @comments to an array of @standards.
+# The optional annotated element argument is used to determine whether
+# @standards or @standardsx macros are generated.
+sub convert
+{
+    my ($hl, $sl, $el) = @_;
+    my (@hdrs, @stds);
+    my ($i, $j, @arr);
+
+    # Useful routine to split a header or standard line.  Uses a
+    # little magic to distinguish the two where it counts.
+    my $split = sub {
+	my ($line, $ish) = @_;
+	$line =~ s/^${cmt}//;
+	chomp $line;
+	if ($ish) {split /\s+/, $line}
+	else {split /,\s+/, $line}
+    };
+
+    # Split the header and standards lines, handling cases of partial
+    # or absent annotations.
+    if ($hl =~ $hdr && $sl =~ $std) {
+	@hdrs = $split->($hl, 1);
+	@stds = $split->($sl, 0);
+    } elsif ($sl =~ $hdr) {
+	@hdrs = $split->($sl, 0);
+	@stds = ('???');
+    } elsif ($sl =~ $std) {
+	@hdrs = ('???');
+	@stds = $split->($sl, 0);
+    } else {
+	return (); # Unannotated.
+    }
+
+    # Append "(optional)" to the preceding header, which would have
+    # incorrectly split on the intervening whitespace.
+    for ($i=0; $i<@hdrs; ++$i) {
+	if ($hdrs[$i] eq '(optional)') {
+	    $hdrs[$i-1] .= " $hdrs[$i]";
+	    splice @hdrs, $i--, 1;
+	}
+    }
+
+    # Ensure we have equal length, paired, and populated header and
+    # standards arrays.  Propagates the last header or standard; not
+    # necessarily a convention, just a coping strategy.
+    if (@hdrs != @stds) {
+	if (@hdrs < @stds) {
+	    $i = $#hdrs;
+	    for ($j=@hdrs; $j<@stds; ++$j) {
+		$hdrs[$j] = $hdrs[$i];
+	    }
+	} else {
+	    $i = $#stds;
+	    for ($j=@stds; $j<@hdrs; ++$j) {
+		$stds[$j] = $stds[$i];
+	    }
+	}
+    }
+
+    # Generate the list of @standards.
+    for ($i=0; $i<@hdrs; ++$i) {
+	if ($el) {
+	    push @arr, "\@standardsx{$el, $stds[$i], $hdrs[$i]}\n";
+	} else {
+	    push @arr, "\@standards{$stds[$i], $hdrs[$i]}\n";
+	}
+    }
+
+    return @arr;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]