/*
* Copyright (C) 2014 Eric Biggers
*
- * This file is part of wimlib, a library for working with WIM files.
+ * This file 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 3 of the License, or (at your option) any
+ * later version.
*
- * wimlib is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option)
- * any later version.
- *
- * wimlib 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 General Public License for more
+ * This file 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 General Public License
- * along with wimlib; if not, see http://www.gnu.org/licenses/.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this file; if not, see http://www.gnu.org/licenses/.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-#include "wimlib/assert.h"
#include "wimlib/encoding.h"
#include "wimlib/error.h"
#include "wimlib/file_io.h"
#include <unistd.h>
static int
-read_file_contents(const tchar *path, u8 **buf_ret, size_t *bufsize_ret)
+read_file_contents(const tchar *path, void **buf_ret, size_t *bufsize_ret)
{
int raw_fd;
struct filedes fd;
struct stat st;
- u8 *buf;
+ void *buf;
int ret;
int errno_save;
}
static int
-read_text_file_contents(const tchar *path,
- tchar **buf_ret, size_t *buflen_ret)
+translate_text_buffer(const u8 *buf_raw, size_t bufsize_raw,
+ tchar **tstr_ret, size_t *tstr_nchars_ret)
{
- int ret;
- u8 *buf_raw;
- size_t bufsize_raw;
size_t offset_raw;
bool utf8;
tchar *buf_tstr;
size_t bufsize_tstr;
-
- ret = read_file_contents(path, &buf_raw, &bufsize_raw);
- if (ret)
- return ret;
+ int ret;
/* Guess the encoding: UTF-8 or UTF-16LE. (Something weirder and you're
* out of luck, sorry...) */
bufsize_raw - offset_raw,
&buf_tstr, &bufsize_tstr);
} else {
- #if TCHAR_IS_UTF16LE
- bufsize_tstr = bufsize_raw - offset_raw;
- buf_tstr = MALLOC(bufsize_tstr + 2);
- if (buf_tstr) {
- memcpy(buf_tstr, buf_raw + offset_raw, bufsize_tstr);
- ((u8*)buf_tstr)[bufsize_tstr + 0] = 0;
- ((u8*)buf_tstr)[bufsize_tstr + 1] = 0;
- } else {
- ret = WIMLIB_ERR_NOMEM;
- }
- #else
ret = utf16le_to_tstr((const utf16lechar *)(buf_raw + offset_raw),
bufsize_raw - offset_raw,
&buf_tstr, &bufsize_tstr);
- #endif
}
- FREE(buf_raw);
if (ret)
return ret;
- *buf_ret = buf_tstr;
- *buflen_ret = bufsize_tstr / sizeof(tchar);
+ *tstr_ret = buf_tstr;
+ *tstr_nchars_ret = bufsize_tstr / sizeof(tchar);
return 0;
}
}
}
line_begin[line_len - 1] = T(']');
- if (current_section < 0)
- WARNING("%"TS":%lu: Unrecognized section \"%"TS"\"",
- path, line_no, line_begin);
+ if (current_section < 0) {
+ if (!(flags & LOAD_TEXT_FILE_NO_WARNINGS)) {
+ WARNING("%"TS":%lu: Unrecognized section \"%"TS"\"",
+ path, line_no, line_begin);
+ }
+ }
continue;
}
if (current_section < 0) {
- if (current_section == NOT_IN_SECTION)
- WARNING("%"TS":%lu: Not in a bracketed section!",
- path, line_no);
+ if (current_section == NOT_IN_SECTION) {
+ if (!(flags & LOAD_TEXT_FILE_NO_WARNINGS)) {
+ WARNING("%"TS":%lu: Not in a bracketed section!",
+ path, line_no);
+ }
+ }
continue;
}
* Path to the file on disk to read, or a dummy name for the buffer.
* @buf
* If NULL, the data will be read from the @path file. Otherwise the data
- * will be read from this buffer, which must be newline-terminated.
- * @buflen
- * Length of buffer in 'tchars'; ignored if @buf is NULL.
- * @buf_ret
+ * will be read from this buffer.
+ * @bufsize
+ * Length of buffer in bytes; ignored if @buf is NULL.
+ * @mem_ret
* On success, a pointer to a buffer backing the parsed lines is stored
- * here. If @buf is not NULL, this will be @buf. Otherwise, this will be
- * an allocated buffer that must be freed when finished with the lines.
+ * here. This must be freed after the parsed lines are done being used.
* @pos_sections
* Specifications of allowed sections in the file. Each such specification
* consists of the name of the section (e.g. [ExclusionList], like in the
* INI file format), along with a pointer to the list of lines parsed for
* that section. Use an empty name to indicate the destination of lines
- * not in any section.
+ * not in any section. Each list must be initialized to an empty string
+ * set.
* @num_pos_sections
- * Length of @pos_sections array.
+ * Number of entries in the @pos_sections array.
* @flags
- * LOAD_TEXT_FILE_REMOVE_QUOTES or 0.
+ * Flags: LOAD_TEXT_FILE_REMOVE_QUOTES, LOAD_TEXT_FILE_NO_WARNINGS.
* @mangle_line
- * Optional callback to modify each line being read.
+ * Optional callback to validate and/or modify each line being read.
*
- * Returns 0 on success or a positive error code on failure.
+ * Returns 0 on success; nonzero on failure.
*
- * Unknown sections are ignored (warning printed).
+ * Unknown sections are ignored, but a warning is printed for each, unless
+ * LOAD_TEXT_FILE_NO_WARNINGS is specified.
*/
int
do_load_text_file(const tchar *path,
- tchar *buf, size_t buflen,
- tchar **buf_ret,
+ const void *buf, size_t bufsize,
+ void **mem_ret,
const struct text_file_section *pos_sections,
int num_pos_sections,
int flags,
{
int ret;
bool pathmode = (buf == NULL);
+ tchar *tstr;
+ size_t tstr_nchars;
if (pathmode) {
- ret = read_text_file_contents(path, &buf, &buflen);
+ ret = read_file_contents(path, (void **)&buf, &bufsize);
if (ret)
return ret;
-
- /* Overwrite '\0' with '\n' to avoid special case of last line
- * not terminated with '\n'. */
- buf[buflen++] = T('\n');
- } else {
- wimlib_assert(buflen > 0 && buf[buflen - 1] == T('\n'));
}
- ret = parse_text_file(path, buf, buflen, pos_sections,
+ ret = translate_text_buffer(buf, bufsize, &tstr, &tstr_nchars);
+ if (pathmode)
+ FREE((void *)buf);
+ if (ret)
+ return ret;
+
+ tstr[tstr_nchars++] = T('\n');
+
+ ret = parse_text_file(path, tstr, tstr_nchars, pos_sections,
num_pos_sections, flags, mangle_line);
if (ret) {
for (int i = 0; i < num_pos_sections; i++)
FREE(pos_sections[i].strings->strings);
- if (pathmode)
- FREE(buf);
+ FREE(tstr);
return ret;
}
- *buf_ret = buf;
+ *mem_ret = tstr;
return 0;
}