|
@@ -747,6 +747,79 @@ escaped(const char *s)
|
|
|
return _escaped_val;
|
|
|
}
|
|
|
|
|
|
+/** Rudimentary string wrapping code: given a un-wrapped <b>string</b> (no
|
|
|
+ * newlines!), break the string into newline-terminated lines of no more than
|
|
|
+ * <b>width</b> characters long (not counting newline) and insert them into
|
|
|
+ * <b>out</b> in order. Precede the first line with prefix0, and subsequent
|
|
|
+ * lines with prefixRest.
|
|
|
+ */
|
|
|
+/* This uses a stupid greedy wrapping algorithm right now:
|
|
|
+ * - For each line:
|
|
|
+ * - Try to fit as much stuff as possible, but break on a space.
|
|
|
+ * - If the first "word" of the line will extend beyond the allowable
|
|
|
+ * width, break the word at the end of the width.
|
|
|
+ */
|
|
|
+void
|
|
|
+wrap_string(smartlist_t *out, const char *string, size_t width,
|
|
|
+ const char *prefix0, const char *prefixRest)
|
|
|
+{
|
|
|
+ size_t p0Len, pRestLen, pCurLen;
|
|
|
+ const char *eos, *prefixCur;
|
|
|
+ tor_assert(out);
|
|
|
+ tor_assert(string);
|
|
|
+ tor_assert(width);
|
|
|
+ if (!prefix0)
|
|
|
+ prefix0 = "";
|
|
|
+ if (!prefixRest)
|
|
|
+ prefixRest = "";
|
|
|
+
|
|
|
+ p0Len = strlen(prefix0);
|
|
|
+ pRestLen = strlen(prefixRest);
|
|
|
+ tor_assert(width > p0Len && width > pRestLen);
|
|
|
+ eos = strchr(string, '\0');
|
|
|
+ tor_assert(eos);
|
|
|
+ pCurLen = p0Len;
|
|
|
+ prefixCur = prefix0;
|
|
|
+
|
|
|
+ while ((eos-string)+pCurLen > width) {
|
|
|
+ const char *eol = string + width - pCurLen;
|
|
|
+ while (eol > string && *eol != ' ')
|
|
|
+ --eol;
|
|
|
+ /* eol is now the last space that can fit, or the start of the string. */
|
|
|
+ if (eol > string) {
|
|
|
+ size_t line_len = (eol-string) + pCurLen + 2;
|
|
|
+ char *line = tor_malloc(line_len);
|
|
|
+ memcpy(line, prefixCur, pCurLen);
|
|
|
+ memcpy(line+pCurLen, string, eol-string);
|
|
|
+ line[line_len-2] = '\n';
|
|
|
+ line[line_len-1] = '\0';
|
|
|
+ smartlist_add(out, line);
|
|
|
+ string = eol + 1;
|
|
|
+ } else {
|
|
|
+ size_t line_len = width + 2;
|
|
|
+ char *line = tor_malloc(line_len);
|
|
|
+ memcpy(line, prefixCur, pCurLen);
|
|
|
+ memcpy(line+pCurLen, string, width - pCurLen);
|
|
|
+ line[line_len-2] = '\n';
|
|
|
+ line[line_len-1] = '\0';
|
|
|
+ smartlist_add(out, line);
|
|
|
+ string += width-pCurLen;
|
|
|
+ }
|
|
|
+ prefixCur = prefixRest;
|
|
|
+ pCurLen = pRestLen;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (string < eos) {
|
|
|
+ size_t line_len = (eos-string) + pCurLen + 2;
|
|
|
+ char *line = tor_malloc(line_len);
|
|
|
+ memcpy(line, prefixCur, pCurLen);
|
|
|
+ memcpy(line+pCurLen, string, eos-string);
|
|
|
+ line[line_len-2] = '\n';
|
|
|
+ line[line_len-1] = '\0';
|
|
|
+ smartlist_add(out, line);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/* =====
|
|
|
* Time
|
|
|
* ===== */
|