Example #1
0
        /// <summary>
        /// Parsing process, processing single trimmed FULL-line as new section start
        /// </summary>
        /// <param name="oneLine">Line to be processed</param>
        /// <param name="fullLineComment">Comment to given section</param>
        /// <param name="curLine">Current line number, for when exception occurs</param>
        /// <param name="knownSections">Dictionary of all pre-parsed sections</param>
        /// <returns>Newly entered section</returns>
        internal static QualifiedSectionName processSingleLineAsSectionStart(string oneLine, string fullLineComment, uint curLine, Dictionary <QualifiedSectionName, InnerSection> knownSections)
        {
            //{ a-z, A-Z, 0-9, _, ~, -, ., :, $, mezera } začínající znakem z množiny { a-z, A-Z, . , $, : }
            bool matchesSection = System.Text.RegularExpressions.Regex.IsMatch(oneLine, "\\[[a-zA-Z,\\.$:][a-zA-Z0-9_~\\.:$ -]*\\]");

            // Mismatching format
            if (!matchesSection)
            {
                throw new ParserExceptionWithinConfig(
                          userMsg: "Error when parsing file on line " + curLine + " unexpected section start",
                          developerMsg: "Unexpected start of the file on line " + curLine + ", section start does not match desired format",
                          line: curLine);
            }

            // extract values
            int    rightBracket        = oneLine.IndexOf(']');
            string sectionName         = oneLine.Substring(1, rightBracket - 1);
            QualifiedSectionName qName = new QualifiedSectionName(sectionName);

            // Section redefinition
            if (knownSections.ContainsKey(qName))
            {
                throw new ParserExceptionWithinConfig(
                          userMsg: "Error when parsing file on line " + curLine + " redefinition of section " + sectionName,
                          developerMsg: "Error when parsing file on line " + curLine + " redefinition of section " + sectionName,
                          line: curLine,
                          section: sectionName);
            }

            // Create new section & return it
            knownSections.Add(qName, new InnerSection(qName, fullLineComment));
            return(qName);
        }
Example #2
0
        /// <summary>
        /// Read configuration data from given stream
        /// </summary>
        /// <param name="input">Stream from which data is to be read</param>
        private void readConfig(StreamReader input)
        {
            // Reset known sections and options
            knownSections = new Dictionary <QualifiedSectionName, InnerSection>();

            // State variables
            QualifiedSectionName curSection = null;
            uint curLine = 0;

            // Crawl full stream
            try
            {
                string oneLine;
                string fullLineComment = "";
                while ((oneLine = input.ReadLine()) != null)
                {
                    // Trim & update state variables
                    oneLine = trimRespectLastEscapedSpace(oneLine);
                    ++curLine;

                    // blank line
                    if (oneLine == "")
                    {
                        continue;
                    }

                    // switching logic
                    switch (oneLine[0])
                    {
                    case '[':
                        curSection      = Parser.processSingleLineAsSectionStart(oneLine, fullLineComment, curLine, knownSections);
                        fullLineComment = "";
                        break;

                    case ';':
                        fullLineComment = oneLine.Substring(1);
                        break;

                    default:
                        Parser.processSingleLineAsOption(oneLine, curLine, curSection, knownSections);
                        fullLineComment = "";
                        break;
                    }
                }
            }
            catch (ParserException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new ParserExceptionWithinConfig(
                          userMsg: "Parsing of file failed on line " + curLine,
                          developerMsg: "Unexpected exception ocurred on line " + curLine + ", see inner exception for more details",
                          line: curLine,
                          section: curSection.ID,
                          inner: ex);
            }
        }
Example #3
0
        /// <summary>
        /// Set option info and it's value.
        /// NOTE: Only options which are set via this call can be ADDED into output (readed options are included automatically).
        /// </summary>
        /// <param name="info">Structure describing option format</param>
        /// <param name="value">Structure wearing option value</param>
        internal void SetOption(OptionInfo info, OptionValue value)
        {
            // Check inner constraints
            checkValidity(info, value);

            // obtain qNames
            QualifiedSectionName qSect = value.Name.Section;
            QualifiedOptionName  qOpt  = value.Name;

            // Check that section exists
            if (!knownSections.ContainsKey(qSect))
            {
                throw new ParserException(
                          userMsg: "error, unknown section",
                          developerMsg: "tried to set option in unknown section, sections needs to be retrieved from RegisterStructure() or from the actual file");
            }

            // Ensure option exists
            if (!knownSections[qSect].Options.ContainsKey(qOpt))
            {
                InnerOption newOpt = new InnerOption(qOpt, null);
                knownSections[qSect].Options.Add(qOpt, newOpt);
                newOpt.Comment = info.DefaultComment;
            }

            // along the way, check the comment
            checkOptionCommentAndSeen(info, knownSections);

            // Pass value into option
            InnerOption     curOpt = knownSections[qSect].Options[qOpt];
            IValueConverter converter;

            try
            {
                converter = Converters.ConfigConverters.getConverter(info);
            }
            catch (Exception ex)
            {
                throw new ParserException(userMsg: "Error when deserializing value", developerMsg: "Unsupported value tried to be deserialized", inner: ex);
            }

            if (info.IsContainer)
            {
                curOpt.strValues.Clear();
                foreach (var elem in ConfigRW.ConfigCreation.StructureFactory.GetContainerElements(value.ConvertedValue))
                {
                    curOpt.strValues.Add(converter.Serialize(elem));
                }
            }
            else
            {
                curOpt.strValues.Clear();
                curOpt.strValues.Add(converter.Serialize(value.ConvertedValue));
            }
        }
Example #4
0
        internal SectionInfo(
            QualifiedSectionName name, PropertyInfo associatedProperty,
            bool isOptional,
            string defaultComment,
            List <OptionInfo> options
            )
        {
            Name = name;

            AssociatedProperty = associatedProperty.Name;
            DescribingType     = associatedProperty.PropertyType;
            IsOptional         = isOptional;

            foreach (var option in options)
            {
                _options[option.Name] = option;
            }

            Options = _options.Values;

            DefaultComment = defaultComment;
        }
Example #5
0
        /// <summary>
        /// Evaluates last link in the lexes list
        /// </summary>
        private void evaluateLink()
        {
            var lnkOption = lexes.Last();

            lexes.RemoveAt(lexes.Count - 1);
            var lnkSection = lexes.Last();

            lexes.RemoveAt(lexes.Count - 1);

            if (lnkSection.Item1 != Lexes.NT_LinkSection || lnkOption.Item1 != Lexes.NT_LinkOption)
            {
                throw new ParserException(userMsg: "Error when parsing configuration file", developerMsg: "unexpected element instead of Link parts in Lexer::evaluateLink");
            }

            QualifiedSectionName qSec = new QualifiedSectionName(lnkSection.Item2);
            QualifiedOptionName  qOpt = new QualifiedOptionName(qSec, lnkOption.Item2);

            InnerOption opt;

            try
            {
                opt = knownSections[qSec].Options[qOpt];
            }
            catch (Exception ex)
            {
                throw new ParserException(
                          userMsg: "Error when evaluating link during parsing of configuration file",
                          developerMsg: "Link inside option value points to nonexistent section#option",
                          inner: ex);
            }

            foreach (string val in opt.strValues)
            {
                lexes.Add(new Tuple <Lexes, string>(Lexes.T_ValuePart, val));
            }
        }
Example #6
0
 internal QualifiedOptionName(QualifiedSectionName section, string optionID)
 {
     ID      = optionID;
     Section = section;
 }
Example #7
0
        /// <summary>
        /// Parsing process, processing single trimmed FULL-line as option
        /// </summary>
        /// <param name="oneLine">Line to be processed</param>
        /// <param name="curLine">Current line number, for when exception occurs</param>
        /// <param name="curSection">Currently processed section</param>
        /// <param name="knownSections">Dictionary of all pre-parsed sections</param>
        internal static void processSingleLineAsOption(string oneLine, uint curLine, QualifiedSectionName curSection, Dictionary <QualifiedSectionName, InnerSection> knownSections)
        {
            // no section started yet
            if (curSection == null)
            {
                throw new ParserExceptionWithinConfig(
                          userMsg: "Error when parsing file on line " + curLine + " unexpected element outside of section",
                          developerMsg: "Unexpected start of the file on line " + curLine + ", option with no section",
                          line: curLine,
                          section: curSection.ID);
            }

            try
            {
                Lexer lineLexer = new Lexer(oneLine, knownSections);
                var   lexes     = lineLexer.GetLexes();

                var lxName = lexes[0];
                lexes.RemoveAt(0);
                if (lxName.Item1 != Lexer.Lexes.T_Identifier)
                {
                    throw new ParserExceptionWithinConfig(
                              userMsg: "Error when parsing file on line " + curLine,
                              developerMsg: "Lexer process does not provided option identifier",
                              line: curLine,
                              section: curSection.ID);
                }

                QualifiedOptionName qName = new QualifiedOptionName(curSection, lxName.Item2);
                if (knownSections[curSection].Options.ContainsKey(qName))
                {
                    throw new ParserExceptionWithinConfig(
                              userMsg: "Error when parsing file on line " + curLine + ", duplicit option",
                              developerMsg: "Duplicit option ID occurred inside this section",
                              line: curLine,
                              section: curSection.ID,
                              option: qName.ID);
                }

                InnerOption newOpt = new InnerOption(qName, curLine);
                knownSections[curSection].Options.Add(qName, newOpt);

                foreach (var lexeme in lexes)
                {
                    if (lexeme.Item1 == Lexer.Lexes.T_Comment && lexeme == lexes[lexes.Count - 1])
                    {
                        newOpt.Comment = lexeme.Item2;
                    }
                    else if (lexeme.Item1 == Lexer.Lexes.T_ValuePart)
                    {
                        newOpt.strValues.Add(lexeme.Item2);
                    }
                    else
                    {
                        throw new ParserExceptionWithinConfig(
                                  userMsg: "Error when parsing file on line " + curLine,
                                  developerMsg: "unexpected lexeme pop off the lexer",
                                  line: curLine,
                                  section: curSection.ID,
                                  option: qName.ID);
                    }
                }
            }
            catch (ParserException ex)
            {
                throw new ParserExceptionWithinConfig(
                          userMsg: "Error when parsing file on line " + curLine,
                          developerMsg: "Exception ocurred in Lexer process",
                          line: curLine,
                          section: curSection.ID,
                          inner: ex);
            }
            catch (Exception ex)
            {
                throw new ParserExceptionWithinConfig(
                          userMsg: "Error when parsing file on line " + curLine,
                          developerMsg: "Unexpected exception ocurred in Lexer process",
                          line: curLine,
                          section: curSection.ID,
                          inner: ex);
            }
        }
Example #8
0
 /// <summary>
 /// Name of section as seen in config
 /// </summary>
 /// <param name="name">Qualified name</param>
 /// <param name="comment">Section comment</param>
 internal InnerSection(QualifiedSectionName name, string comment)
 {
     Name    = name;
     Comment = comment;
 }