Ejemplo n.º 1
0
        // Parses the entire file, calls OnEntry each time msgid/msgstr pair is found.
        // return false if parsing failed, true otherwise
        public bool Parse()
        {
            string        line, dummy;
            string        mflags        = String.Empty;
            string        mstr          = String.Empty;
            string        msgidPlural   = String.Empty;
            string        mcomment      = String.Empty;
            List <string> mrefs         = new List <string> ();
            List <string> mautocomments = new List <string> ();
            List <string> mtranslations = new List <string> ();
            bool          hasPlural     = false;

            using (StreamReader sr = new StreamReader(fileName, encoding))
            {
                line = sr.ReadLine();

                while (line == "")
                {
                    line = sr.ReadLine();
                }

                if (line == null)
                {
                    return(false);
                }

                while (line != null)
                {
                    // ignore empty special tags (except for automatic comments which we
                    // DO want to preserve):
                    while (line == "#," || line == "#:")
                    {
                        line = sr.ReadLine();
                    }

                    // flags:
                    // Can't we have more than one flag, now only the last is kept ...
                    if (CatalogParser.ReadParam(line, "#, ", out dummy))
                    {
                        mflags = dummy;                         //"#, " +
                        line   = sr.ReadLine();
                    }

                    // auto comments:
                    if (CatalogParser.ReadParam(line, "#. ", out dummy) || CatalogParser.ReadParam(line, "#.", out dummy))                       // second one to account for empty auto comments
                    {
                        mautocomments.Add(dummy);
                        line = sr.ReadLine();
                    }

                    // references:
                    else if (CatalogParser.ReadParam(line, "#: ", out dummy))
                    {
                        // A line may contain several references, separated by white-space.
                        // Each reference is in the form "path_name:line_number"
                        // (path_name may contain spaces)
                        dummy = dummy.Trim();
                        while (dummy != String.Empty)
                        {
                            int i = 0;
                            while (i < dummy.Length && dummy[i] != ':')
                            {
                                i++;
                            }
                            while (i < dummy.Length && !Char.IsWhiteSpace(dummy[i]))
                            {
                                i++;
                            }

                            //store paths as Unix-type paths, but internally use native style
                            string refpath = dummy.Substring(0, i);
                            if (MonoDevelop.Core.Platform.IsWindows)
                            {
                                refpath = refpath.Replace('/', '\\');
                            }

                            mrefs.Add(refpath);
                            dummy = dummy.Substring(i).Trim();
                        }

                        line = sr.ReadLine();
                    }

                    // msgid:
                    else if (CatalogParser.ReadParam(line, "msgid \"", out dummy) ||
                             CatalogParser.ReadParam(line, "msgid\t\"", out dummy))
                    {
                        mstr = ParseMessage(ref line, ref dummy, sr);
                    }

                    // msgid_plural:
                    else if (CatalogParser.ReadParam(line, "msgid_plural \"", out dummy) ||
                             CatalogParser.ReadParam(line, "msgid_plural\t\"", out dummy))
                    {
                        msgidPlural = ParseMessage(ref line, ref dummy, sr);
                        hasPlural   = true;
                    }

                    // msgstr:
                    else if (CatalogParser.ReadParam(line, "msgstr \"", out dummy) ||
                             CatalogParser.ReadParam(line, "msgstr\t\"", out dummy))
                    {
                        if (hasPlural)
                        {
                            // TODO: use logging
                            Console.WriteLine("Broken catalog file: singular form msgstr used together with msgid_plural");
                            return(false);
                        }

                        string str = ParseMessage(ref line, ref dummy, sr);
                        mtranslations.Add(str);

                        if (!OnEntry(mstr, String.Empty, false, mtranslations.ToArray(),
                                     mflags, mrefs.ToArray(), mcomment,
                                     mautocomments.ToArray()))
                        {
                            return(false);
                        }

                        mcomment  = mstr = msgidPlural = mflags = String.Empty;
                        hasPlural = false;
                        mrefs.Clear();
                        mautocomments.Clear();
                        mtranslations.Clear();
                    }
                    else if (CatalogParser.ReadParam(line, "msgstr[", out dummy))
                    {
                        // msgstr[i]:
                        if (!hasPlural)
                        {
                            // TODO: use logging
                            Console.WriteLine("Broken catalog file: plural form msgstr used without msgid_plural");
                            return(false);
                        }

                        int    pos   = dummy.IndexOf(']');
                        string idx   = dummy.Substring(pos - 1, 1);
                        string label = "msgstr[" + idx + "]";

                        while (CatalogParser.ReadParam(line, label + " \"", out dummy) || CatalogParser.ReadParam(line, label + "\t\"", out dummy))
                        {
                            StringBuilder str = new StringBuilder(dummy.Substring(0, dummy.Length - 1));

                            while (!String.IsNullOrEmpty(line = sr.ReadLine()))
                            {
                                if (line[0] == '\t')
                                {
                                    line = line.Substring(1);
                                }
                                if (line[0] == '"' && line[line.Length - 1] == '"')
                                {
                                    str.Append(line, 1, line.Length - 2);
                                }
                                else
                                {
                                    if (ReadParam(line, "msgstr[", out dummy))
                                    {
                                        pos   = dummy.IndexOf(']');
                                        idx   = dummy.Substring(pos - 1, 1);
                                        label = "msgstr[" + idx + "]";
                                    }
                                    break;
                                }
                            }
                            mtranslations.Add(StringEscaping.FromGettextFormat(str.ToString()));
                        }

                        if (!OnEntry(mstr, msgidPlural, true, mtranslations.ToArray(),
                                     mflags, mrefs.ToArray(), mcomment,
                                     mautocomments.ToArray()))
                        {
                            return(false);
                        }

                        mcomment  = mstr = msgidPlural = mflags = String.Empty;
                        hasPlural = false;
                        mrefs.Clear();
                        mautocomments.Clear();
                        mtranslations.Clear();
                    }
                    else if (CatalogParser.ReadParam(line, "#~ ", out dummy))
                    {
                        // deleted lines:

                        List <string> deletedLines = new List <string> ();
                        deletedLines.Add(line);
                        while (!String.IsNullOrEmpty(line = sr.ReadLine()))
                        {
                            // if line does not start with "#~ " anymore, stop reading
                            if (!ReadParam(line, "#~ ", out dummy))
                            {
                                break;
                            }

                            deletedLines.Add(line);
                        }
                        if (!OnDeletedEntry(deletedLines.ToArray(), mflags, null, mcomment, mautocomments.ToArray()))
                        {
                            return(false);
                        }

                        mcomment  = mstr = msgidPlural = mflags = String.Empty;
                        hasPlural = false;
                        mrefs.Clear();
                        mautocomments.Clear();
                        mtranslations.Clear();
                    }
                    else if (line != null && line[0] == '#')
                    {
                        // comment:

                        //  added line[1] != '~' check as deleted lines where being wrongly detected as comments
                        while (!String.IsNullOrEmpty(line) &&
                               ((line[0] == '#' && line.Length < 2) ||
                                (line[0] == '#' && line[1] != ',' && line[1] != ':' && line[1] != '.' && line[1] != '~')))
                        {
                            mcomment += mcomment.Length > 0 ? '\n' + line : line;
                            line      = sr.ReadLine();
                        }
                    }
                    else
                    {
                        line = sr.ReadLine();
                    }

                    while (line == String.Empty)
                    {
                        line = sr.ReadLine();
                    }
                }
            }
            return(true);
        }
Ejemplo n.º 2
0
 public CatalogParser(string fileName, Encoding encoding)
 {
     //this.fileName = fileName;
     loadedFile = File.ReadAllText(fileName, encoding);
     fileLines  = CatalogParser.GetLines(loadedFile, out newLine);
 }