From 4beec8f055fd3b0cc4ef618cce8b52c58dd0ee08 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 6 Sep 2017 17:40:06 +0300 Subject: Add implementation --- libpkgconf/fileio.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 libpkgconf/fileio.c (limited to 'libpkgconf/fileio.c') diff --git a/libpkgconf/fileio.c b/libpkgconf/fileio.c new file mode 100644 index 0000000..d1c848f --- /dev/null +++ b/libpkgconf/fileio.c @@ -0,0 +1,120 @@ +/* + * fileio.c + * File reading utilities + * + * Copyright (c) 2012 pkgconf authors (see AUTHORS). + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * This software is provided 'as is' and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising + * from the use of this software. + */ + +#include + +char * +pkgconf_fgetline(char *line, size_t size, FILE *stream) +{ + char *s = line; + char *end = line + size - 1; + bool quoted = false; + int c = '\0', c2; + + if (s == NULL) + return NULL; + + while (s < end && (c = getc(stream)) != EOF) + { + if (c == '\\') + { + quoted = true; + continue; + } + else if (c == '#') + { + if (!quoted) { + /* Skip the rest of the line */ + do { + c = getc(stream); + } while (c != '\n' && c != EOF); + *s++ = c; + break; + } + quoted = false; + continue; + } + else if (c == '\n') + { + if (quoted) + { + /* Trim spaces */ + do { + c2 = getc(stream); + } while (c2 == '\t' || c2 == ' '); + + ungetc(c2, stream); + + quoted = false; + continue; + } + else + { + *s++ = c; + } + + break; + } + else if (c == '\r') + { + *s++ = '\n'; + + if ((c2 = getc(stream)) == '\n') + { + if (quoted) + { + quoted = false; + continue; + } + + break; + } + + ungetc(c2, stream); + + if (quoted) + { + quoted = false; + continue; + } + + break; + } + else + { + if (quoted) { + *s++ = '\\'; + quoted = false; + } + *s++ = c; + } + + } + + if (c == EOF && (s == line || ferror(stream))) + return NULL; + + *s = '\0'; + + /* Remove newline character. */ + if (s > line && *(--s) == '\n') { + *s = '\0'; + + if (s > line && *(--s) == '\r') + *s = '\0'; + } + + return line; +} -- cgit v1.1