Пример #1
0
        public string GenerateSource()
        {
            string code = LibnxUtils.MakeInterfaceServiceBaseSource(this) + "\n\n";

            foreach (var c in Commands)
            {
                string cmd = "// [" + c.Id + "] " + NnName + "->" + c.Name + "\n";
                cmd += "Result ";
                if (IsService)
                {
                    cmd += FormattedName + "_";
                }
                else
                {
                    cmd += FormattedNnName + "_";
                }
                cmd += c.Name + "(";
                if (!IsService)
                {
                    cmd += FormattedNnName + " *session";
                }
                uint incounter   = 0;
                uint outcounter  = 0;
                uint ioutcounter = 0;
                if (c.InRawTypes.Count > 0)
                {
                    if (!IsService)
                    {
                        cmd += ", ";
                    }
                    foreach (var irt in c.InRawTypes)
                    {
                        if (irt.ArgType.IsValid)
                        {
                            cmd += irt.ArgType.CName + " ";
                        }
                        else
                        {
                            cmd += "u8 *";
                        }
                        if (string.IsNullOrEmpty(irt.Name))
                        {
                            cmd += "in_" + incounter;
                            incounter++;
                        }
                        else
                        {
                            cmd += irt.Name;
                        }
                        cmd += ", ";
                    }
                    cmd = cmd.Substring(0, cmd.Length - 2);
                }
                if (c.OutRawTypes.Count > 0)
                {
                    foreach (var rawt in c.OutRawTypes)
                    {
                        if (cmd.Last() != '(')
                        {
                            cmd += ", ";
                        }
                        if (rawt.ArgType.IsValid)
                        {
                            cmd += rawt.ArgType.CName + " *";
                        }
                        else
                        {
                            cmd += "u8 *";
                        }
                        if (string.IsNullOrEmpty(rawt.Name))
                        {
                            cmd += "out_" + outcounter;
                            outcounter++;
                        }
                        else
                        {
                            cmd += rawt.Name;
                        }
                    }
                }
                if (c.OutInterfaces.Count > 0)
                {
                    foreach (var intf in c.OutInterfaces)
                    {
                        cmd += ", ";
                        cmd += intf.ArgType.FormattedNnName + " *";
                        if (string.IsNullOrEmpty(intf.Name))
                        {
                            cmd += "iout_" + ioutcounter;
                            ioutcounter++;
                        }
                        else
                        {
                            cmd += intf.Name;
                        }
                    }
                }
                cmd      += ")"; cmd += "\n";
                cmd      += "{"; cmd += "\n";
                cmd      += "    IpcCommand c;"; cmd += "\n";
                cmd      += "    ipcInitialize(&c);"; cmd += "\n";
                cmd      += "    struct {"; cmd += "\n";
                cmd      += "        u64 magic;"; cmd += "\n";
                cmd      += "        u64 cmd_id;"; cmd += "\n";
                incounter = 0;
                if (c.InRawTypes.Count > 0)
                {
                    foreach (var irt in c.InRawTypes)
                    {
                        cmd += "        ";
                        if (irt.ArgType.IsValid)
                        {
                            cmd += irt.ArgType.CName + " in_" + incounter + ";";
                        }
                        else
                        {
                            cmd += "u8 in_" + incounter + "[" + irt.ArgType.Bytes + "];";
                        }
                        cmd += "\n";
                        incounter++;
                    }
                }
                string srvref = IsService ? "&g_" + FormattedName + "_ISrv" : "&session->s";
                cmd      += "    } *raw = serviceIpcPrepareHeader(" + srvref + ", &c, sizeof(*raw));"; cmd += "\n";
                cmd      += "    raw->magic = SFCI_MAGIC;"; cmd += "\n";
                cmd      += "    raw->cmd_id = " + c.Id + ";"; cmd += "\n";
                incounter = 0;
                if (c.InRawTypes.Count > 0)
                {
                    foreach (var irt in c.InRawTypes)
                    {
                        if (irt.ArgType.IsValid)
                        {
                            cmd += "    raw->in_" + incounter + " = ";
                            if (string.IsNullOrEmpty(irt.Name))
                            {
                                cmd += "in_" + incounter;
                            }
                            else
                            {
                                cmd += irt.Name;
                            }
                            cmd += ";"; cmd += "\n";
                        }
                        else
                        {
                            cmd += "    memcpy(raw->in_" + incounter + ", ";
                            if (string.IsNullOrEmpty(irt.Name))
                            {
                                cmd += "in_" + incounter;
                            }
                            else
                            {
                                cmd += irt.Name;
                            }

                            cmd += ", " + irt.ArgType.Bytes + ");"; cmd += "\n";
                        }
                        if (string.IsNullOrEmpty(irt.Name))
                        {
                            incounter++;
                        }
                        incounter++;
                    }
                }
                cmd       += "    Result rc = serviceIpcDispatch(" + srvref + ");"; cmd += "\n";
                cmd       += "    if(R_SUCCEEDED(rc))"; cmd += "\n";
                cmd       += "    {"; cmd += "\n";
                cmd       += "        IpcParsedCommand r;"; cmd += "\n";
                cmd       += "        struct {"; cmd += "\n";
                cmd       += "            u64 magic;"; cmd += "\n";
                cmd       += "            u64 result;"; cmd += "\n";
                outcounter = 0;
                if (c.OutRawTypes.Count > 0)
                {
                    foreach (var rawt in c.OutRawTypes)
                    {
                        cmd += "            ";
                        if (rawt.ArgType.IsValid)
                        {
                            cmd += rawt.ArgType.CName + " out_" + outcounter + ";";
                        }
                        else
                        {
                            cmd += "u8 out_" + outcounter + "[" + rawt.ArgType.Bytes + "];";
                        }
                        cmd += "\n";
                        outcounter++;
                    }
                }
                cmd += "        } *resp;"; cmd += "\n";
                cmd += "        serviceIpcParse(" + srvref + ", &r, sizeof(*resp));"; cmd += "\n";
                cmd += "        resp = r.Raw;"; cmd += "\n";
                cmd += "        rc = resp->result;"; cmd += "\n";
                if ((c.OutInterfaces.Count > 0) || (c.OutRawTypes.Count > 0))
                {
                    cmd += "        if(R_SUCCEEDED(rc))"; cmd += "\n";
                    cmd += "        {"; cmd += "\n";
                    if (c.OutRawTypes.Count > 0)
                    {
                        outcounter = 0;
                        foreach (var rawt in c.OutRawTypes)
                        {
                            cmd += "            if(";
                            if (string.IsNullOrEmpty(rawt.Name))
                            {
                                cmd += "out_" + outcounter;
                            }
                            else
                            {
                                cmd += rawt.Name;
                            }
                            cmd += ")";
                            if (rawt.ArgType.IsValid)
                            {
                                cmd += " { *";
                                if (string.IsNullOrEmpty(rawt.Name))
                                {
                                    cmd += "out_" + outcounter;
                                }
                                else
                                {
                                    cmd += rawt.Name;
                                }
                                cmd += " = resp->out_" + outcounter + "; }";
                                cmd += "\n";
                            }
                            else
                            {
                                cmd += "\n";
                                cmd += "        {"; cmd += "\n";
                                cmd += "            memcpy(";
                                if (string.IsNullOrEmpty(rawt.Name))
                                {
                                    cmd += "out_" + outcounter;
                                }
                                else
                                {
                                    cmd += rawt.Name;
                                }
                                cmd += ", resp->out_" + outcounter + ", " + rawt.ArgType.Bytes + ");"; cmd += "\n";
                            }
                            if (string.IsNullOrEmpty(rawt.Name))
                            {
                                outcounter++;
                            }
                        }
                    }
                    if (c.OutInterfaces.Count > 0)
                    {
                        ioutcounter = 0;
                        foreach (var intf in c.OutInterfaces)
                        {
                            cmd += "            serviceCreateSubservice(";
                            if (string.IsNullOrEmpty(intf.Name))
                            {
                                cmd += "iout_" + ioutcounter;
                                ioutcounter++;
                            }
                            else
                            {
                                cmd += intf.Name;
                            }
                            cmd += ", " + srvref + ", &r, 0);";
                            cmd += "\n";
                        }
                    }
                    cmd += "        }"; cmd += '\n';
                }
                cmd  += "    }"; cmd += "\n";
                cmd  += "    return rc;"; cmd += "\n";
                cmd  += "}"; cmd += "\n";
                code += cmd + "\n";
            }
            return(code);
        }
Пример #2
0
        public string GenerateHeader()
        {
            string code = LibnxUtils.MakeInterfaceServiceBaseHeader(this) + "\n\n";

            foreach (var c in Commands)
            {
                string cmd = "// [" + c.Id + "] " + NnName + "->" + c.Name + "\n";
                cmd += "Result ";
                if (IsService)
                {
                    cmd += FormattedName + "_";
                }
                else
                {
                    cmd += FormattedNnName + "_";
                }
                cmd += c.Name + "(";
                if (!IsService)
                {
                    cmd += FormattedNnName + " *session";
                }
                uint incounter   = 0;
                uint outcounter  = 0;
                uint ioutcounter = 0;
                if (c.InRawTypes.Count > 0)
                {
                    if (!IsService)
                    {
                        cmd += ", ";
                    }
                    foreach (var irt in c.InRawTypes)
                    {
                        if (irt.ArgType.IsValid)
                        {
                            cmd += irt.ArgType.CName + " ";
                        }
                        else
                        {
                            cmd += "u8 *";
                        }
                        if (string.IsNullOrEmpty(irt.Name))
                        {
                            cmd += "in_" + incounter;
                            incounter++;
                        }
                        else
                        {
                            cmd += irt.Name;
                        }
                        cmd += ", ";
                    }
                    cmd = cmd.Substring(0, cmd.Length - 2);
                }
                if (c.OutRawTypes.Count > 0)
                {
                    foreach (var rawt in c.OutRawTypes)
                    {
                        if (cmd.Last() != '(')
                        {
                            cmd += ", ";
                        }
                        if (rawt.ArgType.IsValid)
                        {
                            cmd += rawt.ArgType.CName + " *";
                        }
                        else
                        {
                            cmd += "u8 *";
                        }
                        if (string.IsNullOrEmpty(rawt.Name))
                        {
                            cmd += "out_" + outcounter;
                            outcounter++;
                        }
                        else
                        {
                            cmd += rawt.Name;
                        }
                    }
                }
                if (c.OutInterfaces.Count > 0)
                {
                    foreach (var intf in c.OutInterfaces)
                    {
                        cmd += ", ";
                        cmd += intf.ArgType.FormattedNnName + " *";
                        if (string.IsNullOrEmpty(intf.Name))
                        {
                            cmd += "iout_" + ioutcounter;
                            ioutcounter++;
                        }
                        else
                        {
                            cmd += intf.Name;
                        }
                    }
                }
                cmd  += ");\n";
                code += cmd;
            }
            code = code.Substring(0, code.Length - 1);
            return(code);
        }
Пример #3
0
        public static CCode Parse(string IDText)
        {
            VersionDecorator cur_v = null;

            for (int i = 0; i < IDText.Length; i++)
            {
                char cur = IDText[i];
                if (cur == '@')
                {
                    string tmpv = IDText.Substring(i + 1, 7);
                    if (tmpv == "version")
                    {
                        tmpv  = IDText.Substring(i + 9).Split(')')[0];
                        cur_v = new VersionDecorator(tmpv);
                    }
                }
                else if (cur == '#')
                {
                    do
                    {
                        i++;
                    } while (IDText[i] == '\n');
                }
                else if (cur == 't')
                {
                    string tmpt = IDText.Substring(i, 4);
                    if (tmpt == "type")
                    {
                        int tmpid     = i + 3;
                        int tmpspaces = 0;
                        do
                        {
                            tmpid++;
                            tmpspaces++;
                        } while (IDText[tmpid] == ' ');
                        string typename = "";
                        while ((IDText[tmpid] != ' ') && (IDText[tmpid] != '='))
                        {
                            typename += IDText[tmpid];
                            tmpid++;
                        }
                        if (IDText[tmpid] == ' ')
                        {
                            tmpid++;
                        }
                        do
                        {
                            tmpid++;
                            tmpspaces++;
                        } while (IDText[tmpid] == ' ');
                        string eqname = "";
                        while (IDText[tmpid] != ';')
                        {
                            eqname += IDText[tmpid];
                            tmpid++;
                        }
                        var t = Static.GetCustomType(eqname);
                        if (t == null)
                        {
                            t = Static.GetBuiltInType(eqname);
                        }
                        if (t != null)
                        {
                            var at = new Type(typename, t);
                            if (cur_v != null)
                            {
                                at.Version = cur_v;
                                cur_v      = null;
                            }
                            Static.CustomTypes.Add(at);
                        }
                        else
                        {
                            if (eqname.Substring(0, 5) == "bytes")
                            {
                                long   bsz;
                                string sz = eqname.Substring(eqname.IndexOf('<') + 1).Split(',')[0].Replace(">", "");
                                if (sz.StartsWith("0x"))
                                {
                                    bsz = long.Parse(sz.Substring(2), System.Globalization.NumberStyles.HexNumber);
                                }
                                else
                                {
                                    bsz = long.Parse(sz);
                                }
                                var at = new Type(typename, bsz);
                                if (cur_v != null)
                                {
                                    at.Version = cur_v;
                                    cur_v      = null;
                                }
                                Static.CustomTypes.Add(at);
                            }
                        }
                    }
                }
                else if (cur == 'i')
                {
                    if ((IDText.Length > (i + 9)) && (IDText.Substring(i, 9) == "interface"))
                    {
                        var intf      = new Interface();
                        int tmpid     = i + 9;
                        int tmpspaces = 0;
                        do
                        {
                            tmpid++;
                            tmpspaces++;
                        } while ((IDText.Length > tmpid) && ((IDText[tmpid] == ' ') || (IDText[tmpid] == '\n') || (IDText[tmpid] == '\t') || (IDText[tmpid] == '\r')));
                        string intfname = "";
                        while ((IDText.Length > tmpid) && (IDText[tmpid] != ' '))
                        {
                            intfname += IDText[tmpid];
                            tmpid++;
                        }
                        do
                        {
                            tmpid++;
                            tmpspaces++;
                        } while ((IDText.Length > tmpid) && ((IDText[tmpid] == ' ') || (IDText[tmpid] == '\n') || (IDText[tmpid] == '\t') || (IDText[tmpid] == '\r')));;
                        intf.NnName = intfname;
                        string srvname = null;
                        if ((IDText.Length > tmpid) && (IDText.Substring(tmpid, 2) == "is"))
                        {
                            tmpid++;
                            tmpspaces = 0;
                            do
                            {
                                tmpid++;
                                tmpspaces++;
                            } while (IDText[tmpid] == ' ');
                            srvname = "";
                            while (IDText[tmpid] != ' ')
                            {
                                srvname += IDText[tmpid];
                                tmpid++;
                            }
                            do
                            {
                                tmpid++;
                                tmpspaces++;
                            } while ((IDText.Length > tmpid) && ((IDText[tmpid] == ' ') || (IDText[tmpid] == '\n') || (IDText[tmpid] == '\t') || (IDText[tmpid] == '\r')));
                        }
                        if (srvname == "@managedport")
                        {
                            intf.IsManagedPort = true;
                            tmpid--;
                            do
                            {
                                tmpid++;
                                tmpspaces++;
                            } while (IDText[tmpid] == ' ');
                            srvname = "";
                            while (IDText[tmpid] != ' ')
                            {
                                srvname += IDText[tmpid];
                                tmpid++;
                            }
                            do
                            {
                                tmpid++;
                                tmpspaces++;
                            } while ((IDText.Length > tmpid) && ((IDText[tmpid] == ' ') || (IDText[tmpid] == '\n') || (IDText[tmpid] == '\t') || (IDText[tmpid] == '\r')));
                        }
                        intf.ServiceName = srvname;
                        if (IDText[tmpid] == '{')
                        {
                            while ((tmpid + 1) < IDText.Length)
                            {
                                tmpid++;
                                if (IDText[tmpid] == '}')
                                {
                                    break;
                                }
                                if (IDText[tmpid] == '[')
                                {
                                    var c = new Command();
                                    tmpid++;
                                    string tmpno = IDText.Substring(tmpid).Split(']')[0];
                                    c.Id   = uint.Parse(tmpno);
                                    tmpid += tmpno.Length + 1;
                                    do
                                    {
                                        tmpid++;
                                        tmpspaces++;
                                    } while ((IDText.Length > tmpid) && ((IDText[tmpid] == ' ') || (IDText[tmpid] == '\n') || (IDText[tmpid] == '\t') || (IDText[tmpid] == '\r')));
                                    string cmdname = IDText.Substring(tmpid).Split('(')[0];
                                    tmpid += cmdname.Length + 1;
                                    c.Name = cmdname;
                                    string indata = IDText.Substring(tmpid).Split(')')[0];
                                    var    inargs = ParseNames(indata);

                                    foreach (var pair in inargs)
                                    {
                                        var t2 = Static.GetCustomType(pair.Key);
                                        if (t2 == null)
                                        {
                                            t2 = Static.GetBuiltInType(pair.Key);
                                        }
                                        if (t2 != null)
                                        {
                                            var at = new Argument <Type>(t2);
                                            if (!string.IsNullOrEmpty(pair.Value))
                                            {
                                                at.Name = pair.Value;
                                            }
                                            c.InRawTypes.Add(at);
                                        }
                                        else
                                        {
                                            if (pair.Key.StartsWith("object<"))
                                            {
                                                string objname = pair.Key.Substring(pair.Key.IndexOf('<') + 1).Split('>')[0];
                                                if (Interfaces.Count > 0)
                                                {
                                                    foreach (var intf1 in Interfaces)
                                                    {
                                                        if (intf1.NnName == objname)
                                                        {
                                                            var it = new Argument <Interface>(intf1);
                                                            if (!string.IsNullOrEmpty(pair.Value))
                                                            {
                                                                it.Name = pair.Value;
                                                            }
                                                            c.InInterfaces.Add(it);
                                                            break;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    tmpid += indata.Length;

                                    do
                                    {
                                        tmpid++;
                                        tmpspaces++;
                                    } while ((IDText.Length > tmpid) && ((IDText[tmpid] == ' ') || (IDText[tmpid] == '\n') || (IDText[tmpid] == '\t') || (IDText[tmpid] == '\r')));
                                    if ((IDText.Length > tmpid) && (IDText[tmpid] == '-'))
                                    {
                                        tmpid++;
                                        if ((IDText.Length > tmpid) && (IDText[tmpid] == '>'))
                                        {
                                            do
                                            {
                                                tmpid++;
                                                tmpspaces++;
                                            } while ((IDText.Length > tmpid) && ((IDText[tmpid] == ' ') || (IDText[tmpid] == '(') || (IDText[tmpid] == '\n') || (IDText[tmpid] == '\t') || (IDText[tmpid] == '\r')));
                                            string outdata = IDText.Substring(tmpid).Split(')')[0].Split(';')[0];
                                            var    args    = ParseNames(outdata);
                                            foreach (var pair in args)
                                            {
                                                var t2 = Static.GetCustomType(pair.Key);
                                                if (t2 == null)
                                                {
                                                    t2 = Static.GetBuiltInType(pair.Key);
                                                }
                                                if (t2 != null)
                                                {
                                                    var at = new Argument <Type>(t2);
                                                    if (!string.IsNullOrEmpty(pair.Value))
                                                    {
                                                        at.Name = pair.Value;
                                                    }
                                                    c.OutRawTypes.Add(at);
                                                }
                                                else
                                                {
                                                    if (pair.Key.StartsWith("object<"))
                                                    {
                                                        string objname = pair.Key.Substring(pair.Key.IndexOf('<') + 1).Split('>')[0];
                                                        if (Interfaces.Count > 0)
                                                        {
                                                            foreach (var intf1 in Interfaces)
                                                            {
                                                                if (intf1.NnName == objname)
                                                                {
                                                                    var it = new Argument <Interface>(intf1);
                                                                    if (!string.IsNullOrEmpty(pair.Value))
                                                                    {
                                                                        it.Name = pair.Value;
                                                                    }
                                                                    c.OutInterfaces.Add(it);
                                                                    break;
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                            tmpid += outdata.Length;
                                        }
                                    }
                                    intf.Commands.Add(c);
                                    if (IDText[tmpid] == ';')
                                    {
                                        do
                                        {
                                            tmpid++;
                                            tmpspaces++;
                                        } while ((IDText.Length > tmpid) && ((IDText[tmpid] == ' ') || (IDText[tmpid] == '\n') || (IDText[tmpid] == '\t') || (IDText[tmpid] == '\r')));
                                        tmpid--;
                                        continue;
                                    }
                                    else
                                    {
                                        tmpid++;
                                        if (IDText[tmpid] == ';')
                                        {
                                            do
                                            {
                                                tmpid++;
                                                tmpspaces++;
                                            } while ((IDText.Length > tmpid) && ((IDText[tmpid] == ' ') || (IDText[tmpid] == '\n') || (IDText[tmpid] == '\t') || (IDText[tmpid] == '\r')));
                                            tmpid--;
                                            continue;
                                        }
                                    }
                                }
                            }
                            Interfaces.Add(intf);
                        }
                    }
                }
            }
            CCode code = new CCode();

            code.Header = "#pragma once\n#include <switch.h>\n\n// Bindings generated by swipcgen: https://github.com/XorTroll/swipcgen" + LibnxUtils.MakeCustomTypedefs();
            foreach (var intf in Interfaces)
            {
                code.Header += "\n\n" + intf.GenerateHeader();
                code.Source += intf.GenerateSource() + "\n\n";
            }
            code.Source = code.Source.Substring(0, code.Source.Length - 2);
            return(code);
        }