# bre2ere.sed - convert BRE to ERE sed
#
# note: ^ and $ not at start of end resp. of the RE are considered as
# literal chars.
# (POSIX documents as an option /\(^a$\)/ to be equivalent to /^\(a\)$/,
# here it gets converted to /(\^a\$)/)
s/'/'a/g
s/_/'b/g
# parse the line
s/^/_/
s/_\([ ]*\)/\1_/
# look for optional addresses before the command
:addr
# a 's' in the hold buffer indicates that the RE was part of a subst
# command. Since we're looking for addresses, clear the hold buffer.
x
s/.*//
x
# skip <address>, <address><comma>, <address>!,
s/_\([0-9!,$ ]*\)/\1_/
# handle /re/ as if it was \/re/ (i.e. special case of \xrex)
/_\// {
s//\/_\//
b rebeg
}
# handle \xrex
/_\\'*./ {
# we will carry the delimiter after the _
s/_\\\('*.\)/\\\1_\1/
:rebeg
# first case: ^ as first position
s/\(_'*.\)^/^\1/
:reloop
/_\('*.\)\1/ b reend
# skip one ordinary char
s/\(_'*.\)\([^'/[\(){}+?|^]\)/\2\1/
# ( -> \(
s/\(_'*.\)\([(){}?+|^]\)/\\\2\1/
# \( -> (
s/\(_'*.\)\\\([(){}]\)/\2\1/
# $ -> \$ except if last
s/_\('*.\)$\1/$_\1\1/
s/\(_'*.\)\$/\\$\1/
# skip any other \x
s/\(_'*.\)\([\']'*[^(){}]\)/\2\1/
# skip bracket expression
s/\(_'*.\)\(\[\^'*.[^]]*]\)/\2\1/
s/\(_'*.\)\(\['*.[^]]*]\)/\2\1/
# loop
b reloop
:reend
# if an s is in the hold buf, go back to s
x
/s/ b subst
x
s/_\('*.\)\1/\1_/
}
# skip white space and any !
s/_\([! ]*\)/\1_/
# if a comma is found, loop for the second address
/_,/ b addr
# we now reach the command char
/_s'*./ {
s/_s\('*.\)/s\1_\1/
x
s/^/s/
x
b rebeg
:subst
x
s/_\('*.\)\1/\1_\1/
:rhsloop
/_\('*.\)\1/ b rhsend
s/\(_'*.\)\([^\']\)/\2\1/
s/\(_'*.\)\([\']'*.\)/\2\1/
/_'*.\\$/ {
s/_\('*.\)\\$/\\\1/
s/'b/_/g
s/'a/'/g
N
s/'/'a/g
s/_/'b/g
s/\\\('*.\)\(\n\)/\\\2_\1/
}
b rhsloop
:rhsend
s/_\('*.\)./\1_/
# flags
s/_\([0-9pg]*\)/\1_/
# w flag handled as the w command
}
/_y'*./ {
s/_y\('*.\)/y\1_\1/
:y1loop
/_\('*.\)\1/ {
s/_\('*.\)\1/\1_\1/
b y2loop
}
s/\(_'*.\)\([^\]\)/\2\1/
s/\(_'*.\)\([\']'*.\)/\2\1/
b y1loop
:y2loop
/_\('*.\)\1/ b y2end
s/\(_'*.\)\([^\]\)/\2\1/
s/\(_'*.\)\([\']'*.\)/\2\1/
b y2loop
:y2end
s/_\('*.\)\1/\1_/
}
# :label, b label, t label, r file, w file (cmd & flag), # comment
# all these include the end of line
/_\([bt:rw#]\)/ b out
# simple commands
s/_\([dDgGhHlnNpPqx}]\)/\1_/
# a\, c\, i\
/_\([aic]\)/ {
s//\1_/
:aloop
s/_\([^\]*\)/\1_/
/_\\$/ {
s//\\/
s/'b/_/g
s/'a/'/g
N
s/'/'a/g
s/_/'b/g
s/\(\n\)/\1_/
}
s/_\(\\:*.\)/\1_/
/_$/ !b aloop
b out
}
# skip whitespace
s/_\([ ]*\)/\1_/
# loop while there is still a command
/_[;{]/ {
s/_\([;{]\)/\1_/
b addr
}
/_$/ b out
# weird case
h
s/[^_]*_/unknown construct: /
p
i\
line was:
x
q
:out
# remove the _
s/_//
# unquote _ and '
s/'b/_/g
s/'a/'/g
### colorized by sedsed, a debugger and code formatter for sed scripts
### original script: http://sed.sf.net/local/scripts/bre2ere.sed