summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/context.cxx107
-rw-r--r--cli/context.hxx9
-rw-r--r--cli/html.cxx12
-rw-r--r--cli/man.cxx6
-rw-r--r--cli/source.cxx8
-rw-r--r--cli/txt.cxx5
6 files changed, 125 insertions, 22 deletions
diff --git a/cli/context.cxx b/cli/context.cxx
index ea84f33..9ba20ab 100644
--- a/cli/context.cxx
+++ b/cli/context.cxx
@@ -618,24 +618,29 @@ format_line (output_type ot, string& r, const char* s, size_t n)
throw generation_failed ();
}
- // Extract the link target.
+ // Find the end of the link target.
//
- for (++i; i + 1 < n; ++i)
+ size_t b (++i + 1), e (b);
+ for (; i + 1 < n; ++i)
{
char c (s[i + 1]);
- if (c == ' ')
+ if (c == ' ' || c == '}')
{
- for (++i; i + 1 < n && s[i + 1] == ' '; ++i) ; // Skip spaces.
- break;
- }
+ e = i + 1;
- if (c == '}')
- break;
+ if (c == ' ') // Skip spaces.
+ for (++i; i + 1 < n && s[i + 1] == ' '; ++i) ;
- t += c;
+ break;
+ }
}
+ // Run the link target through format_line(ot_plain) to handle
+ // escaping (e.g., \\$).
+ //
+ format_line (ot_plain, t, s + b, e - b);
+
if (t.empty ())
{
cerr << "error: missing link target in documentation paragraph '"
@@ -1115,7 +1120,7 @@ html_margin (string& v)
string context::
-format (output_type ot, string const& s, bool para)
+format (semantics::scope& scope, output_type ot, string const& s, bool para)
{
stack<block> blocks;
blocks.push (block (block::text, para)); // Top-level.
@@ -1137,6 +1142,7 @@ format (output_type ot, string const& s, bool para)
const char* l;
size_t n;
+ string subst; // Variable-substituted.
if (pre)
{
@@ -1158,6 +1164,14 @@ format (output_type ot, string const& s, bool para)
l = s.c_str () + b;
n = (last ? s.size () : e) - b;
+
+ // Perform variable expansions (\$var$).
+ //
+ if (substitute (scope, l, n, subst))
+ {
+ l = subst.c_str ();
+ n = subst.size ();
+ }
}
const char* ol (l); // Original, full line for diagnostics.
@@ -1840,6 +1854,79 @@ substitute (const string& s, semantics::cli_unit& u, const path* d)
return r;
}
+bool context::
+substitute (semantics::scope& scope, const char* s, size_t n, string& result)
+{
+ bool sub (false);
+ result.clear ();
+
+ // Scan the string looking for variables (\$var$).
+ //
+ size_t b (0), e (b);
+ for (char p ('\0'); e != n; ++e)
+ {
+ char c (s[e]);
+
+ if (p == '\\')
+ {
+ if (c == '\\') // Escape sequence.
+ {
+ p = '\0';
+ continue;
+ }
+
+ if (c == '$')
+ {
+ // Variable expansion.
+ //
+ sub = true;
+
+ // Find the closing '$'.
+ //
+ size_t p (e + 1); // Position of the second '$'.
+ for (; p != n && s[p] != '$'; ++p) ;
+
+ if (p == n)
+ {
+ cerr << "error: missing closing '$' in '" << string (s, n) << "'"
+ << endl;
+ throw generation_failed ();
+ }
+
+ result.append (s, b, e - b - 1); // Save what came before.
+
+ // Var name.
+ //
+ ++e;
+ string v (s, e, p - e);
+
+ // Lookup and substiute.
+ //
+ using semantics::doc;
+
+ if (doc* d = unit.lookup<doc> (scope.fq_name (), "var: " + v))
+ result += d->front ();
+ else
+ {
+ cerr << "error: undefined variable '" << v << "' in '"
+ << string (s, n) << "'" << endl;
+ throw generation_failed ();
+ }
+
+ e = p;
+ b = e + 1;
+ }
+ }
+
+ p = s[e];
+ }
+
+ if (sub)
+ result.append (s, b, e - b); // Last chunk.
+
+ return sub;
+}
+
string context::
fq_name (semantics::nameable& n, bool cxx_name)
{
diff --git a/cli/context.hxx b/cli/context.hxx
index b33bfef..9f10a00 100644
--- a/cli/context.hxx
+++ b/cli/context.hxx
@@ -127,7 +127,7 @@ public:
// If para is true, start a new paragraph.
//
string
- format (output_type, string const&, bool para);
+ format (semantics::scope&, output_type, string const&, bool para);
void
format_line (output_type, string&, const char*, size_t);
@@ -146,6 +146,13 @@ public:
return substitute (s, unit, p);
}
+ // Substitute doc variable expansions (\$var$). Note that it leaves escapes
+ // (\\$) as is. Return true if any substitutions have been made, in which
+ // case result will contain the expansion result.
+ //
+ bool
+ substitute (semantics::scope&, const char* s, size_t n, string& result);
+
public:
static string const&
ename (semantics::nameable& n)
diff --git a/cli/html.cxx b/cli/html.cxx
index 7f68453..da94a65 100644
--- a/cli/html.cxx
+++ b/cli/html.cxx
@@ -139,7 +139,10 @@ namespace
if (n > 1)
translate_arg (ds[0], arg_set);
- string s (format (ot_html, escape_html (translate (d, arg_set)), true));
+ string s (format (ds.scope (),
+ ot_html,
+ escape_html (translate (d, arg_set)),
+ true));
if (s.empty ())
return;
@@ -208,7 +211,7 @@ namespace
translate_arg (
doc.size () > 0 ? doc[0] : string ("<arg>"), arg_set));
- os << ' ' << format (ot_html, escape_html (s), false);
+ os << ' ' << format (o.scope (), ot_html, escape_html (s), false);
}
os << "</dt>" << endl;
@@ -231,7 +234,10 @@ namespace
// Format the documentation string.
//
- d = format (ot_html, escape_html (translate (d, arg_set)), false);
+ d = format (o.scope (),
+ ot_html,
+ escape_html (translate (d, arg_set)),
+ false);
wrap_lines (os, "<dd>" + d + "</dd>", 4);
os << endl;
diff --git a/cli/man.cxx b/cli/man.cxx
index b7bce6f..7e2757c 100644
--- a/cli/man.cxx
+++ b/cli/man.cxx
@@ -94,7 +94,7 @@ namespace
if (n > 1)
translate_arg (ds[0], arg_set);
- string s (format (ot_man, translate (d, arg_set), true));
+ string s (format (ds.scope (), ot_man, translate (d, arg_set), true));
if (s.empty ())
return;
@@ -145,7 +145,7 @@ namespace
translate_arg (
doc.size () > 0 ? doc[0] : string ("<arg>"), arg_set));
- os << ' ' << format (ot_man, s, false);
+ os << ' ' << format (o.scope (), ot_man, s, false);
}
os << "\"" << endl;
@@ -168,7 +168,7 @@ namespace
// Format the documentation string.
//
- d = format (ot_man, translate (d, arg_set), false);
+ d = format (o.scope (), ot_man, translate (d, arg_set), false);
wrap_lines (os, d);
os << endl;
diff --git a/cli/source.cxx b/cli/source.cxx
index f8d367e..14a6a9a 100644
--- a/cli/source.cxx
+++ b/cli/source.cxx
@@ -260,7 +260,7 @@ namespace
if (n > 1 && options.ansi_color ())
translate_arg (ds[0], arg_set);
- d = format (ot_plain, translate (d, arg_set), true);
+ d = format (ds.scope (), ot_plain, translate (d, arg_set), true);
if (d.empty ())
return;
@@ -331,7 +331,7 @@ namespace
s = translate_arg (s, arg_set);
}
- l += txt_size (format (ot_plain, s, false));
+ l += txt_size (format (o.scope (), ot_plain, s, false));
}
if (l > length_)
@@ -422,7 +422,7 @@ namespace
if (color)
s = translate_arg (s, arg_set);
- s = format (ot_plain, s, false);
+ s = format (o.scope (), ot_plain, s, false);
os << escape_str (s);
l += txt_size (s);
@@ -458,7 +458,7 @@ namespace
if (color)
d = translate (d, arg_set);
- d = format (ot_plain, d, false);
+ d = format (o.scope (), ot_plain, d, false);
if (!d.empty ())
wrap_lines (os, d, length_ + 1, l); // +1 for extra space after arg.
diff --git a/cli/txt.cxx b/cli/txt.cxx
index c537c55..ccce8ef 100644
--- a/cli/txt.cxx
+++ b/cli/txt.cxx
@@ -156,7 +156,10 @@ namespace
if (n > 1 && options.ansi_color ())
translate_arg (ds[0], arg_set);
- string s (format (ot_plain, translate (d, arg_set), true));
+ string s (format (ds.scope (),
+ ot_plain,
+ translate (d, arg_set),
+ true));
if (s.empty ())
return;