Mercurial > hg > toybox
comparison toys/posix/sed.c @ 1646:8e506e89bb8c draft
Fix sed backslash parsing in square bracket pattern sections.
author | Rob Landley <rob@landley.net> |
---|---|
date | Sun, 04 Jan 2015 03:50:52 -0600 |
parents | 53bfe8ac762b |
children | 58cb2d7bd461 |
comparison
equal
deleted
inserted
replaced
1645:2ffee259f519 | 1646:8e506e89bb8c |
---|---|
673 | 673 |
674 if (i) { | 674 if (i) { |
675 struct step *primal; | 675 struct step *primal; |
676 | 676 |
677 if (!fd && *name=='-') { | 677 if (!fd && *name=='-') { |
678 error_msg("no -i on stdin"); | 678 error_msg("-i on stdin"); |
679 return; | 679 return; |
680 } | 680 } |
681 TT.fdout = copy_tempfile(fd, name, &tmp); | 681 TT.fdout = copy_tempfile(fd, name, &tmp); |
682 TT.count = 0; | 682 TT.count = 0; |
683 for (primal = (void *)TT.pattern; primal; primal = primal->next) | 683 for (primal = (void *)TT.pattern; primal; primal = primal->next) |
697 // returns processed copy of string (0 if error), *pstr advances to next | 697 // returns processed copy of string (0 if error), *pstr advances to next |
698 // unused char. if delim (or *delim) is 0 uses/saves starting char as delimiter | 698 // unused char. if delim (or *delim) is 0 uses/saves starting char as delimiter |
699 // if regxex, ignore delimiter in [ranges] | 699 // if regxex, ignore delimiter in [ranges] |
700 static char *unescape_delimited_string(char **pstr, char *delim, int regex) | 700 static char *unescape_delimited_string(char **pstr, char *delim, int regex) |
701 { | 701 { |
702 char *to, *from, d; | 702 char *to, *from, mode = 0, d; |
703 | 703 |
704 to = from = *pstr; | 704 to = from = *pstr; |
705 if (!delim || !*delim) { | 705 if (!delim || !*delim) { |
706 if (!(d = *(from++))) return 0; | 706 if (!(d = *(from++))) return 0; |
707 if (d == '\\') d = *(from++); | 707 if (d == '\\') d = *(from++); |
708 if (!d || d == '\\') return 0; | 708 if (!d || d == '\\') return 0; |
709 if (delim) *delim = d; | 709 if (delim) *delim = d; |
710 } else d = *delim; | 710 } else d = *delim; |
711 to = delim = xmalloc(strlen(*pstr)+1); | 711 to = delim = xmalloc(strlen(*pstr)+1); |
712 | 712 |
713 while (*from != d) { | 713 while (mode || *from != d) { |
714 if (!*from) return 0; | 714 if (!*from) return 0; |
715 | 715 |
716 // delimiter in regex character range doesn't count | 716 // delimiter in regex character range doesn't count |
717 if (*from == '[') { | 717 if (*from == '[') { |
718 int len = 1; | 718 mode = '['; |
719 | 719 if (from[1] == ']') *(to++) = *(from++); |
720 if (from[len] == ']') len++; | 720 } else if (mode && *from == ']') mode = 0; |
721 while (from[len] != ']') if (!from[len++]) return 0; | 721 else if (*from == '\\') { |
722 memmove(to, from, ++len); | |
723 to += len; | |
724 from += len; | |
725 continue; | |
726 } | |
727 if (*from == '\\') { | |
728 if (!from[1]) return 0; | 722 if (!from[1]) return 0; |
729 | 723 |
730 // Check escaped end delimiter before printf style escapes. | 724 // Check escaped end delimiter before printf style escapes. |
731 if (from[1] == d) from++; | 725 if (from[1] == d) from++; |
732 else if (from[1]=='\\') *(to++) = *(from++); | 726 else if (from[1]=='\\') *(to++) = *(from++); |
735 | 729 |
736 if (c) { | 730 if (c) { |
737 *(to++) = c; | 731 *(to++) = c; |
738 from+=2; | 732 from+=2; |
739 continue; | 733 continue; |
740 } | 734 } else if (from[1]) *(to++) = *(from++); |
741 } | 735 } |
742 } | 736 } |
743 *(to++) = *(from++); | 737 *(to++) = *(from++); |
744 } | 738 } |
745 *to = 0; | 739 *to = 0; |