(root)/
gettext-0.22.4/
gettext-runtime/
src/
escapes.h
       1  /* Expand escape sequences in a string.
       2     Copyright (C) 1995-1997, 2000-2007, 2012, 2018-2020 Free Software
       3     Foundation, Inc.
       4     Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, May 1995.
       5  
       6     This program is free software: you can redistribute it and/or modify
       7     it under the terms of the GNU General Public License as published by
       8     the Free Software Foundation; either version 3 of the License, or
       9     (at your option) any later version.
      10  
      11     This program is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14     GNU General Public License for more details.
      15  
      16     You should have received a copy of the GNU General Public License
      17     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      18  
      19  /* Expand some escape sequences found in the argument string.
      20     If backslash_c_seen is != NULL, '\c' sequences are recognized and
      21     have the effect of setting *backslash_c_seen to true.
      22     Returns either the argument string or a freshly allocated string.  */
      23  static const char *
      24  expand_escapes (const char *str, bool *backslash_c_seen)
      25  {
      26    const char *cp = str;
      27  
      28    /* Find the location of the first escape sequence.
      29       If the string contains no escape sequences, return it right away.  */
      30    for (;;)
      31      {
      32        while (cp[0] != '\0' && cp[0] != '\\')
      33          ++cp;
      34        if (cp[0] == '\0')
      35          /* The argument string contains no escape sequence.  */
      36          return str;
      37        /* Found a backslash.  */
      38        if (cp[1] == '\0')
      39          return str;
      40        if (strchr ("abcfnrtv\\01234567", cp[1]) != NULL)
      41          break;
      42        ++cp;
      43      }
      44  
      45    {
      46      char *retval = XNMALLOC (strlen (str), char);
      47  
      48      memcpy (retval, str, cp - str);
      49      {
      50        char *rp = retval + (cp - str);
      51  
      52        do
      53          {
      54            /* Here cp[0] == '\\'.  */
      55            switch (*++cp)
      56              {
      57              case 'a':               /* alert */
      58                *rp++ = '\a';
      59                ++cp;
      60                break;
      61              case 'b':               /* backspace */
      62                *rp++ = '\b';
      63                ++cp;
      64                break;
      65              case 'f':               /* form feed */
      66                *rp++ = '\f';
      67                ++cp;
      68                break;
      69              case 'n':               /* new line */
      70                *rp++ = '\n';
      71                ++cp;
      72                break;
      73              case 'r':               /* carriage return */
      74                *rp++ = '\r';
      75                ++cp;
      76                break;
      77              case 't':               /* horizontal tab */
      78                *rp++ = '\t';
      79                ++cp;
      80                break;
      81              case 'v':               /* vertical tab */
      82                *rp++ = '\v';
      83                ++cp;
      84                break;
      85              case '\\':
      86                *rp++ = '\\';
      87                ++cp;
      88                break;
      89              case '0': case '1': case '2': case '3':
      90              case '4': case '5': case '6': case '7':
      91                {
      92                  int ch = *cp++ - '0';
      93  
      94                  if (*cp >= '0' && *cp <= '7')
      95                    {
      96                      ch *= 8;
      97                      ch += *cp++ - '0';
      98  
      99                      if (*cp >= '0' && *cp <= '7')
     100                        {
     101                          ch *= 8;
     102                          ch += *cp++ - '0';
     103                        }
     104                    }
     105                  *rp++ = ch;
     106                }
     107                break;
     108              case 'c':
     109                if (backslash_c_seen != NULL)
     110                  {
     111                    *backslash_c_seen = true;
     112                    ++cp;
     113                    break;
     114                  }
     115                FALLTHROUGH;
     116              default:
     117                *rp++ = '\\';
     118                break;
     119              }
     120  
     121            /* Find the next escape sequence.  */
     122            while (cp[0] != '\0' && cp[0] != '\\')
     123              *rp++ = *cp++;
     124          }
     125        while (cp[0] != '\0');
     126  
     127        /* Terminate the resulting string.  */
     128        *rp = '\0';
     129      }
     130  
     131      return retval;
     132    }
     133  }