Skip to content

Commit 78457bc

Browse files
jrngitster
authored andcommitted
compat: add strtok_r()
Windows does not have strtok_r (and while it does have an identical strtok_s, but it is not obvious how to use it). Grab an implementation from glibc. The svn-fe tool uses strtok_r to parse paths. Acked-by: Johannes Sixt <j6t@kdbg.org> Helped-by: Jakub Narebski <jnareb@gmail.com> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 6ad263c commit 78457bc

File tree

5 files changed

+81
-0
lines changed

5 files changed

+81
-0
lines changed

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ all::
6868
#
6969
# Define NO_MKSTEMPS if you don't have mkstemps in the C library.
7070
#
71+
# Define NO_STRTOK_R if you don't have strtok_r in the C library.
72+
#
7173
# Define NO_LIBGEN_H if you don't have libgen.h.
7274
#
7375
# Define NEEDS_LIBGEN if your libgen needs -lgen when linking
@@ -1041,6 +1043,7 @@ ifeq ($(uname_S),Windows)
10411043
NO_UNSETENV = YesPlease
10421044
NO_STRCASESTR = YesPlease
10431045
NO_STRLCPY = YesPlease
1046+
NO_STRTOK_R = YesPlease
10441047
NO_MEMMEM = YesPlease
10451048
# NEEDS_LIBICONV = YesPlease
10461049
NO_ICONV = YesPlease
@@ -1095,6 +1098,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
10951098
NO_UNSETENV = YesPlease
10961099
NO_STRCASESTR = YesPlease
10971100
NO_STRLCPY = YesPlease
1101+
NO_STRTOK_R = YesPlease
10981102
NO_MEMMEM = YesPlease
10991103
NEEDS_LIBICONV = YesPlease
11001104
OLD_ICONV = YesPlease
@@ -1325,6 +1329,10 @@ endif
13251329
ifdef NO_STRTOULL
13261330
COMPAT_CFLAGS += -DNO_STRTOULL
13271331
endif
1332+
ifdef NO_STRTOK_R
1333+
COMPAT_CFLAGS += -DNO_STRTOK_R
1334+
COMPAT_OBJS += compat/strtok_r.o
1335+
endif
13281336
ifdef NO_SETENV
13291337
COMPAT_CFLAGS += -DNO_SETENV
13301338
COMPAT_OBJS += compat/setenv.o

compat/strtok_r.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/* Reentrant string tokenizer. Generic version.
2+
Copyright (C) 1991,1996-1999,2001,2004 Free Software Foundation, Inc.
3+
This file is part of the GNU C Library.
4+
5+
The GNU C Library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
The GNU C Library 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 GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with the GNU C Library; if not, write to the Free
17+
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18+
02111-1307 USA. */
19+
20+
#include "../git-compat-util.h"
21+
22+
/* Parse S into tokens separated by characters in DELIM.
23+
If S is NULL, the saved pointer in SAVE_PTR is used as
24+
the next starting point. For example:
25+
char s[] = "-abc-=-def";
26+
char *sp;
27+
x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def"
28+
x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL
29+
x = strtok_r(NULL, "=", &sp); // x = NULL
30+
// s = "abc\0-def\0"
31+
*/
32+
char *
33+
gitstrtok_r (char *s, const char *delim, char **save_ptr)
34+
{
35+
char *token;
36+
37+
if (s == NULL)
38+
s = *save_ptr;
39+
40+
/* Scan leading delimiters. */
41+
s += strspn (s, delim);
42+
if (*s == '\0')
43+
{
44+
*save_ptr = s;
45+
return NULL;
46+
}
47+
48+
/* Find the end of the token. */
49+
token = s;
50+
s = strpbrk (token, delim);
51+
if (s == NULL)
52+
/* This token finishes the string. */
53+
*save_ptr = token + strlen (token);
54+
else
55+
{
56+
/* Terminate the token and make *SAVE_PTR point past it. */
57+
*s = '\0';
58+
*save_ptr = s + 1;
59+
}
60+
return token;
61+
}

config.mak.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ NO_IPV6=@NO_IPV6@
4646
NO_C99_FORMAT=@NO_C99_FORMAT@
4747
NO_HSTRERROR=@NO_HSTRERROR@
4848
NO_STRCASESTR=@NO_STRCASESTR@
49+
NO_STRTOK_R=@NO_STRTOK_R@
4950
NO_MEMMEM=@NO_MEMMEM@
5051
NO_STRLCPY=@NO_STRLCPY@
5152
NO_UINTMAX_T=@NO_UINTMAX_T@

configure.ac

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,12 @@ GIT_CHECK_FUNC(strcasestr,
783783
[NO_STRCASESTR=YesPlease])
784784
AC_SUBST(NO_STRCASESTR)
785785
#
786+
# Define NO_STRTOK_R if you don't have strtok_r
787+
GIT_CHECK_FUNC(strtok_r,
788+
[NO_STRTOK_R=],
789+
[NO_STRTOK_R=YesPlease])
790+
AC_SUBST(NO_STRTOK_R)
791+
#
786792
# Define NO_MEMMEM if you don't have memmem.
787793
GIT_CHECK_FUNC(memmem,
788794
[NO_MEMMEM=],

git-compat-util.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,11 @@ extern size_t gitstrlcpy(char *, const char *, size_t);
312312
extern uintmax_t gitstrtoumax(const char *, char **, int);
313313
#endif
314314

315+
#ifdef NO_STRTOK_R
316+
#define strtok_r gitstrtok_r
317+
extern char *gitstrtok_r(char *s, const char *delim, char **save_ptr);
318+
#endif
319+
315320
#ifdef NO_HSTRERROR
316321
#define hstrerror githstrerror
317322
extern const char *githstrerror(int herror);

0 commit comments

Comments
 (0)