コード例 #1
0
ファイル: ESDOptions.cs プロジェクト: vawser/ESDLang
        public static ESDOptions Parse(string[] cargs)
        {
            HashSet <char> invalid = new HashSet <char>(Path.GetInvalidPathChars());
            Queue <string> args    = new Queue <string>(cargs);
            List <Option>  opts    = new List <Option>();

            bool isFlag(string arg)
            {
                // - by itself can be a valid arg
                return(arg.Length > 1 && arg.StartsWith("-"));
            }

            while (args.Count > 0)
            {
                string arg = args.Dequeue();
                if (!isFlag(arg))
                {
                    throw new Exception($"Expected flag; got argument -{arg}");
                }
                arg = arg.Substring(1);
                string getOnlyArg()
                {
                    if (args.Count == 0 || isFlag(args.Peek()))
                    {
                        throw new Exception($"No value provided for flag -{arg}");
                    }
                    return(args.Dequeue());
                }

                List <string> getMultiArg()
                {
                    List <string> ret = new List <string>();

                    while (args.Count > 0 && !isFlag(args.Peek()))
                    {
                        ret.Add(args.Dequeue());
                    }
                    if (ret.Count == 0)
                    {
                        throw new Exception($"No value provided for flag -{arg}");
                    }
                    return(ret);
                }

                void checkFilename(string path)
                {
                    if (invalid.Overlaps(path))
                    {
                        throw new Exception($"Invalid filename {path}");
                    }
                }

                Regex format = new Regex("%.");
                void checkTemplate(string path, string formats)
                {
                    foreach (Match m in format.Matches(path))
                    {
                        char ch = m.Groups[0].Value[1];
                        if (!formats.Contains(ch))
                        {
                            throw new Exception($"Unknown format %{ch} for flag -{arg}");
                        }
                    }
                }

                if (games.Names.ContainsKey(arg))
                {
                    opts.Add(new SetGame {
                        Game = games.Names[arg]
                    });
                }
                else if (specFlags.Contains(arg))
                {
                    SetGameOpt opt = new SetGameOpt {
                        Name = arg
                    };
                    string val = getOnlyArg();
                    if (arg == "outdcx")
                    {
                        opt.Dcx = dcxs[val.ToLower()];
                    }
                    else
                    {
                        opt.Value = val;
                    }
                    opts.Add(opt);
                }
                else if (arg == "cmdtype")
                {
                    string val = getOnlyArg();
                    opts.Add(new SetCmdType {
                        Type = cmdTypes[val]
                    });
                }
                else if (arg == "eddformat")
                {
                    string val = getOnlyArg();
                    opts.Add(new SetEddFormat {
                        Type = eddFormats[val]
                    });
                }
                else if (arg == "edddir")
                {
                    string val = getOnlyArg();
                    checkFilename(val);
                    opts.Add(new SetEddDir {
                        DirName = val
                    });
                }
                else if (allFlags.Contains(arg))
                {
                    bool val = true;
                    if (!defaultFlags.ContainsKey(arg))
                    {
                        arg = arg.Substring(2);
                        val = false;
                    }
                    opts.Add(new SetFlag {
                        Name = arg, Value = val
                    });
                }
                else if (arg == "f")
                {
                    List <string> vals = getMultiArg();
                    foreach (string val in vals)
                    {
                        if (!(val.StartsWith("c") || val.StartsWith("h") || val.StartsWith("m") || ESDName.IsKnownPrefix(val)))
                        {
                            throw new Exception($"Unrecognized filter value {val}");
                        }
                    }
                    opts.Add(new AddFilter {
                        Name = vals
                    });
                }
                else if (arg == "i")
                {
                    List <string> vals = getMultiArg();
                    foreach (string val in vals)
                    {
                        checkFilename(val);
                    }
                    opts.Add(new AddInput {
                        Name = vals
                    });
                }
                else if (arg == "writebnd")
                {
                    string val = getOnlyArg();
                    checkFilename(val);
                    opts.Add(new WriteBnd {
                        DirName = val
                    });
                }
                else if (arg == "writeloose")
                {
                    string val = getOnlyArg();
                    checkFilename(val);
                    checkTemplate(val, "e");
                    opts.Add(new WriteLoose {
                        Template = val
                    });
                }
                else if (arg == "writepy")
                {
                    string val = getOnlyArg();
                    checkFilename(val);
                    checkTemplate(val, "ecm");
                    opts.Add(new WritePy {
                        Template = val
                    });
                }
                else if (arg == "writeedd")
                {
                    string val = getOnlyArg();
                    checkFilename(val);
                    checkTemplate(val, "e");
                    if (!val.EndsWith(".edd.txt"))
                    {
                        throw new Exception("writeedd argument does not end with .edd.txt");
                    }
                    opts.Add(new WriteEdd {
                        Template = val
                    });
                }
                else if (arg == "info")
                {
                    opts.Add(new Info());
                }
                else
                {
                    throw new Exception($"Unknown command line flag -{arg}");
                }
            }
            return(new ESDOptions(opts));
        }
コード例 #2
0
ファイル: ESDOptions.cs プロジェクト: vawser/ESDLang
        public Option NextAction()
        {
            while (opts.Count > 0)
            {
                Option opt = opts.Dequeue();
                if (opt is SetGame game)
                {
                    Spec = ForGame(game.Game);
                    EsdInputs.Clear();
                    ClearFilters();
                }
                else if (opt is SetGameOpt gameOpt)
                {
                    string val = gameOpt.Value;
                    switch (gameOpt.Name)
                    {
                    case "basedir": Spec.GameDir = WindowsifyPath(val); break;

                    case "esddir":
                        Spec.EsdDir = WindowsifyPath(val);
                        EsdInputs.Clear();
                        ClearFilters();
                        break;

                    case "maps": Spec.MsbDir = val; break;

                    case "names": Spec.NameDir = val; break;

                    case "msgs": Spec.MsgDir = val; break;

                    case "layouts": Spec.LayoutDir = WindowsifyPath(val); break;

                    case "params": Spec.ParamFile = WindowsifyPath(val); break;

                    case "outdcx": Spec.Dcx = gameOpt.Dcx; break;

                    default: break;
                    }
                    if (Spec.GameDir == null)
                    {
                        throw new Exception($"Can't set {gameOpt.Name} without setting basedir first");
                    }
                }
                else if (opt is SetFlag flag)
                {
                    Flags[flag.Name] = flag.Value;
                }
                else if (opt is AddFilter filter)
                {
                    ClearFilters();
                    foreach (string val in filter.Name)
                    {
                        if (ESDName.IsKnownPrefix(val))
                        {
                            Esds.Add(val);
                        }
                        else if (val.StartsWith("m"))
                        {
                            Maps.Add(val);
                        }
                        else if (val.StartsWith("c") || val.StartsWith("h"))
                        {
                            Chrs.Add(val);
                        }
                        else
                        {
                            throw new Exception($"Internal error: unknown filter {val}");
                        }
                    }
                }
                else if (opt is AddInput input)
                {
                    if (input.Name.Any(n => n.EndsWith(".py")))
                    {
                        if (!input.Name.All(n => n.EndsWith(".py")))
                        {
                            throw new Exception($"Some but not all input files ended in .py");
                        }
                        PyInputs.Clear();
                        PyInputs.AddRange(input.Name);
                    }
                    else
                    {
                        foreach (string val in input.Name)
                        {
                            if (!(val.EndsWith(".esd") || val.EndsWith("esdbnd.dcx") || val.EndsWith(".esd.dcx")))
                            {
                                throw new Exception($"ESD input files must end in .esd, .esdbnd.dcx, or .esd.dcx");
                            }
                        }
                        EsdInputs.Clear();
                        EsdInputs.AddRange(input.Name);
                    }
                }
                else if (opt is SetCmdType cmd)
                {
                    Type = cmd.Type;
                }
                else if (opt is SetEddFormat eddFormat)
                {
                    EddFormat = eddFormat.Type;
                }
                else if (opt is SetEddDir eddDir)
                {
                    EddDir = eddDir.DirName;
                }
                else
                {
                    // All others are actions
                    LastAction = opt;
                    return(LastAction);
                }
            }
            if (LastAction == null)
            {
                LastAction = new Info();
                return(LastAction);
            }
            return(null);
        }
コード例 #3
0
ファイル: CommandRunner.cs プロジェクト: vawser/ESDLang
 private EzSembleContext LoadContext(string esdName)
 {
     return(LoadContext(options.Type == ESDOptions.CmdType.Unknown ? ESDName.GetCmdType(Path.GetFileNameWithoutExtension(esdName), options.Spec.Game) : options.Type));
 }