Skip to contentSkip to conversation

Replace scripts/headers_install.pl with a shell script.

PATCH In review Rob Landley 3 participants 4 messages Jan 18, 2011 – Jan 24, 2011 Kbuild

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Replace scripts/headers_install.pl with a shell script.

From: Rob Landley <[email protected]>

Remove perl from make headers_install by replacing a perl script (doing a simple regex search and replace) with a smaller and faster shell script implementation. The new shell script is a single for loop calling sed and piping its output through unifdef to produce the target file.

Change from last time: better error handling. Split "sed | unifdef" into two stages with a temp file because dash hasn't got PIPEFAIL. Add check for exit code, add trap handler to delete output when exiting prematurely.

---

 scripts/Makefile.headersinst |    6 ++--
 scripts/headers_install.pl   |   49 ---------------------------------
 scripts/headers_install.sh   |   39 ++++++++++++++++++++++++++
 3 files changed, 42 insertions(+), 52 deletions(-)
scripts/headers_install.sh +42 -0
diff -ruN linux-2.6.30.old/scripts/headers_install.sh linux-2.6.30/scripts/headers_install.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+if [ $# -lt 2 ]
+then
+	echo "Usage: headers_install.sh INDIR OUTDIR [FILES...]
+	echo
+	echo "Prepares kernel header files for use by user space, by removing"
+	echo "all compiler.h definitions and #includes, removing any"
+	echo "#ifdef __KERNEL__ sections, and putting __underscores__ around"
+	echo "asm/inline/volatile keywords."
+	echo
+	echo "INDIR:  directory to read each kernel header FILE from."
+	echo "OUTDIR: directory to write each userspace header FILE to."
+	echo "FILES:  list of header files to operate on."
+
+	exit 1
+fi
+
+# Grab arguments
+
+INDIR="$1"
+shift
+OUTDIR="$1"
+shift
+
+# Iterate through files listed on command line
+
+trap "rm -f $OUTDIR/$i $OUTDIR.sed" EXIT
+for i in "$@"
+do
+	sed -r \
+		-e 's/([ \t(])(__user|__force|__iomem)[ \t]/\1/g' \
+		-e 's/__attribute_const__([ \t]|$)/\1/g' \
+		-e 's@^#include <linux/compiler.h>@@' \
+		-e 's/(^|[ \t])(inline|asm|volatile)([ \t(]|$)/\1__\2__\3/g' \
+		"$INDIR/$i" > "$OUTDIR/$i.sed" || exit 1
+	scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__ "$OUTDIR/$i.sed" \
+		> "$OUTDIR/$i"
+	[ $? -gt 1 ] && exit 1
+	rm -f "$OUTDIR/$i.sed"
+done
+trap - EXIT
scripts/Makefile.headersinst +3 -3
diff -ruN linux-2.6.30.old/scripts/Makefile.headersinst linux-2.6.30/scripts/Makefile.headersinst
@@ -45,8 +45,8 @@
 quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
                             file$(if $(word 2, $(all-files)),s))
       cmd_install = \
-        $(PERL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \
-        $(PERL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \
+      $(CONFIG_SHELL) $< $(srctree)/$(obj) $(install) $(header-y); \
+      $(CONFIG_SHELL) $< $(objtree)/$(obj) $(install) $(objhdr-y); \
         touch $@
 
 quiet_cmd_remove = REMOVE  $(unwanted)
@@ -69,7 +69,7 @@
 	@:
 
 targets += $(install-file)
-$(install-file): scripts/headers_install.pl $(input-files) FORCE
+$(install-file): scripts/headers_install.sh $(input-files) FORCE
 	$(if $(unwanted),$(call cmd,remove),)
 	$(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@)))
 	$(call if_changed,install)
scripts/headers_install.pl deleted +0 -57

57 lines not on this page · raw message

#1 lore raw

Hi,

Quoted 44 lines · Rob Landley

From: Rob Landley <[email protected]>

Remove perl from make headers_install by replacing a perl script (doing a simple regex search and replace) with a smaller and faster shell script implementation.  The new shell script is a single for loop calling sed and piping its output through unifdef to produce the target file.

Change from last time: better error handling.  Split "sed | unifdef" into two stages with a temp file because dash hasn't got PIPEFAIL.  Add check for exit code, add trap handler to delete output when exiting prematurely.

---

 scripts/Makefile.headersinst |    6 ++-- scripts/headers_install.pl   |   49 --------------------------------- scripts/headers_install.sh   |   39 ++++++++++++++++++++++++++

 3 files changed, 42 insertions(+), 52 deletions(-)

diff -ruN linux-2.6.30.old/scripts/headers_install.sh linux-2.6.30/scripts/headers_install.sh

scripts/headers_install.sh     2009-06-22 16:21:23.000000000 -0500 renamed from scripts/headers_install.sh 1969-12-31 18:00:00.000000000 -0600 +21 -0
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+if [ $# -lt 2 ]
+then
+       echo "Usage: headers_install.sh INDIR OUTDIR [FILES...]
+       echo
+       echo "Prepares kernel header files for use by user space, by removing"
+       echo "all compiler.h definitions and #includes, removing any"
+       echo "#ifdef __KERNEL__ sections, and putting __underscores__ around"
+       echo "asm/inline/volatile keywords."
+       echo
+       echo "INDIR:  directory to read each kernel header FILE from."
+       echo "OUTDIR: directory to write each userspace header FILE to."
+       echo "FILES:  list of header files to operate on."
+
+       exit 1
+fi
+
+# Grab arguments
+
+INDIR="$1"

scripts/headers_install.sh     2009-06-22 16:21:23.000000000 -0500 line 31

Quoted 10 lines
scripts/headers_install.sh     2009-06-22 16:21:23.000000000 -0500 renamed from scripts/headers_install.sh 1969-12-31 18:00:00.000000000 -0600 +10 -0
+shift
+OUTDIR="$1"
+shift
+
+# Iterate through files listed on command line
+
+trap "rm -f $OUTDIR/$i $OUTDIR.sed" EXIT
+for i in "$@"
+do
+       sed -r \

-r is not portable outside the GNU world.

scripts/headers_install.sh     2009-06-22 16:21:23.000000000 -0500 line 32

Quoted 1 line
scripts/headers_install.sh     2009-06-22 16:21:23.000000000 -0500 renamed from scripts/headers_install.sh 1969-12-31 18:00:00.000000000 -0600 +1 -0
+               -e 's/([ \t(])(__user|__force|__iomem)[ \t]/\1/g' \

these regex are not portable either.

If this perl is to be replaced by sed, I guess it should at least be POSIX-compliant (cf. [0]).

- Arnaud

[0]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html

Quoted 98 lines
scripts/headers_install.sh     2009-06-22 16:21:23.000000000 -0500 renamed from scripts/headers_install.sh 1969-12-31 18:00:00.000000000 -0600 +10 -0
+               -e 's/__attribute_const__([ \t]|$)/\1/g' \
+               -e 's@^#include <linux/compiler.h>@@' \
+               -e 's/(^|[ \t])(inline|asm|volatile)([ \t(]|$)/\1__\2__\3/g' \
+               "$INDIR/$i" > "$OUTDIR/$i.sed" || exit 1
+       scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__ "$OUTDIR/$i.sed" \
+               > "$OUTDIR/$i"
+       [ $? -gt 1 ] && exit 1
+       rm -f "$OUTDIR/$i.sed"
+done
+trap - EXIT

diff -ruN linux-2.6.30.old/scripts/Makefile.headersinst linux-2.6.30/scripts/Makefile.headersinst

scripts/Makefile.headersinst   2009-06-22 16:21:23.000000000 -0500 renamed from scripts/Makefile.headersinst       2009-06-09 22:05:27.000000000 -0500 +2 -2
@@ -45,8 +45,8 @@
  quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
                             file$(if $(word 2, $(all-files)),s))
       cmd_install = \
-        $(PERL) $< $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \
-        $(PERL) $< $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \
+      $(CONFIG_SHELL) $< $(srctree)/$(obj) $(install) $(header-y); \
+      $(CONFIG_SHELL) $< $(objtree)/$(obj) $(install) $(objhdr-y); \

        touch $@

 quiet_cmd_remove = REMOVE  $(unwanted)

scripts/Makefile.headersinst   2009-06-22 16:21:23.000000000 -0500 renamed from scripts/Makefile.headersinst       2009-06-09 22:05:27.000000000 -0500 +0 -0
@@ -69,7 +69,7 @@

       @:

 targets += $(install-file)
-$(install-file): scripts/headers_install.pl $(input-files) FORCE +$(install-file): scripts/headers_install.sh $(input-files) FORCE $(if $(unwanted),$(call cmd,remove),)
       $(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@))) $(call if_changed,install)

scripts/headers_install.pl deleted +0 -58
@@ -1,57 +0,0 @@
-#!/usr/bin/perl -w
-#
-# headers_install prepare the listed header files for use in
-# user space and copy the files to their destination.
-#
-# Usage: headers_install.pl readdir installdir arch [files...]
-# readdir:    dir to open files
-# installdir: dir to install the files
-# arch:       current architecture
-#             arch is used to force a reinstallation when the arch
-#             changes because kbuild then detect a command line change.
-# files:      list of files to check
-#
-# Step in preparation for users space:
-# 1) Drop all use of compiler.h definitions
-# 2) Drop include of compiler.h
-# 3) Drop all sections defined out by __KERNEL__ (using unifdef)
-
-use strict;
-
-my ($readdir, $installdir, $arch, @files) = @ARGV;
-
-my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__";
-
-foreach my $file (@files) {
-       my $tmpfile = "$installdir/$file.tmp";
-
-       open(my $in, '<', "$readdir/$file")
-           or die "$readdir/$file: $!\n";
-       open(my $out, '>', $tmpfile)
-           or die "$tmpfile: $!\n";
-       while (my $line = <$in>) {
-               $line =~ s/([\s(])__user\s/$1/g;
-               $line =~ s/([\s(])__force\s/$1/g;
-               $line =~ s/([\s(])__iomem\s/$1/g;
-               $line =~ s/\s__attribute_const__\s/ /g;
-               $line =~ s/\s__attribute_const__$//g;
-               $line =~ s/^#include <linux\/compiler.h>//;
-               $line =~ s/(^|\s)(inline)\b/$1__$2__/g;
-               $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g;
-               $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g;
-               printf {$out} "%s", $line;
-       }
-       close $out;
-       close $in;
-
-       system $unifdef . " $tmpfile > $installdir/$file";
-       # unifdef will exit 0 on success, and will exit 1 when the
-       # file was processed successfully but no changes were made,
-       # so abort only when it's higher than that.
-       my $e = $? >> 8;
-       if ($e > 1) {
-               die "$tmpfile: $!\n";
-       }
-       unlink $tmpfile;
-}
-exit 0;
--

To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

#2 lore raw
Quoted 42 lines · Arnaud Lacombe

Hi,

Quoted 39 lines · Rob Landley

From: Rob Landley<[email protected]>

Remove perl from make headers_install by replacing a perl script (doing a simple regex search and replace) with a smaller and faster shell script implementation. The new shell script is a single for loop calling sed and piping its output through unifdef to produce the target file.

Change from last time: better error handling. Split "sed | unifdef" into two stages with a temp file because dash hasn't got PIPEFAIL. Add check for exit code, add trap handler to delete output when exiting prematurely.

---

  scripts/Makefile.headersinst |    6 ++--
  scripts/headers_install.pl   |   49 ---------------------------------
  scripts/headers_install.sh   |   39 ++++++++++++++++++++++++++
  3 files changed, 42 insertions(+), 52 deletions(-)

diff -ruN linux-2.6.30.old/scripts/headers_install.sh linux-2.6.30/scripts/headers_install.sh

scripts/headers_install.sh 2009-06-22 16:21:23.000000000 -0500 renamed from scripts/headers_install.sh 1969-12-31 18:00:00.000000000 -0600 +16 -0
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+if [ $# -lt 2 ]
+then
+       echo "Usage: headers_install.sh INDIR OUTDIR [FILES...]
+       echo
+       echo "Prepares kernel header files for use by user space, by removing"
+       echo "all compiler.h definitions and #includes, removing any"
+       echo "#ifdef __KERNEL__ sections, and putting __underscores__ around"
+       echo "asm/inline/volatile keywords."
+       echo
+       echo "INDIR:  directory to read each kernel header FILE from."
+       echo "OUTDIR: directory to write each userspace header FILE to."
+       echo "FILES:  list of header files to operate on."
+
+       exit 1
Quoted 8 lines

scripts/headers_install.sh 2009-06-22 16:21:23.000000000 -0500 line 24

Quoted 8 lines
scripts/headers_install.sh 2009-06-22 16:21:23.000000000 -0500 renamed from scripts/headers_install.sh 1969-12-31 18:00:00.000000000 -0600 +8 -0
+fi
+
+# Grab arguments
+
+INDIR="$1"
+shift
+OUTDIR="$1"
+shift

INDIR="$1"
OUTDIT="$2"
shift 2

Quoted 4 lines

scripts/headers_install.sh 2009-06-22 16:21:23.000000000 -0500 line 28

Quoted 4 lines
scripts/headers_install.sh 2009-06-22 16:21:23.000000000 -0500 renamed from scripts/headers_install.sh 1969-12-31 18:00:00.000000000 -0600 +4 -0
+
+# Iterate through files listed on command line
+
+trap "rm -f $OUTDIR/$i $OUTDIR.sed" EXIT

Should be $OUTDIR/$i.sed instead of $OUTDIR.sed.

Also, should be :

trap 'rm -f "$OUTDIR/$i" "$OUTDIR/$i.sed"' EXIT

Else $i will be evaluated at the time the trap command is used, not at the time we exit, and you need to protect the filenames using "" everywhere.

And last but not least, doing so, you will only delete the files in the current loop iteration, not all the files build by this run.

Quoted 29 lines

scripts/headers_install.sh 2009-06-22 16:21:23.000000000 -0500 line 31

Quoted 3 lines
scripts/headers_install.sh 2009-06-22 16:21:23.000000000 -0500 renamed from scripts/headers_install.sh 1969-12-31 18:00:00.000000000 -0600 +3 -0
+for i in "$@"
+do
+       sed -r \

-r is not portable outside the GNU world.

scripts/headers_install.sh 2009-06-22 16:21:23.000000000 -0500 line 32

Quoted 1 line
scripts/headers_install.sh 2009-06-22 16:21:23.000000000 -0500 renamed from scripts/headers_install.sh 1969-12-31 18:00:00.000000000 -0600 +1 -0
+               -e 's/([ \t(])(__user|__force|__iomem)[ \t]/\1/g' \

these regex are not portable either.

If this perl is to be replaced by sed, I guess it should at least be POSIX-compliant (cf. [0]).

- Arnaud

[0]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html

Quoted 14 lines
scripts/headers_install.sh 2009-06-22 16:21:23.000000000 -0500 renamed from scripts/headers_install.sh 1969-12-31 18:00:00.000000000 -0600 +10 -0
+               -e 's/__attribute_const__([ \t]|$)/\1/g' \
+               -e 's@^#include<linux/compiler.h>@@' \
+               -e 's/(^|[ \t])(inline|asm|volatile)([ \t(]|$)/\1__\2__\3/g' \
+               "$INDIR/$i">  "$OUTDIR/$i.sed" || exit 1
+       scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__ "$OUTDIR/$i.sed" \
+>  "$OUTDIR/$i"
+       [ $? -gt 1 ]&&  exit 1
+       rm -f "$OUTDIR/$i.sed"
+done
+trap - EXIT

diff -ruN linux-2.6.30.old/scripts/Makefile.headersinst linux-2.6.30/scripts/Makefile.headersinst

scripts/Makefile.headersinst 2009-06-22 16:21:23.000000000 -0500 renamed from scripts/Makefile.headersinst 2009-06-09 22:05:27.000000000 -0500 +0 -0
@@ -45,8 +45,8 @@
Quoted 8 lines

scripts/Makefile.headersinst 2009-06-22 16:21:23.000000000 -0500 line 50

Quoted 8 lines
scripts/Makefile.headersinst 2009-06-22 16:21:23.000000000 -0500 renamed from scripts/Makefile.headersinst 2009-06-09 22:05:27.000000000 -0500 +2 -2
  quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
                             file$(if $(word 2, $(all-files)),s))
       cmd_install = \
-        $(PERL) $<  $(srctree)/$(obj) $(install) $(SRCARCH) $(header-y); \
-        $(PERL) $<  $(objtree)/$(obj) $(install) $(SRCARCH) $(objhdr-y); \
+      $(CONFIG_SHELL) $<  $(srctree)/$(obj) $(install) $(header-y); \
+      $(CONFIG_SHELL) $<  $(objtree)/$(obj) $(install) $(objhdr-y); \
         touch $@

Why did you removed $(SRCARCH) ?

Quoting the original: "arch is used to force a reinstallation when the arch hanges because kbuild then detect a command line change."

So, arch is not used by the script, but by the caller and apparently needs to be in the command line.

All that being said, I'm not sure that using the shell instead of perl will enhance anything. We face the risk to add many regression with this change.

Nicolas.

Quoted 71 lines
Quoted 71 lines
scripts/Makefile.headersinst 2009-06-22 16:21:23.000000000 -0500 renamed from scripts/Makefile.headersinst 2009-06-09 22:05:27.000000000 -0500 +1 -1
  quiet_cmd_remove = REMOVE  $(unwanted)
@@ -69,7 +69,7 @@
        @:
 
  targets += $(install-file)
-$(install-file): scripts/headers_install.pl $(input-files) FORCE
+$(install-file): scripts/headers_install.sh $(input-files) FORCE
        $(if $(unwanted),$(call cmd,remove),)
        $(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@)))
        $(call if_changed,install)
scripts/headers_install.pl deleted +0 -58
@@ -1,57 +0,0 @@
-#!/usr/bin/perl -w
-#
-# headers_install prepare the listed header files for use in
-# user space and copy the files to their destination.
-#
-# Usage: headers_install.pl readdir installdir arch [files...]
-# readdir:    dir to open files
-# installdir: dir to install the files
-# arch:       current architecture
-#             arch is used to force a reinstallation when the arch
-#             changes because kbuild then detect a command line change.
-# files:      list of files to check
-#
-# Step in preparation for users space:
-# 1) Drop all use of compiler.h definitions
-# 2) Drop include of compiler.h
-# 3) Drop all sections defined out by __KERNEL__ (using unifdef)
-
-use strict;
-
-my ($readdir, $installdir, $arch, @files) = @ARGV;
-
-my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__";
-
-foreach my $file (@files) {
-       my $tmpfile = "$installdir/$file.tmp";
-
-       open(my $in, '<', "$readdir/$file")
-           or die "$readdir/$file: $!\n";
-       open(my $out, '>', $tmpfile)
-           or die "$tmpfile: $!\n";
-       while (my $line =<$in>) {
-               $line =~ s/([\s(])__user\s/$1/g;
-               $line =~ s/([\s(])__force\s/$1/g;
-               $line =~ s/([\s(])__iomem\s/$1/g;
-               $line =~ s/\s__attribute_const__\s/ /g;
-               $line =~ s/\s__attribute_const__$//g;
-               $line =~ s/^#include<linux\/compiler.h>//;
-               $line =~ s/(^|\s)(inline)\b/$1__$2__/g;
-               $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g;
-               $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g;
-               printf {$out} "%s", $line;
-       }
-       close $out;
-       close $in;
-
-       system $unifdef . " $tmpfile>  $installdir/$file";
-       # unifdef will exit 0 on success, and will exit 1 when the
-       # file was processed successfully but no changes were made,
-       # so abort only when it's higher than that.
-       my $e = $?>>  8;
-       if ($e>  1) {
-               die "$tmpfile: $!\n";
-       }
-       unlink $tmpfile;
-}
-exit 0;
--
#3 lore raw
In reply to Rob Landley

Hi,

Quoted 11 lines · Rob Landley

From: Rob Landley <[email protected]>

Remove perl from make headers_install by replacing a perl script (doing a simple regex search and replace) with a smaller and faster shell script implementation.  The new shell script is a single for loop calling sed and piping its output through unifdef to produce the target file.

Change from last time: better error handling.  Split "sed | unifdef" into two stages with a temp file because dash hasn't got PIPEFAIL.  Add check for exit code, add trap handler to delete output when exiting prematurely.

one more thing,

Quoted 42 lines

---

 scripts/Makefile.headersinst |    6 ++-- scripts/headers_install.pl   |   49 --------------------------------- scripts/headers_install.sh   |   39 ++++++++++++++++++++++++++

 3 files changed, 42 insertions(+), 52 deletions(-)

diff -ruN linux-2.6.30.old/scripts/headers_install.sh linux-2.6.30/scripts/headers_install.sh

scripts/headers_install.sh     2009-06-22 16:21:23.000000000 -0500 renamed from scripts/headers_install.sh 1969-12-31 18:00:00.000000000 -0600 +30 -0
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+if [ $# -lt 2 ]
+then
+       echo "Usage: headers_install.sh INDIR OUTDIR [FILES...]
+       echo
+       echo "Prepares kernel header files for use by user space, by removing"
+       echo "all compiler.h definitions and #includes, removing any"
+       echo "#ifdef __KERNEL__ sections, and putting __underscores__ around"
+       echo "asm/inline/volatile keywords."
+       echo
+       echo "INDIR:  directory to read each kernel header FILE from."
+       echo "OUTDIR: directory to write each userspace header FILE to."
+       echo "FILES:  list of header files to operate on."
+
+       exit 1
+fi
+
+# Grab arguments
+
+INDIR="$1"
+shift
+OUTDIR="$1"
+shift
+
+# Iterate through files listed on command line
+
+trap "rm -f $OUTDIR/$i $OUTDIR.sed" EXIT
+for i in "$@"
+do

scripts/headers_install.sh     2009-06-22 16:21:23.000000000 -0500 line 40

Quoted 10 lines
scripts/headers_install.sh     2009-06-22 16:21:23.000000000 -0500 renamed from scripts/headers_install.sh 1969-12-31 18:00:00.000000000 -0600 +10 -0
+       sed -r \
+               -e 's/([ \t(])(__user|__force|__iomem)[ \t]/\1/g' \
+               -e 's/__attribute_const__([ \t]|$)/\1/g' \
+               -e 's@^#include <linux/compiler.h>@@' \
+               -e 's/(^|[ \t])(inline|asm|volatile)([ \t(]|$)/\1__\2__\3/g' \
+               "$INDIR/$i" > "$OUTDIR/$i.sed" || exit 1
+       scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__ "$OUTDIR/$i.sed" \
+               > "$OUTDIR/$i"
+       [ $? -gt 1 ] && exit 1
+       rm -f "$OUTDIR/$i.sed"

you can avoid all the ugly and inconsistent[0] errors checking by adding a simple:

set -e

at the beginning of the script.

- Arnaud

ps: sorry for the late review, I was AFK last week.

[0]: ie. using an explicit test (use of the || operator) for the sed invocation, and an implicit test (check of the value of $?) for unifdef.