X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Ftextfile.c;h=9bd9b6a770f1d846ce4cdeac3c7b9d131ddba74a;hb=a4123fea556d6c362318212127e25846981ea190;hp=c42a1724e427c2d7e77a1bc920689e52003357e1;hpb=0230cefb4cee3580a705364232feb72258994237;p=wimlib diff --git a/src/textfile.c b/src/textfile.c index c42a1724..9bd9b6a7 100644 --- a/src/textfile.c +++ b/src/textfile.c @@ -5,33 +5,24 @@ /* * 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 "wimlib/textfile.h" -#include "wimlib/util.h" - #include #include #include @@ -39,13 +30,19 @@ #include #include +#include "wimlib/encoding.h" +#include "wimlib/error.h" +#include "wimlib/file_io.h" +#include "wimlib/textfile.h" +#include "wimlib/util.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; @@ -87,20 +84,14 @@ read_file_contents(const tchar *path, u8 **buf_ret, size_t *bufsize_ret) } 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...) */ @@ -137,28 +128,15 @@ read_text_file_contents(const tchar *path, 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; } @@ -248,16 +226,22 @@ parse_text_file(const tchar *path, tchar *buf, size_t buflen, } } 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; } @@ -298,34 +282,35 @@ parse_text_file(const tchar *path, tchar *buf, size_t buflen, * 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, @@ -333,29 +318,32 @@ do_load_text_file(const tchar *path, { 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; }