Blame lib/trim.c

Packit 709fb3
/* Removes leading and/or trailing whitespaces
Packit 709fb3
   Copyright (C) 2006-2017 Free Software Foundation, Inc.
Packit 709fb3
Packit 709fb3
   This program is free software: you can redistribute it and/or modify
Packit 709fb3
   it under the terms of the GNU General Public License as published by
Packit 709fb3
   the Free Software Foundation; either version 3 of the License, or
Packit 709fb3
   (at your option) any later version.
Packit 709fb3
Packit 709fb3
   This program is distributed in the hope that it will be useful,
Packit 709fb3
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 709fb3
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 709fb3
   GNU General Public License for more details.
Packit 709fb3
Packit 709fb3
   You should have received a copy of the GNU General Public License
Packit 709fb3
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 709fb3
Packit 709fb3
/* Written by Davide Angelocola <davide.angelocola@gmail.com> */
Packit 709fb3
Packit 709fb3
#include <config.h>
Packit 709fb3
Packit 709fb3
/* Specification.  */
Packit 709fb3
#include "trim.h"
Packit 709fb3
Packit 709fb3
#include <ctype.h>
Packit 709fb3
#include <string.h>
Packit 709fb3
#include <stddef.h>
Packit 709fb3
#include <stdlib.h>
Packit 709fb3
Packit 709fb3
#include "mbchar.h"
Packit 709fb3
#include "mbiter.h"
Packit 709fb3
#include "xalloc.h"
Packit 709fb3
Packit 709fb3
/* Use this to suppress gcc's "...may be used before initialized" warnings. */
Packit 709fb3
#if defined GCC_LINT || defined lint
Packit 709fb3
# define IF_LINT(Code) Code
Packit 709fb3
#else
Packit 709fb3
# define IF_LINT(Code) /* empty */
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
trim2 (const char *s, int how)
Packit 709fb3
{
Packit 709fb3
  char *d;
Packit 709fb3
Packit 709fb3
  d = strdup (s);
Packit 709fb3
Packit 709fb3
  if (!d)
Packit 709fb3
    xalloc_die ();
Packit 709fb3
Packit 709fb3
  if (MB_CUR_MAX > 1)
Packit 709fb3
    {
Packit 709fb3
      mbi_iterator_t i;
Packit 709fb3
Packit 709fb3
      /* Trim leading whitespaces. */
Packit 709fb3
      if (how != TRIM_TRAILING)
Packit 709fb3
        {
Packit 709fb3
          mbi_init (i, d, strlen (d));
Packit 709fb3
Packit 709fb3
          for (; mbi_avail (i) && mb_isspace (mbi_cur (i)); mbi_advance (i))
Packit 709fb3
            ;
Packit 709fb3
Packit 709fb3
          memmove (d, mbi_cur_ptr (i), strlen (mbi_cur_ptr (i)) + 1);
Packit 709fb3
        }
Packit 709fb3
Packit 709fb3
      /* Trim trailing whitespaces. */
Packit 709fb3
      if (how != TRIM_LEADING)
Packit 709fb3
        {
Packit 709fb3
          unsigned int state = 0;
Packit 709fb3
          char *r IF_LINT (= NULL); /* used only while state = 2 */
Packit 709fb3
Packit 709fb3
          mbi_init (i, d, strlen (d));
Packit 709fb3
Packit 709fb3
          for (; mbi_avail (i); mbi_advance (i))
Packit 709fb3
            {
Packit 709fb3
              if (state == 0 && mb_isspace (mbi_cur (i)))
Packit 709fb3
                continue;
Packit 709fb3
Packit 709fb3
              if (state == 0 && !mb_isspace (mbi_cur (i)))
Packit 709fb3
                {
Packit 709fb3
                  state = 1;
Packit 709fb3
                  continue;
Packit 709fb3
                }
Packit 709fb3
Packit 709fb3
              if (state == 1 && !mb_isspace (mbi_cur (i)))
Packit 709fb3
                continue;
Packit 709fb3
Packit 709fb3
              if (state == 1 && mb_isspace (mbi_cur (i)))
Packit 709fb3
                {
Packit 709fb3
                  state = 2;
Packit 709fb3
                  r = (char *) mbi_cur_ptr (i);
Packit 709fb3
                }
Packit 709fb3
              else if (state == 2 && mb_isspace (mbi_cur (i)))
Packit 709fb3
                {
Packit 709fb3
                  /* empty */
Packit 709fb3
                }
Packit 709fb3
              else
Packit 709fb3
                {
Packit 709fb3
                  state = 1;
Packit 709fb3
                }
Packit 709fb3
            }
Packit 709fb3
Packit 709fb3
          if (state == 2)
Packit 709fb3
            *r = '\0';
Packit 709fb3
        }
Packit 709fb3
    }
Packit 709fb3
  else
Packit 709fb3
    {
Packit 709fb3
      char *p;
Packit 709fb3
Packit 709fb3
      /* Trim leading whitespaces. */
Packit 709fb3
      if (how != TRIM_TRAILING)
Packit 709fb3
        {
Packit 709fb3
          for (p = d; *p && isspace ((unsigned char) *p); p++)
Packit 709fb3
            ;
Packit 709fb3
Packit 709fb3
          memmove (d, p, strlen (p) + 1);
Packit 709fb3
        }
Packit 709fb3
Packit 709fb3
      /* Trim trailing whitespaces. */
Packit 709fb3
      if (how != TRIM_LEADING)
Packit 709fb3
        {
Packit 709fb3
          for (p = d + strlen (d) - 1;
Packit 709fb3
               p >= d && isspace ((unsigned char) *p); p--)
Packit 709fb3
            *p = '\0';
Packit 709fb3
        }
Packit 709fb3
    }
Packit 709fb3
Packit 709fb3
  return d;
Packit 709fb3
}