# 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