(root)/
m4-1.4.19/
lib/
trim.c
       1  /* Removes leading and/or trailing whitespaces
       2     Copyright (C) 2006-2021 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation; either version 3 of the License, or
       7     (at your option) any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  /* Written by Davide Angelocola <davide.angelocola@gmail.com> */
      18  
      19  #include <config.h>
      20  
      21  /* Specification.  */
      22  #include "trim.h"
      23  
      24  #include <ctype.h>
      25  #include <string.h>
      26  #include <stddef.h>
      27  #include <stdlib.h>
      28  
      29  #include "mbchar.h"
      30  #include "mbiter.h"
      31  #include "xalloc.h"
      32  
      33  /* Use this to suppress gcc's "...may be used before initialized" warnings. */
      34  #if defined GCC_LINT || defined lint
      35  # define IF_LINT(Code) Code
      36  #else
      37  # define IF_LINT(Code) /* empty */
      38  #endif
      39  
      40  char *
      41  trim2 (const char *s, int how)
      42  {
      43    char *d;
      44  
      45    d = strdup (s);
      46  
      47    if (!d)
      48      xalloc_die ();
      49  
      50    if (MB_CUR_MAX > 1)
      51      {
      52        mbi_iterator_t i;
      53  
      54        /* Trim leading whitespaces. */
      55        if (how != TRIM_TRAILING)
      56          {
      57            mbi_init (i, d, strlen (d));
      58  
      59            for (; mbi_avail (i) && mb_isspace (mbi_cur (i)); mbi_advance (i))
      60              ;
      61  
      62            memmove (d, mbi_cur_ptr (i), strlen (mbi_cur_ptr (i)) + 1);
      63          }
      64  
      65        /* Trim trailing whitespaces. */
      66        if (how != TRIM_LEADING)
      67          {
      68            unsigned int state = 0;
      69            char *r IF_LINT (= NULL); /* used only while state = 2 */
      70  
      71            mbi_init (i, d, strlen (d));
      72  
      73            for (; mbi_avail (i); mbi_advance (i))
      74              {
      75                if (state == 0 && mb_isspace (mbi_cur (i)))
      76                  continue;
      77  
      78                if (state == 0 && !mb_isspace (mbi_cur (i)))
      79                  {
      80                    state = 1;
      81                    continue;
      82                  }
      83  
      84                if (state == 1 && !mb_isspace (mbi_cur (i)))
      85                  continue;
      86  
      87                if (state == 1 && mb_isspace (mbi_cur (i)))
      88                  {
      89                    state = 2;
      90                    r = (char *) mbi_cur_ptr (i);
      91                  }
      92                else if (state == 2 && mb_isspace (mbi_cur (i)))
      93                  {
      94                    /* empty */
      95                  }
      96                else
      97                  {
      98                    state = 1;
      99                  }
     100              }
     101  
     102            if (state == 2)
     103              *r = '\0';
     104          }
     105      }
     106    else
     107      {
     108        char *p;
     109  
     110        /* Trim leading whitespaces. */
     111        if (how != TRIM_TRAILING)
     112          {
     113            for (p = d; *p && isspace ((unsigned char) *p); p++)
     114              ;
     115  
     116            memmove (d, p, strlen (p) + 1);
     117          }
     118  
     119        /* Trim trailing whitespaces. */
     120        if (how != TRIM_LEADING)
     121          {
     122            for (p = d + strlen (d) - 1;
     123                 p >= d && isspace ((unsigned char) *p); p--)
     124              *p = '\0';
     125          }
     126      }
     127  
     128    return d;
     129  }