[PATCH 1/2] regedit: Overhaul Unicode line processing
Hugh McMaster
hugh.mcmaster at outlook.com
Sun Nov 20 05:33:34 CST 2016
Signed-off-by: Hugh McMaster <hugh.mcmaster at outlook.com>
---
programs/regedit/regproc.c | 159 +++++++++++++++------------------------------
1 file changed, 51 insertions(+), 108 deletions(-)
diff --git a/programs/regedit/regproc.c b/programs/regedit/regproc.c
index 5e4c2d2..a690a10 100644
--- a/programs/regedit/regproc.c
+++ b/programs/regedit/regproc.c
@@ -584,7 +584,7 @@ static void processSetValue(WCHAR* line, BOOL is_unicode)
*/
static void processRegEntry(WCHAR* stdInput, BOOL isUnicode)
{
- if ( stdInput[0] == '[') /* We are reading a new key */
+ if (stdInput[0] == '[') /* We are reading a new key */
{
WCHAR* keyEnd;
closeKey(); /* Close the previous key */
@@ -600,12 +600,11 @@ static void processRegEntry(WCHAR* stdInput, BOOL isUnicode)
delete_registry_key(stdInput + 1);
else if (openKeyW(stdInput) != ERROR_SUCCESS)
output_message(STRING_OPEN_KEY_FAILED, stdInput);
- } else if( currentKeyHandle &&
- (( stdInput[0] == '@') || /* reading a default @=data pair */
- ( stdInput[0] == '\"'))) /* reading a new value=data pair */
- {
- processSetValue(stdInput, isUnicode);
}
+ else if (currentKeyHandle && (stdInput[0] == '@' || stdInput[0] == '\"'))
+ processSetValue(stdInput, isUnicode); /* process @=data or value=data pairs */
+ else if (stdInput[0] == '#' || stdInput[0] == ';')
+ return; /* skip comment lines */
}
/******************************************************************************
@@ -731,120 +730,64 @@ static void processRegLinesA(FILE *in, char* first_chars)
HeapFree(GetProcessHeap(), 0, buf);
}
-static void processRegLinesW(FILE *in)
+static WCHAR *get_lineW(FILE *fp)
{
- WCHAR* buf = NULL; /* line read from input stream */
- ULONG lineSize = REG_VAL_BUF_SIZE;
- size_t CharsInBuf = -1;
-
- WCHAR* s; /* The pointer into buf for where the current fgets should read */
- WCHAR* line; /* The start of the current line */
-
- buf = HeapAlloc(GetProcessHeap(), 0, lineSize * sizeof(WCHAR));
- CHECK_ENOUGH_MEMORY(buf);
+ static size_t size, count, size_remaining, offset = 0;
+ static WCHAR *buf, *s, *line, *p, *next;
- s = buf;
- line = buf;
-
- while(!feof(in)) {
- size_t size_remaining;
- int size_to_get;
- WCHAR *s_eol = NULL; /* various local uses */
+ if (!size)
+ {
+ size = REG_VAL_BUF_SIZE;
+ s = buf = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
+ CHECK_ENOUGH_MEMORY(buf);
+ }
+ while (1)
+ {
+ static const WCHAR line_endings[] = {'\r','\n',0};
- /* Do we need to expand the buffer ? */
- assert (s >= buf && s <= buf + lineSize);
- size_remaining = lineSize - (s-buf);
- if (size_remaining < 2) /* room for 1 character and the \0 */
+ size_remaining = size - (s - buf);
+ if (size_remaining < 3)
{
- WCHAR *new_buffer;
- size_t new_size = lineSize + (REG_VAL_BUF_SIZE / sizeof(WCHAR));
- if (new_size > lineSize) /* no arithmetic overflow */
- new_buffer = HeapReAlloc (GetProcessHeap(), 0, buf, new_size * sizeof(WCHAR));
- else
- new_buffer = NULL;
- CHECK_ENOUGH_MEMORY(new_buffer);
- buf = new_buffer;
- line = buf;
- s = buf + lineSize - size_remaining;
- lineSize = new_size;
- size_remaining = lineSize - (s-buf);
+ WCHAR *new_buf = HeapReAlloc(GetProcessHeap(), 0, buf, (size * 2) * sizeof(WCHAR));
+ CHECK_ENOUGH_MEMORY(new_buf);
+ buf = new_buf;
+ s = buf + size - size_remaining;
+ size *= 2;
+ size_remaining = size - (s - buf);
}
+ line = s - offset;
+ count = fread(s, sizeof(WCHAR), size_remaining - 1, fp);
+ s[count] = 0;
+ s += count;
- /* Get as much as possible into the buffer, terminated either by
- * eof, error or getting the maximum amount. Abort on error.
- */
- size_to_get = (size_remaining > INT_MAX ? INT_MAX : size_remaining);
-
- CharsInBuf = fread(s, sizeof(WCHAR), size_to_get - 1, in);
- s[CharsInBuf] = 0;
-
- if (CharsInBuf == 0) {
- if (ferror(in)) {
- perror ("While reading input");
- exit (IO_ERROR);
- } else {
- assert (feof(in));
- *s = '\0';
- /* It is not clear to me from the definition that the
- * contents of the buffer are well defined on detecting
- * an eof without managing to read anything.
- */
- }
+ p = strpbrkW(line, line_endings);
+ if (!p)
+ {
+ HeapFree(GetProcessHeap(), 0, buf);
+ return NULL;
}
-
- /* If we didn't read the eol nor the eof go around for the rest */
- while(1)
+ next = p + 1;
+ if (*p == '\r' && *(p + 1) == '\n') next++;
+ *p = 0;
+ if (*(p - 1) == '\\')
{
- const WCHAR line_endings[] = {'\r','\n',0};
- s_eol = strpbrkW(line, line_endings);
-
- if(!s_eol) {
- /* Move the stub of the line to the start of the buffer so
- * we get the maximum space to read into, and so we don't
- * have to recalculate 'line' if the buffer expands */
- MoveMemory(buf, line, (strlenW(line)+1) * sizeof(WCHAR));
- line = buf;
- s = strchrW(line, '\0');
- break;
- }
-
- /* If it is a comment line then discard it and go around again */
- if (*line == '#' || *line == ';') {
- if (*s_eol == '\r' && *(s_eol+1) == '\n')
- line = s_eol + 2;
- else
- line = s_eol + 1;
- continue;
- }
-
- /* If there is a concatenating \\ then go around again */
- if (*(s_eol-1) == '\\') {
- WCHAR* NextLine = s_eol + 1;
-
- if(*s_eol == '\r' && *(s_eol+1) == '\n')
- NextLine++;
-
- while(*(NextLine+1) == ' ' || *(NextLine+1) == '\t')
- NextLine++;
-
- MoveMemory(s_eol - 1, NextLine, (CharsInBuf - (NextLine - s) + 1)*sizeof(WCHAR));
- CharsInBuf -= NextLine - s_eol + 1;
- continue;
- }
-
- /* Remove any line feed. Leave s_eol on the last \0 */
- if (*s_eol == '\r' && *(s_eol + 1) == '\n')
- *s_eol++ = '\0';
- *s_eol = '\0';
-
- processRegEntry(line, TRUE);
- line = s_eol + 1;
+ *(--p) = 0;
+ while (*next && isspace(*next)) next++;
+ MoveMemory(p, next, (lstrlenW(next) + 1) * sizeof(WCHAR));
+ continue;
}
+ offset = s - next;
+ return line;
}
+}
- closeKey();
+static void processRegLinesW(FILE *fp)
+{
+ WCHAR *line;
- HeapFree(GetProcessHeap(), 0, buf);
+ while ((line = get_lineW(fp)))
+ processRegEntry(line, TRUE);
+ closeKey();
}
/******************************************************************************
--
2.7.4
More information about the wine-patches
mailing list