Skip to content
Snippets Groups Projects
Commit 408ec13e authored by deuce's avatar deuce
Browse files

Add a POSIX.1 getdelim() implementation ispired by FreeBSDs.

parent 894bdb5b
No related branches found
No related tags found
No related merge requests found
...@@ -275,6 +275,85 @@ int DLLCALL unlock(int file, off_t offset, off_t size) ...@@ -275,6 +275,85 @@ int DLLCALL unlock(int file, off_t offset, off_t size)
return(i); return(i);
} }
static inline size_t
p2roundup(size_t n)
{
if(n & (n-1)) { // If n isn't a power of two already...
n--;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
#if SIZE_T_MAX > 0xffffffffU
n |= n >> 32;
#endif
n++;
}
return (n);
}
static inline int expandtofit(char **linep, size_t len, size_t *linecapp)
{
char *newline;
size_t newcap;
if(len > LONG_MAX + 1)
return -1;
if(len > *linecapp) {
if(len == LONG_MAX + 1)
newcap = LONG_MAX + 1;
else
newcap = p2roundup(len);
newline = realloc(*linep, newcap);
if(newline == NULL)
return -1;
*linecapp = newcap;
*linep = newline;
}
return 0;
}
long getdelim(char **linep, size_t *linecapp, int delimiter, FILE *stream)
{
size_t linelen;
char lbuf[1024];
size_t bc;
char *term = NULL;
long pos = ftell(stream);
if(linep == NULL || linecapp == NULL)
return -1;
if(*linep == NULL)
*linecapp = 0;
if(feof(stream)) {
if(expandtofit(linep, 1, linecapp))
return -1;
(*linep)[0]=0;
return -1;
}
linelen = 0;
for(;;) {
bc = fread(lbuf, 1, sizeof(lbuf), stream);
if(expandtofit(linep, linelen+bc, linecapp))
return -1;
memcpy(*linep+linelen, lbuf, bc);
term = strchr(*linep+linelen, delimiter);
linelen += bc;
if(bc < sizeof(lbuf))
break;
if(term)
break;
}
if(term) {
linelen = term - *linep;
linelen++;
fseek(stream, pos+linelen, SEEK_SET);
}
return linelen;
}
#endif /* !Unix && (MSVC || MinGW) */ #endif /* !Unix && (MSVC || MinGW) */
#ifdef __unix__ #ifdef __unix__
......
...@@ -166,6 +166,10 @@ extern "C" { ...@@ -166,6 +166,10 @@ extern "C" {
DLLEXPORT int DLLCALL unlock(int fd, off_t pos, off_t len); DLLEXPORT int DLLCALL unlock(int fd, off_t pos, off_t len);
#endif #endif
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__DMC__)) && !defined(__unix__)
long getdelim(char **linep, size_t *linecapp, int delimiter, FILE *stream)
#endif
#if !defined(__BORLANDC__) && defined(__unix__) #if !defined(__BORLANDC__) && defined(__unix__)
DLLEXPORT int DLLCALL sopen(const char* fn, int sh_access, int share, ...); DLLEXPORT int DLLCALL sopen(const char* fn, int sh_access, int share, ...);
DLLEXPORT off_t DLLCALL filelength(int fd); DLLEXPORT off_t DLLCALL filelength(int fd);
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#ifndef _WINSOCKAPI_ #ifndef _WINSOCKAPI_
#include <winsock2.h> /* socket/bind/etc. */ #include <winsock2.h> /* socket/bind/etc. */
#include <mswsock.h> /* Microsoft WinSock2 extensions */ #include <mswsock.h> /* Microsoft WinSock2 extensions */
#include <wspiapi.h> /* getaddrinfo() for Windows 2000 apparently */
#if defined(__BORLANDC__) #if defined(__BORLANDC__)
// Borland C++ builder 6 comes with a broken ws2tcpip.h header for GCC. // Borland C++ builder 6 comes with a broken ws2tcpip.h header for GCC.
#define _MSC_VER 7 #define _MSC_VER 7
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment