# 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
, , !,
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