Mercurial > projects > dil
changeset 744:7173ece1b696
Wrapped some macro functions inside struct MacroExpander.
Warning messages from the macro expansion pass are collected now.
Tidied up predefined.ddoc a bit, and added some macros.
Added two messages to struct MSG.
Added another opCatAssign to class InfoManager.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Sat, 09 Feb 2008 22:54:31 +0100 |
parents | 764f660e3909 |
children | 7299159c3a19 |
files | trunk/src/cmd/DDoc.d trunk/src/dil/Information.d trunk/src/dil/Location.d trunk/src/dil/Messages.d trunk/src/dil/doc/Macro.d trunk/src/main.d trunk/src/predefined.ddoc |
diffstat | 7 files changed, 220 insertions(+), 166 deletions(-) [+] |
line wrap: on
line diff
--- a/trunk/src/cmd/DDoc.d Sat Feb 09 19:27:14 2008 +0100 +++ b/trunk/src/cmd/DDoc.d Sat Feb 09 22:54:31 2008 +0100 @@ -61,13 +61,20 @@ // Generate documentation. auto dest = new FilePath(destDir); dest.append(mod.getFQN() ~ ".html"); + InfoManager infoMan2; // Collects warnings from the macro expander. if (verbose) + { Stdout.formatln("{} > {}", mod.filePath, dest); - writeDocFile(dest.toString(), mod, mtable, incUndoc); + infoMan2 = new InfoManager(); + } + writeDocFile(dest.toString(), mod, mtable, incUndoc, infoMan2); + if (infoMan2) + infoMan ~= infoMan2.info; } } -void writeDocFile(string dest, Module mod, MacroTable mtable, bool incUndoc) +void writeDocFile(string dest, Module mod, MacroTable mtable, bool incUndoc, + InfoManager infoMan) { // Create a macro environment for this module. mtable = new MacroTable(mtable); @@ -87,7 +94,7 @@ // Set BODY macro to the text produced by the DDocEmitter. mtable.insert("BODY", doc.text); // Do the macro expansion pass. - auto fileText = expandMacros(mtable, "$(DDOC)"); + auto fileText = MacroExpander.expand(mtable, "$(DDOC)", mod.filePath, infoMan); // Finally write the file out to the harddisk. auto file = new File(dest); file.write(fileText);
--- a/trunk/src/dil/Information.d Sat Feb 09 19:27:14 2008 +0100 +++ b/trunk/src/dil/Information.d Sat Feb 09 22:54:31 2008 +0100 @@ -22,6 +22,11 @@ { this.info ~= info; } + + void opCatAssign(Information[] info) + { + this.info ~= info; + } } class Problem : Information
--- a/trunk/src/dil/Location.d Sat Feb 09 19:27:14 2008 +0100 +++ b/trunk/src/dil/Location.d Sat Feb 09 22:54:31 2008 +0100 @@ -11,7 +11,7 @@ { char[] filePath; size_t lineNum; - char* lineBegin, to; // Used to calculate column. + char* lineBegin, to; /// Used to calculate column. this(char[] filePath, size_t lineNum) {
--- a/trunk/src/dil/Messages.d Sat Feb 09 19:27:14 2008 +0100 +++ b/trunk/src/dil/Messages.d Sat Feb 09 22:54:31 2008 +0100 @@ -105,6 +105,9 @@ auto InvalidUTF32Character = "invalid UTF-32 character '\\U{:X8}'."; auto UTF16FileMustBeDivisibleBy2 = "the byte length of a UTF-16 source file must be divisible by 2."; auto UTF32FileMustBeDivisibleBy4 = "the byte length of a UTF-32 source file must be divisible by 4."; + // DDoc macros: + auto UndefinedDDocMacro = "DDoc macro '{}' is undefined"; + auto UnterminatedDDocMacro = "DDoc macro '{}' has no closing ')'"; // Parser messages: auto ModuleDeclarationNotFirst = "a module declaration is only allowed as the first declaration in a file"; auto StringPostfixMismatch = "string literal has mistmatching postfix character";
--- a/trunk/src/dil/doc/Macro.d Sat Feb 09 19:27:14 2008 +0100 +++ b/trunk/src/dil/doc/Macro.d Sat Feb 09 22:54:31 2008 +0100 @@ -7,6 +7,8 @@ import dil.doc.Parser; import dil.lexer.Funcs; import dil.Unicode; +import dil.Information; +import dil.Messages; import common; class Macro @@ -81,183 +83,213 @@ } } -/// Expands the macros from the table in text. -char[] expandMacros(MacroTable table, char[] text, char[][] args = null) +struct MacroExpander { - char[] result; - char* p = text.ptr; - char* textEnd = p + text.length; - char* macroEnd = p; - while (p+3 < textEnd) // minimum 4 chars: $(x) + MacroTable mtable; /// Used to look up macros. + InfoManager infoMan; /// Collects warning messages. + char[] filePath; /// Used in warning messages. + + static char[] expand(MacroTable mtable, char[] text, + char[] filePath, + InfoManager infoMan = null) { - if (*p == '$' && p[1] == '(') + MacroExpander me; + me.mtable = mtable; + me.infoMan = infoMan; + me.filePath = filePath; + return me.expandMacros(text); + } + + void warning(char[] msg, char[] macroName) + { + msg = Format(msg, macroName); + if (infoMan) + infoMan ~= new Warning(new Location(filePath, 0), msg); + } + + /// Expands the macros from the table in text. + char[] expandMacros(char[] text, char[][] args = null) + { + char[] result; + char* p = text.ptr; + char* textEnd = p + text.length; + char* macroEnd = p; + while (p+3 < textEnd) // minimum 4 chars: $(x) { - // Copy string between macros. - if (macroEnd !is p) - result ~= makeString(macroEnd, p); - p += 2; - auto idBegin = p; - if (isidbeg(*p) || isUnicodeAlpha(p, textEnd)) // IdStart + if (*p == '$' && p[1] == '(') { - do // IdChar* + // Copy string between macros. + if (macroEnd !is p) + result ~= makeString(macroEnd, p); + p += 2; + auto idBegin = p; + if (isidbeg(*p) || isUnicodeAlpha(p, textEnd)) // IdStart + { + do // IdChar* + p++; + while (p < textEnd && (isident(*p) || isUnicodeAlpha(p, textEnd))) + // Create macro name. + auto macroName = makeString(idBegin, p); + // Get arguments. + auto macroArgs = scanArguments(p, textEnd); + // TODO: still expand macro if no closing bracket was found? + if (p == textEnd) + { + warning(MSG.UnterminatedDDocMacro, macroName); + break; // No closing bracket found. + } + assert(*p == ')'); p++; - while (p < textEnd && (isident(*p) || isUnicodeAlpha(p, textEnd))) - // Create macro name. - auto macroName = makeString(idBegin, p); - // Get arguments. - auto macroArgs = scanArguments(p, textEnd); - // TODO: still expand macro if no closing bracket was found? - if (p == textEnd) - break; // No closing bracket found. - assert(*p == ')'); - p++; - macroEnd = p; + macroEnd = p; - auto macro_ = table.search(macroName); - if (macro_) - { // Ignore recursive macro if: - if (macro_.callLevel != 0 && - (macroArgs.length == 0 || // Macro has no arguments. - args.length && args[0] == macroArgs[0]) // arg0 == macroArg0. - ) - continue; - macro_.callLevel++; - auto expandedText = expandArguments(macro_.text, macroArgs); - result ~= expandMacros(table, expandedText, macroArgs); - macro_.callLevel--; + auto macro_ = mtable.search(macroName); + if (macro_) + { // Ignore recursive macro if: + if (macro_.callLevel != 0 && + (macroArgs.length == 0 || // Macro has no arguments. + args.length && args[0] == macroArgs[0]) // arg0 == macroArg0. + ) + continue; + macro_.callLevel++; + auto expandedText = expandArguments(macro_.text, macroArgs); + result ~= expandMacros(expandedText, macroArgs); + macro_.callLevel--; + } + else + warning(MSG.UndefinedDDocMacro, macroName); + continue; } - continue; } + p++; } - p++; + if (macroEnd < textEnd) + result ~= makeString(macroEnd, textEnd); + return result; } - if (macroEnd < textEnd) - result ~= makeString(macroEnd, textEnd); - return result; -} -/// Scans until the closing ')' is found. -/// Returns: [$0, $1, $2 ...]. -char[][] scanArguments(ref char* p, char* textEnd) -out(args) { assert(args.length != 1); } -body -{ - // D specs: "The argument text can contain nested parentheses, - // "" or '' strings, comments, or tags." - uint level = 1; // Nesting level of the parentheses. - char[][] args; + /// Scans until the closing ')' is found. + /// Returns: ['$0', $1, $2 ...]. + char[][] scanArguments(ref char* p, char* textEnd) + out(args) { assert(args.length != 1); } + body + { + // D specs: "The argument text can contain nested parentheses, + // "" or '' strings, comments, or tags." + uint level = 1; // Nesting level of the parentheses. + char[][] args; + + // Skip leading spaces. + while (p < textEnd && isspace(*p)) + p++; - // Skip leading spaces. - while (p < textEnd && isspace(*p)) - p++; - - char* arg0Begin = p; // Whole argument list. - char* argBegin = p; -Loop: - while (p < textEnd) - { - switch (*p) + char* arg0Begin = p; // Whole argument list. + char* argBegin = p; + Loop: + while (p < textEnd) { - case ',': - if (level != 1) // Ignore comma if inside (). + switch (*p) + { + case ',': + if (level != 1) // Ignore comma if inside (). + break; + // Add a new argument. + args ~= makeString(argBegin, p); + while (++p < textEnd && isspace(*p)) + {} + argBegin = p; + continue; + case '(': + level++; break; - // Add a new argument. - args ~= makeString(argBegin, p); - while (++p < textEnd && isspace(*p)) - {} - argBegin = p; - continue; - case '(': - level++; - break; - case ')': - if (--level == 0) - break Loop; - break; - case '"', '\'': - auto c = *p; - while (++p < textEnd && *p != c) // Scan to next " or '. - {} - assert(*p == c || p == textEnd); - if (p == textEnd) - break Loop; - break; - case '<': - if (p+3 < textEnd && p[1] == '!' && p[2] == '-' && p[3] == '-') // <!-- - { - p += 3; - // Scan to closing "-->". - while (++p + 2 < textEnd) - if (*p == '-' && p[1] == '-' && p[2] == '>') - { - p += 3; - continue Loop; - } - p = textEnd; // p += 2; - } // <tag ...> or </tag> - else if (p+1 < textEnd && (isalpha(p[1]) || p[1] == '/')) - while (++p < textEnd && *p != '>') // Skip to closing '>'. + case ')': + if (--level == 0) + break Loop; + break; + case '"', '\'': + auto c = *p; + while (++p < textEnd && *p != c) // Scan to next " or '. {} - if (p == textEnd) - break Loop; - break; - default: + assert(*p == c || p == textEnd); + if (p == textEnd) + break Loop; + break; + case '<': + if (p+3 < textEnd && p[1] == '!' && p[2] == '-' && p[3] == '-') // <!-- + { + p += 3; + // Scan to closing "-->". + while (++p + 2 < textEnd) + if (*p == '-' && p[1] == '-' && p[2] == '>') + { + p += 3; + continue Loop; + } + p = textEnd; // p += 2; + } // <tag ...> or </tag> + else if (p+1 < textEnd && (isalpha(p[1]) || p[1] == '/')) + while (++p < textEnd && *p != '>') // Skip to closing '>'. + {} + if (p == textEnd) + break Loop; + break; + default: + } + p++; } - p++; + assert(*p == ')' && level == 0 || p == textEnd); + if (arg0Begin is p) + return null; + // arg0 spans the whole argument list. + auto arg0 = makeString(arg0Begin, p); + // Add last argument. + args ~= makeString(argBegin, p); + return arg0 ~ args; } - assert(*p == ')' && level == 0 || p == textEnd); - if (arg0Begin is p) - return null; - // arg0 spans the whole argument list. - auto arg0 = makeString(arg0Begin, p); - // Add last argument. - args ~= makeString(argBegin, p); - return arg0 ~ args; -} -/// Expands "$+", "$0" - "$9" with args[n] in text. -/// Params: -/// text = the text to scan for argument placeholders. -/// args = the first element, args[0], is the whole argument string and -/// the following elements are slices into it. -/// The array is empty if there are no arguments. -char[] expandArguments(char[] text, char[][] args) -in { assert(args.length != 1, "zero or more than 1 args expected"); } -body -{ - char[] result; - char* p = text.ptr; - char* textEnd = p + text.length; - char* placeholderEnd = p; - - while (p+1 < textEnd) + /// Expands "$+", "$0" - "$9" with args[n] in text. + /// Params: + /// text = the text to scan for argument placeholders. + /// args = the first element, args[0], is the whole argument string and + /// the following elements are slices into it. + /// The array is empty if there are no arguments. + char[] expandArguments(char[] text, char[][] args) + in { assert(args.length != 1, "zero or more than 1 args expected"); } + body { - if (*p == '$' && (p[1] == '+' || isdigit(p[1]))) + char[] result; + char* p = text.ptr; + char* textEnd = p + text.length; + char* placeholderEnd = p; + + while (p+1 < textEnd) { - // Copy string between argument placeholders. - if (placeholderEnd !is p) - result ~= makeString(placeholderEnd, p); - p++; - placeholderEnd = p + 1; // Set new argument end. + if (*p == '$' && (p[1] == '+' || isdigit(p[1]))) + { + // Copy string between argument placeholders. + if (placeholderEnd !is p) + result ~= makeString(placeholderEnd, p); + p++; + placeholderEnd = p + 1; // Set new argument end. - if (args.length == 0) - continue; + if (args.length == 0) + continue; - if (*p == '+') - { // $+ = $2 to $n - if (args.length > 2) - result ~= makeString(args[2].ptr, args[0].ptr + args[0].length); + if (*p == '+') + { // $+ = $2 to $n + if (args.length > 2) + result ~= makeString(args[2].ptr, args[0].ptr + args[0].length); + } + else + { // 0 - 9 + uint nthArg = *p - '0'; + if (nthArg < args.length) + result ~= args[nthArg]; + } } - else - { // 0 - 9 - uint nthArg = *p - '0'; - if (nthArg < args.length) - result ~= args[nthArg]; - } + p++; } - p++; + if (placeholderEnd < textEnd) + result ~= makeString(placeholderEnd, textEnd); + return result; } - if (placeholderEnd < textEnd) - result ~= makeString(placeholderEnd, textEnd); - return result; }
--- a/trunk/src/main.d Sat Feb 09 19:27:14 2008 +0100 +++ b/trunk/src/main.d Sat Feb 09 22:54:31 2008 +0100 @@ -311,6 +311,8 @@ errorFormat = GlobalSettings.parserErrorFormat; else if (info.classinfo is SemanticError.classinfo) errorFormat = GlobalSettings.semanticErrorFormat; + else if (info.classinfo is Warning.classinfo) + errorFormat = "{0}: Warning: {3}"; else continue; auto err = cast(Problem)info;
--- a/trunk/src/predefined.ddoc Sat Feb 09 19:27:14 2008 +0100 +++ b/trunk/src/predefined.ddoc Sat Feb 09 22:54:31 2008 +0100 @@ -38,17 +38,18 @@ BLACK = <font color="black">$0</font> WHITE = <font color="white">$0</font> -D_CODE = <pre class="d_code">$0</pre> +D_CODE = <pre class="d_code">$0</pre> D_COMMENT = $(GREEN $0) D_STRING = $(RED $0) D_KEYWORD = $(BLUE $0) D_PSYMBOL = $(U $0) -D_PARAM = $(I $0) +D_PARAM = $(I $0) DDOC_COMMENT = <!-- $0 --> DDOC_DECL = $(DT $(BIG $0)) DDOC_DECL_DD = $(DD $0) DDOC_DITTO = $(BR)$0 + DDOC_SECTIONS = $0 DDOC_SUMMARY = $0$(BR)$(BR) DDOC_DESCRIPTION = $0$(BR)$(BR) @@ -78,14 +79,18 @@ $0$(BR)$(BR) DDOC_VERSION = $(B Version:)$(BR) $0$(BR)$(BR) -DDOC_SECTION_H = $(B $0)$(BR)$(BR) +DDOC_SECTION_H = $(B $0)$(BR) DDOC_SECTION = $0$(BR)$(BR) + DDOC_MEMBERS = $(DL $0) -DDOC_MODULE_MEMBERS = $(DDOC_MEMBERS $0) -DDOC_CLASS_MEMBERS = $(DDOC_MEMBERS $0) -DDOC_STRUCT_MEMBERS = $(DDOC_MEMBERS $0) -DDOC_ENUM_MEMBERS = $(DDOC_MEMBERS $0) -DDOC_TEMPLATE_MEMBERS = $(DDOC_MEMBERS $0) +DDOC_MODULE_MEMBERS = $(DDOC_MEMBERS $0) +DDOC_CLASS_MEMBERS = $(DDOC_MEMBERS $0) +DDOC_INTERFACE_MEMBERS = $(DDOC_MEMBERS $0) +DDOC_STRUCT_MEMBERS = $(DDOC_MEMBERS $0) +DDOC_UNION_MEMBERS = $(DDOC_MEMBERS $0) +DDOC_TEMPLATE_MEMBERS = $(DDOC_MEMBERS $0) +DDOC_ENUM_MEMBERS = $(DDOC_MEMBERS $0) + DDOC_PARAMS = $(B Params:)$(BR) $(TABLE $0)$(BR) DDOC_PARAM_ROW = $(TR $0)