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); }
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); }
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); }