(root)/
gettext-0.22.4/
gettext-tools/
src/
quote.h
       1  /* Handle quoted segments of a string.
       2     Copyright (C) 2014-2016 Free Software Foundation, Inc.
       3     Written by Daiki Ueno <ueno@gnu.org>, 2015.
       4  
       5     This program is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU General Public License as published by
       7     the Free Software Foundation; either version 3 of the License, or
       8     (at your option) any later version.
       9  
      10     This program is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU General Public License for more details.
      14  
      15     You should have received a copy of the GNU General Public License
      16     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  #ifndef _QUOTE_H
      19  #define _QUOTE_H
      20  
      21  #include <stdbool.h>
      22  
      23  
      24  #ifdef __cplusplus
      25  extern "C" {
      26  #endif
      27  
      28  static void
      29  scan_quoted (const char *input, size_t length,
      30               void (* callback) (char quote, const char *quoted,
      31                                  size_t quoted_length,
      32                                  void *data),
      33               void *data)
      34  {
      35    const char *p, *start, *end;
      36    bool seen_opening;
      37  
      38    /* START shall point to the beginning of a quoted segment, END
      39       points to the end of the entire input string.  */
      40    start = input;
      41    end = &input[length - 1];
      42    
      43    /* True if we have seen a character which could be an opening
      44       quotation mark.  Note that we can't determine if it is really an
      45       opening quotation mark until we see a closing quotation mark.  */
      46    seen_opening = false;
      47  
      48    for (p = start; p <= end; p++)
      49      {
      50        switch (*p)
      51          {
      52          case '"':
      53            if (seen_opening)
      54              {
      55                if (*start == '"')
      56                  {
      57                    if (p == start + 1)
      58                      /* Consider "" as "".  */
      59                      callback ('\0', "\"\"", 2, data);
      60                    else
      61                      /* "..." */
      62                      callback ('"', start + 1, p - (start + 1), data);
      63  
      64                    start = p + 1;
      65                    seen_opening = false;
      66                  }
      67              }
      68            else
      69              {
      70                callback ('\0', start, p - start, data);
      71                start = p;
      72                seen_opening = true;
      73              }
      74            break;
      75  
      76          case '`':
      77            if (seen_opening)
      78              {
      79                if (*start == '`')
      80                  {
      81                    callback ('\0', start, p - start, data);
      82                    start = p;
      83                  }
      84              }
      85            else
      86              {
      87                callback ('\0', start, p - start, data);
      88                start = p;
      89                seen_opening = true;
      90              }
      91            break;
      92  
      93          case '\'':
      94            if (seen_opening)
      95              {
      96                if (/* `...' */
      97                    *start == '`'
      98                    /* '...', where
      99                       - The left quote is preceded by a space, and the
     100                         right quote is followed by a space.
     101                       - The left quote is preceded by a space, and the
     102                         right quote is at the end of line.
     103                       - The left quote is at the beginning of the line, and
     104                         the right quote is followed by a space.  */
     105                    || (*start == '\''
     106                        && (((start > input && *(start - 1) == ' ')
     107                             && (p == end || *(p + 1) == '\n' || *(p + 1) == ' '))
     108                            || ((start == input || *(start - 1) == '\n')
     109                                && p < end && *(p + 1) == ' '))))
     110                  {
     111                    callback ('\'', start + 1, p - (start + 1), data);
     112                    start = p + 1;
     113                  }
     114                else
     115                  {
     116                    callback ('\0', start, p - start, data);
     117                    start = p;
     118                  }
     119                seen_opening = false;
     120              }
     121            else if (p == input || *(p - 1) == '\n' || *(p - 1) == ' ')
     122              {
     123                callback ('\0', start, p - start, data);
     124                start = p;
     125                seen_opening = true;
     126              }
     127            break;
     128          }
     129      }
     130  
     131    /* Copy the rest.  */
     132    if (p > start)
     133      callback ('\0', start, p - start, data);
     134  }
     135  
     136  
     137  #ifdef __cplusplus
     138  }
     139  #endif
     140  
     141  
     142  #endif /* _QUOTE_H */