Example #1
0
        public static bool PerformPreProcessFile(string filePath, List<PreProcessFile> ppFiles, List<preprocessFile_IfDefModes> ifdefs = null, string name = "", Dictionary<string, PPDefine> defines = null)
        {
            if (name == "")
                name = filePath.Substring(filePath.LastIndexOf('\\') + 1);
            if (ifdefs == null)
                ifdefs = new List<preprocessFile_IfDefModes>();
            if (defines == null)
                defines = new Dictionary<string, PPDefine>();
            //Open given file
            StreamReader reader = new StreamReader(filePath);
            PreProcessFile ppFile = new PreProcessFile(filePath, name);
            if (ppFiles != null)
                ppFiles.Add(ppFile);
            StreamWriter writer = new StreamWriter(ppFile.FileStream);

            //Prepare some variables needed for the entire processing periode in this function
            string s;
            uint filelinenumber = 0;
            while ((s = reader.ReadLine()) != null)
            {
                filelinenumber++;
                //skip empty lines
                if (string.IsNullOrWhiteSpace(s))
                {
                    writer.WriteLine();
                    continue;
                }
                //Remove left & right whitespaces and tabs from current string
                string sTrimmed = s.TrimStart();
                string leading = s.Substring(0, s.Length - sTrimmed.Length);
                s = sTrimmed;
                if (s[0] != '#')
                {//Current line is no define, thus handle it normally (find & replace)
                 //Make sure we are not inside of an ifdef/ifndef that disallows further processing of following lines
                    int i = ifdefs.Count - 1;
                    if (i >= 0 && ifdefs[i] != preprocessFile_IfDefModes.TRUE)
                        continue;
                    try
                    {
                        //Let every define check if it is inside of current line
                        foreach (PPDefine def in defines.Values)
                            s = def.replace(s);
                    }
                    catch (Exception ex)
                    {
                        //Catch possible exceptions from define parsing
                        Logger.Error(string.Concat("Experienced some error while parsing existing defines. ", ex.Message, ". file: ", filePath, ". linenumber: ", filelinenumber));
                        reader.Close();
                        return false;
                    }
                    writer.WriteLine(leading + s);
                    continue;
                }
                //We DO have a define here
                //get end of the define name
                int spaceIndex = s.IndexOf(' ');
                if (spaceIndex < 0)
                    spaceIndex = s.Length;
                //set some required variables for the switch
                int index = -1;
                int index2 = -1;
                //get text AFTER the define
                string afterDefine = s.Substring(spaceIndex).TrimStart();

                writer.WriteLine();

                //Check which define was used
                switch (s.Substring(0, spaceIndex))
                {
                    default:
                        throw new Exception("Encountered unknown define '" + s.Substring(0, spaceIndex) + "'");
                    case "#include":
                        //We are supposed to include a new file at this spot so lets do it
                        //Beautify the filepath so we can work with it
                        afterDefine.Trim();
                        string newFile;
                        newFile = afterDefine.Trim(new char[] { '"', '\'', ' ' });
                        //make sure we have no self reference here
                        if (newFile.Equals(filePath, StringComparison.OrdinalIgnoreCase))
                        {
                            //Ohhh no ... some problem in OSI layer 8
                            reader.Close();
                            writer.Close();
                            throw new Exception("Include contains self reference. file: " + filePath + ". linenumber: " + filelinenumber);
                        }
                        //process the file before continuing with this
                        try
                        {
                            if (!PerformPreProcessFile(newFile, ppFiles, ifdefs, afterDefine.Trim(new char[] { '<', '>', '"', '\'', ' ' }), defines))
                            {
                                //A sub file encountered an error, so stop here to prevent useles waste of ressources
                                reader.Close();
                                writer.Close();
                                return false;
                            }
                        }
                        catch (Exception e)
                        {
                            throw new Exception(e.Message + ", from " + filePath);
                        }
                        break;
                    case "#define":
                        //The user wants to define something here
                        while (s.EndsWith("\\"))
                        {
                            writer.WriteLine();
                            afterDefine += reader.ReadLine();
                            filelinenumber++;
                        }
                        //Get the two possible characters index that can be encountered after a define
                        index = afterDefine.IndexOf(' ');
                        index2 = afterDefine.IndexOf('(');
                        //check which one is found first
                        if (index < 0 || (index2 < index && index2 >= 0))
                            index = afterDefine.IndexOf('(');
                        //check that we really got a define with a value here, if not just take the entire length as no value is needed and only value provided
                        if (index < 0)
                            index = afterDefine.Length;
                        if (defines.ContainsKey(afterDefine.Substring(0, index)))
                        {
                            //Redefining something is not allowed, so throw an error here
                            reader.Close();
                            writer.Close();
                            throw new Exception("Redefining a define is not allowed! Use #undefine to undef something. file: " + filePath + ". linenumber: " + filelinenumber);
                        }
                        //FINALLY add the define
                        defines.Add(afterDefine.Substring(0, index), new PPDefine(afterDefine));
                        break;
                    case "#undefine":
                        //just remove straigth
                        defines.Remove(s.Substring(spaceIndex).Trim());
                        break;
                    case "#ifdef":
                        //do required stuff for define ifs
                        if (defines.ContainsKey(afterDefine))
                            ifdefs.Add(ifdefs.Count == 0 || ifdefs[ifdefs.Count - 1] == preprocessFile_IfDefModes.TRUE ? preprocessFile_IfDefModes.TRUE : preprocessFile_IfDefModes.IGNORE);
                        else
                            ifdefs.Add(ifdefs.Count == 0 || ifdefs[ifdefs.Count - 1] == preprocessFile_IfDefModes.TRUE ? preprocessFile_IfDefModes.FALSE : preprocessFile_IfDefModes.IGNORE);
                        break;
                    case "#ifndef":
                        //do required stuff for define ifs
                        if (defines.ContainsKey(afterDefine))
                            ifdefs.Add(ifdefs.Count == 0 || ifdefs[ifdefs.Count - 1] == preprocessFile_IfDefModes.TRUE ? preprocessFile_IfDefModes.FALSE : preprocessFile_IfDefModes.IGNORE);
                        else
                            ifdefs.Add(ifdefs.Count == 0 || ifdefs[ifdefs.Count - 1] == preprocessFile_IfDefModes.TRUE ? preprocessFile_IfDefModes.TRUE : preprocessFile_IfDefModes.IGNORE);
                        break;
                    case "#else":
                        //do required stuff for define ifs
                        index = ifdefs.Count - 1;
                        if (index < 0)
                        {
                            reader.Close();
                            writer.Close();
                            throw new Exception("unexpected #else. file: " + filePath + ". linenumber: " + filelinenumber);
                        }
                        //swap the value of currents if scope to the correct value
                        ifdefs[index] = (ifdefs[index] == preprocessFile_IfDefModes.TRUE ? preprocessFile_IfDefModes.FALSE : (ifdefs[index] == preprocessFile_IfDefModes.FALSE ? preprocessFile_IfDefModes.TRUE : preprocessFile_IfDefModes.IGNORE));
                        break;
                    case "#endif":
                        //do required stuff for define ifs
                        index = ifdefs.Count - 1;
                        if (index < 0)
                        {
                            reader.Close();
                            writer.Close();
                            throw new Exception("unexpected #endif. file: " + filePath + ". linenumber: " + filelinenumber);
                        }
                        //remove current if scope
                        ifdefs.RemoveAt(index);
                        break;
                }
            }
            reader.Close();
            writer.Flush();
            ppFile.resetPosition();
            return true;
        }
        public static bool PerformPreProcessFile(string filePath, List <PreProcessFile> ppFiles, List <preprocessFile_IfDefModes> ifdefs = null, string name = "", Dictionary <string, PPDefine> defines = null)
        {
            if (name == "")
            {
                name = filePath.Substring(filePath.LastIndexOf('\\') + 1);
            }
            if (ifdefs == null)
            {
                ifdefs = new List <preprocessFile_IfDefModes>();
            }
            if (defines == null)
            {
                defines = new Dictionary <string, PPDefine>();
            }
            //Open given file
            StreamReader   reader = new StreamReader(filePath);
            PreProcessFile ppFile = new PreProcessFile(filePath, name);

            if (ppFiles != null)
            {
                ppFiles.Add(ppFile);
            }
            StreamWriter writer = new StreamWriter(ppFile.FileStream);

            //Prepare some variables needed for the entire processing periode in this function
            string s;
            uint   filelinenumber = 0;

            while ((s = reader.ReadLine()) != null)
            {
                filelinenumber++;
                //skip empty lines
                if (string.IsNullOrWhiteSpace(s))
                {
                    writer.WriteLine();
                    continue;
                }
                //Remove left & right whitespaces and tabs from current string
                string sTrimmed = s.TrimStart();
                string leading  = s.Substring(0, s.Length - sTrimmed.Length);
                s = sTrimmed;
                if (s[0] != '#')
                {//Current line is no define, thus handle it normally (find & replace)
                 //Make sure we are not inside of an ifdef/ifndef that disallows further processing of following lines
                    int i = ifdefs.Count - 1;
                    if (i >= 0 && ifdefs[i] != preprocessFile_IfDefModes.TRUE)
                    {
                        continue;
                    }
                    try
                    {
                        //Let every define check if it is inside of current line
                        foreach (PPDefine def in defines.Values)
                        {
                            s = def.replace(s);
                        }
                    }
                    catch (Exception ex)
                    {
                        //Catch possible exceptions from define parsing
                        Logger.Error(string.Concat("Experienced some error while parsing existing defines. ", ex.Message, ". file: ", filePath, ". linenumber: ", filelinenumber));
                        reader.Close();
                        return(false);
                    }
                    writer.WriteLine(leading + s);
                    continue;
                }
                //We DO have a define here
                //get end of the define name
                int spaceIndex = s.IndexOf(' ');
                if (spaceIndex < 0)
                {
                    spaceIndex = s.Length;
                }
                //set some required variables for the switch
                int index  = -1;
                int index2 = -1;
                //get text AFTER the define
                string afterDefine = s.Substring(spaceIndex).TrimStart();

                writer.WriteLine();

                //Check which define was used
                switch (s.Substring(0, spaceIndex))
                {
                default:
                    throw new Exception("Encountered unknown define '" + s.Substring(0, spaceIndex) + "'");

                case "#include":
                    //We are supposed to include a new file at this spot so lets do it
                    //Beautify the filepath so we can work with it
                    afterDefine.Trim();
                    string newFile;
                    newFile = afterDefine.Trim(new char[] { '"', '\'', ' ' });
                    //make sure we have no self reference here
                    if (newFile.Equals(filePath, StringComparison.OrdinalIgnoreCase))
                    {
                        //Ohhh no ... some problem in OSI layer 8
                        reader.Close();
                        writer.Close();
                        throw new Exception("Include contains self reference. file: " + filePath + ". linenumber: " + filelinenumber);
                    }
                    //process the file before continuing with this
                    try
                    {
                        if (!PerformPreProcessFile(newFile, ppFiles, ifdefs, afterDefine.Trim(new char[] { '<', '>', '"', '\'', ' ' }), defines))
                        {
                            //A sub file encountered an error, so stop here to prevent useles waste of ressources
                            reader.Close();
                            writer.Close();
                            return(false);
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception(e.Message + ", from " + filePath);
                    }
                    break;

                case "#define":
                    //The user wants to define something here
                    while (s.EndsWith("\\"))
                    {
                        writer.WriteLine();
                        afterDefine += reader.ReadLine();
                        filelinenumber++;
                    }
                    //Get the two possible characters index that can be encountered after a define
                    index  = afterDefine.IndexOf(' ');
                    index2 = afterDefine.IndexOf('(');
                    //check which one is found first
                    if (index < 0 || (index2 < index && index2 >= 0))
                    {
                        index = afterDefine.IndexOf('(');
                    }
                    //check that we really got a define with a value here, if not just take the entire length as no value is needed and only value provided
                    if (index < 0)
                    {
                        index = afterDefine.Length;
                    }
                    if (defines.ContainsKey(afterDefine.Substring(0, index)))
                    {
                        //Redefining something is not allowed, so throw an error here
                        reader.Close();
                        writer.Close();
                        throw new Exception("Redefining a define is not allowed! Use #undefine to undef something. file: " + filePath + ". linenumber: " + filelinenumber);
                    }
                    //FINALLY add the define
                    defines.Add(afterDefine.Substring(0, index), new PPDefine(afterDefine));
                    break;

                case "#undefine":
                    //just remove straigth
                    defines.Remove(s.Substring(spaceIndex).Trim());
                    break;

                case "#ifdef":
                    //do required stuff for define ifs
                    if (defines.ContainsKey(afterDefine))
                    {
                        ifdefs.Add(ifdefs.Count == 0 || ifdefs[ifdefs.Count - 1] == preprocessFile_IfDefModes.TRUE ? preprocessFile_IfDefModes.TRUE : preprocessFile_IfDefModes.IGNORE);
                    }
                    else
                    {
                        ifdefs.Add(ifdefs.Count == 0 || ifdefs[ifdefs.Count - 1] == preprocessFile_IfDefModes.TRUE ? preprocessFile_IfDefModes.FALSE : preprocessFile_IfDefModes.IGNORE);
                    }
                    break;

                case "#ifndef":
                    //do required stuff for define ifs
                    if (defines.ContainsKey(afterDefine))
                    {
                        ifdefs.Add(ifdefs.Count == 0 || ifdefs[ifdefs.Count - 1] == preprocessFile_IfDefModes.TRUE ? preprocessFile_IfDefModes.FALSE : preprocessFile_IfDefModes.IGNORE);
                    }
                    else
                    {
                        ifdefs.Add(ifdefs.Count == 0 || ifdefs[ifdefs.Count - 1] == preprocessFile_IfDefModes.TRUE ? preprocessFile_IfDefModes.TRUE : preprocessFile_IfDefModes.IGNORE);
                    }
                    break;

                case "#else":
                    //do required stuff for define ifs
                    index = ifdefs.Count - 1;
                    if (index < 0)
                    {
                        reader.Close();
                        writer.Close();
                        throw new Exception("unexpected #else. file: " + filePath + ". linenumber: " + filelinenumber);
                    }
                    //swap the value of currents if scope to the correct value
                    ifdefs[index] = (ifdefs[index] == preprocessFile_IfDefModes.TRUE ? preprocessFile_IfDefModes.FALSE : (ifdefs[index] == preprocessFile_IfDefModes.FALSE ? preprocessFile_IfDefModes.TRUE : preprocessFile_IfDefModes.IGNORE));
                    break;

                case "#endif":
                    //do required stuff for define ifs
                    index = ifdefs.Count - 1;
                    if (index < 0)
                    {
                        reader.Close();
                        writer.Close();
                        throw new Exception("unexpected #endif. file: " + filePath + ". linenumber: " + filelinenumber);
                    }
                    //remove current if scope
                    ifdefs.RemoveAt(index);
                    break;
                }
            }
            reader.Close();
            writer.Flush();
            ppFile.resetPosition();
            return(true);
        }