diff --git a/Makefile b/Makefile
index 3002572..3f5e205 100644
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,7 @@ CFLAGS += -W -Wall -Werror -std=c89 -pedantic -I.
ifeq ($(DEBUG),)
CFLAGS += -O2
else
-CFLAGS += -DDEBUG -O0
+CFLAGS += -DDEBUG -O0 -g3
endif
CLEANFILES =
diff --git a/buffer.c b/buffer.c
index 84fed94..33f1ce5 100644
--- a/buffer.c
+++ b/buffer.c
@@ -69,11 +69,10 @@ int buffer_close (s_buffer *b)
int buffer_fp (s_buffer *b, FILE *fp, const char *file_path)
{
assert(b);
- if (b->fp) {
+ if (b->fp)
fclose(b->fp);
- b->fp = fp;
- b->file_path = file_path;
- }
+ b->fp = fp;
+ b->file_path = file_path;
return 0;
}
@@ -96,6 +95,7 @@ int buffer_fill (s_buffer *b)
{
size_t r;
assert(b);
+ assert(b->fp);
if (b->wpos == b->size &&
buffer_resize(b, b->size + BUFFER_SIZE))
return -1;
diff --git a/kv.c b/kv.c
index 7d8189d..f836bd1 100644
--- a/kv.c
+++ b/kv.c
@@ -93,6 +93,8 @@ int quote (int argc, char **argv)
if (!(r = kv_quote(&q, &q_size)) &&
fwrite(q, q_size, 1, stdout) != 1)
err(1, "stdout");
+ fflush(stdout);
+ free(q);
return r;
}
diff --git a/kv_chars.c b/kv_chars.c
index d86efb0..b06fb9c 100644
--- a/kv_chars.c
+++ b/kv_chars.c
@@ -11,9 +11,13 @@ int kv_is_quotable_char (int c)
switch (c) {
case '"':
case '\\':
+ case '\n':
+ case '\r':
+ case '\t':
+ case '\v':
return 1;
default:
- return kv_is_space(c);
+ return 0;
}
return 0;
}
diff --git a/kv_quote.c b/kv_quote.c
index a25a091..bb06419 100644
--- a/kv_quote.c
+++ b/kv_quote.c
@@ -38,13 +38,12 @@ int kv_check_delimiter (const char *delim)
int kv_contains_delimiter (const char *str, size_t str_size,
const char *delim)
{
- size_t dsz;
+ size_t delim_len;
assert(str);
assert(delim);
- dsz = strlen(delim);
- while (str_size >= 4) {
- if (str[0] == '\n' && str[1] == '"' && str[2] == '"' &&
- str[3] == '"')
+ delim_len = strlen(delim);
+ while (str_size >= delim_len) {
+ if (!strcmp(str, delim))
return 1;
str++;
str_size--;
@@ -65,9 +64,8 @@ int kv_contains_reserved_char (const char *str, size_t str_size)
int kv_contains_triple_double_quotes (const char *str, size_t str_size)
{
- while (str_size >= 4) {
- if (str[0] == '\n' && str[1] == '"' && str[2] == '"' &&
- str[3] == '"')
+ while (str_size >= 3) {
+ if (str[0] == '"' && str[1] == '"' && str[2] == '"')
return 1;
str++;
str_size--;
@@ -75,6 +73,15 @@ int kv_contains_triple_double_quotes (const char *str, size_t str_size)
return 0;
}
+size_t kv_count_quotable_chars (const char *str, size_t str_size)
+{
+ size_t c = 0;
+ while (str_size--)
+ if (kv_is_quotable_char(*str++))
+ c++;
+ return c;
+}
+
int kv_needs_quoting (const char *str, size_t str_size)
{
if (str_size == 0 ||
@@ -114,8 +121,7 @@ int kv_quote (char **str, size_t *str_size)
q = *str;
q_size = *str_size;
delim = &g_delims[0];
- r = kv_quote_delim(&q, &q_size, *delim);
- delim++;
+ r = 1;
while (*delim && r > 0) {
r = kv_quote_delim(&q, &q_size, *delim);
delim++;
@@ -128,7 +134,10 @@ int kv_quote (char **str, size_t *str_size)
}
if (!rope)
return 1;
+ rope_print(rope, stderr);
rope_sort_by_size(rope);
+ rope_print(rope, stderr);
+ fflush(stderr);
*str = rope->str;
*str_size = rope->size;
rope = rope->next;
@@ -136,13 +145,33 @@ int kv_quote (char **str, size_t *str_size)
return 0;
}
-size_t kv_count_reserved_chars (const char *str, size_t str_size)
+int kv_quote_delim (char **str, size_t *str_size, const char *delim)
{
- size_t c = 0;
- while (str_size--)
- if (kv_is_reserved_char(*str++))
- c++;
- return c;
+ char *s;
+ size_t delim_len;
+ size_t len;
+ assert(str);
+ assert(str_size);
+ assert(delim);
+ if (kv_check_delimiter(delim)) {
+ fprintf(stderr, "bad delimiter: %s\n", delim);
+ return 1;
+ }
+ if (kv_contains_delimiter(*str, *str_size, delim))
+ return 1;
+ delim_len = strlen(delim);
+ len = *str_size + delim_len * 2 + 3;
+ s = calloc(len + 1, 1);
+ if (!s)
+ return -1;
+ s[0] = '<'; s[1] = '<';
+ memcpy(s + 2, delim, delim_len);
+ s[2 + delim_len] = '\n';
+ memcpy(s + delim_len + 3, *str, *str_size);
+ memcpy(s + *str_size + delim_len + 3, delim, delim_len);
+ *str = s;
+ *str_size = len;
+ return 0;
}
int kv_quote_double_quotes (char **str, size_t *str_size)
@@ -153,20 +182,25 @@ int kv_quote_double_quotes (char **str, size_t *str_size)
char *s;
assert(str);
assert(str_size);
- res = kv_count_reserved_chars(*str, *str_size);
+ res = kv_count_quotable_chars(*str, *str_size);
s = calloc(*str_size + res + 3, 1);
if (!s)
return -1;
- s[0] = '"';
+ s[o++] = '"';
while (i < *str_size) {
- int c = (*str)[i];
- if (kv_is_reserved_char(c))
+ int c = (*str)[i++];
+ if (kv_is_quotable_char(c))
s[o++] = '\\';
- if (c == 0)
- s[o++] = '0';
- else
- s[o++] = c;
+ switch (c) {
+ case 0: s[o++] = '0'; break;
+ case '\n': s[o++] = 'n'; break;
+ case '\r': s[o++] = 'r'; break;
+ case '\t': s[o++] = 't'; break;
+ case '\v': s[o++] = 'v'; break;
+ default: s[o++] = c;
+ }
}
+ s[o++] = '"';
assert(o == *str_size + res + 2);
s[o] = 0;
*str = s;
@@ -180,14 +214,14 @@ int kv_quote_triple_double_quotes (char **str, size_t *str_size)
char *s;
if (kv_contains_triple_double_quotes(*str, *str_size))
return 1;
- s = calloc(*str_size + 9, 1);
+ s = calloc(*str_size + 8, 1);
if (!s)
return -1;
s[0] = '"'; s[1] = '"'; s[2] = '"'; s[3] = '\n';
memcpy(s + 4, *str, *str_size);
e = s + 4 + *str_size;
- e[0] = '\n'; e[1] = '"'; e[2] = '"'; e[3] = '"'; e[4] = 0;
- *str = e;
- *str_size = *str_size + 8;
+ e[0] = '"'; e[1] = '"'; e[2] = '"'; e[3] = 0;
+ *str = s;
+ *str_size = *str_size + 7;
return 0;
}
diff --git a/rope.c b/rope.c
index 9f519de..477d19e 100644
--- a/rope.c
+++ b/rope.c
@@ -5,6 +5,7 @@
*/
#include <assert.h>
+#include <stdio.h>
#include <stdlib.h>
#include "rope.h"
@@ -111,3 +112,28 @@ void rope_sort_by_size (s_rope *r)
n--;
}
}
+
+int rope_print (s_rope *r, FILE *fp)
+{
+ int ret;
+ if (r) {
+ assert(fp);
+ ret = fwrite(r->str, r->size, 1, fp);
+ if (ret != 1)
+ return -1;
+ r = r->next;
+ while (r) {
+ ret = fwrite("\n\n", 2, 1, fp);
+ if (ret != 1)
+ return -1;
+ ret = fwrite(r->str, r->size, 1, fp);
+ if (ret != 1)
+ return -1;
+ r = r->next;
+ }
+ }
+ ret = fwrite("\n", 1, 1, fp);
+ if (ret != 1)
+ return -1;
+ return 0;
+}
diff --git a/rope.h b/rope.h
index 7c04be9..1e769f9 100644
--- a/rope.h
+++ b/rope.h
@@ -22,5 +22,6 @@ void rope_delete_all (s_rope *r);
void rope_delete_all_free (s_rope *r);
int rope_push (s_rope **r, char *str, size_t size);
void rope_sort_by_size (s_rope *r);
+int rope_print (s_rope *r, FILE *fp);
#endif