static const gchar * next_word_start (const gchar *haystack) { for (; *haystack; haystack = g_utf8_next_char (haystack)) { gunichar ch = g_utf8_get_char (haystack); if (is_word_break (ch)) break; } for (; *haystack; haystack = g_utf8_next_char (haystack)) { gunichar ch = g_utf8_get_char (haystack); if (is_word_break (ch)) continue; break; } g_return_val_if_fail (*haystack == '\0' || !is_word_break (*haystack), NULL); return haystack; }
static bool put_string(char **_buffer, size_t *_bufferSize, char *string) { size_t length, reserved, quotes; char *buffer = *_buffer, c; bool quoted; if (string == NULL) return true; for (length = reserved = quotes = 0; (c = string[length]) != '\0'; length++) { if (c == '"') quotes++; else if (is_word_break(c)) reserved++; } quoted = reserved || quotes; // update _bufferSize in any way, so that we can chain several // of these calls without having to check the return value // everytime *_bufferSize -= length + (quoted ? 2 + quotes : 0); if (*_bufferSize <= 0) return false; if (quoted) *(buffer++) = '"'; for (;(c = string[0]) != '\0'; string++) { if (c == '"') *(buffer++) = '\\'; *(buffer++) = c; } if (quoted) *(buffer++) = '"'; buffer[0] = '\0'; // update the buffer position *_buffer = buffer; return true; }
static status_t get_word(char **_pos, char **_word, int32 assignmentMode, bool allowNewLine) { char *pos = *_pos; char quoted = 0; bool newLine = false, end = false; int escaped = 0; bool charEscaped = false; // Skip any white space and comments while (pos[0] && ((allowNewLine && (isspace(pos[0]) || is_parameter_separator(pos[0]) || pos[0] == '#')) || (!allowNewLine && (pos[0] == '\t' || pos[0] == ' ')) || (assignmentMode == ALLOW_ASSIGNMENT && pos[0] == '='))) { // skip any comment lines if (pos[0] == '#') { while (pos[0] && pos[0] != '\n') pos++; } pos++; } if (pos[0] == '}' || pos[0] == '\0') { // if we just read some white space before an end of a // parameter, this is just no parameter at all *_pos = pos; return NO_PARAMETER; } // Read in a word - might contain escaped (\) spaces, or it // might also be quoted (" or '). if (pos[0] == '"' || pos[0] == '\'') { quoted = pos[0]; pos++; } *_word = pos; while (pos[0]) { if (charEscaped) charEscaped = false; else if (pos[0] == '\\') { charEscaped = true; escaped++; } else if ((!quoted && (is_word_break(pos[0]) || (assignmentMode != IGNORE_ASSIGNMENT && pos[0] == '='))) || (quoted && pos[0] == quoted)) break; pos++; } // "String exceeds line" - missing end quote if (quoted && pos[0] != quoted) return B_BAD_DATA; // last character is a backslash if (charEscaped) return B_BAD_DATA; end = pos[0] == '\0'; newLine = is_parameter_separator(pos[0]) || end; pos[0] = '\0'; // Correct name if there were any escaped characters if (escaped) { char *word = *_word; int offset = 0; while (word <= pos) { if (word[0] == '\\') { offset--; word++; } word[offset] = word[0]; word++; } } if (end) { *_pos = pos; return B_OK; } // Scan for next beginning word, open brackets, or comment start pos++; while (true) { *_pos = pos; if (!pos[0]) return B_NO_ERROR; if (is_parameter_separator(pos[0])) { // an open bracket '{' could follow after the first // newline, but not later if (newLine) return B_NO_ERROR; newLine = true; } else if (pos[0] == '{' || pos[0] == '}' || pos[0] == '#') return B_NO_ERROR; else if (!isspace(pos[0])) return newLine ? B_NO_ERROR : CONTINUE_PARAMETER; pos++; } }