summaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/solaris2/kopensolaris-gnu/deflt.c
blob: c75c1af83f8717981ab4ec9d442d58456f9d31ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/* Copyright (C) 2008 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by David Bartley <dtbartle@csclub.uwaterloo.ca>, 2008.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <defltP.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static __thread FILE *deflt_fp = NULL;
static __thread int deflt_flags = 0;
static __thread char deflt_buf[_DEFLT_BUFSIZE];


int defopen (char *fn)
{
  /* Close old file if open.  */
  if (deflt_fp)
    {
      fclose (deflt_fp);
      deflt_fp = NULL;
    }
  if (!fn)
    return 0;

  deflt_fp = fopen (fn, "r");
  if (!deflt_fp)
    return -1;

  /* Set default flags.  */
  deflt_flags = DC_STD;

  return 0;
}


char * defread (char *cp)
{
  if (!deflt_fp)
      return NULL;

  /* Rewind if needed.  */
  if ((deflt_flags & DC_NOREWIND) == 0)
    rewind (deflt_fp);

  size_t cplen = strlen (cp);
  int (*strcmpfunc)(const char *, const char *, size_t) =
      (deflt_flags & DC_CASE) ? strncmp : strncasecmp;
  while (fgets (deflt_buf, _DEFLT_BUFSIZE + 2, deflt_fp))
    {
      if (strlen (deflt_buf) > _DEFLT_BUFSIZE)
        break;

      /* Trim trailing newline.  */
      size_t len = strlen (deflt_buf);
      if (len && deflt_buf[len - 1] == '\n')
        deflt_buf[len - 1] = '\0';

      /* Eat spaces.  */
      char *bufp = deflt_buf - 1;
      while (*++bufp == ' ') ;

      if ((*strcmpfunc)(bufp, cp, cplen) == 0)
        {
          bufp += cplen;

          /* Strip quotes.  */
          if ((deflt_flags & DC_STRIP_QUOTES) && *bufp)
            {
              /* Strip leading quote.  */
              if (*bufp == '"' || *bufp == '\'')
                {
                  char *bufp2 = bufp, *bufp3 = bufp;
                  while ((*bufp2++ = *++bufp3)) ;
                }

              /* Strip trailing quote.  */
              len = strlen (bufp);
              if (len && (bufp[len - 1] == '"' || bufp[len - 1] == '\''))
                bufp[len - 1] = '\0';
            }

          return bufp;
        }
    }

  return NULL;
}


int defcntl (int cmd, int newflags)
{
  int oldflags = deflt_flags;
  switch (cmd)
    {
    case DC_GETFLAGS:
      return oldflags;
    case DC_SETFLAGS:
      deflt_flags = newflags;
      return oldflags;
    default:
      return -1;
    }
}