private void ReadInstance(XDLInstance inst, char c, StreamReader sr, ref int charIndex)
 {
     inst.AddCode(c);
     while (c != ';')
     {
         c = (char)sr.Read(); charIndex++;
         inst.AddCode(c);
     }
 }
        public static XDLInstance ExtractInstance(string instanceCode)
        {
            instanceCode = Regex.Replace(instanceCode, @"^\s*", "");

            List <string> atoms = SplitLine(instanceCode);

            // extract instance
            XDLInstance inst = new XDLInstance();

            inst.Name      = Regex.Replace(atoms[1], "\"", "");
            inst.SliceType = Regex.Replace(atoms[2], "\"", "");

            for (int i = 0; i < atoms.Count; i++)
            {
                if (atoms[i].Equals("placed"))
                {
                    int      index         = i + 1;
                    string[] locationAtoms = atoms[index].Split('X', 'Y');
                    inst.LocationX = int.Parse(locationAtoms[locationAtoms.Length - 2]);
                    inst.LocationY = int.Parse(locationAtoms[locationAtoms.Length - 1]);
                    inst.Location  = atoms[index];

                    inst.SliceName = atoms[index + 1];
                    break;
                }
            }
            // fields TileKey can only be set if the target FPGA is loaded,
            // they will be set on first get

            inst.AddCode(instanceCode);

            return(inst);
        }
        public override void ParseDesign(NetlistContainer nlc, Command caller)
        {
            XDLContainer xdlContainer = (XDLContainer)nlc;

            bool        readNet      = false;
            bool        readDesign   = false;
            bool        readModule   = false;
            bool        readInstance = false;
            XDLNet      net          = null;
            XDLInstance inst         = null;
            XDLModule   module       = null;

            char[] buffer       = new char[1];
            bool   pendingQuote = false;

            StringBuilder designConfig = new StringBuilder();
            StringBuilder lineBuffer   = new StringBuilder();

            Regex anchorMatch     = new Regex("^\".*\"$", RegexOptions.Compiled);
            Regex whiteSpaceMatch = new Regex(@"\s+", RegexOptions.Compiled);

            FileInfo fi     = new FileInfo(m_fileName);
            int      length = (int)fi.Length;
            char     c      = ' ';

            char[] modReferenceBuffer      = new char[2048];
            int    modReferenceBufferIndex = 0;

            char[] keyWordBuffer      = new char[2048];
            int    keyWordBufferIndex = 0;

            char[] locationBuffer = new char[2048];
            char[] fromBuffer     = new char[32];
            char[] toBuffer       = new char[32];

            StreamReader sr = new StreamReader(m_fileName);

            int charIndex = 0;

            while (charIndex < length)
            {
                // get next char
                c = (char)sr.Read(); charIndex++;

                // measure progress
                if (caller != null)
                {
                    caller.ProgressInfo.Progress = (int)((double)charIndex / (double)length * 100);
                }

                // skip comments
                while (c == '#' && !readNet && !readInstance && !readDesign && !readModule)
                {
                    while (true)
                    {
                        c = (char)sr.Read();
                        charIndex++;
                        if (c == '\n')
                        {
                            break;
                        }
                    }
                    c = (char)sr.Read(); charIndex++;
                }

                if (readNet)
                {
                    ReadNet(net, c, sr, ref charIndex, length, caller);
                    readNet = false;
                    if (readModule)
                    {
                        module.Add(net);
                    }
                    else
                    {
                        xdlContainer.Add(net);
                    }
                    lineBuffer.Clear();
                }
                else if (readInstance)
                {
                    ReadInstance(inst, c, sr, ref charIndex);
                    readInstance = false;

                    if (readModule)
                    {
                        module.Add(inst);
                    }
                    else
                    {
                        xdlContainer.Add(inst);
                    }
                    lineBuffer.Clear();
                }
                else
                {
                    keyWordBufferIndex = 0;

                    switch (c)
                    {
                    case 'n':
                        // read everything until first comma outside quotes
                        // net "Inst_PE/Mmult_OPA[31]_OPB[31]_MuLt_18_OUT_OPA,OPB<10>_x_OPA,OPB<62>_mand1_FRB"
                        pendingQuote = false;
                        keyWordBuffer[keyWordBufferIndex++] = c;
                        while (true)
                        {
                            //c = (char)byteBuffer[charIndex++];
                            c = (char)sr.Read(); charIndex++;
                            keyWordBuffer[keyWordBufferIndex++] = c;

                            if (c == '"')
                            {
                                pendingQuote = !pendingQuote;
                            }
                            if (c == ',' && !pendingQuote)
                            {
                                break;
                            }
                        }
                        readNet = true;
                        break;

                    case 'c':
                        // read everything until first ; outside quotes
                        // may appear anywhere and will be ignore (Jo)
                        //cfg "
                        //# _DESIGN_PROP:P3_PLACE_OPTIONS:EFFORT_LEVEL:high
                        //# _DESIGN_PROP::P3_PLACED:
                        //# _DESIGN_PROP::P3_PLACE_OPTIONS:
                        //# _DESIGN_PROP::PK_NGMTIMESTAMP:1397048215";
                        pendingQuote = false;
                        keyWordBuffer[keyWordBufferIndex++] = c;
                        while (true)
                        {
                            c = (char)sr.Read(); charIndex++;
                            keyWordBuffer[keyWordBufferIndex++] = c;
                            if (c == '"')
                            {
                                pendingQuote = !pendingQuote;
                            }
                            if (c == ';' && !pendingQuote)
                            {
                                break;
                            }
                        }
                        break;

                    case 'i':
                        // read two commas outside qoutes
                        // inst "Inst_PE/Mmult_OPA[31]_OPB[31]_MuLt_18_OUT_OPA,OPB<21>_x_OPA,OPB<62>_mand1_FRB" "SLICEL",placed CLBLM_X18Y191 SLICE_X27Y191  ,
                        pendingQuote = false;
                        int commas = 0;
                        keyWordBuffer[keyWordBufferIndex++] = c;
                        while (commas != 2)
                        {
                            //c = (char)byteBuffer[charIndex++];
                            c = (char)sr.Read();
                            charIndex++;
                            keyWordBuffer[keyWordBufferIndex++] = c;

                            if (c == '"')
                            {
                                pendingQuote = !pendingQuote;
                            }
                            if (c == ',' && !pendingQuote)
                            {
                                commas++;
                            }
                        }
                        readInstance = true;
                        break;

                    case 'd':
                        designConfig.Append(c);
                        while (true)
                        {
                            c = (char)sr.Read(); charIndex++;
                            designConfig.Append(c);
                            if (c == ';')
                            {
                                break;
                            }
                        }
                        string[] atoms = whiteSpaceMatch.Split(designConfig.ToString());
                        // do not modify name here
                        if (xdlContainer.DesignName == null)
                        {
                            xdlContainer.DesignName = Regex.Replace(atoms[1], "\"", "");
                            xdlContainer.Family     = (atoms.Length > 3 ? Regex.Replace(atoms[2], "\"", "") : "unknown");
                            xdlContainer.AddDesignConfig(designConfig.ToString());
                        }
                        else
                        {
                            caller.OutputManager.WriteWarning("Ignoring the device config as there is already a device name " + xdlContainer.DesignName + " present");
                        }
                        if (!FPGA.FPGA.Instance.DeviceName.ToString().Equals(xdlContainer.Family) && !xdlContainer.Family.Equals("unknown"))
                        {
                            // TODO wenn das obige if GARANTIERT "tut", dann kann man auch eine ArgumentException werden
                            caller.OutputManager.WriteWarning("The currenlty loaded device is " + FPGA.FPGA.Instance.DeviceName + ". However, the device specified in the currently parsed in netlist is " + xdlContainer.Family);
                        }

                        break;

                    case 'm':
                        module = new XDLModule();

                        readModule = true;
                        string moduleHeader = "";
                        moduleHeader += c;
                        while (true)
                        {
                            if (charIndex >= length)
                            {
                                throw new ArgumentException("Unexpected end of file while reading module. Missing endmodule statement?");
                            }

                            c             = (char)sr.Read(); charIndex++;
                            moduleHeader += c;
                            if (c == ';')
                            {
                                break;
                            }
                        }

                        moduleHeader = Regex.Replace(moduleHeader, @"^\s*", "");
                        string[] moduleAtoms = whiteSpaceMatch.Split(moduleHeader);
                        // extract module
                        module.Name = Regex.Replace(moduleAtoms[1], "\"", "");
                        module.Name = Regex.Replace(module.Name, ",", "");
                        // names is used as a key
                        xdlContainer.Add(module);

                        // extract explicit anchor
                        string anchor = moduleAtoms[2];
                        module.ExplicitAnchorFound = anchorMatch.IsMatch(anchor);
                        if (module.ExplicitAnchorFound)
                        {
                            module.Anchor = Regex.Replace(anchor, "\"", "");
                        }

                        break;

                    case 'p':
                        //port "H0" "SliceInstance" "A6";
                        ReadPort(module, c, sr, ref charIndex);
                        break;

                    case 'e':     // endmodule
                        while (true)
                        {
                            c = (char)sr.Read(); charIndex++;
                            if (c == ';')
                            {
                                break;
                            }
                        }
                        readModule = false;
                        break;
                    }

                    string s = new string(keyWordBuffer, 0, keyWordBufferIndex);

                    if (readNet)
                    {
                        net = new XDLNet();

                        net.Header = s;
                        List <string> atoms = SplitLine(s);
                        for (int i = 0; i < atoms.Count; i++)
                        {
                            if (atoms[i].Equals("net"))
                            {
                                net.Name = atoms[i + 1];
                                net.Name = net.Name.Replace("\"", "");
                                if (atoms.Count > i + 2)
                                {
                                    net.HeaderExtension = atoms[i + 2];
                                }
                                break;
                            }
                        }
                        lineBuffer.Clear();
                    }
                    else if (readInstance)
                    {
                        inst = new XDLInstance();
                        List <string> atoms = SplitLine(s);
                        inst.AddCode(s);
                        for (int i = 0; i < atoms.Count; i++)
                        {
                            if (atoms[i].Equals("inst"))
                            {
                                //inst.Name = Regex.Replace(atoms[i + 1], "\"", "");
                                inst.Name = atoms[i + 1];
                                inst.Name = inst.Name.Replace("\"", "");
                                //inst.SliceType = Regex.Replace(atoms[i + 2], "\"", "");
                                inst.SliceType = atoms[i + 2];
                                inst.SliceType = inst.SliceType.Replace("\"", "");
                            }
                            else if (atoms[i].Equals("placed"))
                            {
                                string[] locationAtoms = atoms[i + 1].Split('X', 'Y');
                                inst.LocationX = int.Parse(locationAtoms[locationAtoms.Length - 2]);
                                inst.LocationY = int.Parse(locationAtoms[locationAtoms.Length - 1]);
                                inst.Location  = atoms[i + 1];
                                inst.SliceName = atoms[i + 2];

                                break;
                            }
                        }

                        c = (char)sr.Read(); charIndex++;
                        if (c != 'm') // should be \r
                        {
                            inst.AddCode(c);
                        }
                        else
                        {
                            modReferenceBufferIndex = 0;
                            // consume module reference (will not become part of the module)
                            modReferenceBuffer[modReferenceBufferIndex++] = c;
                            while (true)
                            {
                                c = (char)sr.Read(); charIndex++;
                                modReferenceBuffer[modReferenceBufferIndex++] = c;
                                if (c == ',')
                                {
                                    break;
                                }
                            }
                            inst.ModuleReference = new string(modReferenceBuffer, 0, modReferenceBufferIndex);
                        }
                    }
                }
            }
            sr.Close();
        }