// parse a script string static public scriptParserCmd parseString(string s) { // create a new cmd scriptParserCmd cmd = new scriptParserCmd(); cmd.error = true; cmd.strCmd = s; // is comment? if (isComment(s)) { cmd.cmd = cmdType.comment; cmd.error = false; return(cmd); } // try to parse var reg = Regex.Match(s, @"\b(\w+)\s*\({1}\s*(.*)\)\s*;"); if (reg.Success) { string funcName = reg.Groups[1].Value.ToLower(); string funcParams = reg.Groups[2].Value; // try to parse as sleep cmd cmd = parseSleep(funcName, funcParams); // try to parse as send cmd if (cmd.error) { cmd = parseSend(funcName, funcParams); } // try to parse as read cmd if (cmd.error) { cmd = parseRead(s, funcName, funcParams); } // try to parse as trace cmd if (cmd.error) { cmd = parseTrace(funcName, funcParams); } // breakpoint if (cmd.error) { cmd = parseBreakpoint(funcName, funcParams); } // try to parse as send uds request cmd if (cmd.error) { cmd = parseSendUds(s, funcName, funcParams); } if (cmd.error) { cmd = parseSendBmw(s, funcName, funcParams); } } cmd.strCmd = s; return(cmd); }
// parser static public scriptParserCmd[] parseText(string txt) { // replace '\t' txt = txt.Replace('\t', ' '); // remove comments txt = removeComments(txt); // remove #if 0 else #endif txt = removeIfElse(txt); // remove #if 0 txt = removeIf0(txt); // defines, as int = .. txt = applyDefines(txt); // connect strings txt = connectStrings(txt); // split string[] ls = txt.Split('\n'); for (int i = 0; i < ls.Count(); i++) { ls[i] += "\n"; } // parse scriptParserCmd[] cmd = new scriptParserCmd[ls.Length]; for (int i = 0; i < ls.Length; i++) { cmd[i] = parseString(ls[i]); } return(cmd); }
// parser: breakpoint static private scriptParserCmd parseBreakpoint(string funcName, string args) { // create a new cmd scriptParserCmd cmd = new scriptParserCmd(); cmd.error = true; if (funcName == "breakpoint" && string.IsNullOrEmpty(args)) { cmd.error = false; cmd.cmd = cmdType.breakpoint; } return(cmd); }
// parser: sleep message static private scriptParserCmd parseSleep(string funcName, string args) { // create a new cmd scriptParserCmd cmd = new scriptParserCmd(); cmd.error = true; if (funcName == "sleep") { int val = 0; if (canAnalyzer.Tools.tryParseInt(args, out val)) { // complete cmd.error = false; cmd.sleepTmo = val; cmd.cmd = cmdType.sleep; } } return(cmd); }
// format: bmw_req(ecu_id, data..); // example: buff2 = bmw_req(0x60, 0x22, 0xF1, 0x90); static private scriptParserCmd parseSendBmw(string inString, string funcName, string args) { // create a new cmd scriptParserCmd cmd = new scriptParserCmd(); cmd.error = true; // remove spaces args = args.Replace(" ", ""); if (funcName == "bmw_req" || funcName == "bmw_req11") { bool asVar = false; int varIdx = -1; // remove spaces args = args.Replace(" ", ""); inString = inString.Replace(" ", ""); // should we save a response as a variable? for (int i = 0; i < 10 && !asVar; i++) { string txt = string.Format("arr{0}=", i); asVar = inString.IndexOf(txt) == 0; if (asVar) { varIdx = i; } } string[] paramList = args.Split(','); if (paramList.Length > 1 && paramList.Length <= 5) { // ecu_id, data (1..5) int ecu_id = 0; int dlc = paramList.Length - 1; List <string> sData = new List <string>(); bool failed = false; object calc = null; // ecalute: req id calc = canAnalyzer.MyCalc.evaluate(paramList[0]); failed = calc == null; if (!failed) { ecu_id = canAnalyzer.MyCalc.objToI32(calc); } if (!failed) { failed = ecu_id == 0 || ecu_id > 0xFF; } // evaluate: data bytes for (int i = 1; i < paramList.Length && !failed; i++) { string param = paramList[i]; string s_byte = null; calc = canAnalyzer.MyCalc.evaluate(param); failed = calc == null; // just append if (!failed) { byte b = canAnalyzer.MyCalc.objToByte(calc); s_byte = b.ToString(); } else { string s_tmp = null; // may contain variables if (param.Contains("var")) { const string pattern = @"var\d\[\s*\d\s*\]"; s_tmp = Regex.Replace(param, pattern, "1", RegexOptions.Singleline); } // evaluate if (s_tmp != null) { calc = canAnalyzer.MyCalc.evaluate(s_tmp); failed = calc == null; // append if (!failed) { s_byte = param.ToString(); } } } // append if (!failed) { if (s_byte != null) { sData.Add(s_byte); } else { failed = true; } } } if (!failed) { cmd.cmd = cmdType.udsReqSend; cmd.paramsUdsReq = new cmdUdsReqParams((byte)(ecu_id), sData.ToArray(), asVar, varIdx); cmd.error = false; } } } return(cmd); }
// format: printf("format", arg1, arg2, ..); // example: printf("rpm = %d", var[0] << 8 | var[1]); static private scriptParserCmd parseTrace(string funcName, string args) { // create a new cmd scriptParserCmd cmd = new scriptParserCmd(); cmd.error = true; if (funcName == "printf") { cmd.cmd = cmdType.trace; string[] argList = new string[args.Length - 1]; var regFormat = Regex.Match(args, "\".*\""); if (regFormat.Success) { string s = args.Replace(regFormat.Value, ""); s = s.Replace(" ", ""); if (s.Length > 0 && s[0] == ',') { s = s.Remove(0, 1); } string format = regFormat.Value; List <string> ls = new List <string>(s.Split(',')); for (int i = 0; i < ls.Count; i++) { if (string.IsNullOrEmpty(ls[i])) { ls.RemoveAt(i); } } // %x, %02x == X, X2 // %d // %f // List<string> lsFormat = new List<string>(); // check skobochki foreach (string str in ls) { int open = 0, close = 0; open = str.ToCharArray().Where(i => i == '(').Count(); close = str.ToCharArray().Where(i => i == ')').Count(); if (open != close) { return(cmd); } } // extra format parser // {s0-s6} // {0-6} var regFormatVarsAsArray = Regex.Matches(format, @"{(\d+)-(\d+)}"); foreach (Match v in regFormatVarsAsArray) { string s1 = v.Groups[1].ToString(); string s2 = v.Groups[2].ToString(); int i1 = Convert.ToInt32(s1); int i2 = Convert.ToInt32(s2); if (i2 > i1) { string newFormat = string.Empty; for (int i = i1; i <= i2; i++) { newFormat += "{" + i.ToString() + "}"; } format = format.Replace(v.Groups[0].ToString(), newFormat); } } var regFormatVarsStrAsArray = Regex.Matches(format, @"{s(\d+)-s(\d+)}"); foreach (Match v in regFormatVarsStrAsArray) { string s1 = v.Groups[1].ToString(); string s2 = v.Groups[2].ToString(); int i1 = Convert.ToInt32(s1); int i2 = Convert.ToInt32(s2); if (i2 > i1) { string newFormat = string.Empty; for (int i = i1; i <= i2; i++) { newFormat += "{s" + i.ToString() + "}"; } format = format.Replace(v.Groups[0].ToString(), newFormat); } } cmd.cmd = cmdType.trace; cmd.paramsTrace = new cmdTrace(format, ls.ToArray()); cmd.error = false; } } return(cmd); }
// format: read(0x316, 1000, **, 0x*F, 0x33, ***); // var2 = read(0x123, ***); static private scriptParserCmd parseRead(string inString, string funcName, string args) { // create a new cmd scriptParserCmd cmd = new scriptParserCmd(); cmd.error = true; if (funcName == "read" || funcName == "read11" || funcName == "read29") { string inString_original = inString; // remove spaces args = args.Replace(" ", ""); inString = inString.Replace(" ", ""); bool is29bit = funcName.Contains("29"); bool asVar = false; int varIdx = -1; // should we save a response as a variable? for (int i = 0; i <= 9 && !asVar; i++) { string txt = string.Format("var{0}=", i); asVar = inString.IndexOf(txt) == 0; if (asVar) { varIdx = i; } } // parse all the arguments string[] paramList = args.Split(','); if (paramList.Length > 2 && paramList.Length <= 10) { // id, tmo, data mask (1..8) int canID = -1; string canIdPattern = string.Empty; int tmo = -1; string mask = args.Substring(paramList[0].Length + paramList[1].Length + 2); // +2 commas string[] dataMask = mask.Split(','); bool failed = false; // get CAN id if (!parseReadId(paramList[0], is29bit, out canID, out canIdPattern)) { canID = -1; canIdPattern = string.Empty; failed = true; } // timeout tmo = parseReadTimeout(paramList[1]); if (tmo <= 0) { failed = true; } int minDLC = -1; for (int i = 0; i < dataMask.Length && -1 == minDLC; i++) { if (dataMask[i].Contains("***")) { minDLC = i; } } // get a var name /* * var regVarName = Regex.Match(inString, @"var\s+(\w+)\s*="); * string varName = string.Empty; * if (regVarName.Success) * varName = regVarName.Groups[1].ToString(); */ if (!failed) { cmd.cmd = cmdType.read; cmd.paramsRead = new cmdReadParams(canID, dataMask, is29bit, tmo, minDLC, asVar, varIdx); cmd.error = false; } } } return(cmd); }
// parser: send a CAN message static private scriptParserCmd parseSend(string funcName, string args) { // create a new cmd scriptParserCmd cmd = new scriptParserCmd(); cmd.error = true; // remove spaces args = args.Replace(" ", ""); if (funcName == "send" || funcName == "send11" || funcName == "send29") { bool is29bit = funcName.Contains("29"); string[] paramList = args.Split(','); if (paramList.Length >= 2 && paramList.Length <= 9) { // id, data (1..8) int canID = -1; int dlc = paramList.Length - 1; string[] sData = new string[dlc]; bool failed = false; object calc = null; // ecalute: can id //int val = -1; calc = canAnalyzer.MyCalc.evaluate(paramList[0]); failed = (calc == null) || (Convert.ToInt32(calc) > canAnalyzer.canMessageId.GetMaxId(is29bit)); if (!failed) { canID = canAnalyzer.MyCalc.objToI32(calc); } // evaluate: data bytes for (int i = 1; i < paramList.Length && !failed; i++) { string param = paramList[i]; string s_byte = null; calc = canAnalyzer.MyCalc.evaluate(param); failed = calc == null; // just append if (!failed) { byte b = canAnalyzer.MyCalc.objToByte(calc); s_byte = b.ToString(); } else { string s_tmp = null; // may contain variables if (param.Contains("var")) { const string pattern = @"var\d\[\s*\d\s*\]"; s_tmp = Regex.Replace(param, pattern, "1", RegexOptions.Singleline); } // may contain arrays if (param.Contains("arr")) { const string pattern = @"arr\d\[\s*\d\s*\]"; s_tmp = Regex.Replace(param, pattern, "1", RegexOptions.Singleline); } // evaluate if (s_tmp != null) { calc = canAnalyzer.MyCalc.evaluate(s_tmp); failed = calc == null; // append if (!failed) { s_byte = param.ToString(); } } } // append if (!failed) { if (s_byte != null) { sData[i - 1] = s_byte; } else { failed = true; } } } if (!failed) { cmd.cmd = cmdType.send; cmd.paramsSend = new cmdSendParams(canID, sData, is29bit); cmd.error = false; } } } return(cmd); }