diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 4a7edfdacab..248bbf88635 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,13 @@ +2007-06-07 Steven G. Kargl + Jerry DeLisle + + PR fortran/32223 + * match.c (gfc_match_special_char): New function. Match special char. + Add handling '\0'. + * match.h: Add prototype. + * io.c (next_char): Use it. + * primary.c (next_string_char): Ditto. + 2007-06-06 Steven G. Kargl * decl.c: Miscellaneous whitespace fixes. diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c index 8e81d6a19fe..4d12b2416fb 100644 --- a/gcc/fortran/io.c +++ b/gcc/fortran/io.c @@ -141,40 +141,17 @@ next_char (int in_string) if (gfc_option.flag_backslash && c == '\\') { + int tmp; locus old_locus = gfc_current_locus; - switch (gfc_next_char_literal (1)) - { - case 'a': - c = '\a'; - break; - case 'b': - c = '\b'; - break; - case 't': - c = '\t'; - break; - case 'f': - c = '\f'; - break; - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case 'v': - c = '\v'; - break; - case '\\': - c = '\\'; - break; + /* Use a temp variable to avoid side effects from gfc_match_special_char + since it uses an int * for its argument. */ + tmp = (int)c; - default: - /* Unknown backslash codes are simply not expanded. */ - gfc_current_locus = old_locus; - break; - } + if (gfc_match_special_char (&tmp) == MATCH_NO) + gfc_current_locus = old_locus; + + c = (char)tmp; if (!(gfc_option.allow_std & GFC_STD_GNU) && !inhibit_warnings) gfc_warning ("Extension: backslash character at %C"); diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index 0f99a521189..e544d6d2a32 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -64,6 +64,56 @@ mstring intrinsic_operators[] = { /******************** Generic matching subroutines ************************/ +/* See if the next character is a special character that has + escaped by a \ via the -fbackslash option. */ + +match +gfc_match_special_char (int *c) +{ + + match m; + + m = MATCH_YES; + + switch (gfc_next_char_literal (1)) + { + case 'a': + *c = '\a'; + break; + case 'b': + *c = '\b'; + break; + case 't': + *c = '\t'; + break; + case 'f': + *c = '\f'; + break; + case 'n': + *c = '\n'; + break; + case 'r': + *c = '\r'; + break; + case 'v': + *c = '\v'; + break; + case '\\': + *c = '\\'; + break; + case '0': + *c = '\0'; + break; + default: + /* Unknown backslash codes are simply not expanded. */ + m = MATCH_NO; + break; + } + + return m; +} + + /* In free form, match at least one space. Always matches in fixed form. */ diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h index ffba10251a4..8a309c5f2dd 100644 --- a/gcc/fortran/match.h +++ b/gcc/fortran/match.h @@ -39,6 +39,7 @@ extern gfc_st_label *gfc_statement_label; /* match.c. */ /* Generic match subroutines. */ +match gfc_match_special_char (int *); match gfc_match_space (void); match gfc_match_eos (void); match gfc_match_small_literal_int (int *, int *); diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c index ce81f44fd2d..90b1d6840e4 100644 --- a/gcc/fortran/primary.c +++ b/gcc/fortran/primary.c @@ -732,38 +732,8 @@ next_string_char (char delimiter) { old_locus = gfc_current_locus; - switch (gfc_next_char_literal (1)) - { - case 'a': - c = '\a'; - break; - case 'b': - c = '\b'; - break; - case 't': - c = '\t'; - break; - case 'f': - c = '\f'; - break; - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case 'v': - c = '\v'; - break; - case '\\': - c = '\\'; - break; - - default: - /* Unknown backslash codes are simply not expanded */ - gfc_current_locus = old_locus; - break; - } + if (gfc_match_special_char (&c) == MATCH_NO) + gfc_current_locus = old_locus; if (!(gfc_option.allow_std & GFC_STD_GNU) && !inhibit_warnings) gfc_warning ("Extension: backslash character at %C");