[Mesa-dev] [PATCH 04/12] glcpp: Use string_buffer for continuations removal
Vladislav Egorov
vegorov180 at gmail.com
Sat Jan 7 19:02:05 UTC 2017
Migrate removal of line continuations to string_buffer. Before this
it used ralloc_strncat() to append strings, which internally
each time calculates strlen() of its argument. Its argument is
entire shader, so it multiple time scans the whole shader text.
---
src/compiler/glsl/glcpp/glcpp.h | 11 +++++++++--
src/compiler/glsl/glcpp/pp.c | 28 +++++++++++++++++++++-------
2 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/src/compiler/glsl/glcpp/glcpp.h b/src/compiler/glsl/glcpp/glcpp.h
index a9c08e6..34f8b66 100644
--- a/src/compiler/glsl/glcpp/glcpp.h
+++ b/src/compiler/glsl/glcpp/glcpp.h
@@ -275,9 +275,9 @@ glcpp_printf(glcpp_parser_t *parser, struct string_buffer *str,
/* Inlining is necessary to resolve length of literal strings statically */
static inline bool
-glcpp_append(glcpp_parser_t *parser, struct string_buffer *str, const char *s)
+glcpp_append_length(glcpp_parser_t *parser, struct string_buffer *str,
+ const char *s, size_t len)
{
- size_t len = strlen(s);
if (likely(glcpp_strbuffer_ensure_capacity(parser, str, len))) {
/* Don't copy null-terminator, str->buf is
* not a null-terminating string
@@ -291,6 +291,13 @@ glcpp_append(glcpp_parser_t *parser, struct string_buffer *str, const char *s)
}
static inline bool
+glcpp_append(glcpp_parser_t *parser, struct string_buffer *str, const char *s)
+{
+ size_t len = strlen(s);
+ return glcpp_append_length(parser, str, s, len);
+}
+
+static inline bool
glcpp_append_char(glcpp_parser_t *parser, struct string_buffer *str, char ch)
{
assert(str->capacity > 0 && ch != '\0');
diff --git a/src/compiler/glsl/glcpp/pp.c b/src/compiler/glsl/glcpp/pp.c
index 7fbadf9..af4ec93 100644
--- a/src/compiler/glsl/glcpp/pp.c
+++ b/src/compiler/glsl/glcpp/pp.c
@@ -229,11 +229,16 @@ skip_newline (const char *str)
static char *
remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
{
- char *clean = ralloc_strdup(ctx, "");
+ struct string_buffer sb;
const char *backslash, *newline, *search_start;
const char *cr, *lf;
char newline_separator[3];
int collapsed_newlines = 0;
+ int separator_len;
+
+ sb.capacity = 4096 - RALLOC_OVERHEAD;
+ sb.buf = ralloc_size(ctx, sb.capacity);
+ sb.length = 0;
search_start = shader;
@@ -273,6 +278,7 @@ remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
newline_separator[0] = '\n';
newline_separator[1] = '\r';
}
+ separator_len = strlen(newline_separator);
while (true) {
backslash = strchr(search_start, '\\');
@@ -294,10 +300,12 @@ remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
if (newline &&
(backslash == NULL || newline < backslash))
{
- ralloc_strncat(&clean, shader,
- newline - shader + 1);
+ glcpp_append_length(ctx, &sb, shader,
+ newline - shader + 1);
while (collapsed_newlines) {
- ralloc_strcat(&clean, newline_separator);
+ glcpp_append_length(ctx, &sb,
+ newline_separator,
+ separator_len);
collapsed_newlines--;
}
shader = skip_newline (newline);
@@ -318,15 +326,21 @@ remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
if (backslash[1] == '\r' || backslash[1] == '\n')
{
collapsed_newlines++;
- ralloc_strncat(&clean, shader, backslash - shader);
+ glcpp_append_length(ctx, &sb, shader,
+ backslash - shader);
shader = skip_newline (backslash + 1);
search_start = shader;
}
}
- ralloc_strcat(&clean, shader);
+ glcpp_append(ctx, &sb, shader);
+
+ /* string_buffer's string is not null-terminated, but it has enough
+ * of space for '\0'. Don't forget to put null-terminator.
+ */
+ sb.buf[sb.length] = '\0';
- return clean;
+ return sb.buf;
}
int
--
2.7.4
More information about the mesa-dev
mailing list