- va_list args;
- char buffer[256], *p;
-
- va_start(args, fmt);
- vsnprintf(buffer, sizeof(buffer), fmt, args);
- va_end(args);
-
- cairo_set_font_size(cr, size);
-
- p = buffer;
- do {
- char *n = strchr(p, '\n');
- if (n)
- *n++ = 0;
- cairo_move_to(cr, x, y);
- cairo_show_text(cr, p);
- p = n;
- y += size;
- } while (p);
+ if (len < size)
+ buffer[len++] = c;
+ return len;
+}
+
+/* Add an escape string "atomically" - all or nothing */
+static int add_str(char *buffer, size_t size, int len, const char *s)
+{
+ int oldlen = len;
+ char c;
+ while ((c = *s++) != 0) {
+ if (len >= size)
+ return oldlen;
+ buffer[len++] = c;
+ }
+ return len;
+}
+
+static int add_quoted_string(char *buffer, size_t size, int len, const char *s)
+{
+ if (!s)
+ return len;
+
+ /* Room for '\0' */
+ size--;
+ for (;;) {
+ const char *escape;
+ unsigned char c = *s++;
+ switch(c) {
+ default:
+ len = add_char(buffer, size, len, c);
+ continue;
+ case 0:
+ escape = "\n";
+ break;
+ case '&':
+ escape = "&";
+ break;
+ case '>':
+ escape = ">";
+ break;
+ case '<':
+ escape = "<";
+ break;
+ }
+ len = add_str(buffer, size, len, escape);
+ if (c)
+ continue;
+ buffer[len] = 0;
+ return len;
+ }