Merge pull request #4630 from Red-F/gotham-resume-pvr-lastplayedposition
[vuplus_xbmc] / xbmc / freebsd / FreeBSDGNUReplacements.c
1
2 #include "FreeBSDGNUReplacements.h"
3
4 #if __FreeBSD_version < 800067
5
6 /*-
7  * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 size_t
33 strnlen(const char *s, size_t maxlen)
34 {
35         size_t len;
36
37         for (len = 0; len < maxlen; len++, s++) {
38                 if (!*s)
39                         break;
40         }   
41         return (len);
42 }
43
44 /* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
45    This file is part of the GNU C Library.
46
47    The GNU C Library is free software; you can redistribute it and/or
48    modify it under the terms of the GNU Library General Public License as
49    published by the Free Software Foundation; either version 2 of the
50    License, or (at your option) any later version.
51
52    The GNU C Library is distributed in the hope that it will be useful,
53    but WITHOUT ANY WARRANTY; without even the implied warranty of
54    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
55    Library General Public License for more details.
56
57    You should have received a copy of the GNU Library General Public
58    License along with the GNU C Library; see the file COPYING.LIB.  If not,
59    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
60    Boston, MA 02111-1307, USA.
61 */
62
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <limits.h>
66 #include <errno.h>
67
68 /* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
69    (and null-terminate it). *LINEPTR is a pointer returned from malloc (or
70    NULL), pointing to *N characters of space.  It is realloc'd as
71    necessary.  Returns the number of characters read (not including the
72    null terminator), or -1 on error or EOF.  */
73
74 ssize_t
75 getdelim(char **lineptr, size_t *n, int terminator, FILE *stream)
76 {
77   char *line, *p;
78   size_t size, copy;
79
80   if (stream == NULL || lineptr == NULL || n == NULL)
81     {
82       errno = EINVAL;
83       return -1;
84     }
85
86   if (ferror (stream))
87     return -1;
88
89   /* Make sure we have a line buffer to start with.  */
90   if (*lineptr == NULL || *n < 2) /* !seen and no buf yet need 2 chars.  */
91     {
92 #ifndef MAX_CANON
93 #define MAX_CANON       256
94 #endif
95       line = (char *)realloc (*lineptr, MAX_CANON);
96       if (line == NULL)
97         return -1;
98       *lineptr = line;
99       *n = MAX_CANON;
100     }
101
102   line = *lineptr;
103   size = *n;
104
105   copy = size;
106   p = line;
107
108       while (1)
109         {
110           size_t len;
111
112           while (--copy > 0)
113             {
114               register int c = getc (stream);
115               if (c == EOF)
116                 goto lose;
117               else if ((*p++ = c) == terminator)
118                 goto win;
119             }
120
121           /* Need to enlarge the line buffer.  */
122           len = p - line;
123           size *= 2;
124           line = (char *)realloc (line, size);
125           if (line == NULL)
126             goto lose;
127           *lineptr = line;
128           *n = size;
129           p = line + len;
130           copy = size - len;
131         }
132
133  lose:
134   if (p == *lineptr)
135     return -1;
136   /* Return a partial line since we got an error in the middle.  */
137  win:
138   *p = '\0';
139   return p - *lineptr;
140 }
141
142 #endif
143
144 /* Compare strings while treating digits characters numerically.
145    Copyright (C) 1997, 2002, 2005 Free Software Foundation, Inc.
146    This file is part of the libiberty library.
147    Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
148
149    Libiberty is free software; you can redistribute it and/or
150    modify it under the terms of the GNU Lesser General Public
151    License as published by the Free Software Foundation; either
152    version 2.1 of the License, or (at your option) any later version.
153
154    Libiberty is distributed in the hope that it will be useful,
155    but WITHOUT ANY WARRANTY; without even the implied warranty of
156    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
157    Lesser General Public License for more details.
158
159    You should have received a copy of the GNU Lesser General Public
160    License along with the GNU C Library; if not, write to the Free
161    Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
162    02110-1301 USA.  */
163
164 #include <ctype.h>
165
166 #define ISASCII(c) isascii(c)
167 #define ISDIGIT(c) (ISASCII (c) && isdigit (c))
168 /* states: S_N: normal, S_I: comparing integral part, S_F: comparing
169            fractional parts, S_Z: idem but with leading Zeroes only */
170 #define  S_N    0x0
171 #define  S_I    0x4
172 #define  S_F    0x8
173 #define  S_Z    0xC
174
175 /* result_type: CMP: return diff; LEN: compare using len_diff/diff */
176 #define  CMP    2
177 #define  LEN    3
178
179
180 /* Compare S1 and S2 as strings holding indices/version numbers,
181    returning less than, equal to or greater than zero if S1 is less than,
182    equal to or greater than S2 (for more info, see the Glibc texinfo doc).  */
183
184 int
185 strverscmp (const char *s1, const char *s2)
186 {
187   const unsigned char *p1 = (const unsigned char *) s1;
188   const unsigned char *p2 = (const unsigned char *) s2;
189   unsigned char c1, c2;
190   int state;
191   int diff;
192
193   /* Symbol(s)    0       [1-9]   others  (padding)
194      Transition   (10) 0  (01) d  (00) x  (11) -   */
195   static const unsigned int next_state[] =
196     {
197       /* state    x    d    0    - */
198       /* S_N */  S_N, S_I, S_Z, S_N,
199       /* S_I */  S_N, S_I, S_I, S_I,
200       /* S_F */  S_N, S_F, S_F, S_F,
201       /* S_Z */  S_N, S_F, S_Z, S_Z
202     };
203
204   static const int result_type[] =
205     {
206       /* state   x/x  x/d  x/0  x/-  d/x  d/d  d/0  d/-
207                  0/x  0/d  0/0  0/-  -/x  -/d  -/0  -/- */
208
209       /* S_N */  CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
210                  CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
211       /* S_I */  CMP, -1,  -1,  CMP, +1,  LEN, LEN, CMP,
212                  +1,  LEN, LEN, CMP, CMP, CMP, CMP, CMP,
213       /* S_F */  CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
214                  CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
215       /* S_Z */  CMP, +1,  +1,  CMP, -1,  CMP, CMP, CMP,
216                  -1,  CMP, CMP, CMP
217     };
218
219   if (p1 == p2)
220     return 0;
221
222   c1 = *p1++;
223   c2 = *p2++;
224   /* Hint: '0' is a digit too.  */
225   state = S_N | ((c1 == '0') + (ISDIGIT (c1) != 0));
226
227   while ((diff = c1 - c2) == 0 && c1 != '\0')
228     {
229       state = next_state[state];
230       c1 = *p1++;
231       c2 = *p2++;
232       state |= (c1 == '0') + (ISDIGIT (c1) != 0);
233     }
234
235   state = result_type[state << 2 | (((c2 == '0') + (ISDIGIT (c2) != 0)))];
236
237   switch (state)
238     {
239     case CMP:
240       return diff;
241       
242     case LEN:
243       while (ISDIGIT (*p1++))
244         if (!ISDIGIT (*p2++))
245           return 1;
246       
247       return ISDIGIT (*p2) ? -1 : diff;
248       
249     default:
250       return state;
251     }
252 }