static void Main(string[] args) { string pattern = "#include\\s+\"test.h\""; StreamReader reader = new StreamReader(FILENAME); string input = ""; DEFINE_STATE state = DEFINE_STATE.FIND_DEFINE; int line_number = 0; int defineLine_Number = 0; Boolean foundInclude = false; while ((input = reader.ReadLine()) != null) { line_number++; switch (state) { case DEFINE_STATE.FIND_DEFINE: if (input.Contains("#define")) { state = DEFINE_STATE.FOUND_DEFINE; defineLine_Number = line_number; foundInclude = false; } break; case DEFINE_STATE.FOUND_DEFINE: Match match = Regex.Match(input, pattern); if (match.Success) { foundInclude = true; } if (input.Contains("#else") || input.Contains("#endif") || input.Contains("#define")) { if (foundInclude == false) { Console.WriteLine("Define at line {0} does not have and include", defineLine_Number.ToString()); } if (input.Contains("#define")) { defineLine_Number = line_number; foundInclude = false; } else { state = DEFINE_STATE.FIND_DEFINE; } } break; } } Console.ReadLine(); }
static void Main(string[] args) { string pattern = "#include\\s+\"test.h\""; StreamReader reader = new StreamReader(FILENAME); string input = ""; DataTable dt = new DataTable(); dt.Columns.Add("State", typeof(int)); dt.Columns.Add("Description", typeof(DEFINE_STATE)); dt.Columns.Add("Next Define State", typeof(int)); dt.Columns.Add("Next Include State", typeof(int)); dt.Columns.Add("Next IF State", typeof(int)); dt.Columns.Add("Next Else State", typeof(int)); dt.Columns.Add("Next ENDIF State", typeof(int)); dt.Columns.Add("Error Number", typeof(ERROR)); dt.Columns.Add("Action", typeof(ACTION)); //0 do not care //-1 error //-2 invalid dt.Rows.Add(new object[] { 1, DEFINE_STATE.START, 4, 0, 2, -2, -2, ERROR.NO_ERROR, ACTION.NONE }); dt.Rows.Add(new object[] { 2, DEFINE_STATE.FOUND_IF, 3, 0, 2, 6, 10, ERROR.NO_ERROR, ACTION.NONE }); dt.Rows.Add(new object[] { 3, DEFINE_STATE.FOUND_DEFINE_IN_IF, -1, 5, 2, 6, 10, ERROR.DEFINE_FOLLOWED_BY_DEFINE, ACTION.SET_DEFINE_IF_LINE_NUMBER }); dt.Rows.Add(new object[] { 4, DEFINE_STATE.FOUND_DEFINE_NOT_IN_IF, -1, 9, -4, -2, -2, ERROR.DEFINE_FOLLOWED_BY_DEFINE, ACTION.SET_DEFINE_LINE_NUMBER }); dt.Rows.Add(new object[] { 5, DEFINE_STATE.FOUND_INCLUDE_IN_IF, 3, 0, 2, 6, 10, ERROR.NO_ERROR, ACTION.RESET_DEFINE_IF_LINE_NUMBER }); dt.Rows.Add(new object[] { 6, DEFINE_STATE.FOUND_ELSE, 7, 0, 2, -2, 10, ERROR.NO_ERROR, ACTION.NONE }); dt.Rows.Add(new object[] { 7, DEFINE_STATE.FOUND_DEFINE_IN_ELSE, -1, 8, 2, -2, 10, ERROR.DEFINE_FOLLOWED_BY_DEFINE, ACTION.SET_DEFINE_ELSE_LINE_NUMBER }); dt.Rows.Add(new object[] { 8, DEFINE_STATE.FOUND_INCLUDE_IN_ELSE, 7, 0, 2, -2, 10, ERROR.NO_ERROR, ACTION.RESET_DEFINE_ELSE_LINE_NUMBER }); dt.Rows.Add(new object[] { 9, DEFINE_STATE.FOUND_INCLUDE_NOT_IN_IF, 4, 0, 2, -2, -2, ERROR.NO_ERROR, ACTION.RESET_DEFINE_LINE_NUMBER }); dt.Rows.Add(new object[] { 10, DEFINE_STATE.FOUND_END_IF, 11, 1, 2, -2, -2, ERROR.NO_ERROR, ACTION.NONE }); dt.Rows.Add(new object[] { 11, DEFINE_STATE.RETURN, -2, -2, 2, -2, -2, ERROR.NO_ERROR, ACTION.NONE }); int level = 0; List <State_Variables> states = new List <State_Variables>(); State_Variables newState = new State_Variables(); states.Add(newState); DEFINE_STATE nextState = DEFINE_STATE.START; ACTION action = ACTION.NONE; int line_number = 0; while ((input = reader.ReadLine()) != null) { line_number++; input = input.Trim(); if (input.StartsWith("//")) { continue; //ignore comments } if (input.Length == 0) { continue; } Boolean returnFromIF = false; //test if end if is followed by include Match match = Regex.Match(input, pattern); if (states[level].state == DEFINE_STATE.FOUND_END_IF) { if (!match.Success) { int define_If_Line_Number = states[level].define_If_Line_Number; int define_Else_Line_Number = states[level].define_Else_Line_Number; if (define_If_Line_Number != 0) { Console.WriteLine("Define in IF at line {0} does not have and include", define_If_Line_Number.ToString()); } if (define_Else_Line_Number != 0) { Console.WriteLine("Define in ELSE at line {0} does not have and include", define_Else_Line_Number.ToString()); } } returnFromIF = true; states.RemoveAt(level--); } else { states[level].row = dt.AsEnumerable().Where(x => x.Field <int>((int)TABLE_COLUMN.STATE) == (int)states[level].state).FirstOrDefault(); } nextState = DEFINE_STATE.NONE; //check if defines are terminated with include if (input.Contains("#define")) { nextState = (DEFINE_STATE)states[level].row.Field <int>((int)TABLE_COLUMN.DEFINE); } if (match.Success) { if (returnFromIF) { nextState = DEFINE_STATE.START; } else { nextState = (DEFINE_STATE)states[level].row.Field <int>((int)TABLE_COLUMN.INCLUDE); } } if (input.Contains("#if")) { nextState = (DEFINE_STATE)states[level].row.Field <int>((int)TABLE_COLUMN.IF); states.Add(new State_Variables()); level++; } if (input.Contains("#else")) { nextState = (DEFINE_STATE)states[level].row.Field <int>((int)TABLE_COLUMN.ELSE); } if (input.Contains("#endif")) { nextState = (DEFINE_STATE)states[level].row.Field <int>((int)TABLE_COLUMN.END_IF); } if ((nextState != DEFINE_STATE.ERROR) && (nextState != DEFINE_STATE.DO_NOT_CARE)) { states[level].state = nextState; } switch (nextState) { case DEFINE_STATE.NONE: //stay at current state Console.WriteLine("Did not find state at line {0}", line_number); break; case DEFINE_STATE.INVALID: Console.WriteLine("Invalid IF/ELSE/END_IF at line {0}", line_number); break; case DEFINE_STATE.ERROR: action = states[level].row.Field <ACTION>((int)TABLE_COLUMN.ACTION); switch (action) { case ACTION.SET_DEFINE_LINE_NUMBER: Console.WriteLine("Define followed by Define at line {0}", states[level].define_Line_Number.ToString()); states[level].define_Line_Number = line_number; break; case ACTION.SET_DEFINE_IF_LINE_NUMBER: Console.WriteLine("Define in IF followed by Define by at line {0}", states[level].define_If_Line_Number.ToString()); states[level].define_If_Line_Number = line_number; break; case ACTION.SET_DEFINE_ELSE_LINE_NUMBER: Console.WriteLine("Define in ELSE followed by Define at line {0}", states[level].define_Else_Line_Number.ToString()); states[level].define_Else_Line_Number = line_number; break; } break; case DEFINE_STATE.SPECIAL: Console.WriteLine("Define followed IF at line {0}", states[level].define_Line_Number.ToString()); nextState = DEFINE_STATE.FOUND_IF; break; default: //if (states[level].row != null)//value will be null when entering IF so there will never be an action //{ states[level].row = dt.AsEnumerable().Where(x => x.Field <DEFINE_STATE>((int)TABLE_COLUMN.STATE) == nextState).FirstOrDefault(); action = states[level].row.Field <ACTION>((int)TABLE_COLUMN.ACTION); switch (action) { case ACTION.RESET_DEFINE_LINE_NUMBER: states[level].define_Line_Number = 0; break; case ACTION.RESET_DEFINE_IF_LINE_NUMBER: states[level].define_If_Line_Number = 0; break; case ACTION.RESET_DEFINE_ELSE_LINE_NUMBER: states[level].define_Else_Line_Number = 0; break; case ACTION.SET_DEFINE_LINE_NUMBER: states[level].define_Line_Number = line_number; break; case ACTION.SET_DEFINE_IF_LINE_NUMBER: states[level].define_If_Line_Number = line_number; break; case ACTION.SET_DEFINE_ELSE_LINE_NUMBER: states[level].define_Else_Line_Number = line_number; break; } states[level].state = nextState; //} break; } } //final checks int define_Line_Number = states[level].define_Line_Number; if (define_Line_Number != 0) { Console.WriteLine("Define at line {0} does not have and include", define_Line_Number.ToString()); } if (level != 0) { Console.WriteLine("Did not close all IFs with End_If"); } Console.WriteLine("Done"); Console.ReadLine(); }