コード例 #1
0
ファイル: Preprocessor.cs プロジェクト: Treer/POpp
        /// <summary>
        /// Plural msgstr encountered - Abort if it contains a reference, as plural forms
        /// are not supported yet and will result in the msgstr not being expanded.
        /// </summary>
        void TestPluralForm(LineInfo pluralMsgstrLine)
        {
            if (GetFirstReference(pluralMsgstrLine.Line, 0) != null) {

                throw new LineException(pluralMsgstrLine, "Multiple msgstrs encountered, PO plural-forms are not currently supported - Aborting because the msgstr contains a reference which popp will fail to expand.");

            } else {
                ErrorEncountered(pluralMsgstrLine, "Multiple msgstrs encountered, PO plural-forms are not currently supported. Non-fatal as line contains nothing to expand (skipping).");
            }
        }
コード例 #2
0
ファイル: Preprocessor.cs プロジェクト: Treer/POpp
        /// <summary>
        /// Returns a TextReader for the file pointed to by the $include line.
        /// Remember to Dispose() of it.
        /// May return null. 
        /// </summary>
        /// <param name="inputDirectory">The directory that contained the source file that was supplied to popp, or null (e.g. if stdin was the source)</param>
        /// <param name="currentIncludeDirectory">null unless 'line' is from an $included file, in which case it 
        /// should contain the directory containing the $included file so we can add that to our search path</param>
        /// <param name="includedFileNameAndPath">set to null unless the function returns a TextReader, in 
        /// which case it's </param>
        TextReader IncludedTextReader(LineInfo line, string inputDirectory, string currentIncludeDirectory, out string includedFileNameAndPath)
        {
            TextReader result = null;
            FileStream sourceStream = null;

            includedFileNameAndPath = null;

            try {
                string pathAndFileName = null;
                string fileName = ExtractString(line);

                // Add inputDirectory and "no directory" to the front of the list of include-directories to search
                List<string> directoryList = new List<string>();
                directoryList.Add(inputDirectory);
                if (currentIncludeDirectory != null) directoryList.Add(currentIncludeDirectory);
                directoryList.Add("");
                directoryList.AddRange(_options.IncludeDirectories);

                foreach (string directory in directoryList) {

                    string tempPath = Path.Combine(directory, fileName);
                    if (File.Exists(tempPath)) {
                        pathAndFileName = tempPath;
                        break;
                    }
                }

                if (pathAndFileName == null) {

                    throw new LineException(
                        line,
                        "$included source-file not found" +
                        (String.IsNullOrEmpty(fileName) ? "" : ": " + fileName)
                    );

                } else {

                    sourceStream = new FileStream(pathAndFileName, FileMode.Open, FileAccess.Read);
                    result = new StreamReader(sourceStream);
                    includedFileNameAndPath = Path.GetFullPath(pathAndFileName);
                }

            } catch (LineException) {
                throw;

            } catch (Exception ex) {

                if (sourceStream != null) sourceStream.Close();
                throw new LineException(line, "Unexpected error while expanding $include: " + ex);
            }

            return result;
        }
コード例 #3
0
ファイル: Preprocessor.cs プロジェクト: Treer/POpp
        /// <summary>
        /// Returns either 'line x' or 'line x of "file.po"' depending on whether the 
        /// line came from the source file or an included file.
        /// </summary>
        /// <param name="lineInfo"></param>
        /// <returns></returns>
        string LineNumberToString(LineInfo lineInfo)
        {
            if (lineInfo.IncludeFileID >= 0) {

                return String.Format(
                        "line {0} of \"{1}\"",
                        lineInfo.LineNumber,
                        Path.GetFileName(_includeFileNames[lineInfo.IncludeFileID])
                );

            } else {
                return "line " + lineInfo.LineNumber;
            }
        }
コード例 #4
0
ファイル: Preprocessor.cs プロジェクト: Treer/POpp
        /// <summary>
        /// Extracts the string inside the left-most " and the right-most "
        /// i.e. extracts the string specified in the line, but does not unencode any escaped characters
        /// </summary>
        string ExtractString(LineInfo lineInfo)
        {
            string result = String.Empty;

            // find the characters between the left-most " and the right-most "
            int quotePosLeft = lineInfo.Line.IndexOf('"');
            int quotePosRight = lineInfo.Line.LastIndexOf('"');

            if (quotePosLeft < 0 || quotePosRight <= quotePosLeft) {
                // A note about the wording of this error message: It can occur when quotes are missing
                // from a .PO entry such as a msgid or msgstr, but it can also happen if quotes are missing
                // from an $include statement intended for popp.
                ErrorEncountered(lineInfo, "Missing quotemarks - very bad - line will be missing from output");

            } else {
                result = lineInfo.Line.Substring(quotePosLeft + 1, quotePosRight - quotePosLeft - 1);
            }

            return result;
        }
コード例 #5
0
ファイル: Preprocessor.cs プロジェクト: Treer/POpp
 /// <summary>
 /// Sends an error message to the console, if errors are not suppressed
 /// and sets the return value to indicate a non-fatal error.
 /// </summary>
 /// <param name="lineNumber">0 if line number is not known, otherwise provide the line of the source file the error was encountered at</param>
 /// <seealso cref="DisplayInfo"/>
 void ErrorEncountered(LineInfo lineInfo, string message)
 {
     if (!_options.Quiet) {
         if (lineInfo == null) {
             Console.Error.WriteLine("Error: " + message);
         } else {
             Console.Error.WriteLine("Error on " + LineNumberToString(lineInfo) + ": " + message);
         }
     }
     if (_errorLevel == 0) _errorLevel = (int)ErrorLevel.NonFatalError;
 }
コード例 #6
0
ファイル: Preprocessor.cs プロジェクト: Treer/POpp
        /// <param name="expandIncludes">if true the referenced file will be inserted, if false, the include will be removed</param>
        /// <param name="depth">how many includes deep are we</param>
        /// <param name="includeFileStack">tracks the include files we are inside of, to prevent loops, and to know how deep we are</param>
        /// <param name="inputDirectory">The directory that contained the source file that was supplied to popp, or null (e.g. if stdin was the source)</param>
        IEnumerable<LineInfo> BuildListOfLines(TextReader inputReader, string inputDirectory, bool expandIncludes, List<int> includeFileIDStack)
        {
            int line_num = 0;
            int includeFileID = -1;
            string includeDirectory = null;

            if (includeFileIDStack.Count > 0) {
                // We're inside an include file, find our current directory
                includeFileID = includeFileIDStack.First();
                includeDirectory = Path.GetDirectoryName(_includeFileNames[includeFileID]);
            }

            string line;
            List<LineInfo> result = new List<LineInfo>();
            while ((line = inputReader.ReadLine()) != null) {

                line_num++;
                LineType lineType = DetermineLineType(line, line_num, includeFileID);
                LineInfo lineInfo = new LineInfo(lineType, line_num, includeFileID, line);

                if (lineType != LineType.IncludeStatement) {

                    result.Add(lineInfo);

                } else {
                    // this line is an $include statement
                    if (expandIncludes && includeFileIDStack.Count < cMaxIncludeDepth) {
                        // Expand the included file

                        string includeStatement_File;
                        TextReader includeStatement_FileReader = IncludedTextReader(lineInfo, inputDirectory, includeDirectory, out includeStatement_File);

                        if (includeStatement_FileReader != null) using(includeStatement_FileReader) {

                            int includeStatement_FileID = _includeFileNames.IndexOfFileInList(includeStatement_File);

                            if (includeFileIDStack.Contains(includeStatement_FileID)) {
                                throw new LineException(lineInfo, "Recursive $include statement found. Aborting.");
                            }

                            if (includeStatement_FileID < 0) {
                                // The $include statement is pointing to a new include file, add it to the global list of _includeFileNames
                                _includeFileNames.Add(includeStatement_File);
                                includeStatement_FileID = _includeFileNames.Count - 1;
                            }

                            // push includeStatement_FileID onto includeFileIDStack
                            includeFileIDStack.Insert(0, includeStatement_FileID);
                            try {
                                IEnumerable<LineInfo> includedLines = BuildListOfLines(includeStatement_FileReader, inputDirectory, true, includeFileIDStack);
                                result.AddRange(includedLines);
                            } finally {
                                // pop includeStatement_FileID off includeFileIDStack
                                includeFileIDStack.RemoveAt(0);
                            }
                        }
                    }
                }
            }

            return result;
        }
コード例 #7
0
ファイル: Preprocessor.cs プロジェクト: Treer/POpp
        /// <param name="expandIncludes">if true the referenced file will be inserted, if false, the include will be removed</param>
        /// <param name="depth">how many includes deep are we</param>
        /// <param name="includeFileStack">tracks the include files we are inside of, to prevent loops, and to know how deep we are</param>
        /// <param name="inputDirectory">The directory that contained the source file that was supplied to popp, or null (e.g. if stdin was the source)</param>
        IEnumerable <LineInfo> BuildListOfLines(TextReader inputReader, string inputDirectory, bool expandIncludes, List <int> includeFileIDStack)
        {
            int    line_num         = 0;
            int    includeFileID    = -1;
            string includeDirectory = null;

            if (includeFileIDStack.Count > 0)
            {
                // We're inside an include file, find our current directory
                includeFileID    = includeFileIDStack.First();
                includeDirectory = Path.GetDirectoryName(_includeFileNames[includeFileID]);
            }

            string          line;
            List <LineInfo> result = new List <LineInfo>();

            while ((line = inputReader.ReadLine()) != null)
            {
                line_num++;
                LineType lineType = DetermineLineType(line, line_num, includeFileID);
                LineInfo lineInfo = new LineInfo(lineType, line_num, includeFileID, line);

                if (lineType != LineType.IncludeStatement)
                {
                    result.Add(lineInfo);
                }
                else
                {
                    // this line is an $include statement
                    if (expandIncludes && includeFileIDStack.Count < cMaxIncludeDepth)
                    {
                        // Expand the included file

                        string     includeStatement_File;
                        TextReader includeStatement_FileReader = IncludedTextReader(lineInfo, inputDirectory, includeDirectory, out includeStatement_File);

                        if (includeStatement_FileReader != null)
                        {
                            using (includeStatement_FileReader) {
                                int includeStatement_FileID = _includeFileNames.IndexOfFileInList(includeStatement_File);

                                if (includeFileIDStack.Contains(includeStatement_FileID))
                                {
                                    throw new LineException(lineInfo, "Recursive $include statement found. Aborting.");
                                }

                                if (includeStatement_FileID < 0)
                                {
                                    // The $include statement is pointing to a new include file, add it to the global list of _includeFileNames
                                    _includeFileNames.Add(includeStatement_File);
                                    includeStatement_FileID = _includeFileNames.Count - 1;
                                }

                                // push includeStatement_FileID onto includeFileIDStack
                                includeFileIDStack.Insert(0, includeStatement_FileID);
                                try {
                                    IEnumerable <LineInfo> includedLines = BuildListOfLines(includeStatement_FileReader, inputDirectory, true, includeFileIDStack);
                                    result.AddRange(includedLines);
                                } finally {
                                    // pop includeStatement_FileID off includeFileIDStack
                                    includeFileIDStack.RemoveAt(0);
                                }
                            }
                        }
                    }
                }
            }

            return(result);
        }
コード例 #8
0
ファイル: LineException.cs プロジェクト: Treer/POpp
 public LineException(LineInfo lineInfo, string message)
     : base(message)
 {
     _lineInfo = lineInfo;
 }