annotate trunk/src/dil/doc/Macro.d @ 727:c204b6a9e0ef

Added new module dil.doc.Parser.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Sat, 02 Feb 2008 22:51:20 +0100
parents 84291c0a9e13
children ca7607226caa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
718
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
1 /++
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
2 Author: Aziz Köksal
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
3 License: GPL3
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
4 +/
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
5 module dil.doc.Macro;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
6
727
c204b6a9e0ef Added new module dil.doc.Parser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 725
diff changeset
7 import dil.doc.Parser;
718
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
8 import dil.lexer.Funcs;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
9 import dil.Unicode;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
10 import common;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
11
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
12 class Macro
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
13 {
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
14 string name; /// The name of the macro.
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
15 string text; /// Substitution text.
725
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
16 uint callLevel; /// Recursive call level.
718
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
17 this (string name, string text)
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
18 {
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
19 this.name = name;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
20 this.text = text;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
21 }
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
22 }
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
23
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
24 class MacroTable
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
25 {
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
26 MacroTable parent;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
27 Macro[string] table;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
28
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
29 this(MacroTable parent = null)
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
30 {
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
31 this.parent = parent;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
32 }
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
33
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
34 void insert(Macro macro_)
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
35 {
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
36 table[macro_.name] = macro_;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
37 }
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
38
727
c204b6a9e0ef Added new module dil.doc.Parser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 725
diff changeset
39 void insert(Macro[] macros)
c204b6a9e0ef Added new module dil.doc.Parser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 725
diff changeset
40 {
c204b6a9e0ef Added new module dil.doc.Parser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 725
diff changeset
41 foreach (macro_; macros)
c204b6a9e0ef Added new module dil.doc.Parser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 725
diff changeset
42 insert(macro_);
c204b6a9e0ef Added new module dil.doc.Parser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 725
diff changeset
43 }
c204b6a9e0ef Added new module dil.doc.Parser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 725
diff changeset
44
718
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
45 Macro search(string name)
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
46 {
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
47 auto pmacro = name in table;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
48 if (pmacro)
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
49 return *pmacro;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
50 if (parent)
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
51 return parent.search(name);
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
52 return null;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
53 }
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
54
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
55 bool isRoot()
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
56 { return parent is null; }
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
57 }
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
58
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
59 struct MacroParser
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
60 {
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
61 Macro[] parse(string text)
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
62 {
727
c204b6a9e0ef Added new module dil.doc.Parser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 725
diff changeset
63 IdentValueParser parser;
c204b6a9e0ef Added new module dil.doc.Parser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 725
diff changeset
64 auto idvalues = parser.parse(text);
c204b6a9e0ef Added new module dil.doc.Parser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 725
diff changeset
65 auto macros = new Macro[idvalues.length];
c204b6a9e0ef Added new module dil.doc.Parser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 725
diff changeset
66 foreach (i, idvalue; idvalues)
c204b6a9e0ef Added new module dil.doc.Parser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 725
diff changeset
67 macros[i] = new Macro(idvalue.ident, idvalue.value);
718
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
68 return macros;
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
69 }
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
70 }
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
71
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
72 char[] makeString(char* begin, char* end)
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
73 {
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
74 return begin[0 .. end - begin];
be887ada3e3e Added new module dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
75 }
722
ceaac6a24258 Added isUnicodeAlpha() for DDocParser and MacroParser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 718
diff changeset
76
725
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
77 char[] expandMacros(MacroTable table, char[] text, char[][] args = null)
722
ceaac6a24258 Added isUnicodeAlpha() for DDocParser and MacroParser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 718
diff changeset
78 {
ceaac6a24258 Added isUnicodeAlpha() for DDocParser and MacroParser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 718
diff changeset
79 char[] result;
ceaac6a24258 Added isUnicodeAlpha() for DDocParser and MacroParser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 718
diff changeset
80 char* p = text.ptr;
ceaac6a24258 Added isUnicodeAlpha() for DDocParser and MacroParser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 718
diff changeset
81 char* textEnd = p + text.length;
723
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
82 char* macroEnd = p;
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
83 while (p+3 < textEnd) // minimum 4 chars: $(x)
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
84 {
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
85 if (*p == '$' && p[1] == '(')
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
86 {
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
87 // Copy string between macros.
724
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
88 if (macroEnd !is p)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
89 result ~= makeString(macroEnd, p);
723
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
90 p += 2;
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
91 auto idBegin = p;
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
92 if (isidbeg(*p) || isUnicodeAlpha(p, textEnd)) // IdStart
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
93 {
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
94 do // IdChar*
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
95 p++;
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
96 while (p < textEnd && (isident(*p) || isUnicodeAlpha(p, textEnd)))
724
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
97 // Create macro name.
723
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
98 auto macroName = makeString(idBegin, p);
724
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
99 // Get arguments.
725
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
100 auto macroArgs = scanArguments(p, textEnd);
724
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
101 // TODO: still expand macro if no closing bracket was found?
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
102 if (p == textEnd)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
103 break; // No closing bracket found.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
104 assert(*p == ')');
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
105 p++;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
106 macroEnd = p;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
107
723
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
108 auto macro_ = table.search(macroName);
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
109 if (macro_)
725
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
110 { // Ignore recursive macro if:
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
111 if (macro_.callLevel != 0 &&
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
112 (macroArgs.length == 0 || // Macro has no arguments.
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
113 args.length && args[0] == macroArgs[0]) // arg0 == macroArg0.
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
114 )
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
115 continue;
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
116 macro_.callLevel++;
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
117 auto expandedText = expandArguments(macro_.text, macroArgs);
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
118 result ~= expandMacros(table, expandedText, macroArgs);
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
119 macro_.callLevel--;
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
120 }
724
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
121 continue;
723
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
122 }
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
123 }
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
124 p++;
5dd17d4568ce Wrote code for expandMacros().
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 722
diff changeset
125 }
724
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
126 if (macroEnd < textEnd)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
127 result ~= makeString(macroEnd, textEnd);
722
ceaac6a24258 Added isUnicodeAlpha() for DDocParser and MacroParser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 718
diff changeset
128 return result;
ceaac6a24258 Added isUnicodeAlpha() for DDocParser and MacroParser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 718
diff changeset
129 }
ceaac6a24258 Added isUnicodeAlpha() for DDocParser and MacroParser.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 718
diff changeset
130
724
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
131 /// Scans until the closing ')' is found.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
132 /// Returns [$0, $1, $2 ...].
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
133 char[][] scanArguments(ref char* p, char* textEnd)
725
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
134 out(args) { assert(args.length != 1); }
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
135 body
724
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
136 {
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
137 // D specs: "The argument text can contain nested parentheses,
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
138 // "" or '' strings, comments, or tags."
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
139 uint level = 1; // Nesting level of the parentheses.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
140 char[][] args;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
141
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
142 // Skip leading spaces.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
143 while (p < textEnd && isspace(*p))
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
144 p++;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
145
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
146 char* arg0Begin = p; // Whole argument list.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
147 char* argBegin = p;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
148 Loop:
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
149 while (p < textEnd)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
150 {
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
151 switch (*p)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
152 {
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
153 case ',':
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
154 // Add a new argument.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
155 args ~= makeString(argBegin, p);
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
156 while (++p < textEnd && isspace(*p))
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
157 {}
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
158 argBegin = p;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
159 continue;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
160 case '(':
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
161 level++;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
162 break;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
163 case ')':
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
164 if (--level == 0)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
165 break Loop;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
166 break;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
167 case '"', '\'':
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
168 auto c = *p;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
169 while (++p < textEnd && *p != c) // Scan to next " or '.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
170 {}
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
171 assert(*p == c || p == textEnd);
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
172 if (p == textEnd)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
173 break Loop;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
174 break;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
175 case '<':
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
176 if (p+3 < textEnd && p[1] == '!' && p[2] == '-' && p[3] == '-') // <!--
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
177 {
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
178 p += 3;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
179 // Scan to closing "-->".
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
180 while (++p + 2 < textEnd)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
181 if (*p == '-' && p[1] == '-' && p[2] == '>')
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
182 {
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
183 p += 3;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
184 continue Loop;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
185 }
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
186 p = textEnd; // p += 2;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
187 } // <tag ...> or </tag>
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
188 else if (p+1 < textEnd && (isalpha(p[1]) || p[1] == '/'))
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
189 while (++p < textEnd && *p != '>') // Skip to closing '>'.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
190 {}
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
191 if (p == textEnd)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
192 break Loop;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
193 break;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
194 default:
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
195 }
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
196 p++;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
197 }
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
198 assert(*p == ')' && level == 0 || p == textEnd);
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
199 if (arg0Begin is p)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
200 return null;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
201 // arg0 spans the whole argument list.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
202 auto arg0 = makeString(arg0Begin, p);
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
203 // Add last argument.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
204 args ~= makeString(argBegin, p);
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
205 return arg0 ~ args;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
206 }
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
207
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
208 /// Expands "$+", "$0" - "$9" with args[n] in text.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
209 /// Params:
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
210 /// text = the text to scan for argument placeholders.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
211 /// args = the first element, args[0], is the whole argument string and
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
212 /// the following elements are slices into it.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
213 /// The array is empty if there are no arguments.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
214 char[] expandArguments(char[] text, char[][] args)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
215 in { assert(args.length != 1, "zero or more than 1 args expected"); }
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
216 body
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
217 {
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
218 char[] result;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
219 char* p = text.ptr;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
220 char* textEnd = p + text.length;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
221 char* placeholderEnd = p;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
222
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
223 while (p+1 < textEnd)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
224 {
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
225 if (*p == '$' && (p[1] == '+' || isdigit(p[1])))
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
226 {
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
227 // Copy string between argument placeholders.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
228 if (placeholderEnd !is p)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
229 result ~= makeString(placeholderEnd, p);
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
230 p++;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
231 placeholderEnd = p + 1; // Set new argument end.
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
232
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
233 if (args.length == 0)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
234 continue;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
235
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
236 if (*p == '+')
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
237 { // $+ = $2 to $n
725
84291c0a9e13 Added member callLevel to class Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 724
diff changeset
238 if (args.length > 2)
724
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
239 result ~= makeString(args[2].ptr, args[0].ptr + args[0].length);
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
240 }
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
241 else
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
242 { // 0 - 9
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
243 uint nthArg = *p - '0';
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
244 if (nthArg < args.length)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
245 result ~= args[nthArg];
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
246 }
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
247 }
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
248 p++;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
249 }
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
250 if (placeholderEnd < textEnd)
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
251 result ~= makeString(placeholderEnd, textEnd);
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
252 return result;
0b8a6e876b6d Added scanArguments() and expandArguments() to dil.doc.Macro.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 723
diff changeset
253 }