public string[] Process(string sourcePath, string releaseOutputPath) { List <String> paths = new List <String>(); // Make sure destination directory exits string basePath = Path.GetDirectoryName(releaseOutputPath); if (!Directory.Exists(basePath)) { Directory.CreateDirectory(basePath); } string ext = Path.GetExtension(releaseOutputPath); string debugOutputPath = Path.ChangeExtension(releaseOutputPath, "debug" + ext); string resourcesField = null; bool resourcesNamespace = false; string resourcesXmlPath = null; string resourcesXmlPathExtension = null; Dictionary <String, String>[] neutralResources = null; Dictionary <CultureInfo, Dictionary <String, String>[]> cultureResources = null; // examine first non-empty line in source file for #localize directive using (var sourceReader = new StreamReader(sourcePath)) { string line; do { line = sourceReader.ReadLine().Trim(); }while (String.IsNullOrEmpty(line) && !sourceReader.EndOfStream); if (!String.IsNullOrEmpty(line) && DirectiveRegex.IsMatch(line)) { try { var directive = new Directive(1, line); if (directive.Command.Equals("localize", StringComparison.OrdinalIgnoreCase) && directive.Parameters.Count >= 2) { resourcesField = directive.Parameters[0]; resourcesNamespace = bool.Parse(directive.Parameters[1]); resourcesXmlPath = directive.Parameters[2]; resourcesXmlPathExtension = Path.GetExtension(resourcesXmlPath); } } catch (Exception ex) { throw new InvalidOperationException(String.Format("Error while attempting to parse #localize directive for {0}.", sourcePath), ex); } } } if (!String.IsNullOrEmpty(resourcesXmlPath)) { resourcesXmlPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(sourcePath), resourcesXmlPath)); // build the invariant resources cultureResources = new Dictionary <CultureInfo, Dictionary <String, String>[]>(); neutralResources = GetDebugReleaseResources(resourcesXmlPath, null, null); // if neither debug or release resources found, throw if (neutralResources == null) { throw new InvalidOperationException("String resources not found: " + resourcesXmlPath); } // build a list of all the available resources from this resource path. For example, // if the given path is foo.resx, look for foo.FR-fr.resx, and the debug versions of each. foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.NeutralCultures | CultureTypes.SpecificCultures)) { if (!String.IsNullOrEmpty(culture.Name)) { string name = culture.Name; // replace foo.resx with foo.<culture>.resx string fileName = Path.ChangeExtension(resourcesXmlPath, name + resourcesXmlPathExtension); Dictionary <String, String>[] resources = GetDebugReleaseResources(fileName, name, neutralResources); if (resources != null) { cultureResources[culture] = resources; } } } } string debugBaseScript; string releaseBaseScript; using (var releaseWriter = new StringWriter()) { using (var debugWriter = new StringWriter()) { using (var sourceReader = new StreamReader(sourcePath)) { Process(sourcePath, sourceReader, debugWriter, releaseWriter); } debugBaseScript = debugWriter.ToString(); } releaseBaseScript = releaseWriter.ToString(); } // create output for neutral release/debug scripts CreateOutput(/*paths*/ paths, /*culture*/ CultureInfo.InvariantCulture, /*stringResources*/ neutralResources, /*resourcesField*/ resourcesField, /*resourcesNamespace*/ resourcesNamespace, /*releaseBaseScript*/ releaseBaseScript, /*releasePath*/ releaseOutputPath, /*debugBaseScript*/ debugBaseScript, /*debugPath*/ debugOutputPath); if (neutralResources != null) { // Also output a version of the scripts which has no resources. // This version of the script can then be embedded into an assembly and make use of the // localization feature of ScriptResourceHandler -- otherwise, the resources would be // duplicated. // The script is placed into an 'embed' folder in the same directory as the normal output. string debugEmbedPath = Path.Combine(Path.GetDirectoryName(debugOutputPath), "embed"); string noResourceDebugPath = Path.Combine(debugEmbedPath, Path.GetFileName(debugOutputPath)); string releaseEmbedPath = Path.Combine(Path.GetDirectoryName(releaseOutputPath), "embed"); string noResourceReleasePath = Path.Combine(releaseEmbedPath, Path.GetFileName(releaseOutputPath)); CreateOutput(/*paths*/ paths, /*culture*/ CultureInfo.InvariantCulture, /*stringResources*/ null, /*resourcesField*/ null, /*resourcesNamespace*/ false, /*releaseBaseScript*/ releaseBaseScript, /*releasePath*/ noResourceReleasePath, /*debugBaseScript*/ debugBaseScript, /*debugPath*/ noResourceDebugPath); } // create output for each culture in a 'loc' subdirectory if (cultureResources != null) { string releaseLocPath = Path.Combine(Path.Combine(Path.GetDirectoryName(releaseOutputPath), "loc"), Path.GetFileName(releaseOutputPath)); string debugLocPath = Path.Combine(Path.Combine(Path.GetDirectoryName(debugOutputPath), "loc"), Path.GetFileName(debugOutputPath)); foreach (KeyValuePair <CultureInfo, Dictionary <String, String>[]> resources in cultureResources) { CreateOutput(/*paths*/ paths, /*culture*/ resources.Key, /*stringResources*/ resources.Value, /*resourcesField*/ resourcesField, /*resourcesNamespace*/ resourcesNamespace, /*releaseBaseScript*/ releaseBaseScript, /*releasePath*/ releaseLocPath, /*debugBaseScript*/ debugBaseScript, /*debugPath*/ debugLocPath); } } return(paths.ToArray()); }
public StackFrame(Directive directive, bool writeDebug, bool writeRelease) { _directive = directive; _writeDebug = writeDebug; _writeRelease = writeRelease; }
private void Process(string sourcePath, TextReader sourceReader, TextWriter debugWriter, TextWriter releaseWriter) { _activeDebug = IsActive(true); _activeRelease = IsActive(false); using (sourceReader) { if (!String.IsNullOrEmpty(ReleaseHeader)) { releaseWriter.WriteLine(ReleaseHeader); } if (!String.IsNullOrEmpty(DebugHeader)) { debugWriter.WriteLine(DebugHeader); } while ((_line = sourceReader.ReadLine()) != null) { _lineNumber++; if (DirectiveRegex.IsMatch(_line)) { var directive = new Directive(_lineNumber, _line); switch (directive.Command) { case "LOCALIZE": // already processed break; case "IF": ProcessIFDirective(directive); break; case "ELSE": ProcessELSEDirective(directive); break; case "ENDIF": ProcessENDIFDirective(directive); break; case "INCLUDE": ProcessINCLUDEDirective(sourcePath, directive, debugWriter, releaseWriter); break; case "DEFINE": ProcessDEFINEDirective(directive, false); break; case "UNDEFINE": ProcessDEFINEDirective(directive, true); break; default: throw new InvalidOperationException("Unknown directive " + directive.Command); } _activeDebug = IsActive(true); _activeRelease = IsActive(false); } else if (!StripComments || !OneLineCommentRegex.IsMatch(_line)) { if (_activeDebug) { debugWriter.WriteLine(_line); } if (_activeRelease) { releaseWriter.WriteLine(_line); } } } } }
public string[] Process(string sourcePath, string releaseOutputPath) { List<String> paths = new List<String>(); // Make sure destination directory exits string basePath = Path.GetDirectoryName(releaseOutputPath); if (!Directory.Exists(basePath)) { Directory.CreateDirectory(basePath); } string ext = Path.GetExtension(releaseOutputPath); string debugOutputPath = Path.ChangeExtension(releaseOutputPath, "debug" + ext); string resourcesField = null; bool resourcesNamespace = false; string resourcesXmlPath = null; string resourcesXmlPathExtension = null; Dictionary<String, String>[] neutralResources = null; Dictionary<CultureInfo, Dictionary<String, String>[]> cultureResources = null; // examine first non-empty line in source file for #localize directive using (var sourceReader = new StreamReader(sourcePath)) { string line; do { line = sourceReader.ReadLine().Trim(); } while (String.IsNullOrEmpty(line) && !sourceReader.EndOfStream); if (!String.IsNullOrEmpty(line) && DirectiveRegex.IsMatch(line)) { try { var directive = new Directive(1, line); if (directive.Command.Equals("localize", StringComparison.OrdinalIgnoreCase) && directive.Parameters.Count >= 2) { resourcesField = directive.Parameters[0]; resourcesNamespace = bool.Parse(directive.Parameters[1]); resourcesXmlPath = directive.Parameters[2]; resourcesXmlPathExtension = Path.GetExtension(resourcesXmlPath); } } catch (Exception ex) { throw new InvalidOperationException(String.Format("Error while attempting to parse #localize directive for {0}.", sourcePath), ex); } } } if (!String.IsNullOrEmpty(resourcesXmlPath)) { resourcesXmlPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(sourcePath), resourcesXmlPath)); // build the invariant resources cultureResources = new Dictionary<CultureInfo, Dictionary<String, String>[]>(); neutralResources = GetDebugReleaseResources(resourcesXmlPath, null, null); // if neither debug or release resources found, throw if (neutralResources == null) { throw new InvalidOperationException("String resources not found: " + resourcesXmlPath); } // build a list of all the available resources from this resource path. For example, // if the given path is foo.resx, look for foo.FR-fr.resx, and the debug versions of each. foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.NeutralCultures | CultureTypes.SpecificCultures)) { if (!String.IsNullOrEmpty(culture.Name)) { string name = culture.Name; // replace foo.resx with foo.<culture>.resx string fileName = Path.ChangeExtension(resourcesXmlPath, name + resourcesXmlPathExtension); Dictionary<String, String>[] resources = GetDebugReleaseResources(fileName, name, neutralResources); if (resources != null) { cultureResources[culture] = resources; } } } } string debugBaseScript; string releaseBaseScript; using (var releaseWriter = new StringWriter()) { using (var debugWriter = new StringWriter()) { using (var sourceReader = new StreamReader(sourcePath)) { Process(sourcePath, sourceReader, debugWriter, releaseWriter); } debugBaseScript = debugWriter.ToString(); } releaseBaseScript = releaseWriter.ToString(); } // create output for neutral release/debug scripts CreateOutput(/*paths*/ paths, /*culture*/ CultureInfo.InvariantCulture, /*stringResources*/ neutralResources, /*resourcesField*/ resourcesField, /*resourcesNamespace*/ resourcesNamespace, /*releaseBaseScript*/ releaseBaseScript, /*releasePath*/ releaseOutputPath, /*debugBaseScript*/ debugBaseScript, /*debugPath*/ debugOutputPath); if (neutralResources != null) { // Also output a version of the scripts which has no resources. // This version of the script can then be embedded into an assembly and make use of the // localization feature of ScriptResourceHandler -- otherwise, the resources would be // duplicated. // The script is placed into an 'embed' folder in the same directory as the normal output. string debugEmbedPath = Path.Combine(Path.GetDirectoryName(debugOutputPath), "embed"); string noResourceDebugPath = Path.Combine(debugEmbedPath, Path.GetFileName(debugOutputPath)); string releaseEmbedPath = Path.Combine(Path.GetDirectoryName(releaseOutputPath), "embed"); string noResourceReleasePath = Path.Combine(releaseEmbedPath, Path.GetFileName(releaseOutputPath)); CreateOutput(/*paths*/ paths, /*culture*/ CultureInfo.InvariantCulture, /*stringResources*/ null, /*resourcesField*/ null, /*resourcesNamespace*/ false, /*releaseBaseScript*/ releaseBaseScript, /*releasePath*/ noResourceReleasePath, /*debugBaseScript*/ debugBaseScript, /*debugPath*/ noResourceDebugPath); } // create output for each culture in a 'loc' subdirectory if (cultureResources != null) { string releaseLocPath = Path.Combine(Path.Combine(Path.GetDirectoryName(releaseOutputPath), "loc"), Path.GetFileName(releaseOutputPath)); string debugLocPath = Path.Combine(Path.Combine(Path.GetDirectoryName(debugOutputPath), "loc"), Path.GetFileName(debugOutputPath)); foreach (KeyValuePair<CultureInfo, Dictionary<String, String>[]> resources in cultureResources) { CreateOutput(/*paths*/ paths, /*culture*/ resources.Key, /*stringResources*/ resources.Value, /*resourcesField*/ resourcesField, /*resourcesNamespace*/ resourcesNamespace, /*releaseBaseScript*/ releaseBaseScript, /*releasePath*/ releaseLocPath, /*debugBaseScript*/ debugBaseScript, /*debugPath*/ debugLocPath); } } return paths.ToArray(); }
protected void ProcessINCLUDEDirective(string sourcePath, Directive directive, TextWriter debugWriter, TextWriter releaseWriter) { string includeFile = directive.Parameters[0]; if (String.IsNullOrEmpty(includeFile)) { ThrowProcessingError("#INCLUDE missing include file "); } // Recurse string includePath = Path.Combine(Path.GetDirectoryName(sourcePath), includeFile); var includeReader = new StreamReader(includePath); var includePreprocessor = new Preprocessor(_directiveFrames) { Symbols = Symbols, StripComments = StripComments }; includePreprocessor.Process(includePath, includeReader, debugWriter, releaseWriter); }
protected void ProcessIFDirective(Directive directive) { string symbol = directive.Parameters[0].ToUpperInvariant(); if (String.IsNullOrEmpty(symbol)) { ThrowProcessingError("Invalid #IF parameter"); } // Process IF bool activeDebug = false; bool activeRelease = false; switch (symbol) { case "DEBUG": activeDebug = true; activeRelease = false; break; case "RELEASE": activeDebug = false; activeRelease = true; break; default: activeDebug = activeRelease = Symbols.Contains(symbol, StringComparer.OrdinalIgnoreCase); break; } _directiveFrames.Add(new DirectiveFrame { Directive = directive, ActiveDebug = activeDebug, ActiveRelease = activeRelease }); }
protected void ProcessENDIFDirective(Directive directive) { if (_directiveFrames.Count == 0) { ThrowProcessingError("#ENDIF without #IF"); } _directiveFrames.RemoveAt(_directiveFrames.Count - 1); }
protected void ProcessELSEDirective(Directive directive) { var frame = _directiveFrames[_directiveFrames.Count - 1]; frame.ActiveDebug = !frame.ActiveDebug; frame.ActiveRelease = !frame.ActiveRelease; }
protected void ProcessDEFINEDirective(Directive directive, bool remove) { foreach (string parameter in directive.Parameters) { if (remove) { Symbols.Remove(parameter); } else { Symbols.Add(parameter); } } }