1#!/usr/bin/perl -w 2#- 3# Copyright (c) 2005 Dag-Erling Coïdan Smørgrav 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer 11# in this position and unchanged. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27# 28# $FreeBSD$ 29# 30 31use v5.6.0; 32use strict; 33 34use Getopt::Long; 35 36my $caddr_t; 37 38sub ansify($$$) { 39 my $ifh = shift; 40 my $ofh = shift; 41 my $fn = shift; 42 43 my $line = 0; 44 OUTER: 45 while (<$ifh>) { 46 # look for K&R-style function definitions 47 if (m/^(\w+)\s*\(([\w,\s]+)\)$/) { 48 my @saved = ($_); 49 my $func = $1; 50 my @args = split(/\s*,\s*/, $2); 51 my $arglist = ""; 52 # capture K&R-style argument list 53 while (<$ifh>) { 54 push(@saved, $_); 55 last if (m/^\{\s*$/); 56 $arglist .= $_; 57 } 58 # remove comments (common in vfs code) 59 $arglist =~ s/\/\*([^*]|\*[^\/])*\*\// /gs; 60 # identify type of each argument 61 my %type; 62 foreach (split('\n', $arglist)) { 63 s/\s+/ /g; 64 if (!/^\s*([\w\s\*]+?)\s*(\w+?);\s*$/) { 65 warn("[$fn:$line] $func(): can't parse argument list\n"); 66 print $ofh @saved; 67 $line += @saved; 68 next OUTER; 69 } 70 $type{$2} = $1; 71 } 72 # construct ANSI-style function definition 73 my $repl = "$func("; 74 foreach my $arg (@args) { 75 # missing arguments in argument list 76 if (!exists($type{$arg})) { 77 warn("[$fn:$line] $func(): unknown type for '$arg' argument\n"); 78 print $ofh @saved; 79 $line += @saved; 80 next OUTER; 81 } 82 if ($caddr_t) { 83 $type{$arg} = "void *" 84 if $type{$arg} eq "caddr_t"; 85 } 86 $repl .= $type{$arg}; 87 $repl .= " " 88 unless ($type{$arg} =~ m/\*$/); 89 $repl .= $arg; 90 $repl .= ", " 91 unless $arg eq $args[-1]; 92 delete $type{$arg}; 93 } 94 $repl .= ")"; 95 # extra arguments in argument list 96 if (%type) { 97 warn("[$fn:$line] $func(): too many arguments\n"); 98 print $ofh @saved; 99 $line += @saved; 100 next OUTER; 101 } 102 print $ofh "$repl\n"; 103 ++$line; 104 # warn about long lines so they can be fixed up manually 105 warn("[$fn:$line] $func(): definition exceeds 80 characters\n") 106 if length($repl) >= 80; 107 print $ofh "{\n"; 108 ++$line; 109 } else { 110 print $ofh $_; 111 ++$line; 112 } 113 } 114} 115 116sub ansify_file($) { 117 my $fn = shift; 118 119 my $tfn = "$fn.ansify"; 120 local *IN; 121 local *OUT; 122 123 if (open(IN, "<", $fn)) { 124 if (open(OUT, ">", $tfn)) { 125 ansify(*IN{IO}, *OUT{IO}, $fn); 126 if (!rename($tfn, $fn)) { 127 warn("$fn: $!\n"); 128 unlink($tfn); 129 } 130 } else { 131 warn("$fn.ansify: $!\n"); 132 } 133 } else { 134 warn("$fn: $!\n"); 135 } 136} 137 138sub usage() { 139 print STDERR "usage: ansify [options] [file ...] 140 141Options: 142 -c, --caddr_t Replace caddr_t with void * in converted 143 function definitions 144"; 145 exit(1); 146} 147 148MAIN:{ 149 Getopt::Long::Configure("auto_abbrev", "bundling"); 150 GetOptions( 151 "c|caddr_t" => \$caddr_t, 152 ) 153 or usage(); 154 155 if (@ARGV) { 156 foreach (@ARGV) { 157 ansify_file($_); 158 } 159 } else { 160 ansify(*STDIN{IO}, *STDOUT{IO}, "(stdin)"); 161 } 162} 163