/* mygetline.c: An implementation of getline to be used with Visual Studio.

   Copyright 2013 Akira Kakuto.

   This 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.

   This 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 this library; if not, see <http://www.gnu.org/licenses/>.  */

#include <stdio.h>
#include <errno.h>
#include <malloc.h>
#include <string.h>

#define  MAYBEOK 1024

int getline (char **line, size_t *n, FILE *fp)
{
  char buffer[MAYBEOK];
  char *p;
  int  len;

  if (line == NULL || n == NULL) {
    errno = EINVAL;
    return -1;
  }

  if (ferror (fp))
    return -1;

  if (feof (fp))
    return -1;

  buffer[MAYBEOK - 2] = '\0';
  (void)fgets (buffer, MAYBEOK, fp);

  if (buffer[MAYBEOK - 2] && buffer[MAYBEOK - 2] != '\n')
    return -1; /* line is too long */

  p = strchr (buffer, '\r');   
  if (p) {
    *p = '\n';
    *(p+1) = '\0';
  }

  len = strlen (buffer);

  if (*line == NULL) {
    *line = malloc (len + 1);
    *n = len + 1;
  } else if (*n < len + 1) {
    p = realloc (*line, len + 1);
    if (p == NULL)
      return -1;
    *line = p;
    *n = len + 1;
  }

  strcpy (*line, buffer); 
  return len;
}
