Skip to content

Commit

Permalink
cmdline.c: add getdelim code for old macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
barracuda156 committed Jun 1, 2022
1 parent 3463610 commit 10cf452
Showing 1 changed file with 94 additions and 0 deletions.
94 changes: 94 additions & 0 deletions lib/cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,100 @@
#include "treemerge.h"
#include "utilities.h"

#if defined(__APPLE__)
#include <AvailabilityMacros.h>
#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
/* there is no getdelim */
#if __STDC_VERSION__ >= 199901L
/* restrict is a keyword */
#else
# define restrict
#endif

#ifndef _POSIX_SOURCE
typedef long ssize_t;
#define SSIZE_MAX LONG_MAX
#endif

ssize_t getdelim(char **restrict lineptr, size_t *restrict n, int delimiter,
FILE *restrict stream);
ssize_t getline(char **restrict lineptr, size_t *restrict n,
FILE *restrict stream);

#define _GETDELIM_GROWBY 128 /* amount to grow line buffer by */
#define _GETDELIM_MINLEN 4 /* minimum line buffer size */

ssize_t getdelim(char **restrict lineptr, size_t *restrict n, int delimiter,
FILE *restrict stream)
{
char *buf, *pos;
int c;
ssize_t bytes;

if (lineptr == NULL || n == NULL) {
errno = EINVAL;
return -1;
}
if (stream == NULL) {
errno = EBADF;
return -1;
}

/* resize (or allocate) the line buffer if necessary */
buf = *lineptr;
if (buf == NULL || *n < _GETDELIM_MINLEN) {
buf = realloc(*lineptr, _GETDELIM_GROWBY);
if (buf == NULL) {
/* ENOMEM */
return -1;
}
*n = _GETDELIM_GROWBY;
*lineptr = buf;
}

/* read characters until delimiter is found, end of file is reached, or an error occurs. */
bytes = 0;
pos = buf;
while ((c = getc(stream)) != EOF) {
if (bytes + 1 >= SSIZE_MAX) {
errno = EOVERFLOW;
return -1;
}
bytes++;
if (bytes >= *n - 1) {
buf = realloc(*lineptr, *n + _GETDELIM_GROWBY);
if (buf == NULL) {
/* ENOMEM */
return -1;
}
*n += _GETDELIM_GROWBY;
pos = buf + bytes - 1;
*lineptr = buf;
}

*pos++ = (char) c;
if (c == delimiter) {
break;
}
}

if (ferror(stream) || (feof(stream) && (bytes == 0))) {
/* EOF, or an error from getc(). */
return -1;
}

*pos = '\0';
return bytes;
}

ssize_t getline(char **restrict lineptr, size_t *restrict n,
FILE *restrict stream)
{
return getdelim(lineptr, n, '\n', stream);
}
#endif
#endif

/* define paranoia levels */
static const RmDigestType RM_PARANOIA_LEVELS[] = {RM_DIGEST_METRO,
RM_DIGEST_METRO256,
Expand Down

0 comments on commit 10cf452

Please sign in to comment.