예제 #1
0
파일: VarStorg.cs 프로젝트: omuleanu/oss
        public bool ContainsKey(string name)
        {
            var res = vars.ContainsKey(name);

            if (!res && bvars != null)
            {
                res = bvars.ContainsKey(name);
            }

            return(res);
        }
예제 #2
0
        public OssParseResult ParseOssString(string str, string rootPath)
        {
            int errors       = 0;
            var insertedList = new List <string>();
            var lres         = new List <Rule>();
            var namedRules   = new Dictionary <string, Rule>();
            var rheader      = string.Empty;

            // named rule, used for inheritance
            string ruleName = null;

            var vars = new VarStorg();

            //var vars = new SortedDictionary<string, OssVar>(new ReverseComparer<string>(StringComparer.InvariantCulture));

            void ClearEmpty()
            {
                if (rheader.Trim(StrConst.EmptyChars).Length == 0)
                {
                    rheader = string.Empty;
                }
            }

            void AddHeaderToBase(IEnumerable <string> inherits)
            {
                if (inherits == null)
                {
                    return;
                }

                foreach (var name in inherits)
                {
                    if (!namedRules.ContainsKey(name))
                    {
                        logger.Error($"could not find name {name} to inherit");
                        errors++;
                        continue;
                    }

                    //if (namedRules[name].IsEmpty)
                    //{
                    //    logger.Info($"inheriting empty rule {name}, statement can be removed");
                    //}

                    var baseRule = namedRules[name];

                    if (baseRule.Header != null)
                    {
                        baseRule.Header = StrUtil.InsertStrBeforeEmptys(baseRule.Header,
                                                                        ",\r\n" + StrUtil.GetLastIndentation(baseRule.Header) + StrUtil.TrimEmptys(rheader));
                    }
                    else
                    {
                        baseRule.Header = rheader;
                    }

                    AddHeaderToBase(baseRule.Inherits);
                }
            }

            for (var i = 0; i < str.Length; i++)
            {
                if (str.IsNextStr(i, OssConst.VarDeclKey))
                {
                    // var = x / {x:y} / { header { x: y } .. };

                    i += OssConst.VarDeclKey.Length;

                    var varname = str.GetVarName(i, out i);
                    var varval  = str.GetVarVal(i, out i);
                    var keepraw = false;

                    if (varname[0] == ':')
                    {
                        keepraw = true;
                        varname = varname.Substring(1);
                    }

                    var osv = new OssVar();
                    osv.Name    = varname;
                    osv.IsRules = varval.IsRules;

                    osv.Val = osv.IsRules || keepraw ? new ParseContentRes {
                        Content = varval.Val, IsRaw = true
                    } : ParseContent(varval.Val, vars);

                    osv.Val.RawContent = varval.Val;

                    vars.Add(varname, osv);

                    if (i < str.Length - 1 && str[i + 1] == ';')
                    {
                        i++;
                    }

                    rheader = rheader.TrimEnd(StrConst.EmptyChars);
                }
                else if (str.IsNextStr(i, "{"))
                {
                    // rule block

                    var endi = str.GetBlockEnd(i);

                    var block = str.FromTo(i, endi);
                    i = endi;
                    var vpr = ParseContent(block, vars);

                    var val = vpr.Content;

                    var lrule = new Rule();

                    if (rheader.Trim(StrConst.EmptyChars) == string.Empty)
                    {
                        rheader           = null;
                        lrule.EmptyHeader = true;
                    }

                    lrule.Header   = rheader;
                    lrule.Body     = val;
                    lrule.Name     = ruleName;
                    lrule.Inherits = vpr.Inherits;
                    lrule.IsEmpty  = val.Trim(StrConst.RuleTrimChars).Length == 0;

                    lres.Add(lrule);

                    if (ruleName != null)
                    {
                        if (namedRules.ContainsKey(ruleName))
                        {
                            logger.Error($"name {ruleName} already defined");
                        }

                        namedRules.Add(ruleName, lrule);
                    }

                    if (vpr.Inherits.Any())
                    {
                        AddHeaderToBase(vpr.Inherits);
                    }

                    rheader  = string.Empty;
                    ruleName = null;
                }
                else if (str.IsNextStr(i, OssConst.InsertKey))
                {
                    // insert file.txt content

                    i += OssConst.InsertKey.Length;
                    var url     = str.GetNextWordToSemicol(i, out i);
                    var insPath = rootPath + "\\" + url;

                    // add inserted file to watchlist
                    insertedList.Add(insPath);

                    // read inserted file
                    var instr = fileOp.ReadText(insPath);
                    str = str.Insert(i + 1, instr);
                }
                else if (str.IsNextStr(i, OssConst.NameKey))
                {
                    // define rule name (for inheritance)

                    i       += OssConst.NameKey.Length;
                    ruleName = str.GetNextWordToSemicol(i, out i);
                }
                else if (str.IsNextStr(i, OssConst.Atvar))
                {
                    // insert var content

                    i += OssConst.Atvar.Length;
                    var name = str.GetNextWordToSemicol(i, out i);
                    if (vars.ContainsKey(name))
                    {
                        var osv = vars[name];
                        if (string.IsNullOrWhiteSpace(osv.Val.RawContent))
                        {
                            ClearEmpty();
                        }
                        else
                        {
                            str = str.Insert(i + 1, osv.Val.RawContent);
                        }
                    }
                    else
                    {
                        ClearEmpty();
                        logger.Info($"could not find var {name}");
                    }
                }
                else
                {
                    var c = str[i];
                    rheader += c;
                }
            }

            lres.Add(new Rule {
                IsComment = true, Body = rheader
            });

            var slres = string.Empty;

            foreach (var rule in lres.Where(o => !o.IsEmpty && o.Header != null))
            {
                slres += rule.Header + rule.Body;
            }

            slres = slres.Trim(StrConst.EmptyChars);

            var unusedVars = vars.GetUnusedNames().ToArray();

            if (unusedVars.Any())
            {
                logger.Warn("unused variables: " + string.Join(", ", unusedVars));
            }

            return(new OssParseResult
            {
                ParseRes = slres,
                InsertedFiles = insertedList,
                Errors = errors,
                UnusedVars = unusedVars
            });
        }